Utilisation de Git comment trouver les changements entre local et distant

152

Voici deux questions différentes mais je pense qu'elles sont liées.

  1. Lorsque j'utilise Git, comment trouver les modifications que j'ai validées localement, mais que je n'ai pas encore poussées vers une branche distante? Je recherche quelque chose de similaire à la commande Mercurial hg outgoing.

  2. Lors de l'utilisation de Git, comment trouver les modifications apportées à une branche distante avant de faire un pull? Je recherche quelque chose de similaire à la commande Mercurial hg incoming.

Pour la seconde: y a-t-il un moyen de voir ce qui est disponible, puis de choisir les changements que je souhaite apporter?

ejunker
la source
11
En regardant les réponses, il semble y avoir une certaine confusion quant à ce que faire hg incominget à hg outgoingfaire réellement. L'équivalent Git le plus proche que j'ai trouvé est l' --dry-runoption. Juste git pull --dry-runet vous verrez une liste de toutes les choses qui doivent arriver.
Roman Starkov du

Réponses:

97

Git ne peut pas envoyer ce genre d'informations sur le réseau, comme le peut Hg. Mais vous pouvez exécuter git fetch(ce qui ressemble plus hg pullà hg fetch) pour récupérer de nouveaux commits depuis vos serveurs distants.

Donc, si vous avez une branche appelée masteret une télécommande appelée origin, après l'exécution git fetch, vous devriez également avoir une branche appelée origin/master. Vous pouvez alors obtenir le git logde tous les commits qui masterdoivent être un sur-ensemble de origin/masteren faisant git log master..origin/master. Inversez ces deux pour obtenir le contraire.

Un de mes amis, David Dollar, a créé quelques scripts shell git à simuler hg incoming/outgoing. Vous pouvez les trouver sur http://github.com/ddollar/git-utils .

Jordi Bunster
la source
113

À partir de Git 1.7.0, il existe une syntaxe spéciale qui vous permet de faire référence de manière générique à la branche amont: @{u}ou @{upstream}.

Pour imiter hg incoming:

git log ..@{u}

Pour imiter hg outgoing:

git log @{u}..

J'utilise ce qui suit incominget les outgoingalias pour rendre ce qui précède plus facile à utiliser:

git config --global alias.incoming '!git remote update -p; git log ..@{u}'
git config --global alias.outgoing 'log @{u}..'
Richard Hansen
la source
git log .. @ {u} me donne ces erreurs. (J'ai à la fois l'origine et un référentiel en amont dans ma configuration git). erreur: aucune branche amont trouvée pour '' erreur: aucune branche amont trouvée pour '..' erreur: aucune branche amont trouvée pour '..' fatale: argument ambigu '.. @ {u}': révision inconnue ou chemin absent l'arbre de travail. Utilisez '-' pour séparer les chemins des révisions
Henrik
6
Vous obtiendrez ces erreurs si votre succursale locale n'est pas configurée avec un en amont. Pour réparer, exécutez git branch --set-upstream foo origin/foo.
Richard Hansen
git log @{u}..répertorie chaque changement dans le repo pour moi. Il n'y a aucun moyen qu'ils n'existent pas encore.
Roman Starkov
@romkyns: Il est possible que votre branche locale ait la mauvaise branche distante configurée en amont. Assurez-vous d' git rev-parse --symbolic-full-name @{u}imprimer la référence distante appropriée. Aussi,git log @{u}.. les commits qui ne sont pas accessibles par la branche en amont, qui peuvent inclure des commits qui sont déjà dans le référentiel distant (s'ils sont accessibles par une référence différente). Cela se produira juste après la fusion dans une branche déjà poussée.
Richard Hansen
@RichardHansen J'ai peur de ne pas savoir ce qui serait approprié pour une référence à distance, mais il s'agissait d'un repo fraîchement cloné sur lequel je n'ai fait qu'un checkout <somebranch> et merge <otherbranch>. À ce stade, j'ai fait le log @{u}..et j'ai vu tous les changements répertoriés.
Roman Starkov
42

Ce n'est pas une réponse complète, mais git fetch tirera le dépôt distant et ne fera pas de fusion. Vous pouvez alors faire un

git diff master origin / master

Martin Redmond
la source
1
A travaillé pour moi (mais dans l'autre sens) -git diff origin/master master
Nick Grealy
34
  1. Utilisez "git log origin..HEAD"

  2. Utilisez "git fetch" suivi de "git log HEAD..origin". Vous pouvez sélectionner des validations individuelles à l'aide des ID de validation répertoriés.

Ce qui précède suppose, bien sûr, que "origin" est le nom de votre branche de suivi à distance (ce qui est le cas si vous avez utilisé le clonage avec les options par défaut).

Greg Hewgill
la source
3
(Et si vous ne suivez pas la branche distante, c'est "git log origin / master..HEAD".)
plindberg
4
"origine" n'est pas le nom de la branche de suivi à distance, c'est le nom de la télécommande. Et le simple fait de spécifier le nom distant ne fonctionne pas, vous devez spécifier la branche de suivi distant, qui serait origine / maître.
robinst
22

Il y a aussi ceci, pour comparer toutes les branches:

git log --branches --not --remotes=origin

Voici ce que dit la page de manuel de git log à ce sujet:

Affiche tous les commits qui se trouvent dans l'une des branches locales mais pas dans l'une des branches de suivi distantes pour l'origine (ce que vous avez cette origine ne le fait pas).

Ce qui précède est pour outgoing. Pour incoming, échangez simplement:

git log --remotes=origin --not --branches
robinst
la source
8

je ferais

$ git fetch --dry-run

pour hg incominget

$ git push --dry-run

pour hg outgoing.

Chris
la source
Désolé, j'ai oublié que cela avait déjà été dit en commentaire au PO.
chris
1

git-out est un script qui émule hg outgoingassez précisément. Il analyse la sortie "push -n", donc il produit une sortie précise si vous avez besoin de spécifier des arguments supplémentaires à pousser.

stepancheg
la source
0

git entrant

$ git fetch && git log ..origin/master --stat
OR
$ git fetch && git log ..origin/master --patch

git sortant

$ git fetch && git log origin/master.. --stat
OR
$ git fetch && git log origin/master.. --patch
prier
la source
0

Lorsque les réponses "git log" et @ {u} m'ont initialement donné des erreurs de "révision inconnue", j'ai essayé la suggestion de Chris / romkyns de git push --dry-run .

Vous obtiendrez une sortie telle que "5905..4878 master-> master". 5905 est le dernier commit de la télécommande et les validations via (et y compris) 4878 seront appliquées à la télécommande.

Vous pouvez ensuite utiliser 5905..4878 comme arguments pour plusieurs autres commandes git pour obtenir plus de détails:

git diff 5905..4878 # Gives full code changes in diff style

git log --online 5905..4878 # Displays each commit's comment
pierce.jason
la source
-1

Lorsque vous faites git fetch, tout le contenu, y compris les branches, les balises (refs) sont stockés temporairement dans .git / FETCH_HEAD dont le contenu peut être visualisé avec la commande: git log FETCH_HEAD Si vous n'utilisez pas le suffixe -a avec git fetch alors par défaut , Le contenu de FETCH_HEAD sera écrasé par un nouveau contenu. À partir de ces contenus, vous pouvez afficher et décider dans quelle branche vous souhaitez les fusionner si vous le faites ou vous pouvez simplement choisir en cerise si vous ne voulez que quelques commits de ce qui a été apporté par fetch.

AMIT PRAKASH PANDEY
la source