Changer de base de branche


145

J'ai un arbre comme celui-ci:

(commit 1) - master
                \-- (commit 2) - (commit 3) - demo
                                                \-- (commit 4) - (commit 5) - PRO

et je dois déplacer la branche PRO vers master

(commit 1) - master
                |-- (commit 2) - (commit 3) - demo
                \-- (commit 4) - (commit 5) - PRO

J'ai essayé une git rebase masterbranche PRO, mais rien ne se passe.

Pour clarifier : je travaillais en master puis j'ai dû faire une démo produit ( git checkout -b demoet quelques commits). Ensuite, par erreur, je crée une autre branche à partir de la démo ( git checkout -b PROet quelques commits) et maintenant je dois déplacer la branche PRO vers master et laisser la démo intacte. À la fin, la démo et PRO seront suspendus au maître.


Réponses:


283

Utilisez --ontopour cela:

git rebase --onto newBase oldBase feature/branch

Compte tenu de votre cas:

git checkout PRO # Just to be clear which branch to be on.
git rebase --onto master demo PRO

En gros, vous prenez tous les commits de suite demojusqu'à PRO, et les rebasage sur la mastervalidation.


Est-ce aussi la voie à suivre si la situation est inverse? == Je vérifie -b du master de la deuxième branche, mais je voulais le faire à partir de la première. Donc je l'ai fait git rebase --onto first-branch second-branch second-branchmais je ne comprends pas la syntaxe
Fla

1
@Fla dans ce cas, ce seraitgit rebase --onto first-branch master second-branch
nVitius

9
J'ai lu ce guide sur --onto, et comment ils ont écrit m'a aidégit rebase --onto newBase oldBase feature/branch
gabe

@PhilipRego C'est incorrect. origin/newBaseest le nom d'une branche, comme newBasedans mon exemple. Cela dépendrait simplement si vous rebasez sur une branche qui existe dans votre référentiel local ( newBase), ou une qui existe sur le remote ( origin/newBase).
loganfsmyth

@PhilipRego Ce ne sont pas des choses indépendantes. newBaseest le nom d'une succursale locale et origin/newBaseest le nom d'une succursale distante. Lequel vous voulez dépend de ce sur quoi vous vous référez. Ce n'est pas qu'on travaille et on ne fonctionne pas, c'est qu'ils rebasent sur différentes choses. La question d'origine ne mentionne jamais les télécommandes, donc l'utilisation de télécommandes dans mon exemple ne correspondrait pas à la question posée.
loganfsmyth

22

J'essaierai d'être aussi générique que possible. Tout d'abord, assurez-vous que vous êtes sur la branche souhaitée:

git checkout current-branch

Ensuite, utilisez la commande suivante (où new-base-branchest la branche que vous voulez être votre nouvelle base, et current-base-branchest la branche qui est votre base actuelle.)

git rebase --onto new-base-branch current-base-branch

Si vous n'avez pas de conflits, alors c'est parfait - vous avez terminé. Si vous le faites (dans la plupart des cas), veuillez lire la suite.

Des conflits peuvent survenir et vous devrez les résoudre manuellement. Git essaie maintenant de faire une "fusion à 3 voies" entre votre current-branch, current-base-branchet new-base-branch. En gros, voici comment git fonctionnera en interne:

  1. Git va d'abord rebaser current-base-branchle dessus du new-base-branch. Il pourrait y avoir des conflits; que vous devrez résoudre manuellement. Après cela, vous faites généralement git add .et git rebase --continue. Cela créera un nouveau commit temporaire temp-commit-hashpour cela.

  2. Après cela, Git va maintenant rebaser votre current-branchdessus temp-commit-hash. Il peut y avoir d'autres conflits et encore une fois, vous devrez les résoudre manuellement. Une fois cela fait, vous continuez avec git add .et git rebase --continue, après quoi vous avez rebasé avec succès votre current-branchsur le dessus du new-base-branch.


Remarque: si vous commencez à gâcher, vous pouvez le faire à git rebase --aborttout moment pendant le processus de rebase et revenir au point de départ.


La rebasecommande telle que publiée me donne juste "fatal: invalid upstream 'current-base-branch'". Aussi, pourquoi est-il même nécessaire de dire à GIT quelle est la branche parente actuelle de la branche actuelle - ne devrait-il pas déjà le savoir?
Matt Arnold le

22

Checkout to PRObranch, Copiez les hachages de commit les plus anciens ( commit4 ) et les derniers ( commit5 ) de cette branche et collez ailleurs:

$ git checkout PRO
$ git log            # see the commit history
# copy the oldest & latest commit-hash 

Supprimez la PRObranche (gardez une sauvegarde juste pour la sécurité). Créez et passez à une nouvelle PROsuccursale à partir de master:

$ git branch PRO.bac    # create a new branch PRO.bac = PRO as backup

$ git checkout master
$ git branch -D PRO     # delete the local PRO branch
$ git checkout -b PRO   # create and checkout to a new 'PRO' branch from 'master'

Prenez ( choisissez en cerisier ) la plage de commits de la PRObranche précédente dans la nouvelle PRObranche:

$ git cherry-pick commit4^..commit5   # cherry-pick range of commits
# note the '^' after commit4

Maintenant, si tout va bien, alors forcez (-f) push to remote PRObranch et supprimez la PRO.bacbranche locale :

$ git log                  # check the commit history

$ git push -f origin HEAD  # replace the remote PRO by local PRO branch history
# git branch -D PRO.bac    # delete local PRO.bac branch

1

J'avais une approche légèrement différente en utilisant la réinitialisation et les stashes qui évite de supprimer et de recréer des branches ainsi que d'éliminer le besoin de changer de branche:

$ git checkout PRO
$ git reset commit4 # This will set PROs HEAD to be at commit 4, and leave the modified commit 5 files in ur working index
$ git stash save -m "Commit message"
$ git reset commit 3
$ git stash save -m "Commit message"
$ git reset master --hard
$ git stash pop
$ git stash pop
$ git push --force # force if its already been push remotely

En réinitialisant la branche sur une base de validation par validation, vous ne faites que rembobiner l'historique des branches une validation à la fois.


Devez-vous supprimer l'espace entre "commit" et "3" sur la 4ème ligne?
Alexis Wilke
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.