web-dev-qa-db-ja.com

git-fetchを理解するのに苦労している

Git-fetchのニュアンスを理解するのに苦労しています。 fetchを実行すると、リモート参照がローカルの追跡ブランチにフェッチされることを理解しています。

ただし、いくつか質問があります。

  1. ローカル追跡ブランチが存在しない可能性はありますか?もしそうなら、それは自動的に作成されますか?

  2. fetchを実行し、非追跡ブランチを宛先として指定するとどうなりますか?

  3. Git-fetchのマニュアルページでは、次のことを指定しています。

    git-fetch <options> <repository> <refspec>
    

Refspecを使用して、リモートマスターからリモートトラッキングブランチにコンテンツをフェッチするにはどうすればよいですか?私の現在のHEADがマスターであり、

git fetch Origin master

ただし、<+?src:dest> refspecで同じことを実現するには?これは、概念をよりよく理解するのに役立つと思います。

そしてもう一つの質問:

私の.git/configファイルには、フェッチするための次の行があります(関連する行のみを表示しています)。

fetch = +refs/heads/*:refs/remotes/Origin/*

誰かがこの行の正確な意味を説明できますか?

52
Parag

まず、ローカルトラッキングブランチという概念はなく、リモートトラッキングのみです枝。つまり、Origin/masterOriginリポジトリ内のmasterのリモート追跡ブランチです。

通常はgit fetch $ remoteを実行し、すべてのリモート追跡ブランチを更新し、必要に応じて新しい追跡ブランチを作成します。

ただし、refspecを指定することもできますが、リモートトラッキングブランチには影響しません。代わりに、宛先を指定しない限り、指定したブランチをフェッチしてFETCH_HEADに保存します。一般的に、これを台無しにしたくない。

最終的に、

fetch = +refs/heads/*:refs/remotes/Origin/*

ということは

git fetch Origin

それは実際に行います:

git fetch Origin +refs/heads/*:refs/remotes/Origin/*

つまり、リモートheads/foobarはローカルremotes/Origin/foobarになります。プラス記号は、早送りでなくても更新されることを意味します。

おそらくあなたが追跡ブランチとして考えるのはgit pullとマージ構成に関連するものでしょう。

59
FelipeC

felipec あります 問題のほとんどの問題に彼の回答で答えました

残りのいくつか(ほとんどは git fetch のマンページから抜粋;残念ながら、いくつかの場所で少し日付が付けられています):

  • remote-tracking branch(リモートリポジトリのブランチを追跡するブランチ)が存在しない場合、作成されます。

  • フェッチするブランチ(<dst>[+]<src>:<dst>)は、remotes/<remote>/名前空間に存在する必要はありません。たとえば、ミラーリングリポジトリ(git clone --mirror)の場合、refspecは1から1です。昔は、個別のリモートレイアウトの前(リモートトラッキング参照のremotes/<remote>/名前空間の前)masterブランチがOriginというブランチにフェッチされました。現在でもタグはミラーリング方式でtags/名前空間に直接フェッチされます。

  • フェッチ先のブランチ(refspec <src>:<dst>の右側が存在する場合)は、Gitがダウンロードによって早送りになるかどうか、つまり、<dst>の現在の状態が特定のリモートリポジトリの<src>の状態の祖先であるかどうかをチェックします。それ以外の場合t、およびgit-fetchに-f/--forceオプションを使用しないか、refspecの前に '+'(+<src>:<dst> refspecを使用)をフェッチすると、そのブランチの更新が拒否されます。

  • git fetch Origin mastergit fetch Origin master:ではなくgit fetch Origin master:masterと同等です。 masterブランチ(リモートのOrigin)のフェッチされた値をFETCH_HEADに格納し、masterブランチまたはリモートには格納しません-追跡remotes/Origin/masterブランチ。その後にgit merge FETCH_HEADを続けることができます。通常は直接使用されませんが、リモート追跡ブランチを設定せずに1回限りのプルの一部として:git pull <URL> <branch>

  • remote.Origin.fetch構成変数の値としての+refs/heads/*:refs/remotes/Origin/*は、リモートOriginの各ブランチ(refs/heads/名前空間の参照)が、refs/remotes/Origin/名前空間のそれぞれの名前付きリモート追跡ブランチにフェッチされることを意味します、例えばmasterブランチOrigin(つまり、refs/heads/master ref)がOrigin/masterリモート追跡ブランチ(つまり、refs/remotes/Origin/master ref)にフェッチされます。接頭辞「+」は、早送り以外の場合でもフェッチが成功することを意味します。つまり、リモートのブランチがリベースされるか、巻き戻される(過去の状態にリセットされる)か、またはその他の方法で修正されます。

補足:おそらく、より高いレベルの git remote コマンドを使用してリモートリポジトリを管理し、更新を取得します。

23
Jakub Narębski

Gitのメインのメンテナが(Git 2.1、2014年8月)に git fetch の説明を追加したことに注意してください。
(- commit fcb14bJunio C Hamano(gitster を参照:

構成済みのリモート追跡ブランチ

頻繁に同じリモートリポジトリと定期的に繰り返しフェッチすることで、それらと対話します。このようなリモートリポジトリの進行状況を追跡するために、git fetchではremote.<repository>.fetch構成変数を構成できます。

通常、このような変数は次のようになります。

[remote "Origin"]
fetch = +refs/heads/*:refs/remotes/Origin/*

この構成は、次の2つの方法で使用されます。

  • コマンドラインでフェッチするブランチやタグを指定せずにgit fetchを実行した場合。 git fetch Originまたはgit fetchremote.<repository>.fetchの値は、refspecsとして使用され、フェッチする参照と更新するローカル参照を指定します
    上記の例は、Originに存在するすべてのブランチ(つまり、値の左側に一致するすべての参照、refs/heads/*)をフェッチし、対応するリモート追跡を更新しますrefs/remotes/Origin/*階層のブランチ。

  • git fetchが明示的なブランチやタグとともに実行され、コマンドラインでフェッチする場合。 git fetch Origin master、コマンドラインで指定された<refspec>sは、何をフェッチするかを決定します(例ではmaster。これはmaster:の省略形です。 turnは「 'master'ブランチをフェッチしますが、コマンドラインから更新するリモートトラッキングブランチを明示的に指定しません」)を意味し、サンプルコマンドはonlyをフェッチします'master'ブランチ。
    remote.<repository>.fetchの値は、更新されるリモート追跡ブランチ(存在する場合)を決定します。
    このように使用した場合、remote.<repository>.fetch値はwhatが取得されるかどうかの決定に影響を与えません(つまり、コマンドラインリストの場合、値は参照仕様として使用されません) refspecs);それらは、決定にのみ使用されますwhereフェッチされた参照は、マッピングとして機能することによって格納されます。

4
VonC

また、Git 2.5以降(2015年第2四半期)では、git merge FETCH_HEADは複数のgitフェッチをマージできることに注意してください。

2015年3月26日の Junio C Hamano(gitster による commit d45366e を参照してください。
Junio C Hamano-gitster- によってマージ commit bcd1ecd 、2015年5月19日)

"git merge FETCH_HEAD"は、以前の "git fetch"がOctopusマージを作成すること、つまり「非マージ」としてマークされていない複数のブランチを記録することである可能性があることを学びました。
これにより、「git merge <msg> HEAD $commits...」スクリプトの実装で古いスタイルの呼び出し「git pull」を失う可能性があります。古いスタイルの構文は廃止されました。

git merge doc は今言及します:

FETCH_HEAD(および他のコミットなし)が指定されている場合、マージのために.git/FETCH_HEADを以前に呼び出してgit fetchファイルに記録されたブランチは、現在のブランチ


Git 2.13(2017年第2四半期)は、git mergeの古い構文を正式に廃止します。
Junio C Hamano(gitstercommit b439165 (2015年3月26日)を参照してください。
Junio C Hamano-gitster- によってマージ commit 1fdbfc4 、2017年3月30日)

merge:ドロップ 'git merge <message> HEAD <commit>'構文

2007年10月以降廃止された「git merge <message> HEAD <commit>」構文のサポートを停止し、v2.5.0以降、廃止警告メッセージを発行します。

つまり、古いスタイルの警告メッセージ「'git merge <msg> HEAD <commit>' is deprecated.」はもうありません。

2
VonC