我读到在Git中重命名文件时,你应该提交任何更改,执行重命名,然后展示重命名的文件。Git将从内容中识别文件,而不是将其视为一个新的未跟踪的文件,并保留更改历史。

然而,今晚这样做,我最终恢复到git mv。

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

我重命名我的样式表在Finder从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,这也可以:

将父目录/dir/RenamedFile.js重命名为/whatever/RenamedFile.js。 git添加-A来进行更改 重命名父目录为/dir/RenamedFile.js。 git add -A再次,将重新stage vs该更改,迫使git拾取文件名更改。

其他回答

对于git mv手册页说

索引在成功完成后更新, […]

因此,首先,您必须自己更新索引 (使用git添加mobile.css)。但是git状态 仍然会显示两个不同的文件:

$ 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状态和git提交之间——dry-run -a,但是 下面是莱纳斯的提示:

Git根本不关心整体 在内部“重命名检测”,以及您拥有的任何提交 所做的重命名完全独立于 然后我们使用启发式来显示重命名。

试运行使用真正的重命名机制,而 Git状态可能不会。

您必须将这两个修改后的文件添加到索引中,Git才能将其识别为移动。

mv old new和git mv old new之间的唯一区别是git mv也将文件添加到索引中。

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

请注意,不能只使用git add .,因为它不会向索引添加删除。

参见“git add -A”和“git add”的区别。

刚刚遇到了这个问题-如果你更新了一堆文件,不想把它们都做git mv,这也可以:

将父目录/dir/RenamedFile.js重命名为/whatever/RenamedFile.js。 git添加-A来进行更改 重命名父目录为/dir/RenamedFile.js。 git add -A再次,将重新stage vs该更改,迫使git拾取文件名更改。

你没有展示你的搜索结果。我相信如果你通过Finder移动然后git添加css/mobile。css;git rm css/iphone.css, git会计算新文件的哈希值,然后才意识到文件的哈希值匹配(因此这是一个重命名)。

在你必须手动重命名文件的情况下,例如,使用脚本批量重命名一堆文件,然后使用git add -A。为我工作。