在git中处理文件重命名

我读过,当在git中重命名文件时,您应该提交任何更改,执行重命名,然后重命名您的文件。 Git会从内容中识别文件,而不是将其视为新的未跟踪文件,并保留更改历史记录。

然而,今晚我只是做了这件事,结果我又回到了git mv

> $ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   index.html
#

在Finder mobile.css我的样式表从iphone.css重命名为mobile.css

> $ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   index.html
#
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   deleted:    css/iphone.css
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   css/mobile.css

所以git现在认为我已经删除了一个CSS文件,并添加了一个新文件。 不是我想要的,让我们撤销重命名并让git完成这项工作。

> $ git reset HEAD .
Unstaged changes after reset:
M   css/iphone.css
M   index.html

回到我开始的地方。

> $ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   index.html
#

让我们改用git mv

> $ git mv css/iphone.css css/mobile.css
> $ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   renamed:    css/iphone.css -> css/mobile.css
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   index.html
#

看起来我们很好。 那么为什么git在我使用Finder时第一次认识到重命名?


对于手册页说git mv

该指数在成功完成后更新,[...]

所以,首先你必须自己更新索引(通过使用git add mobile.css )。 然而
git status仍然会显示两个不同的文件

$ git status
# On branch master
warning: LF will be replaced by CRLF in index.html
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   index.html
#       new file:   mobile.css
#
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       deleted:    iphone.css
#

你可以通过运行git commit --dry-run -a来获得不同的输出,这会导致你期望的结果

Tanascius@H181 /d/temp/blo (master)
$ git commit --dry-run -a
# On branch master
warning: LF will be replaced by CRLF in index.html
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   index.html
#       renamed:    iphone.css -> mobile.css
#

我无法确切地告诉你为什么我们会看到git statusgit status之间的这些差异
git commit --dry-run -a ,但这里是来自Linus的提示

git实际上并不关心内部的整个“重命名检测”,你对重命名所做的任何提交都完全独立于我们用来显示重命名的启发式。

dry-run使用真正的重命名机制,而git status可能不会。


你必须将两个修改后的文件添加到索引,然后git才会将其识别为移动。

mv old newgit mv old new的唯一区别就是git mv也会将这些文件添加到索引中。

mv old new then git add -A也可以工作。

请注意,你不能只使用git add . 因为这不会增加清除指数。

查看“git add -A”和“git add”之间的区别。


最好的事情是自己尝试。

mkdir test
cd test
git init
touch aaa.txt
git add .
git commit -a -m "New file"
mv aaa.txt bbb.txt
git add .
git status
git commit --dry-run -a

现在git status和git commit --dry-run -a显示两个不同的结果,其中git status显示bbb.txt,因为删除了新文件/aaa.txt,而--dry-run命令显示实际重命名。

~/test$ git status

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   bbb.txt
#
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   deleted:    aaa.txt
#


/test$ git commit --dry-run -a

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   renamed:    aaa.txt -> bbb.txt
#

现在继续进行检查。

git commit -a -m "Rename"

现在您可以看到该文件实际上已重命名,并且在git状态中显示的内容是错误的。

故事的道德:如果您不确定您的文件是否已重命名,请发出“git commit --dry-run -a”。 如果它显示该文件被重命名,那么你很好。

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

上一篇: Handling file renames in git

下一篇: Difference between git add ., git add