Git - will the file moves be detected?
I performed some modifications on a branch (A).
I then decided to create a brand new branch (B) based on the state of my existing working copy and commit and push to that.
The开发者_如何学运维re were a number of files that had been moved during my earlier refactoring, and hence were now not included in version control having been moved directly in the filesystem. By accident I did not add these files to git before committing and pushing to the new branch (B).
If I now add these files and commit and push, will Git be able to detect the file move operations?
Not if they're done as two separate commits, because the files will have been deleted in one revision and a new file created in the new revision. If you want to preserve the rename, you should do a git commit --amend
to append your additions to the previous commit with the deletions.
The move will be detected if you do a direct comparison between before and after revisions, but not if you view a regular 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
This behavior is because git does not actually save move/rename information - it reconstructs it by comparing the contents of added/removed files. With a direct comparison, it only looks at the before/after state, so exactly how the files were added/removed doesn't matter. However, with git log
, it compares pairwise revisions, so it only ever sees either 'removed' or 'added', not both.
If this is a problem, you may want to consider using git rebase --interactive
to merge the add of the files back into the revision that deleted them. However, this can have unwanted side effects if the revisions with the bad history have already been downloaded by others.
But git treats objects by content and not by paths. That means it does not make a difference when you move an object (a file) or delete/add an object. It will be stored only once in the git repo database.
Given that Git does not store any renaming information, but rather runs some sort of rename detection mechanism you should be fine. See also Handling renames: svn vs. git vs. mercurial
精彩评论