9

我想知道是否有可能显示两个提交之间的差异是什么之一?换句话说,git 是否将修改后的提交保存在某个地方的历史记录中?

4

2 回答 2

5

修改后的提交与任何其他提交没有什么不同。从这个意义上说,完全有可能区分“正常”提交和修改后的提交。

换句话说,git 是否将修改后的提交保存在某个地方的历史记录中?

没有一些列表包含所有已修改的提交,不。修改后的提交就像所有其他提交一样在历史记录中。

当您修改提交时,它基本上会被删除并被一个新提交(它也获得一个新的提交哈希)替换,该提交具有原始提交的更改+修改后的更改。

在中git reflog您可以看到您最近的操作,这确实显示了提交的修改。来自那里的引用可用于例如撤消git commit --amend. 另请参阅如何撤消“git commit --amend”而不是“git commit”以获取更多详细信息。

于 2015-11-06T09:23:36.567 回答
2

我不认为我理解这个问题,但我认为部分原因是因为我认为你对做什么有错误的想法git commit --amend

git 中的提交实际上无法更改。所做git commit --amend的只是使用故意更改的父 ID 编写提交。

让我们看一下进行新提交的正常过程。

在进行新的提交之前,您修改工作树中的一些文件,然后使用git add暂存这些更改,以便提交文件的新版本。这git add会将文件的新版本放入 git 的“索引”,即它的暂存区。

已经在上一次提交中的文件已经在暂存区域中。因此,您将进行的新提交将包含所有原始文件,除了您更改的任何内容然后git add-ed 将是新版本而不是旧版本。

现在你运行git commit(不带--amend)并且 git 执行以下操作:

  • 收集提交消息(来自-m-F或运行您的编辑器);
  • 获取您的姓名和电子邮件,以及当前时间;
  • 获取当前提交的 SHA-1 ID(不是新的);
  • 使用暂存区编写一个“树”对象:这是将与新提交关联的源树;
  • 使用所有这些信息(作者+提交者、树、父 ID 和您的消息)创建一个提交对象——这个新的提交对象具有一个新的唯一 SHA-1 ID;
  • 最后,将新的 ID 写入分支,使分支标签指向新的 ID,而不是过去最尖端的分支。

最后一步“增长分支”,所以如果你曾经有一些提交,像这样:

... <- E <- F <- G   <-- master

你现在还有一个:

... <- E <- F <- G <- H   <-- master

分支名称(master或任何可能的名称)现在指向您的最新提交H,并H指向您过去的最新提交G

如果你使用git commit --amend,git 只会稍微改变这个序列:git 不会让新的提交 ( H) 指向当前的 ( G),而是让新的提交 ( ) 指向当前的父级(在这种情况下,F):

                G
              /
... <- E <- F <- H   <-- master

现在master(或您所在的任何分支)指向H,指向F,依此类推。

如果你运行git log,git 从当前提交 ( H) 开始并记录它,然后移动到它的父提交 ( ) 并记录F它,依此类推。提交G似乎消失了。

在“reflogs”中,SHA-1 IDG 仍然存在(默认为 30 天)。有一个 reflog HEAD,一个用于您当前的分支。如果您在分支上master并且刚刚完成H,那么master@{1}就是 的上一个提示master,即 commit G。或者,如果您将 SHA-1 ID 保存在屏幕上的某个位置,则可以剪切并粘贴它以查看 commit G

(该--amend开关也可以修改合并提交。这与上面的工作方式完全相同,只是意味着 git 必须将所有父 ID 从旧分支提示复制到新分支。)

于 2015-11-06T09:34:50.117 回答