web-dev-qa-db-fra.com

Comment puis-je prévisualiser une fusion dans git?

J'ai une branche git (la ligne principale, par exemple) et je souhaite fusionner dans une autre branche de développement. Ou je

Afin de décider si je veux vraiment fusionner cette branche, j'aimerais voir un aperçu de ce que la fusion va faire. De préférence avec la possibilité de voir la liste des commits appliqués.

Jusqu'ici, le mieux que je puisse trouver est merge --no-ff --no-commit, puis diff HEAD.

354
Glenjamin

J'ai trouvé que la solution qui me convient le mieux est de effectuez simplement la fusion et annulez-la si vous n'aimez pas les résultats. Cette syntaxe particulière me semble propre et simple. Si vous voulez vous assurer de ne pas gâcher votre branche actuelle, ou si vous n'êtes pas prêt à fusionner, indépendamment de l'existence de conflits, créez simplement une nouvelle sous-branche et fusionnez-la.

Stratégie 1: le moyen sûr de fusionner une branche temporaire:

git checkout mybranch
git checkout -b mynew-temporary-branch
git merge some-other-branch

De cette façon, vous pouvez simplement jeter la branche temporaire si vous voulez juste voir quels sont les conflits. Vous n'avez pas besoin de vous soucier "d'abandonner" la fusion et vous pouvez revenir à votre travail - il vous suffit de cocher à nouveau "mybranch" et vous n'aurez pas de code fusionné ni de conflit de fusion dans votre branche.

Ceci est fondamentalement une piste sèche.

Stratégie 2: Quand vous voulez vraiment fusionner, mais seulement s'il n'y a pas de conflits

git checkout mybranch
git merge some-other-branch

Si git signale des conflits (et UNIQUEMENT EN CAS DE conflits), vous pouvez alors:

git merge --abort

Si la fusion réussit, vous ne pouvez pas l'annuler (réinitialiser uniquement).

Si vous n'êtes pas prêt à fusionner, utilisez la méthode plus sûre ci-dessus.

