如何让你的 Git 历史保持“干净”?!

首页 > 财经新闻 > CSDN
来源:CSDN 发布日期:2019-09-10 18:53 浏览:12次

消除 Git 历史的最佳手段有哪些?

作者 | Manuel Sidler

译者 | 谭开朗,责编 | 屠敏

出品 | CSDN(ID:CSDNnews)

以下为译文:

使用Git已有几年的时间了,我必须承认,干净的提交历史并不总是那么重要。我们从《回到未来》中知道,改写历史可能会造成某些糟糕的后果。我只能假设,这就是为什么这是一个可怕的话题。在这篇文章中,我想分享一些基本的命令,这些命令将帮助你保持Git历史的整洁,并消除《回到未来》中的糟糕后果。

要事第一

本文中的所有命令都将生成新的提交哈希码,从而将其与原始分支区别开来。这意味着,你必须使用git push -force或git push -f强制覆盖远程上的历史记录。这又意味着:永远不要更改共享分支上的git历史记录。如果远程分支有新的提交,则有一个更安全的命令,它甚至可以拒绝强制推送:git push –force-with-lease。

场景1:在最后一次提交中添加内容

每个人都有过这样的经历:将改动添加到暂存区,提交并等待构建。但不幸的是,构建失败了。哦,你忘了添加文件x。接下来会发生什么?将文件x添加到暂存区,并提交一条类似于“愚蠢的我忘了添加文件x”的内容。请不要这么做!让我来介绍第一个命令:

git commit -amend

该命令将暂存区的改动添加到最近一次提交,并支持更改最近一次的提交内容。使用以下简单的命令也能达到相同的效果:

git commit –amend -m“new message”

如果不想修改最后的提交信息,可以添加no-edit参数:

git commit --amend --no-edit

所以不要再犯“愚蠢的我忘了…”的错误了!

Git的交互式rebase

在接下来的几个场景中,我们将使用交互式git rebase。这个工具能帮助修改历史上更早的更改。只需使用以下命令启动一个交互式rebase:

git rebase –i <base>

其中<base>表示要重写历史的节点。

例如,重写最后三次提交:

git rebase -i HEAD~3

另一个例子,重写历史到一个特定的提交:

git rebase -i 63a2356

该命令显示了配置编辑器的提交和选项:

pick bcfd87e add sql scripts for databasepick 9fb0b9c prevent users from changing their emailpick e0b46b9 cleanup web config# Rebase dfef724..e0b46b9 onto dfef724 (3 commands)## Commands:# p, pick <commit> = use commit# r, reword <commit> = use commit, but edit the commit message# e, edit <commit> = use commit, but stop for amending# s, squash <commit> = use commit, but meld into previous commit# f, fixup <commit> = like "squash", but discard this commits log message# x, exec <command> = run command (the rest of the line) using shell# b, break = stop here (continue rebase later with git rebase --continue)# d, drop <commit> = remove commit# l, label <label> = label current HEAD with a name# t, reset <label> = reset HEAD to a label# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]# .       create a merge commit using the original merge commits# .       message (or the oneline, if no original merge commit was# .       specified). Use -c <commit> to reword the commit message.## These lines can be re-ordered; they are executed from top to bottom.## If you remove a line here THAT COMMIT WILL BE LOST.## However, if you remove everything, the rebase will be aborted.## Note that empty commits are commented out

让我们进入第一个rebase场景。

场景2:向历史记录中的任意提交添加内容

就像在场景1中,我们忘记在提交中添加内容。但是,与其添加到最后一次提交中,不如将改动修改为历史上更远的一次提交。对于这种情况,交互式rebase为我们提供了编辑选项。

我们从交互式rebase命令开始,然后在我们想要更改的提交上设置编辑命令:

pick bcfd87e add sql scripts for databaseedit 9fb0b9c prevent users from changing their emailpick e0b46b9 cleanup web config

交互式rebase停止此提交,我们可以添加更改:

Stopped at 9fb0b9c...  prevent users from changing their emailYou can amend the commit nowwith  git commit --amend Once you are satisfied with your changes, run  git rebase --continue

完成后,只需将更改添加到暂存区,并使用amend命令提交:

