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.defaultKonfigurationsoption). - Falls beide
behind_countundahead_count0 sind, dann ist der aktuelle Zweig aktuell. - Falls
behind_countist 0 undahead_countgrößer als 0 ist, dann ist der aktuelle Zweig voraus. - Falls
behind_countgrößer als 0 undahead_countist 0 ist, dann liegt der aktuelle Zweig zurück. - Falls beide
behind_countundahead_countgrößer als 0 sind, dann wird der Stromzweig divergiert.
Erklärung:
git rev-listListen Sie alle Commits auf, die einen Commits-Bereich angeben.--countOption gibt aus, wie viele Commits aufgelistet worden wären, und unterdrückt alle anderen Ausgaben.HEADNamen aktuellen Zweig.@{u}bezieht sich auf den lokalen Upstream des Current Branch (konfiguriert mitbranch.<name>.remoteundbranch.<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:
currentBrancherhält die Konsolenausgabe, die eine Zeichenfolge des aktuellen Zweignamens istcanCommitbekommt, ob die Konsole etwas ausgibt (Unterschied zwischen aktuellen Änderungen und HEAD, Submodule ignorieren)canPusherhält die Anzahl der Änderungen zwischen origin/currentBranchund 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