1. ホーム
  2. git

[解決済み] Gitでpullが必要かを確認する

2022-03-14 12:17:48

質問

リモートリポジトリが変更され、プルする必要があるかどうかを確認するにはどうすればよいですか?

今はこんな簡単なスクリプトを使っています。

git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1

でも、割と重いんですよね。

もっと良い方法はないでしょうか?理想的なのは、すべてのリモートブランチをチェックして、変更されたブランチの名前とそれぞれのブランチでの新しいコミットの数を返すことです。

解決方法は?

最初の使用 git remote update で、リモート参照を最新にします。そうすれば、次のようないくつかのことのうちの1つを行うことができます。

  1. git status -uno は、追跡しているブランチが進んでいるのか、遅れているのか、分岐しているのかを教えてくれます。何も表示されない場合は、ローカルとリモートが同じであることを示しています。

  2. git show-branch *master は、名前が 'master' で終わるすべてのブランチでのコミットを表示します (たとえば マスター オリジン/マスター ).

を使用する場合 -v と共に git remote update ( git remote -v update ) を実行すると、どのブランチが更新されたかがわかるので、これ以上のコマンドは必要ありません。

しかし、スクリプトやプログラムの中でこれを行い、最終的にtrue/falseの値を出したいようです。もしそうなら、現在の HEAD コミットと追跡中のブランチの先頭は、4つの可能性があるため、イエスかノーかの答えにはならないでしょう。しかし、もしあなたが pull --rebase であれば、"local is behind" と "local has diverged" を "need to pull" 、他の二つを "don't need to pull" として扱うことができます。

任意の ref のコミット ID を取得するには git rev-parse <ref> に対して行うことができます。 マスター オリジン/マスター と入力し、比較します。同じであれば、分岐は同じになります。もし不等間隔であれば、どちらが先に進んでいるのかを知ることができます。使用方法 git merge-base master origin/master は、両方の枝の共通の祖先を教えてくれます。もし分岐していなければ、この祖先はどちらか一方と同じになります。もし、3つの異なるIDが得られたら、分岐していることになります。

これを適切に行うには、例えばスクリプトの中で、現在のブランチと追跡しているリモートブランチを参照できるようにする必要があります。の bash プロンプト設定関数は /etc/bash_completion.d には、ブランチ名を取得するための便利なコードがあります。しかし、実際には名前を取得する必要はないでしょう。Git には、ブランチやコミットを参照するためのすてきなショートカットがあります (詳細は git rev-parse --help ). 特に @ は現在のブランチ(detached-head の状態でないと仮定)、そして @{u} は、その上流のブランチ(例えば origin/master ). そのため git merge-base @ @{u} は、現在のブランチとその上流が分岐した時点の(ハッシュの)コミットを返しますし git rev-parse @git rev-parse @{u} を実行すると、2つのTipsのハッシュが得られます。これをまとめると、次のようなスクリプトになります。

#!/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}'} は、オプションで上流ブランチを明示的に渡すことができます。これは、現在のブランチに設定されているものとは異なるリモートブランチに対してチェックを行いたい場合に使用します。これは通常、次のような形式になります。 リモコン名/ブランチ名 . パラメータを指定しない場合、デフォルトの値は @{u} .

スクリプトは、あなたが git fetch または git remote update を最初に実行し、トラッキングブランチを最新の状態にします。スクリプトにこれを組み込まなかったのは、取得と比較を別々の操作で行える方が柔軟性が高いからです。例えば、最近すでに取得したので取得せずに比較したい場合などです。