当git reset修改HEAD和Staging Index状态时,如何获得视觉输出?

时间:2017-12-01 00:10:13

标签: git git-reset git-show

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

我一直在使用git status来演示git reset进程,并且当git status在“要提交的更改中显示待处理的更新”时发现“暂存索引未更改”会让人感到困惑“ 部分。我开始了解到git status并不代表分期索引的状态,而是代表Head和索引之间的差异。

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

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

,那么在repos生命中的这一点
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 showgit 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似乎将一些索引Object SHA附加到输出的末尾。我可以使用它来指示重置更改索引吗?

git ls-files -s
100644 d7d77c1b04b5edd5acfc85de0b592449e5303770 0   reset_lifecycle_file

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

1 个答案:

答案 0 :(得分:1)

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

这不会显示索引的更改。索引本身只是一个状态:它是一个文件,包含在运行git commit时将提交的文件集,或者在某些情况下,还包含您必须解决的持续冲突。因此,要显示索引的更改,您必须查看一次,然后对其进行一些更改,然后再次查看它。两个输出的两个不同之处是什么?看看&#34;步骤是这两次之间索引的变化。

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

索引的内部格式很复杂,只有半文件记录;见Git&#39; Documentation/technical/index-format.txt file。但是,外部视图非常简单:对于存储在索引中的每个文件,因此将在下一次提交时,索引具有:

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

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

(另外,git status实际上显示了两个 git diff命令的输出:一个用于HEAD对比索引,一个用于索引与工作树。 )

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

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