Wie kann ich einen Git-Diff von dem generieren, was sich seit dem letzten Ziehen geändert hat?

76

Ich möchte die folgenden Aktionen, vorzugsweise in Rake, in einem einzigen Befehl zusammenfassen:

  1. Holen Sie sich die Version meines lokalen Git-Repository.
  2. Git ziehen den neuesten Code.
  3. Git unterscheidet sich von der Version, die ich in Schritt 1 extrahiert habe, von der Version, die sich jetzt in meinem lokalen Repository befindet.

Mit anderen Worten, ich möchte den neuesten Code aus dem zentralen Repository abrufen und sofort einen Unterschied darüber generieren, was sich seit dem letzten Ziehen geändert hat.

Teflon Ted
quelle

Antworten:

91

Sie können dies ziemlich einfach mit refspecs tun.

git pull origin
git diff @{1}..

Dadurch erhalten Sie einen Unterschied zum aktuellen Zweig, wie er vor und nach dem Ziehen vorhanden war. Beachten Sie, dass der Diff die falschen Ergebnisse liefert, wenn der Pull den aktuellen Zweig nicht aktualisiert. Eine andere Möglichkeit besteht darin, die aktuelle Version explizit aufzuzeichnen:

current=`git rev-parse HEAD`
git pull origin
git diff $current..

Ich persönlich verwende einen Alias, der mir einfach ein Protokoll in umgekehrter Reihenfolge (dh das älteste bis das neueste) ohne Zusammenführung aller Commits seit meinem letzten Pull zeigt. Ich führe dies jedes Mal aus, wenn mein Pull den Zweig aktualisiert:

git config --global alias.lcrev 'log --reverse --no-merges --stat @{1}..
Lily Ballard
quelle
1
@leemes: Hmm? git diff HEADzeigt Ihnen, was sich zwischen HEAD und Ihrer aktuellen Arbeitskopie geändert hat. Darum hat Teflon Ted nicht gebeten.
Lily Ballard
Entschuldigung, ich habe die Frage falsch verstanden. Ich suchte nach einem Befehl, um meine Änderungen anzuzeigen, seit ich das letzte Mal hier gezogen und gelandet bin. git diff HEADarbeitete für das, was ich brauchte (zumindest denke ich, dass es das war, wonach ich suchte: D)
leemes
4
Könnte jemand erklären (oder mir sagen, wo ich nachlesen soll), was @{1}..genau gemessen wird? Es hilft nicht, es einfach in Google zu werfen.
user1129682
5
@ user1129682: Dies ist die Syntax für den Zugriff auf das Reflog . Ohne Filialnamen bedeutet dies, auf das Reflog für die aktuelle Filiale zuzugreifen. Ein Wert von @{1}bedeutet den letzten Reflog-Eintrag, z. B. was auch immer der aktuelle Zweig zeigte, bevor er auf das aktuelle Commit zeigte.
Lily Ballard
2
+1, das ist der richtige Weg. Sie sollten die @{1}..Notation etwas erweitern, möglicherweise die Standardeinstellungen explizit dort einfügen und dann die kompakte Version anzeigen, damit sie weniger magisch ist.
Slezica
12

Gregs Weg sollte funktionieren (nicht ich, andere Greg: P). In Bezug auf Ihren Kommentar ist origin eine Konfigurationsvariable, die von Git festgelegt wird, wenn Sie das zentrale Repository auf Ihren lokalen Computer klonen. Im Wesentlichen merkt sich ein Git-Repository, woher es stammt. Sie können diese Variablen jedoch manuell festlegen, wenn Sie git-config verwenden müssen.

git config remote.origin.url <url>

Dabei ist URL der Remote-Pfad zu Ihrem zentralen Repository.

Hier ist eine Beispiel-Batch-Datei, die funktionieren sollte (ich habe sie nicht getestet).

@ECHO off

:: Retrieve the changes, but don't merge them.
git fetch

:: Look at the new changes
git diff ...origin

:: Ask if you want to merge the new changes into HEAD
set /p PULL=Do you wish to pull the changes? (Y/N)
IF /I %PULL%==Y git pull
Greg
quelle
1
Normalerweise verwenden Sie git remote set-url origin <url>statt git config, um die URL für eine Git- Fernbedienung zu ändern . Ist da ein Unterschied? Ich weiß es nicht, aber es scheint, dass dies git remoteein geeigneteres Werkzeug für den Job ist.
Colin D Bennett
@ColinDBennett Du hast recht, git remote set-urlwäre der geeignetere Weg, es zu tun. Ich habe verwendet, git configweil set-urles keine Option war, als ich das ursprünglich schrieb.
Greg
10

Dies ist einer Frage sehr ähnlich, die ich gestellt habe, wie man Änderungen an einem Zweig in Git erhält . Beachten Sie, dass sich das Verhalten von Git Diff gegenüber Git Log uneinheitlich unterscheidet, wenn zwei Punkte gegenüber drei Punkten verwendet werden. Für Ihre Anwendung können Sie jedoch Folgendes verwenden:

git fetch
git diff ...origin

Danach git pullwerden die Änderungen in Ihrem HEAD zusammengeführt.

Greg Hewgill
quelle
Ich sehe origin nicht als spezielles Schlüsselwort für git-diff oder git-rev-parse definiert. Meinten Sie, dass ich den Hash aus Schritt 1 als Wert für den Ursprung einfügen muss? Wenn ja, wie extrahiere ich diesen Wert programmgesteuert? Ich möchte all diese Schritte der Einfachheit halber in einem einzigen Befehl / Skript zusammenfassen.
Teflon Ted
2
Eine andere Möglichkeit, dies zu tun, besteht darin, den speziellen FETCH_HEAD-Kopf zu verwenden, der das Ergebnis des vorherigen Abrufs widerspiegelt. Also: "git fetch && git diff ... FETCH_HEAD".
Greg Hewgill
Ich denke, dies ist die angemessenere Antwort: git fetchgefolgt von a git diff origin/branchnameist der beste Weg, um den Unterschied vor dem Ziehen zu überprüfen.
Giulio Caccin
4

Wenn Sie dies in Ihr Bash-Profil einfügen, können Sie Grinsen (Git Remote Incoming) und Mörtel (Git Remote Outgoing) ausführen, um verschiedene Commits anzuzeigen, die für den Ursprungsmaster ein- und ausgehen.

function parse_git_branch {
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
}
function gd2 { 
 echo branch \($1\) has these commits and \($2\) does not 
 git log $2..$1 --no-merges --format='%h | Author:%an | Date:%ad | %s' --date=local
}
function grin {
 git fetch origin master
 gd2 FETCH_HEAD $(parse_git_branch)
}
function grout {
 git fetch origin master
 gd2 $(parse_git_branch) FETCH_HEAD
}
Clintm
quelle
Was ist gd2? Irgendein Alias ​​für git diff?
Arved
Es ist eine Bash-Funktion, die im obigen Skript direkt nach parse_git_branch
Clintm