リモート リポジトリが変更されたかどうか、またプルする必要があるかどうかを確認するにはどうすればよいですか?
今、私はこの簡単なスクリプトを使います:
git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1
しかし、かなり重いです。
もっと良い方法はありますか? 理想的な解決策は、すべてのリモート ブランチをチェックし、変更されたブランチの名前と各ブランチの新しいコミットの数を返すことです。
ベストアンサー1
初回使用git remote update
、リモート参照を最新の状態にします。その後、次のようないくつかの操作を実行できます。
git status -uno
追跡しているブランチが先行しているか、遅れているか、または分岐しているかがわかります。何も表示されない場合は、ローカルとリモートは同じです。git show-branch *master
名前が 'master' で終わるすべてのブランチのコミットが表示されます (例: masterおよびorigin/master )。
-v
with git remote update
( ) を使用すると、git remote -v update
どのブランチが更新されたかを確認できるため、それ以上のコマンドは必要ありません。
ただし、スクリプトまたはプログラムでこれを実行し、最終的に true/false 値を取得したいようです。その場合、現在のHEADコミットと追跡しているブランチのヘッドとの関係を確認する方法はありますが、可能な結果は 4 つあるため、yes/no の回答にまとめることはできません。ただし、実行する準備ができている場合は、pull --rebase
「ローカルが遅れている」および「ローカルが分岐した」を「プルが必要」として扱い、他の 2 つ (「ローカルが先行している」および「同じ」) を「プルする必要がない」として扱うことができます。
を使用すると、任意の ref のコミット ID を取得できますgit rev-parse <ref>
。したがって、これをmasterとorigin/masterに対して実行して比較できます。これらが等しい場合、ブランチは同じです。これらが等しくない場合は、どちらが先であるかを知りたいことになります。 を使用すると、git merge-base master origin/master
両方のブランチの共通の祖先がわかり、分岐していない場合は、どちらか一方と同じになります。3 つの異なる ID を取得した場合、ブランチは分岐しています。
これをスクリプトなどで適切に行うには、現在のブランチと、それが追跡しているリモート ブランチを参照できる必要があります。 の bash プロンプト設定関数には、/etc/bash_completion.d
ブランチ名を取得するための便利なコードがあります。ただし、実際に名前を取得する必要はないでしょう。Git には、ブランチとコミットを参照するための便利な省略形があります ( に説明されていますgit rev-parse --help
)。特に、@
現在のブランチ (ヘッドが分離されていない状態であると想定) には を使用し、@{u}
その上流ブランチ (例origin/master
) には を使用できます。したがって、 は、git merge-base @ @{u}
現在のブランチとその上流ブランチが分岐するコミット (のハッシュ) を返し、git rev-parse @
はgit rev-parse @{u}
2 つのヒントのハッシュを提供します。これは、次のスクリプトにまとめることができます。
#!/bin/sh
UPSTREAM=${1:-'@{u}'}
LOCAL=$(git rev-parse @)
REMOTE=$(git rev-parse "$UPSTREAM")
BASE=$(git merge-base @ "$UPSTREAM")
if [ $LOCAL = $REMOTE ]; then
echo "Up-to-date"
elif [ $LOCAL = $BASE ]; then
echo "Need to pull"
elif [ $REMOTE = $BASE ]; then
echo "Need to push"
else
echo "Diverged"
fi
注意:@
git の古いバージョンでは単独では許可されなかったため、@{0}
代わりに を使用する必要がある場合があります。
この行ではUPSTREAM=${1:-'@{u}'}
、現在のブランチに設定されているものとは異なるリモート ブランチに対してチェックを行う場合に、アップストリーム ブランチを明示的に渡すことができます。これは通常、remotename/branchname という形式になります。パラメータが指定されていない場合、値はデフォルトで になります@{u}
。
このスクリプトでは、追跡ブランチを最新の状態にするために、最初にgit fetch
または を実行していることを前提とgit remote update
しています。これをスクリプトに組み込まなかったのは、フェッチと比較を別々の操作として実行できる方が柔軟性が高いためです。たとえば、最近フェッチしたので、フェッチせずに比較したい場合などです。