Git がファイルが最新であると誤って認識するのはなぜですか?

Git がファイルが最新であると誤って認識するのはなぜですか?

ファイル ディレクトリ内に、同じ Git リポジトリにリンクする 2 つのフォルダー (A と B) があります。

フォルダー A に というファイルを作成しましたindex.html。次に、フォルダー B に という別のファイルを作成しましたindex.html。次に、フォルダー B に追加しindex.html、コミットして、B の内容をプッシュしました。

フォルダー A からプルすると、Git はファイルが「すでに最新」であると主張します。しかし、両方のフォルダーには明らかに異なるindex.htmlファイルがあります。何が起こっているのでしょうか?

答え1

git pullの仕事は、fetch新しいコミットをmerge現在のブランチに取り込むことです。現在のブランチがプル元のブランチと比べて古くない場合、プルは次のように言います。Already up-to-date. 作業ディレクトリにローカルの変更があったとしても.git pullは作業ツリーではなくブランチに関係しており、マージを妨げる変更がある場合にのみ作業ツリーにコメントします。

あなたの説明は、既存の に反対していない理由を説明するには不十分ですindex.htmlが、Already up-to-date.git が変更がないと考えているという意味として受け取るべきではありません。代わりに、 を使用してgit status要約を取得してください。

ブランチの状態を理解するには、git branch -vコミット ID と各ブランチの上流ブランチとの関係が表示されるので便利です。また、gitk --allすべてのコミットをグラフィカルに表示する場合にも便利です。

答え2

私の理解が正しければ、次のスクリプトで問題が再現されるはずです。

mkdir テスト
CDテスト
git init --bare テスト.git
gitクローンtest.git
gitクローンtest.git b
エコー a > a/index.html
エコー b > b/index.html
cd b
git で index.html を追加します
git コミット -m 追加
git プッシュオリジンマスター
cd ../a
git プル

最後のgit pullプリント:

リモート: オブジェクトをカウントしています: 3、完了。
リモート: 合計 3 (デルタ 0)、再利用 0 (デルタ 0)
オブジェクトの解凍: 100% (3/3)、完了。
/home/cyrus/tmp/test/test から
 * [新しいブランチ] master -> origin/master

そして、 の内容はindex.html黙って上書きされました:

サイラス:~/tmp/test/a$ cat index.html
b

答え3

一つ覚えておいてほしいのはgitファイルではなくコンテンツを追跡します

内部的には、リポジトリに保存されているすべてのコンテンツは、ブロブどこかにあります。ファイルであるとみなすものは、gitBLOB を指す名前であるとみなします。同じコンテンツを持つ 2 つのファイルであるとみなすものは、git同じ BLOB にリンクされた 2 つの名前であるとみなします。したがって、BLOB はいずれも変更されていないため、リポジトリは変更されていません。

Git がファイルシステムと同じように (あるいは他のほとんどのバージョン管理システムと同じように) 動作することを期待していますが、gitこの点では実際にはよりスペース効率に優れています。この概念を非常にうまく説明しています。具体的には、Git オブジェクト モデル

答え4

異なるフォルダー (またはファイル、わかりません) を異なるリビジョンでチェックアウトできる SVN に慣れているようです。

これは git では不可能です。コミットまたはチェックアウト (これはプル成功の最終ステップでもあります) は、現在いるフォルダーとは関係なく、すべての作業ファイルに対して実行されます。

関連情報