本文共 7051 字,大约阅读时间需要 23 分钟。
相信大家都知道 git 下面的这个命令了:
git commit --amend
通过这个命令可以修改最新的 commit 提交。也就是指向当前 HEAD 的那次提交。但是,如果想修改的是倒数第二次 commit 提交而又不想惊动倒数第一次的 commit 提交,应该怎么办呢?
git rebase 就像一块臭豆腐,没吃之前闻起来好臭,吃过以后发现“真香”。不过话说回来,git rebase 也算是 git 里边的高级操作了,下来我们就来看看是怎么用它来修改倒数第二个 commit 的吧!
任何东西都有个因果缘由,我写这篇博客的原因也是。
某天,我修改了程序文件的某个功能,因为逻辑上是两个东西,所以对这两次修改分别提交了两次 commit,然后 gmail 出去了,结果被 committer 指出我第一次的 commit 提交有问题,还需要进行修改,但是第二次提交应该是没有问题的。
[root@master GitTest]# git logcommit a892d9e31d85c2d37eb036d3ef89197a7bceaacb (HEAD -> master)Author: lookingDate: Mon Aug 31 21:29:24 2020 +0800 nice to meet you toocommit 155cd2e87152c5f60a2421651a86690f7cd984c6Author: looking Date: Mon Aug 31 21:16:51 2020 +0800 nice to meet youcommit 3f2061298d921378da14f4003753f1f277e67243 (origin/master)Author: looking Date: Thu Aug 20 23:02:46 2020 +0800 I am Looking add one line in hello.txt Signed-off-by: Lu Kaiyi
那么?现在该怎么办?我有以下几个选择。
git reset --hard HEAD^1
由于本地提交了两次而且还没有 Applied 到远端,所以领先了远端 2 个 commit。
[root@master GitTest]# git statusOn branch masterYour branch is ahead of 'origin/master' by 2 commits. (use "git push" to publish your local commits)nothing to commit, working tree clean
既然要修改倒数第二个 commit,那我就把 HEAD 切换过那去,修改文件,暂存文件,重新提交 commit:
[root@master GitTest]# git reset --hard HEAD^1HEAD is now at 155cd2e nice to meet you[root@master GitTest]# vim hello.txt [root@master GitTest]# git add hello.txt [root@master GitTest]# git commit --amend
这样做似乎没什么问题,毕竟倒数第二次 commit 的 bug 已经成功修复。但是,我倒数第一次的 commit 和对文件的修改都丢失了,现在不得不重新提交一遍,真 TMD * 蛋(心中暗暗骂了一句)。所以,这只能算是不怎么地的一个可选方案了。
git reset HEAD~
你可能想,我只撤销倒数第一次的 commit,不撤销倒数第一次的文件修改,不还是能回到倒数第二次的 commit 去!
[root@master GitTest]# git reset HEAD~Unstaged changes after reset:M hello.txt[root@master GitTest]# git logcommit 3d879227e4fe5f1091ec431a767308edb3059e21 (HEAD -> master)Author: lookingDate: Mon Aug 31 21:16:51 2020 +0800 nice to meet youcommit 3f2061298d921378da14f4003753f1f277e67243 (origin/master)Author: looking Date: Thu Aug 20 23:02:46 2020 +0800 I am Looking add one line in hello.txt Signed-off-by: Lu Kaiyi
但是你看下边,commit 虽然已经撤销了,但是文件还是被追踪到为 modified,如果两次是对不同文件 commit 的话其实还行(毕竟这种情况你至少可以使用 git add file 单独添加文件到暂存区)。但是如果你倒数第二次和倒数第一次 commit 修改的是同一个文件的内容,岂不又 GG 了,毕竟现在可能没办法做到只 commit 文件的一部分修改(没说太绝,怕打脸)。还有一点就是我倒数第一个 commit 提交写的 comment 内容实在太多了,现在都没了,我还得重新写一遍 commit comment,还是有点不爽快:
[root@master GitTest]# git statusOn branch masterYour branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits)Changes not staged for commit: (use "git add..." to update what will be committed) (use "git restore ..." to discard changes in working directory) modified: hello.txtno changes added to commit (use "git add" and/or "git commit -a")
git rebase -i HEAD~2 和 git rebase --continue
[root@master GitTest]# git logcommit a892d9e31d85c2d37eb036d3ef89197a7bceaacb (HEAD -> master)Author: lookingDate: Mon Aug 31 21:29:24 2020 +0800 nice to meet you toocommit 155cd2e87152c5f60a2421651a86690f7cd984c6Author: looking Date: Mon Aug 31 21:16:51 2020 +0800 nice to meet youcommit 3f2061298d921378da14f4003753f1f277e67243 (origin/master)Author: looking Date: Thu Aug 20 23:02:46 2020 +0800 I am Looking add one line in hello.txt Signed-off-by: Lu Kaiyi
git rebase -i HEAD~2 以后,git 会自动给你切换到下面这个界面,你将你需要修改的那个 commit 前边的 pick 修改为 edit。
[root@master GitTest]# git rebase -i HEAD~2edit 3d87922 nice to meet youpick df5f952 nice to meet you too# Rebase 3f20612..df5f952 onto 3f20612 (2 commands)## Commands:# p, pick= use commit# r, reword = use commit, but edit the commit message# e, edit = use commit, but stop for amending# s, squash = use commit, but meld into previous commit# f, fixup = like "squash", but discard this commit's log message# x, exec = run command (the rest of the line) using shell# b, break = stop here (continue rebase later with 'git rebase --continue')# d, drop = remove commit# l, label
然后保存退出,而且 git 也已经提醒你版本已经 stopped 在这个 commit 节点了,你可以开始你的表演(修改)了:
[root@master GitTest]# git rebase -i HEAD~2Stopped at 3d87922... nice to meet youYou can amend the commit now, with git commit --amend Once you are satisfied with your changes, run git rebase --continue
假如我想把原来插入的 nice to meet you 修改为 nice。用 vim 修改后用 git commit --amend 重新提交 commit。
[root@master GitTest]# vim hello.txt[root@master GitTest]# git add hello.txt [root@master GitTest]# git commit --amendnice # Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.## Date: Mon Aug 31 21:16:51 2020 +0800## interactive rebase in progress; onto 3f20612[detached HEAD bcbfd91] nice Date: Mon Aug 31 21:16:51 2020 +0800 1 file changed, 1 insertion(+)
然后继续 git rebase --continue 就好了(如果没有冲突,直接 git rebase --continue 也是极好的)。
[root@master GitTest]# git add hello.txt [root@master GitTest]# git rebase --continue[detached HEAD 72017cd] nice to meet you too 1 file changed, 1 insertion(+)Successfully rebased and updated refs/heads/master.
如果是对同一个文件修改的话,还是需要自己处理冲突的,不过至少把你当前的提交和最后一次提交的冲突反映到了文件。处理完成以后,重新对冲突文件进行 git add file 来表示你已经处理好冲突了,然后再次执行 git rebase --continue 就大功告成(git 已经帮你把最后一次 commit comment 保存起来的,所以不用担心重新写提交 comment 的问题啦) 。
[root@master GitTest]# git rebase --continueAuto-merging hello.txtCONFLICT (content): Merge conflict in hello.txterror: could not apply df5f952... nice to meet you tooResolve all conflicts manually, mark them as resolved with"git add/rm", then run "git rebase --continue".You can instead skip this commit: run "git rebase --skip".To abort and get back to the state before "git rebase", run "git rebase --abort".Could not apply df5f952... nice to meet you too[root@master GitTest]# git add hello.txt [root@master GitTest]# git rebase --continue[detached HEAD 72017cd] nice to meet you too 1 file changed, 1 insertion(+)Successfully rebased and updated refs/heads/master.
最后查看日志和文件内容,已经成功修改。
[root@master GitTest]# git logcommit 72017cd6e0222ff5fb544ce460ad3f2b046952ed (HEAD -> master)Author: lookingDate: Mon Aug 31 21:59:19 2020 +0800 nice to meet you toocommit 50a084c8cce985ba6b5ee9bb7bce7a950671bb8eAuthor: looking Date: Mon Aug 31 21:16:51 2020 +0800 nicecommit 3f2061298d921378da14f4003753f1f277e67243 (origin/master)Author: looking Date: Thu Aug 20 23:02:46 2020 +0800 I am Looking add one line in hello.txt
如果你在 rebase 的任何过程中想退出 rebase 过程,直接执行 git rebase --abort 就直接退出回到 rebase 之前的状态啦。
转载地址:http://kjjqi.baihongyu.com/