git commit --amend

几乎完成了!现在我们要continue rebase:

git rebase –continue

场景3:合并提交

尽量多做合并。这意味着功能分支中的git历史记录通常是这样的:

9edf77a more review findings67b5e01 review findings940778d enable users to change their namedc6b0db enable users to change their namedfdd77d wip

这在特性开发期间可能很有用,但并不适用于整个git存储库历史。因此将所有提交合并为一个。有两种方式:squash和fixup。这两个命令都是将提交合并到前一个命令中。唯一的区别是,squash支持编辑新的提交内容,而fixup不支持。

我们来squash一些提交。我们像之前一样启动交互式rebase,并设置适当的选项:

pick dfdd77d wipsquash dc6b0db enable users to change their namesquash 940778enable users to change their namesquash 67b5e01 review findingssquash 9edf77a more review findings# Rebase 63a2356..9edf77a onto 63a2356 (5 commands)

现在Git提供了所有消息的概览:

# This is a combination of 5 commits.# This is the 1st commit message:wip# This is the commit message #2:enable users to change their name# This is the commit message #3:enable users to change their name# This is the commit message #4:review findings# This is the commit message #5:more review findings# Please enter the commit message for your changes. Lines starting# with # will be ignored, and an empty message aborts the commit.

删除所有行,只将我们想要的信息写在最后:

enable users to change their name# Please enter the commit message for your changes. Lines starting# with # will be ignored, and an empty message aborts the commit.

瞧,把提交压缩成一个了:

cb88cf6 enable users to change their name

我们可以使用fixup命令执行同样的操作。在下面的场景中,提交消息很完美,我想把提交合并到:

pick dc6b0db enable users to change their namefixup dfdd77d wipfixup 940778enable users to change their namefixup 67b5e01 review findingsfixup 9edf77a more review findings# Rebase 63a2356..9edf77a onto 63a2356 (5 commands)

结果和上面squash的例子一样:

b8e76d1 enable users to change their name

场景4:分割提交

我们常常把两个或两个以上不同的主题合并在一起:

7080968 add sql scripts for database172db2b prevent user from changing their email and cleanup web config

在这种情况下,将web配置的清理分离出来会更干净,对吧?此时,我们可以再次利用edit命令。使用互动rebase可做到这一点:

pick 7080968 add sql scripts for databaseedit 172db2b prevent user from changing their email and cleanup web config# Rebase dfef724..172db2b onto dfef724 (2 commands)

正如我们所期望的,Git在提交时停止了。现在我们可以把更改带回工作区域:

git reset HEAD~

接下来很简单,只需为更改创建两个提交:

git add [files]git commit -m "prevent user from changing their email"git add [files]git commit -m "cleanup web config"

别忘了继续rebase:

git rebase --continue

结果如下:

9fb0b9c prevent user from changing their emaildfef724 cleanup web config7080968 add sql scripts for database

多整洁!

场景5:重新排序提交

如果合并两个或多个提交,但它们的顺序不对怎么办?

09f43c9 validate user inputs62490ed import user datac531f57 validate user inputs

只需在rebase编辑器中重新排序提交,然后再使用fixup或squash合并它们。

pick 62490ed import user datapick c531f57 validate user inputsfixup 09f43c9 validate user inputs# Rebase 6c70ff2..09f43c9 onto 6c70ff2 (3 commands)

场景6:更改提交消息

不满意特定的提交内容?可以使用reword命令随时更改它:

reword c531f57 validate user inputspick 62490ed import user data# Rebase 6c70ff2..09f43c9 onto 6c70ff2 (3 commands)

Git将在此时停止提交,我们可以选择更改消息: 

validate user inputs# Please enter the commit message for your changes. Lines starting# with # will be ignored, and an empty message aborts the commit.

场景7:删除提交

需要完全恢复特定的提交吗?在这种情况下,我们可以使用drop命令:

pick bcfd87e add sql scripts for databasedrop 9fb0b9c prevent users from changing their emailpick e0b46b9 cleanup web config# Rebase dfef724..e0b46b9 onto dfef724 (3 commands)

