7

たとえば、リポジトリにファイル a を作成し (master ブランチにいるとします)、次に Igit add agit commit. その後、私git branch copygit checkout copy。最後に、単語ディレクトリにファイル b を作成しますgit add b

master ブランチにチェックアウトすると、Git はスマートに見えgit ls-filesますが、ファイル b がリストされていません。

リポジトリにはファイルが 1 つしかないので、混乱していindexます。どのように git でブランチの異なるステージング領域を同時に維持できますか?

編集:

ステージングされているがコミットされていないファイルを説明する方法は、ブランチごとに記憶されていますか?

4

2 に答える 2

4

実装については詳しく説明していませんが、ブランチを切り替えると、新しいの内容を反映するようにインデックスファイルが手動で更新されますHEAD

たとえば、ここでmaster(1つのファイルで)分岐し、test(2つのファイルで)分岐する必要があります。

noufal@sanitarium% git branch
  master
* test
noufal@sanitarium% file .git/index
.git/index: Git index, version 2, 2 entries
noufal@sanitarium% git checkout master
Switched to branch 'master'
noufal@sanitarium% file .git/index
.git/index: Git index, version 2, 1 entries

ブランチの切り替えが発生したときにインデックスが変更されました。

また、ブランチを「手動で」切り替えると、gitはインデックスを更新せず、混乱します。上から続けます。

noufal@sanitarium% more .git/HEAD
ref: refs/heads/master
noufal@sanitarium% echo "ref: refs/heads/test" > .git/HEAD
noufal@sanitarium% file .git/index
.git/index: Git index, version 2, 1 entries
noufal@sanitarium% git status
# On branch test
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       deleted:    b
#

つまり、インデックスには現在のリポジトリにあるファイルが欠落しているため、「削除のためにステージング」されます。

ステージング後のブランチの切り替えに関しては、インデックスは変更されない別の領域です。

noufal@sanitarium% git branch
* master
  test
noufal@sanitarium% ls
x
noufal@sanitarium% git status
# On branch master 
nothing to commit (working directory clean)
noufal@sanitarium% git checkout test
Switched to branch 'test'
noufal@sanitarium% ls
x
noufal@sanitarium% echo "Something" > b
noufal@sanitarium% git add b
noufal@sanitarium% git status
# On branch test   
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#
noufal@sanitarium% git checkout master
A       b
Switched to branch 'master'
noufal@sanitarium% git status                    # Also there in index on master branch.
# On branch master 
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#
noufal@sanitarium% git commit -m "Added b in master"
[master 41d0c68] Added b in master
 1 file changed, 1 insertion(+)
 create mode 100644 b
noufal@sanitarium% git status
# On branch master 
nothing to commit (working directory clean)
noufal@sanitarium% git checkout test
Switched to branch 'test'
noufal@sanitarium% ls                           # Missing in the test branch although it was `git add`ed here. 
x
noufal@sanitarium%        
于 2012-08-23T08:54:40.763 に答える
2

これを理解するには、git の内部をもう少し深く掘り下げる必要があります。

Git はあらゆる種類の情報をオブジェクトとして保存します。主に3種類のオブジェクトがあります。

  • ブロブ

    実際のファイル コンテンツを git に保存します。

  • ツリー構造の情報を保存します。他のブロブ オブジェクトやツリー オブジェクトへの参照が含まれる場合があります。

  • 専念

    コミットに関する情報を保存し、ツリー オブジェクトへの参照やその他の情報 (作成者、コミッター、コミット メッセージなど) を含めます。

インデックス ファイルは実際には、現在の作業ツリーに関する情報を表すツリー オブジェクトです。

各オブジェクトは、そのコンテンツの一意の sha1 ハッシュによって識別されます。の下.git/refsまたは中.git/packed_refsの git は、ブランチとそれが指すコミット オブジェクトの sha1 ハッシュとの関係を保持します。

新しいブランチをチェックアウトするたびに、git はそのブランチのコミットに関連付けられたツリー オブジェクトに従ってファイルを抽出し、新しいインデックス ファイルを生成します。

Git Internalsが役に立ちます。

于 2012-08-23T09:03:33.637 に答える