背景

大家都有学习如何规范简洁的编写代码,但却很少学习如何规范简洁的提交代码。现在大家基本上都用 Git 作为源码管理的工具,Git 提供了极大的灵活性,我们按照各种 workflow 来提交/合并 code,这种灵活性把控不好,也会带来很多问题

最常见的问题就是乱成一团的 git log history,那真的是老太太的裹脚布, 又臭又长, 个人极其不喜欢这种 log

造成这个问题的根本原因就是随意提交代码。

代码都提交了,那还有什么办法拯救吗?三个锦囊,就可以完美解决了

善用 git commit --amend

这个命令的帮助文档是这样描述的:

  1. --amend amend previous commit

也就是说,它可以帮助我们修改最后一次提交

既可以修改我们提交的 message,又可以修改我们提交的文件,最后还会替换最后一个 commit-id

我们可能会在某次提交的时候遗漏了某个文件,当我们再次提交就可能会多处一个无用的 commit-id,大家都这样做,git log 慢慢就会乱的无法追踪完整功能了

假设我们有这样一段 log 信息

  1. * 98a75af (HEAD -> feature/JIRA123-amend-test) feat: [JIRA123] add feature 1.2
  2. * 119f86e feat: [JIRA123] add feature 1.1
  3. * 5dd0ad3 feat: [JIRA123] add feature 1
  4. * c69f53d (origin/main, origin/feature/JIRA123-amend-test, origin/HEAD, main) Initial commit

假设我们要修改最后一个 log message,就可以使用下面命令:

  1. git commit --amend -m "feat: [JIRA123] add feature 1.2 and 1.3"

我们再来看一下 log 信息, 可以发现,我们用新的 commit-id 5e354d1 替换了旧的 commit-id 98a75af, 修改了 message,并没有增加节点

  1. * 5e354d1 (HEAD -> feature/JIRA123-amend-test) feat: [JIRA123] add feature 1.2 and 1.3
  2. * 119f86e feat: [JIRA123] add feature 1.1
  3. * 5dd0ad3 feat: [JIRA123] add feature 1
  4. * c69f53d (origin/main, origin/feature/JIRA123-amend-test, origin/HEAD, main) Initial commit

现在我们的 repo 中文件是这样的:

  1. .
  2. ├── README.md
  3. └── feat1.txt
  4. 0 directories, 2 files

假设我们提交 feature 1.3 的时候,忘记了一个配置文件 config.yaml, 不想修改 log,不想添加新的 commit-id,那下面的这个命令就非常好用了

  1. echo "feature 1.3 config info" > config.yaml
  2. git add .
  3. git commit --amend --no-edit

git commit --amend --no-edit 就是灵魂所在了,来看一下当前的 repo 文件:

  1. .
  2. ├── README.md
  3. ├── config.yaml
  4. └── feat1.txt
  5. 0 directories, 3 files

再来看一下 git log

  1. * 247572e (HEAD -> feature/JIRA123-amend-test) feat: [JIRA123] add feature 1.2 and 1.3
  2. * 119f86e feat: [JIRA123] add feature 1.1
  3. * 5dd0ad3 feat: [JIRA123] add feature 1
  4. * c69f53d (origin/main, origin/feature/JIRA123-amend-test, origin/HEAD, main) Initial commit

知道这个技巧,就可以确保我们的每次提交都包含有效的信息了。一张图描述这个过程就是这个样子了:

有了 --no-edit 的 buff 加成,威力更大一些

善用 git rebase -i

可以看着,上面的 log 都是在开发 feature1,我们在把 feature 分支 merge 到 main 分支之前,还是应该继续合并 log commit 节点的,这就用到了

  1. git rebase -i HEAD~n

其中 n 代表最后几个提交,上面我们针对 feature 1 有三个提交,所以就可以使用:

  1. git rebase -i HEAD~3