在这里,我们知道了保持Git历史记录整洁的重要性。假设我们将不同的特性放入一个提交中,或者将一个特性拆分为多个(无意义的)提交,那么还原要复杂得多。 

当事情出现问题时

在重写Git历史时,不要担心会破坏某些东西。

首先,我们总是可以使用git rebase--abort中止交互式rebase会话。 

这个命令将停止rebase会话并恢复所有更改。

其次,即使已经完成了一个rebase并把它搞砸了,我们也可以还原它。幸运的是,Git跟踪执行所有命令,我们可以使用git reflog打开日志。

e0b46b9 (HEAD -> feature/my2, feature/my3) HEAD@{34}: rebase -i (finish): returning to refs/heads/feature/my2e0b46b9 (HEAD -> feature/my2, feature/my3) HEAD@{35}: commit: cleanup web config9fb0b9c HEAD@{36}: commit: prevent users from changing their emailbcfd87e HEAD@{37}: reset: moving to HEAD~3892bc7 HEAD@{38}: rebase -i: fast-forwardbcfd87e HEAD@{39}: rebase -i (start): checkout master3892bc7 HEAD@{40}: rebase -i (finish): returning to refs/heads/feature/my23892bc7 HEAD@{41}: commit (amend): prevent user from changing their email and cleanup web config39262b5 HEAD@{42}: rebase -i: fast-forwardbcfd87e HEAD@{43}: rebase -i (start): checkout master39262b5 HEAD@{44}: rebase -i (abort): updating HEAD39262b5 HEAD@{45}: rebase -i (abort): updating HEADbcfd87e HEAD@{46}: reset: moving to HEAD~39262b5 HEAD@{47}: rebase -i: fast-forwardbcfd87e HEAD@{48}: rebase -i (start): checkout master39262b5 HEAD@{49}: rebase -i (finish): returning to refs/heads/feature/my239262b5 HEAD@{50}: rebase -i (pick): prevent user from changing their email and cleanup web configbcfd87e HEAD@{51}: commit (amend): add sql scripts for database7080968 HEAD@{52}: rebase -i: fast-forwarddfef724 (master) HEAD@{53}: rebase -i (start): checkout master172db2b (feature/my) HEAD@{54}: checkout: moving from feature/my to feature/my2172db2b (feature/my) HEAD@{55}: commit: prevent user from changing their email and cleanup web config7080968 HEAD@{56}: commit: add sql scripts for databasedfef724 (master) HEAD@{57}: checkout: moving from master to feature/mydfef724 (master) HEAD@{58}: commit (initial): init

我们可以找到交互式rebase会话之前的最后一个操作,并将其恢复状态。例如:

git resthard HEAD@{18}

所以,请战胜恐惧,并保持Git历史的干净吧!

原文:https://dev.to/manuelsidler/keep-your-git-history-clean-101-k7

本文为 CSDN 翻译,转载请注明来源出处。

【END】

随着智能物联迅速的兴起,场景联动越来越普遍,作为敲门砖的连接服务该如何实现?

360 资深工程师深度揭秘 360 IoT 云平台连接服务的技术框架实现细节、物联网协议应用和多协议,多网络的落地实践以及连接服务未来的演进方向。

技术干货来袭!立即扫码报名!

 热 文 推 荐 

马云卸任阿里巴巴董事局主席;苹果承认违法中国劳动法;IntelliJ IDEA 2019.2.2 发布 | 极客头条
微软发布IoT应用现状报告:88%国内企业已使用IoT;技术人才仍为最大需求;三分之一企业死于构想阶段
超 60 万 GPS 定位服务被曝漏洞,用户信息或将暴露!
2亿日活,日均千万级视频上传,快手推荐系统如何应对技术挑战?
Docker容器化部署Python应用
☞给面试官讲明白:一致性Hash的原理和实践
预警,CSW的50万枚尘封BTC即将重返市场?
☞她说:行!没事别嫁程序员!

点击阅读原文,输入关键词,即可搜索您想要的 CSDN 文章。

你点的每个“在看”,我都认真当成了喜欢

论坛
  阅读原文
支持0次 | 反对0次  
  用户评论区,文明评论,做文明人!

通行证: *邮箱+888(如:123@qq.com888)