如何压缩合并的git变更集

时间:2015-11-17 17:59:38

标签: git git-branch

是否可以在#9701282历史记录中删除Git之类的提交? 我并不是说#b372fa5以上的回购应该改变,
这个地方应该简化图表 紫枝的提交看起来多余 在#b372fa5合并点内应用它的变化应该不是很难 有什么技术可以实现这个动作?

Git branch

3 个答案:

答案 0 :(得分:3)

Git就像古老的科幻电影的古典时间机器。你可以回到过去,但是如果你改变了过去,你会影响现在。

您可以使用git最强大的功能之一rebase来执行您想要的任何操作,但是,修改后的提交之后的对象名称将会更改。

如果您与他人合作,建议不要这样做,因为他们必须从手术中恢复。

这是一个前后的例子,我只是作为一个例子来运行:

git log --oneline --graph
* d3959f3 Something
* 9e58b42 Modify new
*   ad1dea6 Merge branch 'mybranch'
|\  
| * e75658b somechange
* | 1076214 New File
* | 49fe418 Updated on master
|/  
* b94640d Updated
* da15c9c Initial commit

git log --oneline --graph
* 89fe296 Something
* d9620cc Modify new
* 6301614 New File - somechange
* 49fe418 Updated on master
* b94640d Updated
* da15c9c Initial commit

执行我使用的操作:

git rebase -i ad1dea6~2

# a more common form is to modify n number of commits starting at HEAD
git rebase -i HEAD~n

这将打开配置的编辑器,其中包含您在" todo列表中指定的更改"允许您以交互方式选择,压缩,重写,删除,重新排序,甚至使用exec运行任意shell命令。

以下是vi中的内容:

pick 1076214 New File
pick e75658b somechange
pick 9e58b42 Modify new
pick d3959f3 Something

# Rebase 49fe418..d3959f3 onto 49fe418
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

我选择了最简单的选项来压缩甚至不需要解决冲突的更改,但会提示您确认提交消息(正如您所看到的那样,我确实已经更改)。

保存提交消息后,git会自动重写剩下的历史记录,而不会再提示我。

我甚至可以通过使用git的方便reflog命令来尝试一些不同的排列。

git reflog

在git中甚至可以恢复孤立的更改,只要它们没有在gc运行中收集。您可以随时使用gc调用垃圾收集器,但有些命令会定期执行此操作。

使用reflog从错误状态中恢复的一种方法是在reflog中找到您有兴趣返回并运行的点:

git reset --hard <SHA>

在工作流程中使用rebase

之前的讨论主要是使用rebase来改变rebase -i的历史记录。对于本地工作流而言,这实际上是一个非常有用的功能,您希望在处理功能时进行定期提交,然后在与其他人合并到协作分支之前,您可以重新组织本地提交以使您的历史记录更易于阅读或将提交组合到在每次提交时创建工作代码。

第二个用例是执行rebase合并时。这可以通过将merge的使用替换为rebase来完成。

git rebase master

描述其工作原理的最佳方式是假设当前分支上的所有更改都存储起来,让您处于两个分支发散的公共提交中。接下来,分支被“快速转发”到目标分支上的最新提交。最后,存储的提交在新HEAD的顶部逐个应用,使您有机会在每次提交时解决冲突(而不是只在形成合并提交时才解决的合并)。结果是一组全新的提交(新的时间戳和所有,可能通过冲突解决方案更改修改),使得在目标分支HEAD之后按顺序进行更改的外观。

您还可以将--rebase选项与pull一起使用。

注意:有些工作场所不喜欢更改提交历史记录,更喜欢在执行合并时禁用与--no-ff的快进合并。很明显,由您决定何时使用变基,以及是否对您的情况有意义。您仍然可以使用本地交互式表单来自定义您自己的工作流程,因为这些更改尚未推送到远程。

我从最近的blog post中获取了一些关于git一般用法的内容。我试图在保持尽可能紧凑的同时包含更多的平均信息。

答案 1 :(得分:1)

git branch -d branch_name

删除合并的分支(不要担心,如果它没有合并就不会删除任何内容,你需要git branch -D)

要查看所有当前合并分支,请尝试:

git branch --merged

如果你想保持你的历史线性,我建议使用git rebase

一般来说,保留历史记录有时候是一个好主意。

像往常一样,我会推荐https://git-scm.com/book/en/v2第3章。这将真正帮助你更好地理解一切。

如果你真的想删除提交(删除分支只会使它们无法访问,那么我建议阅读有关reflogs - 小心但,git中的一些东西可以破坏您的仓库并永久删除您的代码,但这可能只是其中之一)

答案 2 :(得分:1)

如果整个提交&#39;树是正确的,如果只需要更改父母,那么使用graftgit filter-branch很容易做到。

首先,假装b372fa5^b372fa5唯一的父母。

echo $(git rev-parse b372fa5 b372fa5^) > .git/info/grafts

然后检查历史记录并检查其是否正确:

git log --graph

然后重写提交以使这种移植永久化:

git filter-branch

最后清理:

rm .git/info/grafts
相关问题