この回答から。
<オール>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 の違い)canPushorigin/currentBranch間の変更の数を取得します およびローカル リポジトリ -> 0の場合 、ローカル リポジトリをプッシュできます
今後の参考のために。 Git v2.17.0 以降
git status -sb
behind という単語が含まれています .したがって、プルをチェックするために直接使用できます。
注:git fetch を実行することを忘れないでください git status -sb を実行する前に