我用:
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
当前回答
在阅读了几个关于压缩的Stackoverflow问题和答案后,我认为这是一个很好的压缩分支上所有提交的代码行:
git reset --soft $(git merge-base master YOUR_BRANCH) && git commit -am "YOUR COMMIT MESSAGE" && git rebase -i master
这是假设master是基础分支。
其他回答
对于喜欢点击的人的解决方案:
安装源代码树(免费) 检查你的提交是什么样的。很可能你有类似的东西 右键单击父提交。在我们的例子中,它是主分支。
您可以通过单击一个按钮来取消上一个提交。在我们的例子中,我们需要点击2次。您也可以更改提交消息 结果非常棒,我们已经准备好了!
旁注:如果你把你的部分提交推到远程,你必须在挤压后强制推
在之前的回答中,我没有看到任何关于如何处理“凌乱的分支”和“自我冲突”的信息。例如,我经常在我的特性分支(称为特性)上有主提交,这导致了它们之间的冲突。我发现这是最难处理的问题之一。
如何挤压凌乱的树枝?使用临时分支!
我发现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之间混乱/复杂关系的奇怪的自我冲突:
您可能会遇到一些不可避免的合并冲突。请相信,这是尽可能少的冲突,因为您跳过了最初创建的许多中间提交。
How
你需要得到分支的合并基
git merge-base master your-branch
# 566f8438e0cd0e331ceb49a9cb0920143dfb065c
然后你就可以改基了
git rebase -i 566f8438e0cd0e331ceb49a9cb0920143dfb065c
# then squash/pick/do commit messages
或者只是进行软重置并提交所有内容
git reset --soft 566f8438e0cd0e331ceb49a9cb0920143dfb065c
git add .
git commit -m "The only commit"
自动化
如果你经常这样做,你可以把这些放在你的.bashrc使用自动化。
g-rebase-branch() {
git branch --show-current | xargs git merge-base master | xargs git rebase -i
}
g-one-commit() {
local last_commit_message=`git show -s --format=%s`
git branch --show-current | xargs git merge-base master | xargs git reset --soft
git add -A
git commit -m "$last_commit_message"
git commit --amend
}
然后直接在终端上做这些。
g-one-commit
但如果你合并的是与master不同的分支,那么你可以用“$1”替换master来做到这一点
g-one-commit staging
如果你使用基于IDE的JetBrains,如IntelliJ Idea和prefare,使用命令行GUI:
进入版本控制窗口(Alt + 9/Command + 9) -“日志”选项卡。 在树中选择创建分支的点 右键点击它->重置当前分支到这里->选择软(!!)(重要的是不要失去你的变化) 按下对话框窗口底部的重置按钮。
就是这样。您未提交所有更改。现在如果你重新提交,它会被压缩
另一种压缩所有提交的方法是将索引重置为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))