下面是我的dev分支上的简化提交状态。
7f75hsyfr - changes to file1
file1
94dfsrg43 - more changes to file2
file2
92d7a513 - changes to file3
file3
035a72fd - Merge branch 'master' into dev
35bcc341 - Merge branch 'master' into dev
2e05a2fc - changes to file2
file2
60c9daaf - changes to file1
file1
由于我在分支机构之间切换,因此我提交了未完成的工作,导致多个提交与相同的文件相关。还有来自master的合并更改的合并提交。如何在推送到主分支之前清理一下?理想情况下,我想重新组织这个,所以每个 file1 和 file2 都有一个提交。
答案 0 :(得分:3)
您需要git rebase -i
命令。查看git rebase
的文档。你可以将你的提交压缩成一个提交,重新命名,重新排序并在你掌握之前进行任何类型的清理。
由于您提到了合并提交,我建议运行git config --global pull.rebase true
,以确保将来无论何时从远程分支中提取,您的提交将在之后重新应用本地分支得到更新。这意味着,您最终不会在提交之间进行合并提交。它还可以轻松实现挑选,并将其与git rebase
相结合,在恢复变更时非常有用。
答案 1 :(得分:1)
我认为没有特别的理由这样做 - 通常你保持所有提交完好无损。但是,如果要执行此操作,可以创建修补程序文件并将其应用于主文件。我通常使用gitk来创建补丁,因为它可以很容易地选择开始和结束,但也有一个命令来执行此操作。
编辑:
命令行解决方案类似于:
git checkout <branch>
git format-patch master --stdout > ../blahblah.patch
git checkout master
git apply ../blahblah.patch
git add .
git commit . -m"apply changes from branch"
这会将分支中的所有更改都放在一次提交中,但您可以选择提交并将其捆绑在一起。
答案 2 :(得分:1)
如果您没有合并提交,您可以只使用交互式rebase,如Combining multiple commits before pushing in Git中所述。
您可以通过简单地重新设置或挑选在master之上的分支特有的提交来摆脱合并提交,因为代码的最终状态将等同于完成合并。
要清理您的分支,以下解决方案将结合使用rebasing和cherry-picking提交来删除合并提交,然后通过交互式重新设置来压缩其他提交。
我们将创建一个临时分支以保持dev
的当前状态,然后在dev
之上与master
合并之前,将master
的部分重新绑定,这相当于首先合并master
:
# Create temporary branch to save current state of dev
git branch temp dev
# Temporarily reset dev to state before the merges
git reset --hard 2e05a2fc
# Rebase dev onto master
git rebase master
接下来,从temp
挑选剩下的提交。我们将使用提交范围,其中范围的开始是独占的(即实际上不包括在内):
git cherry-pick 035a72fd..7f75hsyfr
现在,您已准备好使用交互式rebase来压缩提交。在示例中找到与60c9daaf
对应的重写提交。我们称之为提交X
。然后
git rebase -i X^
X^
表示rebase的基本提交,实际上不会更改。但是,每个后代提交都不会出现在交互式rebase编辑器中,按照从最旧到最新的顺序出现:
pick X changes to file1
pick Y changes to file2
pick Z changes to file3
pick AA more changes to file2
pick AB changes to file1
重新排序提交,以便提交更改文件
pick X changes to file1
pick AB changes to file1
pick Y changes to file2
pick AA more changes to file2
pick Z changes to file3
然后将squash
或s
添加到您要压缩到上一个提交的每个后续提交中:
pick X changes to file1
squash AB changes to file1
pick Y changes to file2
squash AA more changes to file2
pick Z changes to file3
完成后,保存并退出编辑器,除非存在冲突,否则rebase将继续运行,在这种情况下,您需要解决每个冲突并继续使用rebase。
现在,您需要验证结果,以确保在开始修改之前,您所做的更改仍然等同于分支的状态:
git diff temp
如果没有输出,那么分支的最终状态与开始修改之前的状态相同,因此现在您可以使用temp
删除git branch -D temp
。