可以在Git中移动/重命名文件并保留其历史记录吗?

我想重新命名/移动Git中的项目子树

/project/xyz

/components/xyz

如果我使用普通的git mv project components ,那么xyz project所有提交历史记录都会丢失。 有没有办法来移动这样的历史记录?


Git检测重命名而不是用提交持久化操作,所以不管你使用git mv还是mv都不重要。

log命令采用一个--follow参数,它在重命名操作之前继续历史记录,即使用启发式搜索相似的内容:

http://git-scm.com/docs/git-log

要查看完整的历史记录,请使用以下命令:

git log --follow ./path/to/file

可以重命名文件并保持历史记录不变,尽管它会导致文件在存储库的整个历史记录中被重命名。 这可能只适用于迷恋git-log-lovers,并且有一些严重的含义,包括:

  • 你可能会重写共享历史记录,这是使用Git时最重要的。 如果其他人已经克隆了存储库,那么您将会破坏它。 他们将不得不重新克隆以避免头痛。 如果重命名足够重要,这可能是确定的,但您需要仔细考虑这一点 - 最终可能会扰乱整个开源社区!
  • 如果您在存储库历史记录中早些时候使用旧名称引用了该文件,则可以有效地打破早期版本。 为了弥补这一点,你必须做更多的箍跳。 这不是不可能的,只是单调乏味而且可能不值得。
  • 现在,既然你还在我身边,你可能是独立开发者重命名一个完全孤立的文件。 让我们使用filter-tree来移动文件!

    假设你将一个old文件移动到一个文件夹dir ,并将其命名为new

    这可以通过git mv old dir/new && git add -u dir/new ,但是会打破历史记录。

    代替:

    git filter-branch --tree-filter 'if [ -f old ]; then mkdir dir && mv old dir/new; fi' HEAD
    

    将重做分支中的每个提交,在每个迭代的tick中执行命令。 当你这样做时,大量的东西可能会出错。 我通常会测试以查看文件是否存在(否则它还没有移动),然后执行必要的步骤来根据我的喜好来调整树。 在这里你可能通过文件sed来改变对文件的引用等等。 把自己打昏! :)

    完成后,文件被移动并且日志完好无损。 你觉得自己像个忍者海盗。

    也; 当然,如果您将该文件移动到新文件夹,则仅需要mkdir目录。 if会避免在历史早期创建此文件夹,而不是您的文件存在。


    没有。

    简短的答案是NO ,不可能在Git中重命名文件并记住历史记录。 这是一个痛苦。

    有传闻说, git log --follow --find-copies-harder会起作用,但它对我来说不起作用,即使文件内容没有任何改变,并且这些移动都是用git mv

    (最初我使用Eclipse在一个操作重命名和更新包,这可能混淆饭桶。但是,这是做一个很平常的事。 --follow似乎如果仅仅是工作mv进行,然后commitmv不是太远。)

    Linus说,你应该从整体上理解软件项目的全部内容,而不需要跟踪单个文件。 那么,可悲的是,我的小脑子不能这样做。

    真的很烦人 ,很多人无意中重复了这个声明,git自动跟踪移动。 他们浪费了我的时间。 Git没有这样的事情。 按设计(!)Git根本不跟踪移动。

    我的解决方案是将文件重命名回原来的位置。 更改软件以适应源代码管理。 有了git,你似乎需要在第一时间正确使用它。

    不幸的是,这打破了Eclipse,这似乎使用 - --follow
    git log --follow有时不显示具有复杂重命名历史的文件的完整历史记录,即使git log也行。 (我不知道为什么。)

    (有一些过于聪明的黑客可以重新回到原来的工作,但它们相当可怕。请参阅GitHub-Gist:emiller / git-mv-with-history。)

    链接地址: http://www.djcxy.com/p/22653.html

    上一篇: Is it possible to move/rename files in Git and maintain their history?

    下一篇: How to make git mark a deleted and a new file as a file move?