如何从历史记录中删除删除和重命名?

时间:2016-01-31 20:35:31

标签: git git-rewrite-history

在git中,如何从分支中的某个提交开始删除文件删除和重命名,同时保留每个文件的更改历史记录(删除和重命名)?

我的用例是我拿了一个分支并从那里开始了一个新的分支,在那里我删除了一些文件并重命名了其他文件。然后我修改了剩余的(通常是重命名的)文件(还添加了一些文件)。现在我想恢复原始名称并恢复已删除的文件(仍存在于公共基础上),同时保留所有内容的历史记录。我的最终目标是能够在原始分支中合并(所以without the renames and file deletions that I introduced)。

可以这样做吗?我想知道这是多么容易,特别是因为重命名的文件被修改了(所以天真地删除重命名将切断原始文件和修改之间的历史链接,而我想要保留)...

PS:分支分歧后的变化很大(至少在“清理”分支上)。

2 个答案:

答案 0 :(得分:2)

您无需重写历史记录即可进行合并。您可以还原重命名并重新引入已删除的文件,然后提交并合并。使用git mv重命名文件。可以使用git checkout <rev-which-deleted-the-file>^ -- <filename>恢复已删除的文件。 See this answer for details

可以使用git-log的{​​{1}}找到已删除和重命名的文件。

Git不存储重命名,它会动态计算它们并使用一些启发式方法来处理小编辑。 --diff-filtergit-loggit-diff都有git-blame-C等选项来控制Git尝试查找复制和重命名(移动)文件的难度。因此,历史的连续性不一定会因分支中的重命名而丢失。

如果您确实要重写历史记录,请首先查找使用-M删除文件的所有更改。然后,您可以使用git log --diff-filter=D master..branch来更改这些提交并恢复已删除的文件。

重写有点棘手,因为您必须撤消重命名,然后在每次后续提交中重命名该文件。这是git rebase -i的工作,它可以对一系列提交应用相同的更改。

git-filter-branch

git filter-branch --tree-filter 'if [ -f new ]; mv new old; fi' master..branch 在每次提交时运行shell命令,然后根据需要添加和删除文件来改变提交。

与以前一样,要找到您的重命名,请使用--tree-filter

答案 1 :(得分:0)

您可以尝试在分支点为违规分支执行git rebase -i。为了安全起见,我首先要在你要破坏的分支的尖端创建一个新的分支,以防万一(哈!墨菲定律是无情的)出现问题。

如果变化非常广泛,有一些方法可以实现自动化,但这种方式更为明显。有关详细信息,请参阅Pro git book

相关问题