在git中,如何从分支中的某个提交开始删除文件删除和重命名,同时保留每个文件的更改历史记录(删除和重命名)?
我的用例是我拿了一个分支并从那里开始了一个新的分支,在那里我删除了一些文件并重命名了其他文件。然后我修改了剩余的(通常是重命名的)文件(还添加了一些文件)。现在我想恢复原始名称并恢复已删除的文件(仍存在于公共基础上),同时保留所有内容的历史记录。我的最终目标是能够在原始分支中合并(所以without the renames and file deletions that I introduced)。
可以这样做吗?我想知道这是多么容易,特别是因为重命名的文件被修改了(所以天真地删除重命名将切断原始文件和修改之间的历史链接,而我想要保留)...
PS:分支分歧后的变化很大(至少在“清理”分支上)。
答案 0 :(得分:2)
您无需重写历史记录即可进行合并。您可以还原重命名并重新引入已删除的文件,然后提交并合并。使用git mv
重命名文件。可以使用git checkout <rev-which-deleted-the-file>^ -- <filename>
恢复已删除的文件。 See this answer for details
可以使用git-log
的{{1}}找到已删除和重命名的文件。
Git不存储重命名,它会动态计算它们并使用一些启发式方法来处理小编辑。 --diff-filter
,git-log
和git-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。