Z této odpovědi.
- Proveďte načtení:
git fetch
. - Zjistěte, kolik potvrzení je aktuální větev za:
behind_count = $(git rev-list --count [email protected]{u})
. - Zjistěte, o kolik potvrzení má aktuální větev náskok:
ahead_count = $(git rev-list --count @{u}..HEAD)
. (Předpokládá se, že místo, odkud načítáte, je místo, kam tlačíte, vizpush.default
možnost konfigurace). - Pokud obě
behind_count
aahead_count
jsou 0, pak je aktuální větev aktuální. - Pokud
behind_count
je 0 aahead_count
je větší než 0, pak je aktuální větev napřed. - Pokud
behind_count
je větší než 0 aahead_count
je 0, aktuální větev je pozadu. - Pokud obě
behind_count
aahead_count
jsou větší než 0, pak je aktuální větev divergovaná.
Vysvětlení:
git rev-list
seznam všech odevzdání s uvedením rozsahu odevzdání.--count
volba vypíše, kolik potvrzení by bylo uvedeno, a potlačí všechny ostatní výstupy.HEAD
pojmenuje aktuální větev.@{u}
odkazuje na místní upstream aktuální větve (nakonfigurováno pomocíbranch.<name>.remote
abranch.<name>.merge
). Existuje také@{push}
, obvykle ukazuje na totéž jako@{u}
.<rev1>..<rev2>
určuje rozsah potvrzení, který zahrnuje potvrzení, která jsou dosažitelná z, ale vylučuje ty, které jsou dosažitelné z . Když je vynecháno buď nebo, výchozí hodnota je HEAD.
Můžete to udělat kombinací git merge-base
a git rev-parse
. Pokud git merge-base <branch> <remote branch>
vrátí totéž jako git rev-parse <remote branch>
, pak je vaše místní pobočka napřed. Pokud vrátí totéž jako git rev-parse <branch>
, pak je vaše místní pobočka pozadu. Pokud merge-base
vrátí jinou odpověď než buď rev-parse
, pak se větve rozcházejí a budete muset provést sloučení.
Nejlepší by bylo udělat git fetch
před kontrolou větví, jinak bude vaše rozhodnutí, zda potřebujete vytáhnout nebo ne, zastaralé. Budete také chtít ověřit, že každá pobočka, kterou kontrolujete, má pobočku pro vzdálené sledování. Můžete použít git for-each-ref --format='%(upstream:short)' refs/heads/<branch>
udělat to. Tento příkaz vrátí větev vzdáleného sledování <branch>
nebo prázdný řetězec, pokud žádný nemá. Někde na SO je jiná verze, která vrátí chybu, pokud větev nemá větev pro vzdálené sledování, což může být pro váš účel užitečnější.
Nakonec jsem to implementoval do svého pluginu C++ 11 git-ws.
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;
Zdá se, že to zatím funguje. canPull
ještě potřebuje otestovat a implementovat.
Vysvětlení:
currentBranch
získá výstup konzoly, což je řetězec názvu aktuální větvecanCommit
zjistí, zda konzole něco vydává (rozdíl mezi aktuálními změnami a HEAD, ignorování submodulů)canPush
získá počet změn mezi původem/currentBranch
a místní repo – pokud> 0
, lze místní repo přesunout
Pro budoucí reference. Od Git v2.17.0
git status -sb
obsahuje slovo za .Takže to může být použito přímo ke kontrole tahů.
Poznámka:Nezapomeňte spustit git fetch
před spuštěním git status -sb