使用Git压缩我的最后一个X提交
如何使用Git将最后的X次提交压缩为一次提交?使用Git-rebase-I使用Git压缩我的最后一个X提交,git,rebase,squash,git-squash,Git,Rebase,Squash,Git Squash,如何使用Git将最后的X次提交压缩为一次提交?使用Git-rebase-I 在本例中,是SHA1散列或当前分支头的相对位置,从中可以分析rebase命令的提交。例如,如果用户希望查看过去来自当前头部的5次提交,则命令为git rebase-i HEAD~5 您可以使用git merge--squash,这比git rebase-i稍微优雅一些。假设您在master上,希望将最后12次提交压缩为一次提交 警告:首先确保您提交了您的工作,检查git状态是否干净(因为git reset--hard将丢
在本例中,
是SHA1散列或当前分支头的相对位置,从中可以分析rebase命令的提交。例如,如果用户希望查看过去来自当前头部的5次提交,则命令为git rebase-i HEAD~5
您可以使用git merge--squash
,这比git rebase-i
稍微优雅一些。假设您在master上,希望将最后12次提交压缩为一次提交
警告:首先确保您提交了您的工作,检查git状态
是否干净(因为git reset--hard
将丢弃暂存和未暂存的更改)
然后:
更详细地描述了--squash
选项
更新:与Chris Johnsen在年提出的更简单的
git重置--soft HEAD~12&&git commit
相比,这种方法的唯一真正优势在于,您可以在提交消息中预先填充您正在压扁的每一条提交消息。这是一种超级重复的拙劣行为,但方式很酷,因此我将它扔进拳击场:
GIT_EDITOR='f() { if [ "$(basename $1)" = "git-rebase-todo" ]; then sed -i "2,\$s/pick/squash/" $1; else vim $1; fi }; f' git rebase -i foo~5 foo
翻译:为git提供一个新的“编辑器”,如果要编辑的文件名是git rebase todo
(交互式rebase提示符)将除第一个“pick”之外的所有内容都更改为“squash”,否则会生成vim,这样当提示您编辑压缩的提交消息时,您就会得到vim。(很明显,我在branch foo上压缩了最后五次提交,但你可以随意更改。)
不过,我可能会这样做。您可以非常轻松地完成这项工作,而无需
git-rebase
或git-merge-squash
。在本例中,我们将挤压最后3次提交
如果您想从头开始编写新的提交消息,这就足够了:
git reset --soft HEAD~3 &&
git commit
如果要开始编辑新的提交消息,并将现有的提交消息串联在一起(即,类似于pick/squash/squash/../squashgit-rebase-i
指令列表的开头),则需要提取这些消息并将其传递给git-commit
:
git reset --soft HEAD~3 &&
git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"
这两种方法都以相同的方式将最后三次提交压缩为一次新提交。软重置只是将头部重新指向您不想挤压的最后一次提交。软重置既不会触动索引,也不会触动工作树,从而使索引处于新提交所需的状态(即,它已经具有您将要“丢弃”的提交的所有更改)。基于
从bash(或Windows上的Git bash)添加全局“挤压”别名
。。。或使用Windows的命令提示符:
git config --global alias.squash "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"
您的
~/.gitconfig
现在应该包含以下别名:
[alias]
squash = "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"
用法: 。。。它会自动将最后的
N
提交(包括在内)压缩在一起
注意:结果提交消息按顺序是所有压缩提交的组合。如果对此不满意,您可以始终
git commit--amend
手动修改它。(或者,编辑别名以符合您的喜好。)我建议尽可能避免git重置,尤其是对于git新手。除非您真的需要基于大量提交来自动化流程,否则有一种不那么奇特的方法
git合并——挤压(工作分支名称)
git提交
git reset origin/dev
git add --all
git commit -m 'my commit message'
我发现一个更通用的解决方案不是指定'N'提交,而是指定要压扁的分支/提交id。这比计算提交到特定提交的次数更不容易出错—只需直接指定标记,或者如果确实要计算,则可以指定HEAD~N 在我的工作流程中,我启动了一个分支,我对该分支的第一次提交总结了目标(即,通常是我将作为功能的“最终”消息推送到公共存储库的目标)。因此,当我完成后,我所要做的就是
git squash master
返回到第一条消息,然后我准备推送
我使用别名:
squash = !EDITOR="\"_() { sed -n 's/^pick //p' \"\\$1\"; sed -i .tmp '2,\\$s/^pick/f/' \"\\$1\"; }; _\"" git rebase -i
这将在压缩之前转储正在压缩的历史,这样,如果要恢复,您就有机会通过从控制台抓取旧的提交ID进行恢复。(Solaris用户注意到它使用GNU-sed
-i
选项,Mac和Linux用户对此应该没问题。)如果您在一个远程分支(称为功能分支
)上,该分支是从黄金存储库(黄金回购名称
)克隆而来的,那么下面是将您的提交压缩为一个的技术:
git checkout golden_repo_name
git checkout -b dev-branch
git merge --squash feature-branch
git push origin dev-branch
如果使用Ortoisegit,则可以将函数
组合为一个提交
:
git reset --soft HEAD~3 &&
git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"
Show Log
git merge --squash feature-branch
git commit -m "My feature complete"
git push origin dev-branch
git rebase -i HEAD~3
git checkout --orphan <new-branch>
git commit
git rebase -i HEAD~n
pick 01d1124 Message....
pick 6340aaa Message....
pick ebfd367 Message....
pick 30e0ccb Message....
p 01d1124 Message....
s 6340aaa Message....
s ebfd367 Message....
s 30e0ccb Message....
git reset d43e15
git commit -am 'new commit name'
# git log --pretty=oneline --abbrev-commit
abcd1234 Update to Fix for issue B
cdababcd Fix issue B
deab3412 Fix issue A
....
# git rebase -i deab3412
....
pick cdababcd Fix issue B
pick abcd1234 Update to Fix for issue B
....
....
pick cdababcd Fix issue B
squash abcd1234 Update to Fix for issue B
....
# git log --pretty=oneline --abbrev-commit
1122abcd Fix issue B
deab3412 Fix issue A
....
# git push origin +master
git add <files>
git commit --fixup=OLDCOMMIT
git rebase --interactive --autosquash OLDCOMMIT^
# git log --pretty=oneline --abbrev-commit
cdababcd Fix issue B
deab3412 Fix issue A
....
# git add <files> # New changes
# git commit --amend
# git log --pretty=oneline --abbrev-commit
1d4ab2e1 Fix issue B
deab3412 Fix issue A
....
git rebase -i HEAD^^
git checkout master
git checkout -b feature_branch_squashed
git merge --squash feature_branch
$ git rebase -i 2d23ea524936e612fae1ac63c95b705db44d937d
git rebase -i HEAD~(n number of commits back to review)
git rebase -i HEAD~1
git rebase --continue
git reset --soft HEAD~10 && git commit -m "squashed commit"
git push -f
(MASTER)
Fleetwood Mac Fritz
║ ║
Add Danny Lindsey Stevie
Kirwan Buckingham Nicks
║ ╚═══╦══════╝
Add Christine ║
Perfect Buckingham
║ Nicks
LA1974══════════╝
║
║
Bill <══════ YOU ARE EDITING HERE
Clinton (CHECKED OUT, CURRENT WORKING DIRECTORY)
git reset --soft $(git merge-base HEAD master) && git commit --reuse-message=HEAD@{1}
git reset --mixed <commit-hash-into-which-you-want-to-squash>
git commit -a --amend
git rebase -i HEAD~X
pick 1bffc15c My earlier commit
pick 474bf0c2 My recent commit
# ...
pick 1bffc15c My earlier commit
fixup 474bf0c2 My recent commit
# ...