[EDIT: 2016-novembre - J'ai échangé la stratégie 1 pour 2, car il semble que la plupart des gens recherchent "le moyen le plus sûr". La stratégie 2 est maintenant plus une note que vous pouvez simplement abandonner la fusion si la fusion a des conflits que vous n'êtes pas prêt à traiter. Gardez à l'esprit si vous lisez des commentaires!]

248
Kasapo
  • git log ..otherbranch
    • liste des modifications qui seront fusionnées dans la branche actuelle.
  • git diff ...otherbranch
    • diff de l'ancêtre commun (base de fusion) à la tête de ce qui sera fusionné. Notez les trois points, qui ont une signification particulière comparée à deux points (voir ci-dessous).
  • gitk ...otherbranch
    • représentation graphique des branches depuis leur fusion la dernière fois.

Une chaîne vide implique HEAD, alors c'est pourquoi ..otherbranch au lieu de HEAD..otherbranch.

La différence entre les points et les trois points a une signification légèrement différente de celle des commandes qui répertorient les révisions (log, gitk, etc.). Pour log et autres, deux points (a..b) signifient tout ce qui se trouve dans b mais pas a et trois points (a...b) signifient tout ce qui ne figure que dans l'un des a ou b. Mais diff fonctionne avec deux révisions et le cas le plus simple représenté par deux points (a..b) est simple différence de a à b et trois points (a...b) différence moyenne entre ancêtre commun et b (git diff $(git merge-base a b)..b).

375
Jan Hudec

Si vous êtes comme moi, vous recherchez un équivalent de svn update -n. Ce qui suit semble faire l'affaire. Notez que vous devez d'abord faire un git fetch afin que votre référentiel local dispose des mises à jour appropriées pour la comparaison.

$ git fetch Origin
$ git diff --name-status Origin/master
D       TableAudit/Step0_DeleteOldFiles.sh
D       TableAudit/Step1_PopulateRawTableList.sh
A       manbuild/staff_companies.sql
M       update-all-slave-dbs.sh

ou si vous voulez un diff de votre tête à la télécommande:

$ git fetch Origin
$ git diff Origin/master

OMI, cette solution est beaucoup plus facile et moins sujette aux erreurs (et donc beaucoup moins risquée) que la solution la plus avancée qui propose une "fusion puis un abandon".

18
djschny

Si vous avez déjà récupéré les modifications, mon préféré est:

git log ...@{u}

Cela nécessite git 1.7.x Je crois cependant. La notation @{u} est un "raccourci" pour la branche en amont, elle est donc un peu plus polyvalente que git log ...Origin/master.

Remarque: Si vous utilisez zsh et le mécanisme Glog étendu, vous devrez probablement faire quelque chose comme:

git log ...@\{u\}

En ajoutant aux réponses existantes, un alias pourrait être créé pour afficher le diff et/ou le journal avant une fusion. Beaucoup de réponses omettent la fetch à faire avant de "prévisualiser" la fusion; c'est un alias qui combine ces deux étapes en une seule (en émulant quelque chose de similaire à hg incoming/outgoing de Mercurial _)

En vous appuyant sur "git log ..otherbranch", vous pouvez ajouter ce qui suit à ~/.gitconfig:

...
[alias]
    # fetch and show what would be merged (use option "-p" to see patch)
    incoming = "!git remote update -p; git log ..@{u}"

Pour la symétrie, l'alias suivant peut être utilisé pour montrer ce qui est engagé et serait poussé, avant de pousser:

    # what would be pushed (currently committed)
    outgoing = log @{u}..

Ensuite, vous pouvez exécuter "git incoming" pour afficher de nombreuses modifications ou "git incoming -p" pour afficher le patch (c'est-à-dire le "diff"), "git incoming --pretty=oneline", par exemple. Résumé succinct, etc. Vous pouvez ensuite (éventuellement) exécuter "git pull" "pour fusionner. (Cependant, puisque vous avez déjà récupéré, la fusion pourrait être faite directement.)

De même, "git outgoing" indique ce qui serait poussé si vous exécutiez "git Push".

6
michael

La plupart des réponses ici nécessitent soit un répertoire de travail propre et plusieurs étapes interactives (mauvais pour les scripts), soit ne fonctionnent pas dans tous les cas, par exemple. les fusions passées qui apportent déjà certains des changements en suspens dans votre branche cible, ou les choix identiques qui font de même.

Pour vraiment voir ce qui changerait dans la branche master si vous y intégriez develop, maintenant:

git merge-tree $(git merge-base master develop) master develop

Comme il s’agit d’une commande de plomberie, elle ne comprend pas ce que vous voulez dire, vous devez être explicite. De plus, il ne colorise pas la sortie et n’utilise pas votre pageur. La commande complète serait:

git merge-tree $(git merge-base master develop) master develop | colordiff | $(git var GIT_PAGER)

- https://git.seveas.net/previewing-a-merge-result.html

(merci à David Normington pour le lien)

P.S .:

Si vous obtenez des conflits de fusion, ils apparaîtront avec les marqueurs de conflit habituels dans la sortie, par exemple:

$ git merge-tree $(git merge-base a b ) a b 
added in both
  our    100644 78981922613b2afb6025042ff6bd878ac1994e85 a
  their  100644 61780798228d17af2d34fce4cfbdf35556832472 a
@@ -1 +1,5 @@
+<<<<<<< .our
 a
+=======
+b
+>>>>>>> .their

P.S. 2: sur ma machine (Vanilla Mac OS X), la ligne GIT_PAGER finit par utiliser less, qui n'aime pas les entrées en couleur. Je devais ajouter export LESS=FRX à mon ~/.bashrc pour le rendre acceptable. Merci à https://unix.stackexchange.com/questions/153943/git-pager-is-less-but- what-is-causing-the-output-coloring

4
hraban

Requête de tirage - J'ai utilisé la plupart des idées déjà soumises, mais celle que j'utilise souvent (en particulier si elles proviennent d'un autre développeur) est une requête de tirage qui donne un moyen pratique de passer en revue tous les changements de fusion avant qu'ils ne prennent. endroit. Je sais que ce n'est pas GitHub Git mais c'est certainement pratique.

3
G-Man

git log currentbranch..otherbranch vous donnera la liste des commits qui iront dans la branche courante si vous effectuez une fusion. Les arguments habituels de journalisation qui donnent des détails sur les commits vous donneront plus d’informations.

git diff currentbranch otherbranch vous donnera le diff entre les deux commits qui deviendront un. Ce sera un diff qui vous donnera tout ce qui va être fusionné.

Est-ce que cela aiderait?

3
Noufal Ibrahim

À moins de réaliser la fusion à la volée (voir la réponse de Kasapo), il ne semble pas y avoir de moyen fiable de voir cela.

Cela dit, voici une méthode qui se rapproche un peu:

git log TARGET_BRANCH...SOURCE_BRANCH --cherry

Cela donne une bonne indication de ce que les commits feront dans la fusion. Pour voir les diffs, ajoutez -p. Pour voir les noms de fichier, ajoutez l'un des éléments suivants: --raw, --stat, --name-only, --name-status.

Le problème avec l'approche git diff TARGET_BRANCH...SOURCE_BRANCH (voir la réponse de Jan Hudec) est que vous verrez des différences pour les modifications déjà effectuées dans votre branche cible si votre branche source contient des fusions croisées.

2
antak

Peut-être que cela peut vous aider ? git-diff-tree - Compare le contenu et le mode des blobs trouvés via deux objets d'arborescence

1
Chugaister

Je ne souhaite pas utiliser la commande git merge comme précurseur de la révision de fichiers en conflit. Je ne veux pas faire de fusion, je veux identifier les problèmes potentiels avant de fusionner - des problèmes que la fusion automatique pourrait masquer à moi. La solution que je cherchais est de savoir comment faire écrire à git une liste de fichiers qui ont été modifiés dans les deux branches et qui seront fusionnés à l’avenir, par rapport à un ancêtre commun. Une fois que je dispose de cette liste, je peux utiliser d'autres outils de comparaison de fichiers pour approfondir la recherche. J'ai effectué plusieurs recherches et je n'ai toujours pas trouvé ce que je voulais dans une commande git native.

Voici ma solution de contournement, au cas où cela aiderait quelqu'un d'autre:

Dans ce scénario, une branche appelée QA comporte de nombreux changements depuis la dernière version de production. Notre dernière version de production porte la mention "15.20.1". J'ai une autre branche de développement appelée new_stuff que je souhaite fusionner dans la branche QA. QA et new_stuff indiquent tous deux que "suit" (comme indiqué par gitk) la balise 15.20.1.

git checkout QA
git pull
git diff 15.20.1 --name-only > QA_files
git checkout new_stuff
git pull
git diff 15.20.1 --name-only > new_stuff_files
comm -12 QA_files new_stuff_files

Voici quelques discussions qui expliquent pourquoi je suis intéressé par ces fichiers spécifiques:

Comment puis-je faire confiance à la fusion de Git?

https://softwareengineering.stackexchange.com/questions/199780/how-far-do-you-trust-automerge

0
Laura