当我们有多个commit或者从开源处拿到多个commit时,想合成一个commit,并保留每个commit的message时,大家都知道用"git rebase -i"可以解决,但这种方式需要手动进行操作,假如我们要处理的比较多,就想要自动化来处理,下面介绍下怎么自动化处理。

git rebase逻辑

当我们"git rebase -i"后,git在当前.git/rebase-merge目录下生成git-rebase-todo文件,然后调用git editor来让用户编辑git-rebase-todo文件进行处理,如果实现自动化就需要:

  1. 修改git editor来使用我们提供的;
  2. 脚本来处理进行git-rebase-todo文件的处理。

git editor的修改

git提供config命令来查看配置和修改配置,同样editor也可以这样进行设置。

    git config core.editor #查看当前使用editor
git config --local --replace-all core.editor NEW_EDITOR # 修改当前的仓库的editor为NEW_EDITOR

处理git-rebase-todo文件

pick 62e0071 first commit
pick 3bd641a second commit
pick 92c03c7 third commit # 变基 7073047..92c03c7 到 7073047(3 个提交)
#
# 命令:
# p, pick <提交> = 使用提交
# r, reword <提交> = 使用提交,但修改提交说明
# e, edit <提交> = 使用提交,进入 shell 以便进行提交修补
# s, squash <提交> = 使用提交,但融合到前一个提交
# f, fixup <提交> = 类似于 "squash",但丢弃提交说明日志
# x, exec <命令> = 使用 shell 运行命令(此行剩余部分)
# b, break = 在此处停止(使用 'git rebase --continue' 继续变基)
# d, drop <提交> = 删除提交
# l, label <label> = 为当前 HEAD 打上标记
# t, reset <label> = 重置 HEAD 到该标记
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . 创建一个合并提交,并使用原始的合并提交说明(如果没有指定
# . 原始提交,使用注释部分的 oneline 作为提交说明)。使用
# . -c <提交> 可以编辑提交说明。
#
# 可以对这些行重新排序,将从上至下执行。
#
# 如果您在这里删除一行,对应的提交将会丢失。
#
# 然而,如果您删除全部内容,变基操作将会终止。
#
# 注意空提交已被注释掉

上面是有3个commit,需要将后面2个commit合并到第1个,通过后面的注释可以看到,squash是将commit合并到前一个commit上,所以需要将后2个的pick修改为squash,即修改为下面这样:

pick 62e0071 first commit
squash 3bd641a second commit
squash 92c03c7 third commit

Python实现

使用python实现上述逻辑

#!/usr/bin/env python3
#encoding: UTF-8 import os
import sys def change_editor(current_file):
os.system("git config --local --replace-all core.editor " + current_file) # 将当前脚本设置为editor
os.system("git rebase -i") # 执行rebase,触发调用该脚本进行rebase
os.system("git config --local --replace-all core.editor vim") # 执行完后将editor设置回vim def rebase_commits(todo_file):
with open(todo_file, "r+") as f:
contents = f.read() # 读取git-rebase-todo文件内容
contents = contents.split("\n")
first_commit = True
f.truncate()
f.seek(0)
for content in contents:
if content.startswith("pick"):
if first_commit:
first_commit = False
else:
content = content.replace("pick", "squash") # 将除了第一个pick修改为squash
f.write(content + "\n") def main(args):
if len(args) == 2: # 如果将该脚本作为editor,git会调用该脚本,并以git-rebase-todo文件作为第2个参数
rebase_commits(args[1])
else:
change_editor(os.path.abspath(args[0])) # 设置git editor if __name__ == "__main__":
main(sys.argv)

URL: https://liwugang.github.io/2019/04/28/git_commits.html

Git自动化合并多个Commit的更多相关文章

  1. git rebase合并多个commit总结

    git rebase 合并多个commit 方法 在开发过程中,有时一个任务会分几次commit提交,这样可能对于有些分支要cherry pick时会比较麻烦,这是我们可以通过git rebase 将 ...

  2. 巧用 git rebase 合并多个 commit。

    一.为什么需要合并多个 commit 呢?   有时候,我们开发一个功能. 修修补补 commit 了很多次,过多的 commit 会显得很复杂. 不够直观,不能比较清晰查看那些 commit 是对应 ...

  3. Git合并最近的commit

    合并commit的做法一般用在pull request的时候,把开发同一功能时的所有琐碎的commit合并到一个(假装自己的代码是高质量代码(手动滑稽)).主要使用的命令是git rebase 或者g ...

  4. (转)git合并多个commit

    原文地址:http://platinhom.github.io/2016/01/02/git-combine_commit/ 有时commit多了看着会不爽.所以想合并掉一些commit. 这里是最简 ...

  5. git 几个commit点合并成一个commit点

    在用git做版本控制器的时候,经常会遇到以下情况: 1.在做1个功能的时候,你自己觉得代码没问题了,就本地commit,然后提交代码,在gitlab上发起和并请求,老大看完之后,觉得你还有修改的地方, ...

  6. Git如何合并Commit

    如果你在 push 你的修改之前想要将本地多次修改后的 commit 合并一下变得更好看,可以使用下面的方法. 指定你要合并的 commit 相关的命令有两种 你可以通过指定修改过去的几个 commi ...

  7. Git分支合并选择

    用Git进行多人协作开发时,必然会合并代码,解决冲突.然而合并代码也是需要点技巧的,如果对一些关键命令没有理解去使用的话,git的版本演进路线就会变得很乱,从而造成了日后维护的一些麻烦. Git上合并 ...

  8. git 分支合并 强制合并

    常用的提交流程git add *.XXXgit commit -m "备注....." # 提交到本地分支git fetch git merge #"合并远程分支情况,如 ...

  9. Git分支合并冲突解决(续)

    接Git分支合并冲突解决,在使用rebase合并冲突情况下,如果不小心,执行完add后执行了commit,此时本地仓库HEAD处于游离态(即HEAD指向未知的分支),如何解决? 解决方法 (1)此时, ...

随机推荐

  1. nginx配置ssl证书

    一:加装nginx的ssl模块 1.1:切换到源码包 cd /zz/nginx-1.14.2 1.2:查看已安装模块 /usr/local/nginx/sbin/nginx -V [root@game ...

  2. MySQL免编译二进制包安装简记

    相比较于MySQL的源代码安装来说.免编译二进制包的速度实在是快了太多,而且性能损失也不是很大,同时具有一定的定制性.所以,如果没有特殊的 需求,尽量用MySQL免编译二进制包来安装MySQL. 1. ...

  3. win10下运行cmd闪退时检查方法

    在cmd下运行 exe加空格加斜杠加问号

  4. struts2的文件配置以及注释代码

    <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC "-/ ...

  5. 设置ul的指定li 样式

    设置ul的最后li 的样式 .custom-consumerIndex .card-content .list-block ul li:last-child .item-inner { border- ...

  6. bll

    string str = ConfigurationManager.AppSettings["DBName"].ToString(); public Studal ss() { A ...

  7. IDEA Maven项目默认编译器使用JDK1.5的解决办法

    在idea中创建maven项目,项目指定用jdk1.8编译,每次更新maven库后,都会重新变成1.5.解决方案: 第一种: 在pom文件中,增加如下代码: <properties> &l ...

  8. iptables-save命令

    [root@localhost ~]# iptables-save -t filter > iptables.bak [root@localhost ~]# cat iptables.bak # ...

  9. 如何将本地的文件上传到你的github仓库中(首次流程)

    1.(先进入项目文件夹,右键项目文件夹,选择git Bash)通过命令 git init 把这个目录变成git可以管理的仓库 git init 2.把文件添加到版本库中,使用命令 git add . ...

  10. Android Tools&Cmd

    1. 生成Keystore文件 keytool -genkey -v -keystore /Users/shiyantao/Desktop/xxx.keystore -alias aliasName ...