web-dev-qa-db-ja.com

git fetch、FETCH_HEADおよびOrigin / master

私はgitに非常に慣れていないため、単純なfetch操作で問題が発生しています。

私は彼のリポジトリから同僚の進捗状況を取得しようとしています。最初にgit fetch HEADを実行したところ、gitが約350MBのデータをダウンロードするようになり、何かが実行されたと確信しました。ただし、Origin/masterは同じ古いコミットをまだ指し示していました(実際はdevという名前ですが、masterと呼びます-彼にはmaster)。

その後、git fetch Origin masterを試しましたが、何も実行されないようで、更新されたのはFETCH_HEADだけです。失わないようにFETCH_HEADコミットにタグを付けましたが、リモートブランチを更新したいのですが。

何がうまくいかなかったのですか?リモートリポジトリにアクセスできません。それでも自宅で修正できますか?

14
DanielF

私はあなたが使用するコマンドに少し混乱しています。 HEADは通常、gitが現在作業ディレクトリにあるコミットを追跡するために使用するラベルです。 git fetchコマンドは、取得したいものを知るためにremoteまたはremote commit構成を想定しています。 git fetch HEADを使用すると、HEADがリポジトリ内のリモートであることを示します。コマンドがエラーなしで機能したことは奇妙です。

例:現在作業中のリポジトリのgit fetch HEADは、次のエラーになります。

fatal: 'HEAD' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

コマンドgit remoteはすべてのリモートをリストしますが、git remote --verboseはリモートのアドレスを含みます。これを使用して、リモートがHEADとして定義されているかどうか、およびどのリポジトリが友達リポジトリをアドレス指定しているかを確認できますか?

ただし、私の質問は別として、混乱を解消するのに役立ちます。 git fetch ...コマンドはリモート参照のみを更新し、ローカル参照は更新しません。

これを明確にするために、リポジトリの.gitフォルダーを確認します(デフォルトでは非表示になっているため、再表示する必要がある場合があります)。次のようなフォルダ構造が見つかります

working directory
|=>.git
|  |=>objects           <= contains data for each commit
|  |=>refs
|     |=>heads
|        |-master       <= file containing current commit of local master branch
|     |=>remotes
|        |=>Origin
|           |-master    <= file containing current commit of remote Origin's master branch
|-FETCH_HEAD            <= file updated by `git fetch`, contains info of what was fetched

Masterブランチをチェックアウトするとします。git checkout master-gitは作業ディレクトリを変更して、 '。git/refs/heads/master'ファイルのcommit値と一致する 'objects'フォルダーのcommitデータと一致させます。

次にgit fetch Origin masterを実行すると、「。git/refs/remotes/Origin/master」ファイルがリモートOriginのマスターブランチのコミットに更新され、そのコミットに必要なすべてのコミットデータがダウンロードされて配置されます'objects'フォルダー内。

ここで重要な点は、git fetchはチェックアウトされたローカルブランチを反映して作業ディレクトリを更新せず、git fetchがローカルブランチを更新しないことです。

git merge ...の変更でローカルmasterブランチを更新するには、git rebase ...またはOrigin/masterのいずれかを使用する必要があります。 git pull ...は、オプションと構成に応じて、git fetch ...git merge ...またはgit rebase ...の両方を実行します(デフォルトはgit merge ...です)。

そのすべての説明の後、あなたはあなたの友達リポジトリから何が(もしあれば)何がフェッチされたかを確認できるようにしたいと思います。 git branch -avvコマンドは、すべてのローカルブランチとリモートブランチをリストし、コミット番号と、ローカルブランチの場合は追跡しているリモートブランチをリストします。

ブランチが互いにどのように関連しているかを確認するには、リポジトリツリーをグラフ化するツールを使用すると便利です。いくつか選択できますが、git logコマンドで十分です。 git log --all --graph --oneline --decorateなど。公正な警告ですが、これは非常に長く、大規模なリポジトリの場合は複雑です。 --simplify-by-decoration引数を追加すると、短い出力を取得できます。

要約すると、自宅で修正できるかどうかは、リポジトリ内の情報によって異なります。上記のコマンド。 git remote --verbosegit branch -avv、およびgit log ...は、リポジトリの現在の状態を理解するのに役立ちます。そこから、git mergeまたはgit rebaseを使用して、ローカルブランチのデータを取得するためにさらに何かする必要があるかどうかを判断できます。

いつものように、問題が発生した場合は、学んだことを投稿してください。

16
David Culp

Git 1.8.4(2013年8月)以降、 git fetch リモート追跡ブランチを更新します!だけでなく FETCH_HEAD

commit f269048 を参照 Jeff King(peff から:

通常の「git fetch "引数なしで、構成された参照仕様に従って追跡参照を更新します。
ただし、「git fetch Origin master "(または" git pull Origin master ")、構成済みのrefspecはまったく確認せず、FETCH_HEAD

refs/remotes/Origin/master "(またはユーザーが設定したもの)。一部のユーザーは、リモートマスターの古い状態とさらに比較したいため、これを混乱させます。

$ git pull Origin master
$ git log HEAD...Origin/master

しかし、ブランチをフェッチするようにリポジトリを設定したと仮定します。

git config remote.Origin.fetch

空の場合:

git config remote.Origin.fetch '+refs/heads/*:refs/remotes/Origin/*'
9
VonC

git fetchは実際には作業ディレクトリに影響しません。リモートから最新の変更を取得するだけです。現在の状態を実際に更新するには、 git merge または git rebase を使用します。また、 git pull を使用することもできます。これは、git fetch + git mergeへのショートカットのように機能します。

マージとリベースの主な違いは、場合によっては、マージによって、累積された状態(早送りでないマージ)で新しいコミットが作成されることです。私がSVNを使用した時代を思い出させるので、これは悪いことです。リベースは、指定されたコミットの上に変更をリプレイするだけなので、履歴は常に線形です。同僚と同じフローを使用してください。

私はあなたが一般的なgitとgitの流れを読むことをお勧めします:a must-read book and a良い記事

4
madhead

あなたがしたいことは:

  • 同僚にリモコンを追加する
  • リポジトリから変更を取得する
  • リモートブランチを参照するローカルブランチを作成する

おそらく、あなたはすでにステップ1を完了しているでしょう。しかし、完全を期すために、それは:

git remote add coworker git://path/to/coworkers/repo.git

ここで、URLはgitがサポートする任意のURL形式にすることができます。

リモートが追加されたので、彼の変更をフェッチしたいとします。

git fetch coworker

これにより、彼のブランチごとにリモートブランチが提供されます。彼の枝が「ハムスター」と呼ばれているとしましょう。次に、作業を行うために、リモートブランチの独自のローカルコピーを作成します。

git checkout -b hamster coworker/hamster

これにより、ハムスターというブランチが作成され、そのブランチに切り替わります。

その時点から、あなたはハムスターで作業を行い、それを彼にプッシュすることができます

git Push coworker hamster

初めて、次にgit Push その後。

彼の変更をプルダウンしてマージしたいときはいつでもできます:

git pull

1
wadesworld