Gitでプルが必要かどうかを確認する 質問する

Gitでプルが必要かどうかを確認する 質問する

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

今、私はこの簡単なスクリプトを使います:

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

しかし、かなり重いです。

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

ベストアンサー1

初回使用git remote update、リモート参照を最新の状態にします。その後、次のようないくつかの操作を実行できます。

  1. git status -uno追跡しているブランチが先行しているか、遅れているか、または分岐しているかがわかります。何も表示されない場合は、ローカルとリモートは同じです。

  2. git show-branch *master名前が 'master' で終わるすべてのブランチのコミットが表示されます (例: masterおよびorigin/master )。

-vwith git remote update( ) を使用すると、git remote -v updateどのブランチが更新されたかを確認できるため、それ以上のコマンドは必要ありません。

ただし、スクリプトまたはプログラムでこれを実行し、最終的に true/false 値を取得したいようです。その場合、現在のHEADコミットと追跡しているブランチのヘッドとの関係を確認する方法はありますが、可能な結果は 4 つあるため、yes/no の回答にまとめることはできません。ただし、実行する準備ができている場合は、pull --rebase「ローカルが遅れている」および「ローカルが分岐した」を「プルが必要」として扱い、他の 2 つ (「ローカルが先行している」および「同じ」) を「プルする必要がない」として扱うことができます。

を使用すると、任意の ref のコミット ID を取得できますgit rev-parse <ref>。したがって、これをmasterorigin/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しています。これをスクリプトに組み込まなかったのは、フェッチと比較を別々の操作として実行できる方が柔軟性が高いためです。たとえば、最近フェッチしたので、フェッチせずに比較したい場合などです。

おすすめ記事