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

时间:2010-08-18 21:23:01

标签: git

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

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

2 个答案:

答案 0 :(得分:35)

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

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

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

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

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

答案 1 :(得分:7)

确实非常令人困惑。这三个术语可互换使用。以下是我为什么要把这些事情称为每一件事。 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

补充阅读:

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

What does the git index contain EXACTLY?