git中的索引,缓存和暂存之间有什么区别?

all*_*ode 44 git

这些是一回事吗?如果是这样,为什么会有这么多条款?!

另外,我知道有一个名为git stash的东西,你可以在这里暂时存储对工作副本的更改而不将它们提交给repo.我发现这个工具真的很有用,但同样,这个名字与git中的一堆其他概念非常相似 - >这非常令人困惑!

Mic*_*urr 37

索引/阶段/缓存是一回事 - 至于为什么这么多术语,我认为索引是'原始'术语,但人们发现它令人困惑,所以引入了其他术语.而且我同意它有时会让事情有点混乱.

stashgit 的工具是一种存储"进行中"工作的方法,您现在不想在存储在特定存储目录/数据库中的提交对象中提交该工作.基本stash命令将存储对工作目录所做的未提交的更改(缓存/暂存和未缓存/未暂存的更改),然后将工作目录还原为HEAD.

它与索引/阶段/缓存并不真正相关,只是它会存储缓存中未提交的更改.

这使您可以快速保存脏工作目录和索引的状态,以便在干净的环境中执行不同的工作.稍后您可以获取存储对象中的信息并将其应用到您的工作目录(即使工作目录本身处于不同的状态).

官方手册git stash页有很好的细节,但仍然可以理解.它还有关于如何stash使用的场景的很好的例子.

  • git stash与其他人不同:它更像是"匿名提交" (3认同)
  • 但如果索引可以[在合并期间存储多个阶段](http://alblue.bandlem.com/2011/10/git-tip-of-week-index-revisited.html),那么是不是指数和阶段之间的技术差异?索引是一个文件; stage是工作文件系统的抽象表示,并使用唯一的文件格式在索引中编码(并且索引在合并期间可以有多个阶段).但在大多数情况下,这些词是可互换的. (3认同)
  • @allyourcode:在我的一次临时编辑中,我试图明确表示已将暂存和未分阶段的更改*包含在存储中.但看起来我不小心放弃了一些东西并且答案不那么明确.希望现在已经修好了. (2认同)

wis*_*cky 8

这确实令人困惑.这三个术语可互换使用.以下是我为什么要把它们称为每一件事.git索引是:

  • 二进制文件.git/index,它是所有跟踪文件的索引
  • 用作提交的暂存区域
  • 包含文件的缓存 SHA1哈希值(提高性能)

一个重要的注意事项是索引/缓存/阶段包含源代码管理下的所有文件列表,甚至是未更改的文件.不幸的是,诸如"将文件添加到索引"或"文件被暂存到索引"之类的短语可能会误导性地暗示索引仅包含已更改的文件.

这是一个演示,显示git索引包含所有文件的列表,而不仅仅是已更改的文件:

# setup
git init

echo 'x' > committed.txt
git add committed.txt
git commit -m 'initial'

echo 'y' > staged.txt
git add staged.txt

echo 'z' > working.txt

# list HEAD
git ls-tree --name-only -r HEAD
# committed.txt

# list index
git ls-files
# committed.txt
# staged.txt

# raw content of .git/index
strings .git/index
# DIRC
# committed.txt
# staged.txt
# TREE

# list working dir
ls -1
# committed.txt
# staged.txt
# working.txt
Run Code Online (Sandbox Code Playgroud)

补充阅读:

https://www.kernel.org/pub/software/scm/git/docs/technical/racy-git.txt

git索引包含什么?