【问题标题】:Git - will the file moves be detected?Git - 会检测到文件移动吗?
【发布时间】:2011-06-10 08:26:29
【问题描述】:

我对分支 (A) 进行了一些修改。

然后我决定根据我现有工作副本的状态创建一个全新的分支 (B),然后提交并推送到该分支。

在我之前的重构过程中移动了许多文件,因此现在不包含在版本控制中,而是直接移动到文件系统中。偶然地,我在提交并推送到新分支(B)之前没有将这些文件添加到 git。

如果我现在添加这些文件并提交和推送,Git 是否能够检测到文件移动操作?

【问题讨论】:

    标签: git


    【解决方案1】:

    如果它们是作为两个单独的提交完成的,则不会,因为文件将在一个修订版中被删除,而新文件将在新修订版中创建。如果您想保留重命名,您应该使用git commit --amend 将您的添加附加到上一个提交的删除中。

    【讨论】:

    • 我添加了文件并执行了 git commit --amend。提交这导致我使用我的解决的冲突(即 add 而不是 delete)。 GitHub 不再显示文件历史记录。当我拉入其他分支时会检测到文件移动吗?如果是这样,我可以忍受可见文件历史记录的暂时丢失。
    • 供参考:拉入其他分支似乎不会恢复可见的文件历史记录。
    • @Ben:看看 bdonlan 的回答。由于 git 对每个操作进行重命名检测,因此当且仅在适当的情况下,它才会将其检测为重命名。如果您只检查一个提交,那么它当然不会显示为重命名 - 该提交不包含重命名,只是删除或添加!但是,如果您将重命名之前的提交与之后的提交进行比较,那么它将被检测为正常 - 这只是两种状态的比较,与之间的提交无关。
    【解决方案2】:

    如果您在修订前后进行直接比较,则会检测到该移动,但如果您查看常规 git log,则不会:

    [bd@satoko testgit] echo hello world > foo
    [bd@satoko testgit] git init
    gitInitialized empty Git repository in /home/bd/testgit/.git/
    [bd@satoko testgit] git add foo
    [bd@satoko testgit] git commit -m 'test'
    [master (root-commit) 772dbe5] test
     1 files changed, 1 insertions(+), 0 deletions(-)
     create mode 100644 foo
    [bd@satoko testgit] mv foo bar
    [bd@satoko testgit] echo baz > quux
    [bd@satoko testgit] git add quux
    [bd@satoko testgit] git commit -a -m 'rm; add'
    [master 59dd10b] rm; add
     2 files changed, 1 insertions(+), 1 deletions(-)
     delete mode 100644 foo
     create mode 100644 quux
    [bd@satoko testgit] git add bar
    [bd@satoko testgit] git commit -m 'add'
    [master 823f70f] add
     1 files changed, 1 insertions(+), 0 deletions(-)
     create mode 100644 bar
    
    [bd@satoko testgit] git log --stat -m
    commit 823f70fe50828204686a6a42a5e98dc9b258903b
    Author: Bryan Donlan <bdonlan@fushizen.net>
    Date:   Mon Jan 17 05:06:16 2011 -0500
    
        add
    
     bar |    1 +
     1 files changed, 1 insertions(+), 0 deletions(-)
    
    commit 59dd10bfb72bb9005edecb1b7609978d82d21652
    Author: Bryan Donlan <bdonlan@fushizen.net>
    Date:   Mon Jan 17 05:05:58 2011 -0500
    
        rm; add
    
     foo  |    1 -
     quux |    1 +
     2 files changed, 1 insertions(+), 1 deletions(-)
    
    commit 772dbe5357253b533f8f2b9c64836dc09a51def4
    Author: Bryan Donlan <bdonlan@fushizen.net>
    Date:   Mon Jan 17 05:04:35 2011 -0500
    
        test
    
     foo |    1 +
     1 files changed, 1 insertions(+), 0 deletions(-)
    ### As you can see, a log doesn't show the move, but...
    [bd@satoko testgit] git diff --stat  823f..772d -M
     bar => foo |    0
     quux       |    1 -
     2 files changed, 0 insertions(+), 1 deletions(-)
    ### A direct comparison does
    

    这种行为是因为 git 实际上并没有保存移动/重命名信息 - 它通过比较添加/删除文件的内容来重建它。通过直接比较,它只查看之前/之后的状态,因此添加/删除文件的确切方式并不重要。但是,对于 git log,它会比较成对的修订,因此它只会看到“删除”或“添加”,而不是两者。

    如果这是一个问题,您可能需要考虑使用git rebase --interactive 将添加的文件合并回删除它们的修订版。但是,如果其他人已经下载了具有不良历史记录的修订版,则可以使用unwanted side effects

    【讨论】:

      【解决方案3】:

      但是 git 按内容而不是路径来处理对象。这意味着当您移动对象(文件)或删除/添加对象时,它不会产生影响。它只会在 git repo 数据库中存储一次。

      【讨论】:

        【解决方案4】:

        鉴于 Git 不存储任何重命名信息,而是运行某种重命名检测机制,你应该没问题。另见Handling renames: svn vs. git vs. mercurial

        【讨论】:

        • 在我看来,虽然历史记录可能可用,但文件修订历史记录似乎从 GitHub 之类的工具中丢失,可能是因为比较的数量或修订版本。
        猜你喜欢
        • 2016-03-05
        • 1970-01-01
        • 2023-04-11
        • 1970-01-01
        • 2012-05-28
        • 1970-01-01
        • 2021-08-05
        • 2017-11-23
        • 2022-11-18
        相关资源
        最近更新 更多