从这里的其他答案来看,我对如何用来删除提交有点困惑git rebase -i
,所以我希望在这里记下我的测试用例是可以的(与 OP 非常相似)。
这是一个bash
脚本,您可以粘贴它以在文件夹中创建测试存储库/tmp
:
set -x
rm -rf /tmp/myrepo*
cd /tmp
mkdir myrepo_git
cd myrepo_git
git init
git config user.name me
git config user.email me@myself.com
mkdir folder
echo aaaa >> folder/file.txt
git add folder/file.txt
git commit -m "1st git commit"
echo bbbb >> folder/file.txt
git add folder/file.txt
git commit -m "2nd git commit"
echo cccc >> folder/file.txt
git add folder/file.txt
git commit -m "3rd git commit"
echo dddd >> folder/file.txt
git add folder/file.txt
git commit -m "4th git commit"
echo eeee >> folder/file.txt
git add folder/file.txt
git commit -m "5th git commit"
至此,我们有了一个file.txt
带有这些内容的:
aaaa
bbbb
cccc
dddd
eeee
此时,HEAD 处于第 5 次提交,HEAD~1 将是第 4 次 - 而 HEAD~4 将是第一次提交(因此 HEAD~5 将不存在)。假设我们要删除第三次提交 - 我们可以在myrepo_git
目录中发出以下命令:
git rebase -i HEAD~4
(请注意,git rebase -i HEAD~5
结果为“致命:需要单个修订;无效的上游 HEAD~5”。)文本编辑器(参见@Dennis 答案中的屏幕截图)将打开并显示以下内容:
pick 5978582 2nd git commit
pick 448c212 3rd git commit
pick b50213c 4th git commit
pick a9c8fa1 5th git commit
# Rebase b916e7f..a9c8fa1 onto b916e7f
# ...
所以我们得到了自(但不包括)我们请求的 HEAD~4 以来的所有提交。删除该行pick 448c212 3rd git commit
并保存文件;您将收到以下回复git rebase
:
error: could not apply b50213c... 4th git commit
When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To check out the original branch and stop rebasing run "git rebase --abort".
Could not apply b50213c... 4th git commit
此时folder/file.txt
在文本编辑器中打开 myrepo_git/;您会看到它已被修改:
aaaa
bbbb
<<<<<<< HEAD
=======
cccc
dddd
>>>>>>> b50213c... 4th git commit
基本上,git
看到当 HEAD 进行第二次提交时,有aaaa
+的内容bbbb
;然后它有一个添加的cccc
+补丁dddd
,它不知道如何附加到现有内容。
所以这里git
不能为你做决定——你必须做出决定:通过删除第三次提交,你要么保留它引入的更改(这里是 line cccc
) - 或者你不保留。如果你不这样做,只需使用文本编辑器删除额外的行 - 包括cccc
- folder/file.txt
,它看起来像这样:
aaaa
bbbb
dddd
...然后保存folder/file.txt
。myrepo_git
现在您可以在目录中发出以下命令:
$ nano folder/file.txt # text editor - edit, save
$ git rebase --continue
folder/file.txt: needs merge
You must edit all merge conflicts and then
mark them as resolved using git add
啊 - 所以为了标记我们已经解决了冲突,我们必须 git add
在folder/file.txt
做之前 , git rebase --continue
:
$ git add folder/file.txt
$ git rebase --continue
这里文本编辑器再次打开,显示该行4th git commit
- 在这里我们有机会更改提交消息(在这种情况下可以有意义地更改为4th (and removed 3rd) commit
或类似)。假设您不想 - 所以只需退出文本编辑器而不保存;一旦你这样做,你会得到:
$ git rebase --continue
[detached HEAD b8275fc] 4th git commit
1 file changed, 1 insertion(+)
Successfully rebased and updated refs/heads/master.
在这一点上,现在您有这样的历史记录(您也可以使用 saygitk .
或其他工具检查)的内容folder/file.txt
(显然,原始提交的时间戳未更改):
1st git commit | +aaaa
----------------------------------------------
2nd git commit | aaaa
| +bbbb
----------------------------------------------
4th git commit | aaaa
| bbbb
| +dddd
----------------------------------------------
5th git commit | aaaa
| bbbb
| dddd
| +eeee
如果以前,我们决定保留该行cccc
(我们删除的第三个 git 提交的内容),我们将拥有:
1st git commit | +aaaa
----------------------------------------------
2nd git commit | aaaa
| +bbbb
----------------------------------------------
4th git commit | aaaa
| bbbb
| +cccc
| +dddd
----------------------------------------------
5th git commit | aaaa
| bbbb
| cccc
| dddd
| +eeee
嗯,这是我希望我能找到的那种阅读,开始探索git rebase
在删除提交/修订方面是如何工作的;所以希望它也可以帮助其他人......