この回答から。
<オール>git fetch
.behind_count = $(git rev-list --count [email protected]{u})
.ahead_count = $(git rev-list --count @{u}..HEAD)
. (フェッチ元がプッシュ先であると想定しています。push.default
を参照してください) 設定オプション)behind_count
の場合 および ahead_count
0 の場合、現在のブランチは最新です。behind_count
0 および ahead_count
です が 0 より大きい場合、現在のブランチが先行しています。behind_count
0 より大きく、ahead_count
0 の場合、現在のブランチは遅れています。behind_count
の場合 と ahead_count
が 0 より大きい場合、現在のブランチは分岐しています。説明:
git rev-list
指定したコミット範囲のすべてのコミットを一覧表示します。--count
オプションは、リストされたコミットの数を出力し、他のすべての出力を抑制します。HEAD
現在のブランチに名前を付けます。@{u}
現在のブランチのローカル アップストリームを参照します (branch.<name>.remote
で構成) とbranch.<name>.merge
)。@{push}
もあります 、通常は@{u}
と同じものを指します .<rev1>..<rev2>
から到達可能なコミットを含み、 から到達可能なコミットを除外するコミット範囲を指定します。または を省略すると、デフォルトで HEAD になります。
git merge-base
の組み合わせでこれを行うことができます と git rev-parse
. git merge-base <branch> <remote branch>
の場合 git rev-parse <remote branch>
と同じものを返します 、あなたのローカルブランチが先です。 git rev-parse <branch>
と同じ値を返す場合 の場合、ローカル ブランチは遅れています。 merge-base
の場合 rev-parse
とは異なる回答を返します の場合、ブランチが分岐しているため、マージを行う必要があります。
git fetch
を実行するのが最善です ただし、ブランチをチェックする前に、そうしないと、プルする必要があるかどうかの判断が時代遅れになります。また、チェックする各ブランチにリモート追跡ブランチがあることを確認する必要があります。 git for-each-ref --format='%(upstream:short)' refs/heads/<branch>
を使用できます それをするために。そのコマンドは <branch>
のリモート追跡ブランチを返します または空文字列がない場合は空文字列。 SO のどこかに、ブランチにリモート追跡ブランチがない場合にエラーを返す別のバージョンがあります。これは目的により役立つ場合があります。
最終的に、これを 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;
これまでのところうまくいくようです。 canPull
まだテストして実装する必要があります。
説明:
currentBranch
現在のブランチ名の文字列であるコンソール出力を取得しますcanCommit
コンソールが何かを出力するかどうかを取得します (サブモジュールを無視して、現在の変更と HEAD の違い)canPush
origin/currentBranch
間の変更の数を取得します およびローカル リポジトリ -> 0
の場合 、ローカル リポジトリをプッシュできます
今後の参考のために。 Git v2.17.0 以降
git status -sb
behind という単語が含まれています .したがって、プルをチェックするために直接使用できます。
注:git fetch
を実行することを忘れないでください git status -sb
を実行する前に