Java服务_git命令合并或删除提交记录

Java服务_git命令合并或删除提交记录

git reset回滚到指定commit

1.现在有两个commit

使用git log查看commit日志和对应hash码

1
2
3
4
5
6
7
8
9
10
11
12
13
commit def5adef853da4cc05752bdb36577c127be71ba5

Author: xxx
Date: Thu Dec 28 16:01:36 2017 +0800

优化代码

commit f36801544670e00b2f59a28e19017d2786c4085e
Author: xxx
Date: Thu Dec 28 15:59:46 2017 +0800

修复
(END)

2.需要回滚到上一次或者之前某次commit之后

使用如下命令可以回到上一次commit之后

1
git reset --hard HEAD^

使用如下命令也可以回到上一次commit之后

1
git reset --hard HEAD~1

使用如下命令可以回到指定某次commit之后

1
git reset --hard f36801544670e00b2f59a28e19017d2786c4085e

3.执行完之后查看日志确认

使用git log查看commit日志可以发现回到了指定reset的那次commit之后

1
2
3
4
5
6
7
8
git log

commit f36801544670e00b2f59a28e19017d2786c4085e
Author: xxx
Date: Thu Dec 28 15:59:46 2017 +0800

修复
(END)

4.如果你发现回滚错了,还能补救

使用git reflog命令可以查看reset在内的commit日志

1
2
3
4
5
6
7
git reflog

f368015 HEAD@{0}: reset: moving to f36801544670e00b2f59a28e19017d2786c4085e
def5ade HEAD@{1}: reset: moving to def5ade
f368015 HEAD@{2}: reset: moving to f36801544670e00b2f59a28e19017d2786c4085e
def5ade HEAD@{3}: commit: 优化代码
f368015 HEAD@{4}: commit (initial): 修复

然后再用git reset即可定位到目标comimt之后

1
git reset --hard def5ade

5.如果要将reset推到远程仓库,需要使用强推

因为此时本地库head指定的commit版本要比远程仓库更旧

1
git push -f

由此可见git reset可以很方便的回到历史某一commit之后,缺点是该commit后面的所有改动提交都会被删除。如果想要只删除一次commit,保留后续commit,就需要使用另一个命令git revert。

git revert删除指定commit,但是留下commit记录

1.现在有三个commit

使用git log查看commit日志和对应hash码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
commit def5adef853da4cc05752bdb36577c127be71ba5

Author: xxx
Date: Thu Dec 28 16:02:36 2017 +0800

优化代码
commit 853dadef5adef4cc05752bdb36577c127be71ba5

Author: xxx
Date: Thu Dec 28 16:01:36 2017 +0800

增加文件
commit f36801544670e00b2f59a28e19017d2786c4085e
Author: xxx
Date: Thu Dec 28 15:59:46 2017 +0800

修复
(END)

2.现在想要删除第二个commit所提交的改动

也就是想要删除’增加文件’这一步对应的代码改动,那么可以使用git revert -n命令指定hash码进行反做

1
git revert -n 853dadef5adef4cc05752bdb36577c127be71ba5

这时可能会出现冲突,那么需要手动修改冲突的文件,修改之后就相当于又有新代码了,然后需要重新add提交一下

1
2
git add .
git commit -m "重做 增加文件"

3.执行完之后git log查看日志

会发现原来的commit日志记录还在,这次还增加了一个commit日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
git log

commit 05752def5adef853da4ccbdb36577c127be71ba5
Author: xxx
Date: Thu Dec 28 16:01:36 2017 +0800

重做 增加文件

commit def5adef853da4cc05752bdb36577c127be71ba5
Author: xxx
Date: Thu Dec 28 16:01:36 2017 +0800

优化代码
commit 853dadef5adef4cc05752bdb36577c127be71ba5
Author: xxx
Date: Thu Dec 28 16:01:36 2017 +0800

增加文件
commit f36801544670e00b2f59a28e19017d2786c4085e
Author: xxx
Date: Thu Dec 28 15:59:46 2017 +0800

修复
(END)

4.如果这个时候需要推远程仓库,直接git push即可

1
git push

由此可见git revert其实就是帮你快速定位复现某次commit的代码改动点,并辅助你快捷删除,但是本质还是一次commit代码改动。这种方法可以帮助我们快速删除历史某次commit代码,但是commit日志的记录还在,让人看上去并不舒服,如果想要把对应commit日志记录也删除,需要使用git rebase命令。

git rebase删除指定commit,并清理commit日志记录

1.现在有三个commit

使用git log查看commit日志和对应hash码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
commit def5adef853da4cc05752bdb36577c127be71ba5

Author: xxx
Date: Thu Dec 28 16:02:36 2017 +0800

