我每隔几分钟就会将我的代码检查到一个Git分支中,并且评论最终会变成"Everything broken again again"和其他荒谬.
然后,每隔几分钟/小时/天,我会做一个真正的评论,比如"修正了第22,55号错误".我如何区分这两个概念?我希望能够删除所有我的频繁提交,然后离开严肃的提交.
Von*_*onC 98
现在编辑答案(在本条目的后半部分)新的Git1.7修正!--autosquash
用于快速提交重新排序和消息编辑的操作和选项.
首先,经典压缩过程,如Git1.7之前所做的那样.
(Git1.7具有相同的过程,只有通过自动提交重新排序的可能性而不是手动重新排序,以及通过更清洁的压缩消息而更快)
我希望能够删除所有频繁的签到,只留下严肃的签到.
这称为压缩提交.
在这篇Git准备文章中你有一个很好的"comit清理"的例子:(
注意:自2007年9月以来出现了rebase交互功能,允许压缩或拆分或删除或重新排序提交:另请参阅GitPro页面)
需要注意的是:只在尚未推送到外部存储库的提交中执行此操作.如果其他人的工作基于您要删除的提交,则可能会发生许多冲突.如果已经与他人共享,请不要重写您的历史记录.
alt text http://www.gitready.com/images/squash1.png
如果它们被包裹在一起,那么最后4次提交会更快乐
$ git rebase -i HEAD~4
pick 01d1124 Adding license
pick 6340aaa Moving license into its own file
pick ebfd367 Jekyll has become self-aware.
pick 30e0ccb Changed the tagline in the binary, too.
# Rebase 60709da..30e0ccb onto 60709da
#
# Commands:
# p, pick = use commit
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
Run Code Online (Sandbox Code Playgroud)
使用
HEAD
与之相关的最后四次提交进行rebaseHEAD~4
.
我们只是将一切都压缩成一个提交.
因此,将文件的前四行更改为此可以解决问题:
pick 01d1124 Adding license
squash 6340aaa Moving license into its own file
squash ebfd367 Jekyll has become self-aware.
squash 30e0ccb Changed the tagline in the binary, too.
Run Code Online (Sandbox Code Playgroud)
基本上,这告诉Git将所有四个提交合并到列表中的第一个提交中.完成并保存后,会弹出另一个编辑器,其中包含以下内容:
# This is a combination of 4 commits.
# The first commit's message is:
Adding license
# This is the 2nd commit message:
Moving license into its own file
# This is the 3rd commit message:
Jekyll has become self-aware.
# This is the 4th commit message:
Changed the tagline in the binary, too.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Explicit paths specified without -i nor -o; assuming --only paths...
# Not currently on any branch.
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: LICENSE
# modified: README.textile
# modified: Rakefile
# modified: bin/jekyll
#
Run Code Online (Sandbox Code Playgroud)
由于我们正在组合这么多提交,因此Git允许您根据流程中涉及的其他提交修改新提交的消息.根据需要编辑邮件,然后保存并退出.
完成后,您的提交已被成功压缩!
Created commit 0fc4eea: Creating license file, and making jekyll self-aware.
4 files changed, 27 insertions(+), 30 deletions(-)
create mode 100644 LICENSE
Successfully rebased and updated refs/heads/master.
Run Code Online (Sandbox Code Playgroud)
如果我们再看一下历史......
alt text http://www.gitready.com/images/squash2.png
注意:对于"提交挤压"的目的,Git1.7(2010年2月)引入了2个新元素(如Dustin在评论中所述):
- "
git rebase -i
"学会了新的动作"fixup
",它会压缩变化,但不会影响现有的日志消息.- "
git rebase -i
"还学习--autosquash
了与新的"修正"动作一起使用的选项.
--autosquash
这个Thechnosorcery Networks博客文章中都说明了(修正操作和选项).自去年6月以来,这些功能一直在烹饪,并在去年12月进一步辩论.
该fixup
操作或指令用于压缩您在a的提交编辑列表中手动重新排序的提交rebase --interactive
,同时忽略第二个提交消息,这将使消息编辑步骤更快(您可以保存它:压缩的提交将具有首先提交消息)
生成的提交消息将只是第一个提交消息.
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
Run Code Online (Sandbox Code Playgroud)
该--autosquash
选项是为您自动进行提交重新排序过程:
如果您知道要将某些内容压缩到哪个提交,则可以使用"
squash! $other_commit_subject
" 消息进行提交.然后,如果你运行@git rebase --interactive --autosquash commitish@
,该行将自动设置为squash,并放置在$ other_commit_subject主题的提交之下.
(实际上,squash!
只能使用另一个提交消息的开头)
$ vim Foo.txt
$ git commit -am "Change all the 'Bar's to 'Foo's"
[topic 8374d8e] Change all the 'Bar's to 'Foo's
1 files changed, 2 insertions(+), 2 deletions(-)
$ vim Bar.txt
$ git commit -am "Change all the 'Foo's to 'Bar's"
[topic 2d12ce8] Change all the 'Foo's to 'Bar's
1 files changed, 1 insertions(+), 1 deletions(-)
$ vim Foo.txt
$ git commit -am "squash! Change all the 'Bar's"
[topic 259a7e6] squash! Change all the 'Bar's
1 files changed, 2 insertions(+), 1 deletions(-)
Run Code Online (Sandbox Code Playgroud)
看到?这里第三个提交仅使用第一个提交消息的开头.
A rebase --interactive --autosquash
会将压扁的提交移到相关的提交之下:
pick 8374d8e Change all the 'Bar's to 'Foo's
squash 259a7e6 squash! Change all the 'Bar's
pick 2d12ce8 Change all the 'Foo's to 'Bar's
Run Code Online (Sandbox Code Playgroud)
消息版本将是:
# This is a combination of 2 commits.
# The first commit's message is:
Change all the 'Bar's to 'Foo's
# This is the 2nd commit message:
squash! Change all the 'Bar's
Run Code Online (Sandbox Code Playgroud)
默认情况下,您将保持压缩操作记录在提交消息中.
但是有了修复!指令,您可以在提交消息中保持压缩"不可见",同时仍然可以从使用该--autosquash
选项的自动提交重新排序中受益(以及您的第二个提交消息基于您想要被压扁的第一个提交的事实).
pick 8374d8e Change all the 'Bar's to 'Foo's
fixup cfc6e54 fixup! Change all the 'Bar's
pick 2d12ce8 Change all the 'Foo's to 'Bar's
Run Code Online (Sandbox Code Playgroud)
默认情况下,该消息为:
# This is a combination of 2 commits.
# The first commit's message is:
Change all the 'Bar's to 'Foo's
# The 2nd commit message will be skipped:
# fixup! Change all the 'Bar's
Run Code Online (Sandbox Code Playgroud)
请注意,
fixup!
提交的消息已经注释掉了.
您可以按原样保存消息,并保留原始提交消息.
当您意识到忘记添加部分早期提交时,包含更改非常方便.
现在,如果您想根据之前的提交进行修复或压缩,Jacob Helwig(Technosorcery Networks博客条目的作者)推荐以下别名:
[alias]
fixup = !sh -c 'git commit -m \"fixup! $(git log -1 --format='\\''%s'\\'' $@)\"' -
squash = !sh -c 'git commit -m \"squash! $(git log -1 --format='\\''%s'\\'' $@)\"' -
Run Code Online (Sandbox Code Playgroud)
并且做一个rebase交互式,它将始终受益于意图被压缩的提交的自动重新排序:
[alias]
ri = rebase --interactive --autosquash
Run Code Online (Sandbox Code Playgroud)
更新Git 2.18(2018年第二季度):" git rebase -i
"有时会留下中间的" # This is a combination of N commits
"消息,意味着在某些角落案件的最终结果中,编辑内部的人员消费已得到修复.
请参阅Johannes Schindelin()提交15ef693,提交dc4b5bc,提交e12a7ef,提交d5bc6f2(2018年4月27日).(由Junio C Hamano合并- -在提交4a3bf32,2018年5月23日)dscho
gitster
rebase --skip
:修复/壁球失败后清理提交消息在一系列fixup/squash命令期间,交互式rebase构建带有注释的提交消息.如果这些命令中的至少一个是a,则将在编辑器中向用户呈现
squash
.在任何情况下,在这样的fixup/squash链的最后一步中,最终将清除提交消息,删除所有那些中间注释.
但是,如果此类链中的最后一个fixup/squash命令因合并冲突而失败,并且如果用户随后决定跳过它(或将其解析为干净的工作树然后继续rebase),则当前代码无法清除提交消息.
此提交修复了该行为.
这次修复比眼睛更加复杂,因为它不仅仅是关于我们是
git rebase --skip
在进行修复还是壁球的问题.它还涉及从累积的提交消息中删除跳过的fixup/squash的提交消息.这也是关于我们是否应该让用户编辑最终提交消息的问题("链中是否存在未被跳过的壁球?").例如,在这种情况下,我们将要修复提交消息,但不能在编辑器中打开它:
Run Code Online (Sandbox Code Playgroud)pick <- succeeds fixup <- succeeds squash <- fails, will be skipped
这是新引入的
current-fixups
文件非常方便的地方.快速查看,我们可以确定是否有非跳过的壁球.我们只需要确保在跳过的fixup/squash命令方面保持最新.作为奖励,我们甚至可以避免不必要的提交,例如,当只有一次修复时,它失败了,并且被跳过了.要仅修复最终提交消息未正确清理的错误,但没有修复其余的错误,将比一次性修复它更复杂,因此这个提交将多个问题集中在一起.
Git 2.19(Q8 2018)修复了一个错误:当git rebase -i
告诉" "将两个或多个提交压缩成一个时,它会为每个提交标记日志消息及其编号.
它正确地称为第一个"第一次提交",但下一个是" commit #1
",它是一个一个(!).
参见由Phillip Wood()提交dd2e36e(2018年8月15日).(由Junio C Hamano合并- -在提交36fd1e8,2018年8月20日)phillipwood
gitster
rebase -i
:修复壁球消息中的编号提交e12a7ef("
rebase -i
处理"<n>
提交"与GETTEXT_POISON
",2018-04-27,Git 2.18的组合)改变了在压缩提交时标记单个提交消息的方式.
在这样做时,引入了回归,其中消息的编号是一个.此提交修复了该问题,并为编号添加了测试.
Dan*_*ark 27
使用软重置代替Rebase来压制GIT历史
我认为VonC答案的长度说明了数量上的复杂git rebase
程度.这是我对我的问题的另一个答案的延伸.
ticket-201
分支master
.你想假装所有的提交ticket-201
从未发生过,但是你一次性完成了所有的工作.git reset --soft hash
where hash
应该是在ticket-201
日志中的提交哈希.从不同分支的任意提出来创造历史
使用重置,您可以根据需要重写历史记录,但您的编辑将失去拥有正确时间戳的魅力.假设你不关心它(你的文件的时间/日期就足够了,也许?),或者如果你想要随意提交提交,你可以按照以下步骤操作:
commit0
(假装是一个哈希):git checkout -b new-history commit0
commit5
以下位置获取文件:git reset --hard commit5
git reset --soft commit0
这个想法简单,有效和灵活.
使用壁球代替
最近,我一直在另一家分公司工作并使用squash
.另一个分支称为temp,然后我用git merge temp --squash
它将它带入推送到服务器的真实分支.
工作流程是这样的,假设我在工作Ticket65252
:
git branch -d temp #remove old temp bbranch
git checkout -b temp
# work work work, committing all the way
git checkout Ticket65252
git merge temp --squash
git commit -m "Some message here"
Run Code Online (Sandbox Code Playgroud)
使用优势rebase
?方式不那么复杂.
使用的优点reset --hard
然后reset --soft
呢?减少混淆,减少错误.