Aus dieser Antwort.
- Führen Sie einen Abruf durch:
git fetch
. - Ermitteln Sie, wie viele Commits der aktuelle Zweig hinter sich hat:
behind_count = $(git rev-list --count [email protected]{u})
. - Ermitteln Sie, wie viele Commits der aktuelle Zweig voraus ist:
ahead_count = $(git rev-list --count @{u}..HEAD)
. (Es wird davon ausgegangen, dass Sie von dort abrufen, wohin Sie pushen, siehepush.default
Konfigurationsoption). - Falls beide
behind_count
undahead_count
0 sind, dann ist der aktuelle Zweig aktuell. - Falls
behind_count
ist 0 undahead_count
größer als 0 ist, dann ist der aktuelle Zweig voraus. - Falls
behind_count
größer als 0 undahead_count
ist 0 ist, dann liegt der aktuelle Zweig zurück. - Falls beide
behind_count
undahead_count
größer als 0 sind, dann wird der Stromzweig divergiert.
Erklärung:
git rev-list
Listen Sie alle Commits auf, die einen Commits-Bereich angeben.--count
Option gibt aus, wie viele Commits aufgelistet worden wären, und unterdrückt alle anderen Ausgaben.HEAD
Namen aktuellen Zweig.@{u}
bezieht sich auf den lokalen Upstream des Current Branch (konfiguriert mitbranch.<name>.remote
undbranch.<name>.merge
). Es gibt auch@{push}
, es zeigt normalerweise auf dasselbe wie@{u}
.<rev1>..<rev2>
gibt einen Commit-Bereich an, der Commits enthält, die von erreichbar sind, aber diejenigen ausschließt, die von erreichbar sind. Wenn entweder oder weggelassen wird, ist es standardmäßig HEAD.
Sie können dies mit einer Kombination aus git merge-base
tun und git rev-parse
. Wenn git merge-base <branch> <remote branch>
gibt dasselbe zurück wie git rev-parse <remote branch>
, dann ist Ihre Filiale vor Ort. Wenn es dasselbe zurückgibt wie git rev-parse <branch>
, dann ist Ihre örtliche Niederlassung dahinter. Wenn merge-base
gibt eine andere Antwort zurück als rev-parse
, dann sind die Zweige auseinandergegangen und Sie müssen eine Zusammenführung vornehmen.
Am besten machen Sie einen git fetch
bevor Sie jedoch die Zweige überprüfen, da sonst Ihre Entscheidung, ob Sie ziehen müssen oder nicht, veraltet ist. Sie sollten auch sicherstellen, dass jeder Zweig, den Sie überprüfen, einen Remote-Tracking-Zweig hat. Sie können git for-each-ref --format='%(upstream:short)' refs/heads/<branch>
verwenden das zu tun. Dieser Befehl gibt den Remote-Tracking-Zweig von <branch>
zurück oder die leere Zeichenfolge, wenn sie keine hat. Irgendwo auf SO gibt es eine andere Version, die einen Fehler zurückgibt, wenn der Branch keinen Remote-Tracking-Branch hat, was für Ihren Zweck nützlicher sein könnte.
Am Ende habe ich das in meinem C++11 git-ws Plugin implementiert.
string currentBranch = run("git rev-parse --abbrev-ref HEAD");
bool canCommit = run("git diff-index --name-only --ignore-submodules HEAD --").empty();
bool canPush = stoi(run("git rev-list HEAD...origin/" + currentBranch + " --ignore-submodules --count")[0]) > 0;
Scheint soweit zu funktionieren. canPull
muss noch getestet und implementiert werden.
Erklärung:
currentBranch
erhält die Konsolenausgabe, die eine Zeichenfolge des aktuellen Zweignamens istcanCommit
bekommt, ob die Konsole etwas ausgibt (Unterschied zwischen aktuellen Änderungen und HEAD, Submodule ignorieren)canPush
erhält die Anzahl der Änderungen zwischen origin/currentBranch
und das lokale Repo - wenn> 0
, kann das lokale Repo gepusht werden
Zum späteren Nachschlagen. Ab Git v2.17.0
git status -sb
enthält das Wort hinter .Damit kann direkt nach Pulls gesucht werden.
Hinweis:Denken Sie daran, git fetch
auszuführen bevor Sie git status -sb
ausführen