优化代码
commit 853dadef5adef4cc05752bdb36577c127be71ba5

Author: xxx
Date: Thu Dec 28 16:01:36 2017 +0800

增加文件
commit f36801544670e00b2f59a28e19017d2786c4085e
Author: xxx
Date: Thu Dec 28 15:59:46 2017 +0800

修复
(END)

2.用git rebase –onto删除第二个commit带来的代码改动

也就是要删除’增加文件’这一次commit,也就是853dade这次,我们可以使用git rebase --onto [startpoint] [endpoint]命令来删除目标commit,假设是在bugfix_1215分支上,可以使用如下命令

1
git rebase --onto bugfix_1215~853dade bugfix_1215~def5ade bugfix_1215

或者

1
git rebase --onto bugfix_1215~2 bugfix_1215~1 bugfix_1215

3.也可以用git rebase -i打开commit日志文件进行删除操作

注意如果是要删除某次commit,一定要git rebase -i指定这次commit之前一次commit的hash码,因为git rebase -i命令是前开后闭的,不会展示指定的commit日志,而是展示指定commit之后的所有commit日志

1
git rebase -i f368015

然后会进入commit日志文件

1
2
3
4
5
6
7
8
9
10
11
12
pick 853dade 增加文件
pick def5ade 优化代码

#
# 命令:
# p, pick <提交> = 使用提交
# r, reword <提交> = 使用提交,但编辑提交说明
# e, edit <提交> = 使用提交,但停止以便在 shell 中修补提交
# s, squash <提交> = 使用提交,但挤压到前一个提交
# f, fixup [-C | -c] <提交> = 类似于 "squash",但只保留前一个提交
# 的提交说明,除非使用了 -C 参数,此情况下则只
"~/IdeaProjects/clickhouse2hbase/.git/rebase-merge/git-rebase-todo" 29L, 1418B

按i进入编辑,将853dade这个hash码前面的pick改为drop即可删除提交内容,但是同样可能会有冲突,需要手动修改一下,这也可能会带来一个新的commit。

4.同步到远程仓库需要强推

1
git push -f

要注意的是,这样做会 彻底删掉那条commit,唯一的找回方式还是通过git reflog。

git rebase合并commit

git rebase除了可以用于无痕删除commit之外,另一个作用是可以合并多次commit。在开发和调试是可能有很多杂乱的commit记录,最后提交合并时,为了cr可读性需要合并多次commit。

主要还是使用git rebase -i命令,比如有顺序提交的a、b、c、d四次commit,想要合并b、c、d三次commit。那么由于git rebase -i命令的前开后闭特性,需要使用git rebase -i a命令展示出同时包含b、c、d三次commit的日志文件如下

1
2
3
4
5
6
7
8
9
10
11
12
13
pick b 第二次提交
pick c 第三次提交
pick d 第四次提交

#
# 命令:
# p, pick <提交> = 使用提交
# r, reword <提交> = 使用提交,但编辑提交说明
# e, edit <提交> = 使用提交,但停止以便在 shell 中修补提交
# s, squash <提交> = 使用提交,但挤压到前一个提交
# f, fixup [-C | -c] <提交> = 类似于 "squash",但只保留前一个提交
# 的提交说明,除非使用了 -C 参数,此情况下则只
"~/IdeaProjects/clickhouse2hbase/.git/rebase-merge/git-rebase-todo" 29L, 1418B

然后保留最老的一次commit b不动,将c、d前面的pick改成s,然后按esc推出编辑模式,输入:wq保存文件。

之后会马上跳转到commit描述日志文件中,然后同样进入编辑模式,合并为一天commit描述信息,再推出保存即可。

完事之后同步到远程仓库也需要git push -f强推。

squash merge合并commit

squash merge才是我用的最多的合并commit方法,非常方便快捷。

squash merge是一种git合并的方法,可用于将一个分支的多个小的commit整合成一个更干净的提交以便于代码审查和保持版本历史的整洁,特别适用于团队协作项目。

以下是使用Squash merge的步骤:

  1. 在开发分支上进行开发并提交多个小的commit。
  2. 切换到全新分支(通常是从最新master分支checkout出来的一个全新分支)。
  3. 运行git merge --squash branch-name,其中branch-name是开发分支名称,这将把开发分支上的所有改动都应用在全新分支上。
  4. 在全新分支上运行git commit来创建一个新的合并提交,这个提交将包含所有开发分支上的代码更改。
  5. 编写合并提交的信息,并保存退出。
  6. 运行git push将合并提交推送到远程仓库。

参考文献

Git如何删除某次commit 操作

【git】如何利用 rebase 合并多次 commit

Git rebase skip误操作后,找回提交的commit