D'une certaine manière, mon maître et ma branche origine / maître ont divergé.
En fait, je ne veux pas qu'ils divergent.
Comment puis-je voir ces différences et les «fusionner»?
D'une certaine manière, mon maître et ma branche origine / maître ont divergé.
En fait, je ne veux pas qu'ils divergent.
Comment puis-je voir ces différences et les «fusionner»?
Réponses:
Vous pouvez revoir les différences avec:
git log HEAD..origin/master
avant de le tirer (fetch + merge) (voir aussi "Comment faire pour que git tire toujours depuis une branche spécifique?" )
Lorsque vous avez un message comme:
"Votre branche et 'origine / maître' ont divergé, # et ont respectivement 1 et 1 commit (s) différent (s)."
, vérifiez si vous devez mettre à jourorigin
. Si origin
est à jour, certaines validations ont été transférées origin
depuis un autre référentiel pendant que vous effectuez vos propres validations localement.
... o ---- o ---- A ---- B origin/master (upstream work)
\
C master (your work)
Vous avez basé le commit C sur le commit A car c'était le dernier travail que vous aviez récupéré en amont à l'époque.
Cependant, avant que vous n'essayiez de repousser à l'origine, quelqu'un d'autre a poussé la validation B.
L'historique du développement a divergé dans des chemins distincts.
Vous pouvez ensuite fusionner ou rebaser. Voir Pro Git: Git Branching - Rebasing pour plus de détails.
Fusionner
Utilisez la commande git merge:
$ git merge origin/master
Cela indique à Git d'intégrer les modifications de origin/master
dans votre travail et de créer un commit de fusion.
Le graphique de l'histoire ressemble maintenant à ceci:
... o ---- o ---- A ---- B origin/master (upstream work)
\ \
C ---- M master (your work)
La nouvelle fusion, commit M, a deux parents, chacun représentant un chemin de développement qui a conduit au contenu stocké dans ce commit.
Notez que l'historique derrière M est désormais non linéaire.
Rebase
Utilisez la commande git rebase:
$ git rebase origin/master
Cela indique à Git de rejouer la validation C (votre travail) comme si vous l'aviez basée sur la validation B au lieu de A. Les utilisateurs
CVS et Subversion rebasinent régulièrement leurs modifications locales au-dessus du travail en amont lorsqu'ils mettent à jour avant la validation.
Git ajoute simplement une séparation explicite entre les étapes de validation et de rebase.
Le graphique de l'histoire ressemble maintenant à ceci:
... o ---- o ---- A ---- B origin/master (upstream work)
\
C' master (your work)
Commit C 'est un nouveau commit créé par la commande git rebase.
Il diffère de C de deux manières:
Notez que l'histoire derrière C 'est toujours linéaire.
Nous avons choisi (pour l'instant) de n'autoriser que l'histoire linéaire dans cmake.org/cmake.git
.
Cette approche préserve le workflow basé sur CVS utilisé précédemment et peut faciliter la transition.
Une tentative de pousser C 'dans notre référentiel fonctionnera (en supposant que vous avez des autorisations et que personne n'a poussé pendant que vous rebasiez).
La commande git pull fournit un moyen raccourci pour récupérer à partir de l'origine et rebaser le travail local dessus:
$ git pull --rebase
Ceci combine les étapes de récupération et de rebase ci-dessus en une seule commande.
git reset --hard HEAD
ne ferait que supprimer toute modification non indexée commis locale, et ne ferait rien pour concilier les différences entre les locaux et distants commits . Seule une fusion ou un rebase rapprochera les deux ensembles de commits (le local et le distant).
master
montrer B
votre exemple.
git reset --hard origin/master
comme mentionné dans la réponse ci-dessous: stackoverflow.com/a/8476004/6309
J'ai eu cela et je suis mystifié de ce qui l'a causé, même après avoir lu les réponses ci-dessus. Ma solution était de faire
git reset --hard origin/master
Ensuite, cela réinitialise simplement ma copie (locale) de master (que je suppose vissée) au bon point, comme représenté par origine / master (distant).
AVERTISSEMENT : vous perdrez toutes les modifications non encore poussées
origin/master
.
git reflog
ou les voir dedans gitk --all
. Mais pourtant, bien sûr, la réinitialisation matérielle est autre chose qu'un rebase.
git pull --rebase origin/master
est une commande unique qui peut vous aider la plupart du temps.
Modifier: extrait les validations de l'origine / du masque et applique vos modifications à l'historique de branche nouvellement extrait.
Je me suis retrouvé dans cette situation lorsque j'ai essayé de rebaser une branche qui suivait une branche distante, et j'essayais de la rebaser sur master. Dans ce scénario, si vous essayez de rebaser, vous trouverez très probablement que votre branche a divergé et cela peut créer un gâchis qui n'est pas pour les git nubees!
Disons que vous êtes sur la branche my_remote_tracking_branch, qui a été branchée à partir de master
$ git status
# Sur la branche my_remote_tracking_branch
rien à valider (répertoire de travail propre)
Et maintenant, vous essayez de rebaser du maître en tant que:
git rebase master
ARRÊTEZ MAINTENANT et épargnez-vous des ennuis! Utilisez plutôt la fusion comme:
git merge master
Oui, vous vous retrouverez avec des commits supplémentaires sur votre branche. Mais à moins que vous ne souhaitiez des branches "non divergentes", ce sera un flux de travail beaucoup plus fluide que le rebasage. Voir ce blog pour une explication beaucoup plus détaillée.
D'un autre côté, si votre branche est uniquement une branche locale (c'est-à-dire qu'elle n'est pas encore envoyée à une télécommande), vous devez certainement faire un rebase (et votre branche ne divergera pas dans ce cas).
Maintenant , si vous lisez ceci parce que vous avez déjà êtes dans un scénario « divergé » en raison de ce changement de base, vous pouvez revenir à la dernière validation d'origine ( par exemple dans un état divergé non) en utilisant:
git reset --hard origin / my_remote_tracking_branch
rebase
si la branche que vous rebasez n'a pas été publiée (et utilisée par d'autres personnes). Sinon, utilisez merge
. Si vous rebasez des branches déjà publiées (et utilisées), vous devez coordonner un complot pour réécrire l'historique de tous les développeurs qui ont utilisé votre branche.
git rebase master
...
git reset --hard origin/my_remote_tracking_branch
est ce qui a vraiment fonctionné
Dans mon cas, voici ce que j'ai fait pour provoquer le message divergé : je l'ai fait git push
mais j'ai ensuite git commit --amend
ajouté quelque chose au message de validation. Ensuite, j'ai également fait un autre commit.
Dans mon cas, cela signifiait simplement que l'origine / le maître était obsolète. Parce que je savais que personne d'autre ne touchait origine / maître, la correction était triviale: git push -f
(où -f
signifie forcer)
git push -f
écraser les modifications précédemment validées et transmises à l'origine. Je suis également sûr que personne d'autre n'a touché le référentiel.
Dans mon cas, j'ai poussé les modifications vers origin/master
puis j'ai réalisé que je n'aurais pas dû le faire :-( Cela a été compliqué par le fait que les modifications locales étaient dans un sous-arbre. Je suis donc retourné au dernier bon commit avant le "mauvais" local. changements (en utilisant SourceTree) puis j'ai reçu le "message de divergence".
Après avoir corrigé mon désordre localement (les détails ne sont pas importants ici), je voulais "remonter dans le temps" la origin/master
branche distante afin qu'elle soit à nouveau synchronisée avec le local master
. La solution dans mon cas était:
git push origin master -f
Notez l' -f
interrupteur (force). Cela a supprimé les «mauvais changements» qui avaient été poussés origin/master
par erreur et maintenant les branches locales et distantes sont synchronisées.
Veuillez garder à l'esprit qu'il s'agit d'une opération potentiellement destructrice. N'effectuez-la donc que si vous êtes sûr à 100% que "reculer" le maître distant à temps est OK.
You are not allowed to force push code to a protected branch on this project.
. J'essaye de pousser jusqu'à ma fourchette.
Je sais qu'il y a beaucoup de réponses ici, mais je pense qu'il git reset --soft HEAD~1
mérite une certaine attention, car cela vous permet de conserver les modifications dans le dernier commit local (non poussé) tout en résolvant l'état divergent. Je pense que c'est une solution plus polyvalente que de tirer avec rebase
, car le commit local peut être revu et même déplacé vers une autre branche.
La clé utilise --soft
, au lieu de la dure --hard
. S'il y a plus d'un commit, une variation de HEAD~x
devrait fonctionner. Voici donc toutes les étapes qui ont résolu ma situation (j'ai eu 1 commit local et 8 commits dans la télécommande):
1) git reset --soft HEAD~1
pour annuler la validation locale. Pour les étapes suivantes, j'ai utilisé l'interface de SourceTree, mais je pense que les commandes suivantes devraient également fonctionner:
2) git stash
pour cacher les modifications de 1). Maintenant, tous les changements sont sûrs et il n'y a plus de divergence.
3) git pull
pour obtenir les modifications à distance.
4) git stash pop
ou git stash apply
pour appliquer les dernières modifications cachées, suivies d'une nouvelle validation, si vous le souhaitez. Cette étape est facultative, avec 2) , lorsque vous souhaitez supprimer les modifications dans la validation locale. En outre, lorsque vous souhaitez vous engager dans une autre branche, cette étape doit être effectuée après le passage à la branche souhaitée.
pull --rebase
serait caché automatiquement de toute façon. stackoverflow.com/a/30209750/6309
Pour voir les différences:
git difftool --dir-diff master origin/master
Cela affichera les changements ou les différences entre les deux branches. Dans araxis (My favorite), il l'affiche dans un style de dossier différent. Affichage de chacun des fichiers modifiés. Je peux ensuite cliquer sur un fichier pour voir les détails des modifications dans le fichier.
Dans mon cas, cela a été causé par le fait de ne pas avoir engagé ma résolution de conflit.
Le problème est dû à l'exécution de la git pull
commande. Des changements d'origine ont entraîné des conflits avec mon référentiel local, que j'ai résolu. Cependant, je ne les ai pas commis. La solution à ce stade est de valider les modifications ( git commit
le fichier résolu)
Si vous avez également modifié certains fichiers depuis la résolution du conflit, la git status
commande affichera les modifications locales en tant que modifications locales non étagées et fusionnera la résolution en tant que modifications locales étagées. Cela peut être résolu correctement en validant les modifications de la fusion d'abord par git commit
, puis en ajoutant et en validant les modifications non programmées comme d'habitude (par exemple par git commit -a
).
J'ai eu le même message lorsque j'essayais de modifier le dernier message de validation, de validation déjà poussée, en utilisant: git commit --amend -m "New message"
Lorsque j'ai poussé les modifications en utilisant, git push --force-with-lease repo_name branch_name
il n'y avait aucun problème.
J'ai rencontré ce problème lorsque j'ai créé une branche basée sur la branche A par
git checkout -b a
puis je mets le flux ascendant de la branche a à la branche d'origine B par
git branch -u origin/B
Ensuite, j'ai reçu le message d'erreur ci-dessus.
Une façon de résoudre ce problème pour moi était,
git checkout -b b origin/B