运行后,会显示一个 vim 编辑器,内容如下:

  1. 1 pick 5dd0ad3 feat: [JIRA123] add feature 1
  2. 2 pick 119f86e feat: [JIRA123] add feature 1.1
  3. 3 pick 247572e feat: [JIRA123] add feature 1.2 and 1.3
  4. 4
  5. 5 # Rebase c69f53d..247572e onto c69f53d (3 commands)
  6. 6 #
  7. 7 # Commands:
  8. 8 # p, pick <commit> = use commit
  9. 9 # r, reword <commit> = use commit, but edit the commit message
  10. 10 # e, edit <commit> = use commit, but stop for amending
  11. 11 # s, squash <commit> = use commit, but meld into previous commit
  12. 12 # f, fixup <commit> = like "squash", but discard this commit's log message
  13. 13 # x, exec <command> = run command (the rest of the line) using shell
  14. 14 # d, drop <commit> = remove commit
  15. 15 # l, label <label> = label current HEAD with a name
  16. 16 # t, reset <label> = reset HEAD to a label
  17. 17 # m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
  18. 18 # . create a merge commit using the original merge commit's
  19. 19 # . message (or the oneline, if no original merge commit was
  20. 20 # . specified). Use -c <commit> to reword the commit message.
  21. 21 #
  22. 22 # These lines can be re-ordered; they are executed from top to bottom.
  23. 23 #
  24. 24 # If you remove a line here THAT COMMIT WILL BE LOST.
  25. 25 #
  26. 26 # However, if you remove everything, the rebase will be aborted.
  27. 27 #
  28. 28 #
  29. 29 # Note that empty commits are commented out

合并 commit-id 最常用的是 squashfixup, 前者包含 commit message,后者不包含,这里使用 fixup, 然后 :wq 退出

  1. 1 pick 5dd0ad3 feat: [JIRA123] add feature 1
  2. 2 fixup 119f86e feat: [JIRA123] add feature 1.1
  3. 3 fixup 247572e feat: [JIRA123] add feature 1.2 and 1.3

我们再来看一下 log, 这就非常清晰了

  1. * 41cd711 (HEAD -> feature/JIRA123-amend-test) feat: [JIRA123] add feature 1
  2. * c69f53d (origin/main, origin/feature/JIRA123-amend-test, origin/HEAD, main) Initial commit

善用 rebase

上面的 feature1 已经完整的开发完了,main 分支也有了其他人的更新,在将 feature merge 回 main 分支之前,以防代码有冲突,需要先将 main 分支的内容合并到 feature 中,如果用 merge 命令,就会多处一个 merge 节点,log history 中也会出现拐点,并不是线性的,所以这里我们可以在 feature 分支上使用 rebase 命令

  1. git pull origin main --rebase

pull 命令的背后是自动帮我们做 merge 的,但是这里以 rebase 的形式,再来看一下 log

  1. * d40daa6 (HEAD -> feature/JIRA123-amend-test) feat: [JIRA123] add feature 1
  2. * 446f463 (origin/main, origin/HEAD) Create main.properties
  3. * c69f53d (origin/feature/JIRA123-amend-test, main) Initial commit

我们的 feature1 功能 on top of main 的提交节点,还是保持线性,接下来就可以 push 代码,然后提 PR,将你的 feature merge 到 main 分支了

简单描述 merge 和 rebase 的区别就是这样的:

我这里使用 git pull origin main --rebase 省略了切换 main 并拉取最新内容再切回来的过程,一步到位,背后的原理都是上图展示的这样

使用 rebase 是要遵守一个黄金法则的,这个之前有说过,就不再是赘述了

总结

有了这三个锦囊,相信大家的 git log 都无比的清晰,如果你还不知道,完全可以用起来,如果你的组内成员不知道,你完全可以推广起来,这样的 repo 看起来才更健康

接下来会介绍一个多分支切换互不影响的锦囊

个人博客:https://dayarch.top

加我微信好友, 进群娱乐学习交流,备注「进群」

欢迎持续关注公众号:「日拱一兵」

  • 前沿 Java 技术干货分享
  • 高效工具汇总 | 回复「工具」
  • 面试问题分析与解答
  • 技术资料领取 | 回复「资料」

以读侦探小说思维轻松趣味学习 Java 技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,请持续关注......


