【发布时间】:2011-06-10 08:26:29
【问题描述】:
我对分支 (A) 进行了一些修改。
然后我决定根据我现有工作副本的状态创建一个全新的分支 (B),然后提交并推送到该分支。
在我之前的重构过程中移动了许多文件,因此现在不包含在版本控制中,而是直接移动到文件系统中。偶然地,我在提交并推送到新分支(B)之前没有将这些文件添加到 git。
如果我现在添加这些文件并提交和推送,Git 是否能够检测到文件移动操作?
【问题讨论】:
标签: git
我对分支 (A) 进行了一些修改。
然后我决定根据我现有工作副本的状态创建一个全新的分支 (B),然后提交并推送到该分支。
在我之前的重构过程中移动了许多文件,因此现在不包含在版本控制中,而是直接移动到文件系统中。偶然地,我在提交并推送到新分支(B)之前没有将这些文件添加到 git。
如果我现在添加这些文件并提交和推送,Git 是否能够检测到文件移动操作?
【问题讨论】:
标签: git
如果它们是作为两个单独的提交完成的,则不会,因为文件将在一个修订版中被删除,而新文件将在新修订版中创建。如果您想保留重命名,您应该使用git commit --amend 将您的添加附加到上一个提交的删除中。
【讨论】:
如果您在修订前后进行直接比较,则会检测到该移动,但如果您查看常规 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。
【讨论】:
但是 git 按内容而不是路径来处理对象。这意味着当您移动对象(文件)或删除/添加对象时,它不会产生影响。它只会在 git repo 数据库中存储一次。
【讨论】:
鉴于 Git 不存储任何重命名信息,而是运行某种重命名检测机制,你应该没问题。另见Handling renames: svn vs. git vs. mercurial
【讨论】: