「git fetch --tags」には「git fetch」が含まれていますか?


270

素晴らしく単純な質問-「git fetch」の機能は、厳密なサブセットgit fetch --tagsですか?

つまり、私が実行した場合git fetch --tags、すぐにすぐに実行する理由はありgit fetchますか?

何についてgit pullgit pull --tags?同じ状況?


11
Git 1..9 / 2.0(2014年第1四半期)以降、答えはyesになります以下の私の回答を
VonC 2013

3
編集で「私のテキストを修正」した編集者にとって-ハイフンや頭字語の後に大文字を使用する必要はないため、編集は文法的に正しくなかったため、拒否しました。
davidA

回答:


176

注:git 1.9 / 2.0(2014年第1四半期)以降、同じコマンドラインでオプションなしでフェッチしたものに加えてgit fetch --tagsタグもフェッチします。

Michael Haggerty(mhagger)によるcommit c5a84e9を参照してください。

以前は、フェッチの「--tags」オプションは、refspecを指定することと同等と見なされていました。

refs/tags/*:refs/tags/*

コマンドライン; 特に、remote.<name>.refspec構成が無視される原因となりました。

ただし、他の参照をフェッチせずにタグをフェッチすることはあまり役に立ちませんが、他の参照に加えてタグをフェッチできること非常に役立ちます。 したがって、このオプションのセマンティクスを変更して、後者を実行します。

ユーザーがタグのみをフェッチしたい場合でも、明示的なrefspecを指定することが可能です。

git fetch <remote> 'refs/tags/*:refs/tags/*'

1.8.0.3より前のドキュメントでは、「fetch --tags」の動作のこの側面についてあいまいであったことに注意してください。
コミットf0cb2f1(2012-12-14)fetch --tagsにより、ドキュメントは以前の動作と一致しました。
このコミットにより、新しい動作に合わせてドキュメントが変更されます(を参照Documentation/fetch-options.txt)。

他のすべてのものをフェッチすることに加えて、リモートからすべてのタグをフェッチするように要求します


Git 2.5(2015年第2四半期)のgit pull --tags方が堅牢であるため、

参照してください19d122bコミットによってポール・タン(pyokagan、5月13日2015年
(で合併Junio C浜野- gitster-cc77b99をコミットし、2015年5月22日)

pull--tagsマージ候補がない場合のエラーを削除

以来441ed41(」git pull --tags:」より良いメッセージでエラー出て、2007年12月28日、Gitの1.5.4+)、git pull --tags場合、別のエラーメッセージを印刷し git-fetch任意のマージの候補を返しませんでした。

It doesn't make sense to pull all tags; you probably meant:
       git fetch --tags

これは、その時点でgit-fetch --tagsは、構成された参照仕様をオーバーライドするため、マージ候補がないためです。したがって、エラーメッセージは混乱を防ぐために導入されました。

ただし、c5a84e9fetch --tags: 他のものに加えてタグフェッチするため、2013-10-30、Git 1.9.0+)は、git fetch --tags構成済みのrefspecに加えてタグをフェッチします。
したがって、マージ候補の状況が発生しない場合は、--tagsが設定されているためではありません。そのため、この特別なエラーメッセージは無関係になりました。

混乱を避けるために、このエラーメッセージを削除してください。


Git 2.11以降(2016年第4四半期)の方git fetchが高速です。

Jeff King(によるコミット5827a03(2016年10月13日)を参照してください。(合併によりJunio C浜野- -9fcd144コミットし、2016年10月26日)をpeff
gitster

fetchhas_sha1_fileタグのフォローには「quick」を使用します

私たちがフォローしているブランチに関係のない多くのタグを持つリモートからフェッチするとき、タグで指されたオブジェクト(フェッチしない)がリポジトリに存在するかどうかをチェックするときに、あまりにも多くのサイクルを浪費していましたあまりにも慎重に。

このパッチは、フェッチがHAS_SHA1_QUICKを使用して、同時リパックで際どい場合がある場合に速度を上げるために精度を犠牲にすることを教えています。

含まれているperfスクリプトの結果は次のとおりです。これにより、上記と同様の状況が設定されます。

Test            HEAD^               HEAD
----------------------------------------------------------
5550.4: fetch   11.21(10.42+0.78)   0.08(0.04+0.02) -99.3%

これは、以下の状況にのみ適用されます。

  1. reprepare_packed_git()高価にするために、クライアント側に多くのパックがあります(最も高価な部分は、ソートされていないリストで重複を見つけることです。これは現在2次式です)。
  2. 自動フォローの候補となる(つまり、クライアントにはない)サーバー側に多数のタグ参照が必要です。それぞれがパックディレクトリの再読み取りをトリガーします。
  3. 通常の状況では、クライアントはそれらのタグを自動追跡し、1回の大きなフェッチの後で(2)は真ではなくなります。
    ただし、これらのタグが、クライアントがフェッチするものとは切り離された履歴を指している場合、自動追跡されることはなく、候補はフェッチごとに影響します。

Git 2.21(2019年2月)は、設定remote.origin.fetchがデフォルトでない場合'+refs/heads/*:refs/remotes/origin/*')にリグレッションを導入したようです

fatal: multiple updates for ref 'refs/tags/v1.0.0' not allowed

Git 2.24(2019年第4四半期)では、別の最適化が追加されています。

鈴木雅也()によるcommit b7e2d8b(2019年9月15日)を参照してください。(合併によりJunio C浜野- -1d8b0dfコミットし、2019年10月7日)をdraftcode
gitster

fetchoidset必要なOIDを保持して検索を高速化するために使用

の間git fetchに、クライアントは、アドバタイズされたタグのOIDがフェッチリクエストの希望のOIDセットにすでにあるかどうかを確認します。
このチェックは線形スキャンで行われます。
参照が多いリポジトリの場合、このスキャンを繰り返すには15分以上かかります。

これを高速化するにはoid_set、他の参照のOIDのを作成します。


gitのリストでこのスレッドはの行動改正する可能性について議論git fetch <remote> <branch>(それはすでにオリジナルの意図AGAINSTリモートtrackingsを更新するので)自動フォロータグへの:public-inbox.org/git/...
ankostis

@ankostis興味深い:Junioがpublic-inbox.org/git/…で言及しているように、「以前の動作に戻ることは、このスレッドで議論されている問題に対処するための1つのオプションである可能性があります。」(ただし、公開されません:public-inbox.org/git/…
VonC '20

Gitが不要な複雑さをエンドユーザーに公開し、一般的な操作を実行するためにハックに似た点まで構文の多いコマンドを要求することは可能でしたか?十分な内部知識はまだ必要な知識ではないと思います。
John Fantastico

1
@JohnFantasticoその視点は理解できます。以前に見たことがあります:news.ycombinator.com/item?id=16587496。またはhackernoon.com/…(「Gitコマンドは、データストレージのリークの多い抽象化にすぎません。」)
VonC

1
@Vadorequestありがとうございます。回答を更新しましたので、メーリングリストに引き続き注目し
q=

131

注:この回答はgit v1.8以前でのみ有効です。

これのほとんどは他の回答やコメントで述べられていますが、ここに簡潔な説明があります:

  • git fetchすべてのブランチヘッド(またはremote.fetch configオプションで指定されたすべて)、それらに必要なすべてのコミット、およびこれらのブランチから到達可能なすべてのタグをフェッチします。ほとんどの場合、この方法ですべてのタグに到達できます。
  • git fetch --tagsすべてのタグ、それらに必要なすべてのコミットをフェッチします。フェッチされたタグから到達可能であっても、ブランチヘッド更新されません

概要:フェッチのみを使用して完全に最新の状態にしたい場合は、両方を実行する必要があります。

また、コマンドラインでの入力という意味でない限り、「2倍遅くなる」こともありません。その場合、エイリアスが問題を解決します。2つの要求は異なる情報を要求するため、2つの要求を行う際にオーバーヘッドは本質的にありません。


2
コメントありがとうございます。Cygwinで高レイテンシネットワークを介してgitを実行しています。どちらもフェッチするものが何もない場合(約5秒)は、2倍の速度になります。
davidA 2009

ああすごい。git-remoteはうまく機能しますか?ソースを簡単に見ると、呼び出しが1回だけである可能性があると思いますが、ブランチ上にないタグを取得するかどうかは完全にはわかりません。正直なところ、ブランチにないタグを見たことがあるかどうかわかりません。私が引き出すもので、メンテナンスリリース、機能リリース、および古いリリースのメンテナンスの中止を見逃すほど長く待った場合に起こる唯一の方法。
カスカベル

問題は「git fetch」が追跡されたブランチのタグのみをフェッチすることだと思います。ユーザーが作業中のブランチを選択できるようにするスクリプトがあるため、デフォルトでは現在、個人が追跡していないブランチが多数あります。
davidA 2009

私はまだgit-remoteを試していませんが、増え続けるto-doリストに載っています:)
davidA 2009

7
git remote updateは実際にはgit fetchandの代用ではないことに注意してくださいgit fetch --tagsgit remote update変更された既存のタグは更新されませんが、新しいタグが追加されます。git fetch --tags既存のタグのみを更新します。
12

48

自分で答えます。

違いがあると判断しました。"git fetch --tags"はすべてのタグをもたらす可能性がありますが、新しいコミットはもたらされません!

これを完全に「最新」にする、つまりマージせずに「git pull」を複製する必要があることがわかります。

$ git fetch --tags
$ git fetch

2倍遅いので、これは残念です。唯一の場合は、「フェッチGIT」それが正常に何を行うためのオプションを持っていたし、すべてのタグをもたらします。


興味深いことに、私はそれを経験しませんでした(おそらく、私のレポがテスト時に最新であったためです)+1
VonC

1
git remote update myRemoteRepo」はどうですか:リモートのコンテンツタグを取得ますか?
VonC 2009

1
私はgit fetchいつもやっていて、新しいコミット新しいタグを一貫してプルダウンしています。実行しているGitのバージョンは何ですか?
Tim Visher、2009

4
FTR、「git remote update myRemoteRepo」はうまく機能しません-特に後続のマージが効果がないため、「git fetch && git fetch --tags」が行うようには見えません。
davidA 2009

1
@TimVisher git fetchは、ブランチのコミットログにないタグを取得しません。jQuery UIは、たとえばリリースタグでこれを行います。を実行しgit checkout -b temp-branch、リリースを行い、リリースに必要なファイルを追加し、バージョンを更新してから、git commit -m "1.10.x" ; git tag 1.10.x; git push --tagsローカルの一時ブランチを削除します。そのタグに到達するリモートブランチはなく、git fetchダウンロードすることもありません。
gnarf 2013

31

ここでの一般的な問題は、git fetchフェッチすること+refs/heads/*:refs/remotes/$remote/*です。これらのコミットのいずれかにタグがある場合、それらのタグもフェッチされます。ただし、リモートのどのブランチからも到達できないタグがある場合、それらはフェッチされません。

この--tagsオプションは、refspecをに切り替えます+refs/tags/*:refs/tags/*。あなたgit fetch両方をつかむように頼むことができます。私はgit fetch && git fetch -tあなたが次のコマンドを使うだろうと確信しています:

git fetch origin "+refs/heads/*:refs/remotes/origin/*" "+refs/tags/*:refs/tags/*"

これをこのリポジトリのデフォルトにしたい場合は、2番目のrefspecをデフォルトのフェッチに追加できます。

git config --local --add remote.origin.fetch "+refs/tags/*:refs/tags/*"

これfetch =により.git/config、このリモートの2番目の行が追加されます。


私はプロジェクトでこれを処理する方法を探していました。これが私が思いついたものです。

git fetch -fup origin "+refs/*:refs/*"

私の場合、これらの機能が欲しかった

  • リモートからすべてのヘッドとタグを取得するため、refspecを使用します refs/*:refs/*
  • +refspecの前にローカルブランチとタグを非早送りで上書きする
  • 必要に応じて、現在チェックアウトされているブランチを上書きします -u
  • リモートに存在しないブランチとタグを削除する -p
  • そして、確かに力 -f

これが答えです。
2014年

--tagsオプションはrefspecをに切り替えます+refs/tags/*:refs/tags/*」。ただし、man git-fetch先頭に+refs/tags/*:refs/tags/*)を付けずにrefspecを指定しているようです。
ドミトリーミンコフスキー2014年

remote.origin.fetchデフォルトは +refs/heads/*:refs/remotes/origin/*、つまり+バージョンですよね?(つまり、起点/分岐が現在ローカルにある場所に関係なく、起点/分岐は上書きされます。)
Robert Siemer

...そして執筆時点で、最近git --tagsはすでに他のすべてに加えてタグをフェッチしていました。@VonCの回答をご覧ください。
Robert Siemer

10

ほとんどの場合、git fetch「リモートリポジトリから新しいものを取得し、ローカルブランチにマージせずにローカルコピーに配置する」という必要なことを行う必要があります。 git fetch --tags新しいタグ以外は何も取得しないことを除いて、まさにそれを行います。

その意味でgit fetch --tags、はのスーパーセットではありませんgit fetch。それは実際には正反対です。

git pullもちろん、はのラッパーにすぎませんgit fetch <thisrefspec>; git merge。最初に何をしているのかを理解するのに役立つので、ジャンプする前に手動でgit fetchINGを実行git mergeすることに慣れることをお勧めします。git pullgit pull

とはいえ、その関係はとまったく同じgit fetchです。 git pullのスーパーセットですgit pull --tags


1
「gitのプルはgitのプル--tagsのスーパーセットである」 -しかし...「フェッチGIT」ではない関係はまったく同じではありませんので、「--tagsをフェッチGIT」のスーパーセット...?
davidA 2009

9
ちょうどこの質問を見つけた...まあ、すべてのタグを取得するのgit pullなく、現在のブランチヘッドから到達可能なタグのみを取得するようです。ただし、すべてのタグをフェッチするため、明らかにと同等です。git pull --tagsgit fetch --tags
Archimedix

2
git fetch upstream --tags

正常に動作します。新しいタグのみを取得し、他のコードベースは取得しません。


1
upstream通常はと呼ばれoriginます。upstreamGitHubで使われている名前だと思います。いずれの場合も、使用する名前はで示される名前git remoteです。
ファビオはモニカを復活
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.