我用:
git checkout -b testbranch
我做了20次提交。
现在我想要压缩这20个提交。我是这样做的:
git rebase -i HEAD~20
如果我不知道有多少次提交呢?有没有什么方法可以做到:
git rebase -i all on this branch
我用:
git checkout -b testbranch
我做了20次提交。
现在我想要压缩这20个提交。我是这样做的:
git rebase -i HEAD~20
如果我不知道有多少次提交呢?有没有什么方法可以做到:
git rebase -i all on this branch
当前回答
另一种压缩所有提交的方法是将索引重置为master:
git checkout yourBranch
git reset $(git merge-base master $(git branch --show-current))
git add -A
git commit -m "one commit on yourBranch"
这并不完美,因为这意味着你知道“你的分支”来自哪个分支。 注意:在Git中找到原始分支并不容易/不可能(可视化的方式通常是最简单的,如图所示)。
注意:git分支——show-current已在git 2.22(2019年第二季度)中引入。
或者,正如Hiroki Osame在评论中指出的那样:
git switch yourBranch
git reset --soft $(git merge-base main HEAD)
git commit -m "one commit on yourBranch"
不需要git分支——show-current,因为HEAD已经是该分支的引用。 不需要git add -A,因为git重置-soft只移动HEAD,并保持索引不变(换句话说,文件已经“添加”)。
编辑:你将需要使用git push——force
Karlotcha Hoa在评论中写道:
对于重置,可以这样做 git reset $(git merge-base master $(git rev-parse——abbrev-ref HEAD)) 自动使用您当前所在的分支。 如果使用它,还可以使用别名,因为该命令不依赖于分支名称。
Sschoof在评论中补充道:
因为我的默认分支被称为main,我的搜索多次把我带到这里: 为我下次上课抄一份 git reset $(git merge-base main $(git rev-parse——abbrev-ref HEAD))
其他回答
在之前的回答中,我没有看到任何关于如何处理“凌乱的分支”和“自我冲突”的信息。例如,我经常在我的特性分支(称为特性)上有主提交,这导致了它们之间的冲突。我发现这是最难处理的问题之一。
如何挤压凌乱的树枝?使用临时分支!
我发现Felix Rieseberg的解决方案是最好的。以下是我对他的建议略短的抄写:
Create a local tmp branch of off master git checkout master && git pull && git checkout -b tmp Merge all feature changes into tmp (without any commits, only staged file changes). git merge --squash $feature Manually solve all remaining "real conflicts" (This is the only step you cannot have a script do for you) Commit. tmp is now master + 1 commit (containing all changes). git commit ... Checkout feature and git reset --hard tmp (feature's original contents are gone, and it is now basically tmp, but renamed) git checkout $feature && git reset --hard tmp Ignore and override origin/feature (then clean up) git push -f && git branch -D tmp
Felix指出,这将产生最干净的合并,没有任何来自master和feature之间混乱/复杂关系的奇怪的自我冲突:
您可能会遇到一些不可避免的合并冲突。请相信,这是尽可能少的冲突,因为您跳过了最初创建的许多中间提交。
你可以通过子命令来实现
$ git rebase -i HEAD~$(git rev-list -count HEAD ^master)
这将首先计算从master分离后的提交次数,然后将其还原到确切的长度。
假设你从master分支,你不需要一直输入你的branch到重置步骤:
git checkout yourBranch
git reset --soft HEAD~$(git rev-list --count HEAD ^master)
git add -A
git commit -m "one commit on yourBranch"
解释:
git revlist——count HEAD ^master自master创建feature分支以来的提交次数,f.ex。20. git reset——soft HEAD~20将对最近20次提交进行软重置。这将把更改保留在文件中,但删除提交。
用法:
在我的.bash_profile中,我为gisquash添加了一个别名,用一个命令就可以做到这一点:
# squash all commits into one
alias gisquash='git reset --soft HEAD~$(git rev-list --count HEAD ^master)'
在重置和提交后,你需要做一个git push -force。
提示:
如果你正在使用Gitlab >= 11.0,你就不需要再这样做了,因为它在合并分支时有一个压缩选项。
假设你在特征分支上:
在特性分支中找到第一个提交。如果你正在使用gitlab或github,你可以直接在分支中查看它,并从那里复制散列,或者你可以使用以下命令:
Git日志<source_branch>..< feature_branch >——漂亮=格式:% h
执行以下命令:
git reset --soft <base_commit_hash>
git commit --amend --no-edit
现在在这个阶段,在您的本地,您有一个提交,其中包括在所有以前的提交中所做的更改。
回顾它,你需要用力推它。在强制推送之后,所有的更改都将合并到一个提交中,而您的分支将只有1个提交。
在特征分支中强制推送
git push --force
所有这些git重置,硬的,软的,以及这里提到的所有其他东西都可能工作(它不适合我),如果你正确地执行步骤和某种精灵。 如果你是普通的smo,试试这个: 如何使用git合并-squash?
Saved my life, and will be my go to squash, been using this 4 times since I found out about it. Simple, clean and basically 1 comamnd. In short: If you are on a branch lets call it "my_new_feature" off develop and your pull request has 35 commits (or however many) and you want it to be 1. A. Make sure your branch is up to date, Go on develop, get latest and merge and resolve any conflicts with "my_new_feature" (this step really you should take as soon as you can all the time anyway) B. Get latest of develop and branch out to a new branch call it "my_new_feature_squashed"
C.魔法在这里。 你想把你的工作从“my_new_feature”变成“my_new_feature_squashed” 所以只要这样做(在我们创建off develop的新分支上): Git merge—squash my_new_feature
你所有的改变现在都在你的新分支上,你可以自由地测试它,然后只做一个单一的提交,推送,那个分支的新PR——然后等待第二天重复。 你不喜欢编程吗?:)