.git / index文件中最细粒度的操作是什么?

时间:2014-02-05 23:56:56

标签: git

某些git命令(例如git add ...)会修改.git/index文件的状态,但我认为某些此类操作可能被视为一系列较小的操作。例如,

git add foo bar

可以分解为

git add foo
git add bar

事实上,可能(据我所知)上面的命令可能被分解为“更细粒度”(但仍然是“.git/index - 修改”)git命令。 / p>

我的问题是,使用.git/index命令可以在git文件上执行哪些最细粒度的修改? IOW,.git/index上的“原子”命令行操作是什么?

我想所有这些命令都是管道命令。此外,如果我不得不猜测,我认为gid add <file>git rm --cached <file>将近似于其中两个操作。另一方面,git mv <old> <new>可能是“原子”删除,然后是“原子”添加的复合......

编辑:这个问题的动机如下。

我发现最令人困惑的git行为的方面是导致修改.git/index文件的行为。 git那些对检查更加开放的其他所有内容。但是,.git/index文件非常不透明。

出于这个原因,我想更好地了解.git/index文件的修改方式。

2 个答案:

答案 0 :(得分:2)

主索引由多个索引条目组成,条目集合表示下一次提交的内容。当您git add文件时,它会添加(或更新)给定文件名的索引条目。

索引条目本身包含几个与分阶段更改(对象ID和模式)相关的字段,以及与工作目录中的内容(时间戳,文件大小等)相关的字段。您可以使用git ls-files命令查看这两个命令:

C:\Temp\TestRepo>git add file.txt

C:\Temp\TestRepo>git ls-files --stage
100644 9b72baa6b025e0eb1dd8f1fd23bf5d5515012cd6 0       file.txt

C:\Temp\TestRepo>git ls-files --debug
file.txt
  ctime: 1391645170:0
  mtime: 1391645172:0
  dev: 0        ino: 0
  uid: 0        gid: 0
  size: 7       flags: 0

一般来说,只需使用git addgit rm命令添加,更新和删除主索引中的条目。但是,某些命令只会更新部分索引条目。例如,git checkoutgit status将写入索引条目的工作目录缓存内容。例如:

C:\Temp\TestRepo>touch file.txt

C:\Temp\TestRepo>git status
# On branch master
nothing to commit, working directory clean

C:\Temp\TestRepo>git ls-files --debug
file.txt
  ctime: 1391645170:0
  mtime: 1391645458:0
  dev: 0        ino: 0
  uid: 0        gid: 0
  size: 7       flags: 0

(请注意索引条目中更新的mtime(修改时间)字段。

您可以在单个命令中对索引进行的最小单个更改是翻转文件中假设未更改的位:

C:\Temp\TestRepo>git update-index --assume-unchanged file.txt

C:\Temp\TestRepo>git ls-files --debug
file.txt
  ctime: 1391645170:0
  mtime: 1391645458:0
  dev: 0        ino: 0
  uid: 0        gid: 0
  size: 7       flags: 8000

(注意flags字段从0x0000到0x8000的更改,翻转一位。)

答案 1 :(得分:0)

一般来说,git只不过是一个复杂的键值存储,它实际上有一些存储在树中的对象blob。

您可能希望阅读有关Git Objects的内容,这些内容取自官方Git Internals文档,以确切了解它们是如何组合在一起的。

具体来说,关于你的问题:

  

...当您运行git addgit commit命令时Git会执行什么操作 - 它为已更改的文件存储blob,更新索引,写出树,并写入引用的提交对象顶级树和紧接着它们的提交。