当我们有多个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. css样式支持左右滑动要点

    div 包含 ul ,ul 包含 li div宽度固定,ul 宽度随着li的可以无限增加,li 左右滑动的最小容器. div 样式position:relative;width:xxpx;height ...

  2. javascript switch 陷阱

    javascript switch 相等用的是===,就是说不进值相同,类型也要相同 用string的时候,发现无论如何都不满足条件,后来发现是类型不同 string有对象string,还有基本类型s ...

  3. JAVA面向对象之继承

    继承: 子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法 class 子类 extends 父类 { } 继承的特性: 子类拥有父类非private的属性,方法. 子类可以拥有自己 ...

  4. thinkPHP验证码不显示问题

    使用验证码的时候,不显示图片时,要清理下输出缓存:ob_clean_end();

  5. 用java代码作日历

    import java.util.Calendar; public class CalendarBean { String day[]; int year=2005,month=0; public v ...

  6. Educational Codeforces Round 63 (Rated for Div. 2) D. Beautiful Array (简单DP)

    题目:https://codeforces.com/contest/1155/problem/D 题意:给你n,x,一个n个数的序列,你可以选择一段区间,区间的数都乘以x,然后求出最大字段和 思路: ...

  7. Python机器学习(基础篇---监督学习(k近邻))

    K近邻 假设我们有一些携带分类标记的训练样本,分布于特征空间中,对于一个待分类的测试样本点,未知其类别,按照‘近朱者赤近墨者黑’,我们需要寻找与这个待分类的样本在特征空间中距离最近的k个已标记样本作为 ...

  8. JavaScript中Ajax的用法

    XMLHttpRequest 对象的属性和方法: open(method,url,async) 规定请求的类型.URL 以及是否异步处理请求 send(string)   将请求发送到服务器. res ...

  9. 树莓派外网ssh访问holer实现篇

    外网ssh访问树莓派 内网的树莓派(Raspberry Pi),只能在局域网内访问,怎样从公网也能ssh登录访问树莓派? 本文将介绍使用holer实现的具体步骤. 1. 准备工作 1.1 安装并启动树 ...

  10. Sharepoint 2016 配置FBA(二) 编辑Web,config文件

    使FBA生效,下一步在Sharepoint中设置Membership Provider,一个Membership Provider是一个从程序到任证库(credential store)的接口.这样允 ...