从这里的其他答案中,我对如何 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.
至此,您已经有了一个这样的历史记录(也可以使用say gitk .
或其他工具检查)历史记录的内容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
(我们删除的第3个git commit的内容),我们将拥有:
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
删除提交/修订的工作方式。所以希望它也可以帮助其他人...