猿猿有责,维持整洁的 Git 提交记录,三个锦囊送给你的更多相关文章

  1. [译] 怎样(以及为什么要)保持你的 Git 提交记录的整洁

    最近在掘金翻译了一篇文章,主要讲的是 Git 提交记录的维护,确实很有用,感兴趣的同学可以去看一下.链接如下: [译] 怎样(以及为什么要)保持你的 Git 提交记录的整洁 截图:

  2. 如何搜索 git 提交记录

    如何搜索 git 提交记录 git log -p --all -G '可通过正则搜索' --pretty=format:'%ci' # 可跨分支搜索 # -S '通过文本搜索' git branch ...

  3. 怎样快速找到某一行代码的git提交记录

    利用notepad++提高问题分析效率,以及快速找到某一行代码的git提交记录 1. 全目录搜索/替换 Notepad++是一款强大的文本编辑工具,当知道大概的关键词但不知道在哪个日志时可以使用not ...

  4. git使用记录三:查看日志

    git使用记录三: git log git log 的帮助文档 git log --help 查看最后面的两个日志记录 命令如下: git log -n number 比如: git log -n 2 ...

  5. 恢复到版本并销毁之后的git提交记录

    git reset --hard HEAD~1(或者你想要的版本号) git push --force # 千万注意:此操作无法恢复

  6. 自动刷github提交记录

    前言 进入自己github主页会看到自己的提交记录,如果某天没有提交记录,那天的小方框就显示灰色.强迫症的我,每次进来看着就感觉不爽, 想着自己每天记得提交点东西,争取像阮一峰大神一样,每天都有提交记 ...

  7. git使用记录二: 给文件重命名的简单方法

    git使用记录三: 给文件重命名的简单方法 git mv file_name_old file_name_new mv: 文件命名 file_name_old : 文件当前的名字 file_name_ ...

  8. 老鸟都应该注意的git 提交规范

    不知道大家有没有看过自己项目的git 提交信息-----我看过好多次 ,不忍直视  然后提醒一起的小伙伴 :大家规范点 信息要详细, 过段时间再看下 ,还是一样. 相信很多猿都有这样的感受,对于垃圾的 ...

  9. git提交到远程仓库

    Git概述 什么是Git? 刚开始对这个东西也感到挺迷茫,并且问了好多已经学习android一段时间的同学也是一头雾水,直到了解并使用之后,才体会到Git的好处以及重要意义. Git:是目前世界上最先 ...

随机推荐

  1. Fortran学习笔记:03 数组(Array)

    Fortran学习笔记目录 书接上回:Fortran学习笔记:02 流控制语句 数组(Array) 定义数组 一维数组 program main implicit none integer :: i ...

  2. 10.12 LNMP

    yum install nginx php php-fpm mariadb-server php-mysql php.conf server { listen 8000; # pass the PHP ...

  3. 基于python的pixiv爬虫

    基于python的pixiv爬虫 1.目标 在和朋友吹逼过程中,聊到qq群机器人,突发奇想动手做一个p站每日推荐色图的色图机,遂学习爬虫. 目标: 批量下载首页推荐色图. 由于对qq机器人不熟,先利用 ...

  4. webRTC中语音降噪模块ANS细节详解(一)

    ANS(adaptive noise suppression) 是webRTC中音频相关的核心模块之一,为众多公司所使用.从2015年开始,我在几个产品中使用了webRTC的3A(AEC/ANS/AG ...

  5. nGrinder 参数使用

    背景: 性能测试中为了更加接近真实模拟现实应用,对于提交的信息每次都需要提交不同的数据,或使用不同的值,最为典型的就是登录时的账号. 性能测试工具需要提供动态参数化功能,如商业化的LoadRunner ...

  6. Mac录屏同时录制系统声音和画外音(Soundflower无法安装解决方案)

    个人博客地址:xzajyjs.cn 前言 以前一直有录屏的需求,但苦于自带的QuickTime 无法录制内屏声音,一直使用的是第三方的app.近期开腾讯会议需要录屏,但主持人本身没有开启录屏权限,只好 ...

  7. Visual Studio Debug only user code with Just My Code

    Debug only user code with Just My Code By default, the debugger skips over non-user code (if you wan ...

  8. vue.$nextTick实现原理

    源码: const callbacks = [] let pending = false function flushCallbacks () { pending = false const copi ...

  9. shell关键字含义

    linux中shell变量$#,$@,$0,$1,$2的含义解释: 变量说明: $$ Shell本身的PID(ProcessID) $! Shell最后运行的后台Process的PID $? 最后运行 ...

  10. 【UE4 C++】 启动 / 关闭外部exe、开启虚拟键盘

    启动/关闭外部exe 引擎自带 FPlatformProcess::CreateProc() FPlatformProcess::TerminateProc() windows api ShellEx ...