GIT:在几次提交后附加补丁

Dav*_*sky 8 git version-control dvcs

我使用git来跟踪我们的开发团队所做的更改并将其提交到我们的中央cvs样式的存储库中.由于它的cvs,它跟踪文件而不是提交,因此有时很难确切地说出哪些文件构成了bug补丁的完整补丁.我刚刚遇到一个并做了以下事情:

1)拖曳,检查CVS日志并将它们作为完整补丁提交给git

A--B--C--D
Run Code Online (Sandbox Code Playgroud)

2)发现了另一个实际用于票证(B)的文件更改,因此我将当前分支重置为B.

git reset --soft <sha1 ID for commit B>
Run Code Online (Sandbox Code Playgroud)

3)我复制更改,并将其附加到提交(B)

git commit --amend
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,树现在读了

A--B
Run Code Online (Sandbox Code Playgroud)

仅在工作树中提交(C)和(D).他们的详细信息已从日志中删除,我认为我无法取回它们.我哪里做错了?我唯一的选择是在(D)之上进行额外的提交,并且只知道它真的是(B)的一部分吗?

Cas*_*bel 14

发生了什么

你的意思是修改,而不是附加,对吧?为方便起见,我假装这是在一个名为master的分支上.这就是您的存储库现在的样子:

A---B' (master)
 \
  \-B---C---D
Run Code Online (Sandbox Code Playgroud)

Git提交明确依赖于他们的父母 - 在不同父级之上的相同补丁是不同的提交.

如何恢复

您可以通过几种方式恢复以前的位置.以前的位置有一个很好的速记,您可以使用它直接检查或创建分支:

git checkout master@{1}
git branch oldmaster master@{1}
Run Code Online (Sandbox Code Playgroud)

这是假设它是先前的第一个位置.它可能是第二个(master@{2})......或者如果你知道它是什么时候,你可以使用master@{7:35}master@{23.hours.ago}.有关这些表单的摘要,请参阅man git-rev-parse(在此处在线)的"指定修订"部分.

如果您不确定如何实现它,请尝试

git reflog show master
Run Code Online (Sandbox Code Playgroud)

这将为您提供以前的位置列表master,您应该能够从描述中判断出您想要的位置(或者尝试一些).您只需从列表中复制哈希值,然后使用git checkoutgit branch如上所述.

你应该做什么

警告:编辑历史记录是一个坏主意,如果它已经发布 - 在这种情况下,你应该只是提交修复.是的,将它分成存储库中的两个提交是很难看的,但是其他用户必须能够相信他们在公共存储中看到的内容不会改变!

也就是说,要进行这种特殊的历史编辑,你需要交互式变换:

git rebase -i master~4 master
Run Code Online (Sandbox Code Playgroud)

master~4表示在master的提示之前提交四个提交.你可以在这里使用你想要的任何形式 - 也许它是另一个分支,也许是一个提交哈希 - 无论什么工作.

这将在编辑器中打开您正在玩的提交列表:

pick <hash-A>  <message-A>
pick <hash-B>  <message-B>
pick <hash-C>  <message-C>
pick <hash-D>  <message-D>

# Rebase <hash-A^>..<hash-D> onto <hash-A^>
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
Run Code Online (Sandbox Code Playgroud)

注释掉的帮助文本非常明显.在这种情况下,您希望在提交B的行上将"选择"更改为"编辑",保存并退出.rebase将启动,并在申请B允许您进行更改后暂停.你会做你需要的,添加,使用git commit --amend,然后git rebase --continue.它会申请CD,你会做.如果中间出现任何问题,请使用git rebase --abort返回到您开始的位置.

重新定位可能有点吓人 - 例如,不要意外删除该列表中的行!如果你对它不熟悉,那么大量使用gitk和备份分支名称是个好主意.