2

出于教育目的,我正在寻找一种方法来直观地演示 a 如何git reset修改HEAD和暂存索引。在这种情况下--mixed,也许--hard我想获得暂存索引的前后视图,以显示它是如何被修改的。的情况--soft应该证明它保持不变。

我一直在使用git status来演示这些过程,发现在“要提交的更改”部分显示待处理的更新git reset时说“暂存索引未更改”令人困惑。git status我了解到这git status并不代表 Staging Index 的状态,而是 Head 和 index 之间的差异。

到目前为止,我一直在使用以下示例进行演示:

git init .
touch reset_lifecycle_file
git add reset_lifecycle_file
git commit -am"initial commit"
echo 'hello git reset' >> reset_lifecycle_file
git commit -am"update content of reset_lifecycle_file"
git log
commit be4aaa98d6976531fdd28aeff52e233087066049
Author: kevzettler <kevzettler@gmail.com>
Date:   Thu Nov 30 15:31:16 2017 -0800

update content of reset_lifecycle_file

commit 5e2d74b369f57929673d873302eb7ebd752c2a95
Author: kevzettler <kevzettler@gmail.com>
Date:   Thu Nov 30 15:20:43 2017 -0800

initial commit

git status
On branch master
nothing to commit, working tree clean

如果我执行 git reset 到第一次提交,在回购生命的这一点上5e2d74b369f57929673d873302eb7ebd752c2a95

git reset --soft 5e2d74b369f57929673d873302eb7ebd752c2a95
git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   reset_lifecycle_file

这就是混乱的根源。我一直假设“要提交的更改”输出反映了索引的状态,然后假设--soft一直在修改所有 Git 文档状态都没有发生的索引。

我最近发现了git showandgit ls-files命令。我想知道这些是否可以更好地用于可视化这里的过程。

git show --full-index commit 5e2d74b369f57929673d873302eb7ebd752c2a95
Author: kevzettler <kevzettler@gmail.com> Date: Thu Nov 30 15:20:43
2017 -0800

initial commit

diff --git a/reset_lifecycle_file b/reset_lifecycle_file new file mode
100644 index
0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391

git show --full-index似乎将一些索引对象 SHA 附加到输出的末尾。我可以用它来指示对索引的重置更改吗?

git ls-files -s
100644 d7d77c1b04b5edd5acfc85de0b592449e5303770 0   reset_lifecycle_file

git lis-files-s还有另一个对象 SHA 我可以用它来指示索引的更改吗?在示例中的这一点上,它与输出中的 SHA 不同,git show是否表明 HEAD 位于新索引 SHA?

4

1 回答 1

1

你在正确的轨道上git ls-files。该命令实际上是管道。使用--stageor -s,它会列出索引中的每个条目(也称为暂存区),以及它的哈希 ID。

这不会显示对索引的更改。索引本身只是一种状态:它是一个文件,其中包含一组文件,如果您运行git commit,则这些文件将被提交,或者在某些情况下,是您必须解决的持续冲突。因此,要显示对索引的更改,您必须查看一次,然后对其进行一些更改,然后再查看一次。无论两个“查看”步骤的两个输出有何不同,这两次之间的索引发生了什么变化。

(有一些索引条目git ls-files -s没有显示,因为索引也有缓存的作用。添加--debug显示文件条目的缓存信息,但仍然跳过与文件不对应的特殊缓存条目,例如那些记录扩展名,或跟踪未跟踪的文件。后者听起来像是自相矛盾,有点像:缓存至少有时会缓存未跟踪的文件和/或目录数据,以加快稍后的速度git status。因为所有这些条目都不参与在提交中,git ls-files直接跳过它们。)

索引的内部格式复杂,只有半文档化;见 Git 的Documentation/technical/index-format.txt文件。然而,外部视图相当简单:对于存储在索引中的每个文件,因此将在下一次提交中,索引具有:

  • 模式:100644100755任何 blob;
  • 哈希(现在是 SHA-1,也许有一天会更大);
  • 阶段编号:通常为0,但在合并时可能为1、2或3;1
  • 文件的路径名,包括前导目录,例如xdiff/xprepare.c.

同时,git show将提交与其父级进行比较:它很像git log -p -1. 2 这意味着它不查看索引。您在此处获得的index:行给出了正在区分的父文件和子文件的 blob 哈希。

(另外,git status实际上显示了两个 git diff命令的输出:一个用于HEADvs index,一个用于 index vs work-tree。)


1较高编号的阶段条目的存在会阻止进行任何新的提交。您只能在将所有这些解析回正常的零阶段条目后提交。

2如果当前提交是合并,则git show生成组合差异。所以它实际上相当于git log -p -1 --cc.

于 2017-12-01T00:33:05.607 回答