如何告诉 Git 它是同一个目录,只是名称不同
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6628539/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to tell Git that it's the same directory, just a different name
提问by WinWin
After getting past a few hurdles learning Git, I came across a new challenge: Renaming a directory (locally, in the working directory).
在克服了学习 Git 的一些障碍之后,我遇到了一个新的挑战:重命名目录(在本地,在工作目录中)。
When I type git status
, it lists all the files in the old directory name (that exist with the same exact filenames in the new directory) as deletedand the new directory name as "untracked".
当我输入git status
,它列出了旧目录名(在新目录中完全相同的文件名存在)的所有文件删除,新目录名称为“未跟踪”。
Is there a way to tell Git that "it's actually the same directory, just a different name"?
有没有办法告诉 Git “它实际上是同一个目录,只是名称不同”?
So that all the files will be listed by git status
as modified only?
这样所有文件都将被列为 git status
仅修改?
To exemplify the problem, here is the output I receive from git status
when I rename an entire directory:
为了举例说明问题,以下是git status
我重命名整个目录时收到的输出:
git status
# On branch master
# 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: old-dir-name/file1
# deleted: old-dir-name/file2
# deleted: old-dir-name/file3
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# new-dir-name/
no changes added to commit (use "git add" and/or "git commit -a")
~/sb/ws>
采纳答案by WinWin
All answers here were very helpful on the way to the actual solution for the particular scenario I was facing. I am providing what worked for me in the form of actual steps, hopefully helping others encountering the same challenge:
这里的所有答案对于我面临的特定场景的实际解决方案都非常有帮助。我以实际步骤的形式提供对我有用的东西,希望能帮助遇到同样挑战的其他人:
git mv <old-dir-name> <new-dir-name>
git status
(verify that all files marked renamed, not "deleted")git commit -a -m "git mv <old-dir-name> <new-dir-name>"
(this is a "fake" commit, to prepare for the real rename in the next steps)git branch git_mv_20110708_1500_DO_NOT_USE
("fake" branch with timestamp reminding that we only did this as a workaround)/bin/rm -Rf <new-dir-name>
cp -Rp .../<new-dir-name> .
(copy over the actual folder with the renamed name)git status
(most modified files will now be marked correctly as modified, not "deleted". Files that have been renamed will be marked as deleted andadded, despite having the same content! -- repeated steps 1-7 for those files if rename tracking is needed for them too)git add <untracked files>
git commit -a -m "finally renamed this folder"
git branch FOLDER_RENAMED
:)
git mv <old-dir-name> <new-dir-name>
git status
(验证所有标记为重命名的文件,而不是“已删除”)git commit -a -m "git mv <old-dir-name> <new-dir-name>"
(这是一个“假”提交,为后续步骤中的真正重命名做准备)git branch git_mv_20110708_1500_DO_NOT_USE
(带有时间戳的“假”分支提醒我们这样做只是作为一种解决方法)/bin/rm -Rf <new-dir-name>
cp -Rp .../<new-dir-name> .
(复制具有重命名名称的实际文件夹)git status
(大多数修改过的文件现在将被正确标记为已 修改,而不是“已删除”。已重命名的文件将被标记为已删除和已添加,尽管内容相同!--如果重命名跟踪为,则对这些文件重复步骤 1-7他们也需要)git add <untracked files>
git commit -a -m "finally renamed this folder"
git branch FOLDER_RENAMED
:)
P.S. gitk
loves this, but Emacs
is still confused with the renames. :(
PSgitk
喜欢这个,但Emacs
仍然与重命名混淆。:(
回答by Phil Miller
Just git add
the directory at its new name. Git doesn't explicitly track renames, it just detects them later. git mv
might be marginally more efficient to perform (because it can update the index directly), but the effect is exactly the same.
只是git add
新名称的目录。Git 不会明确跟踪重命名,它只是稍后检测它们。git mv
执行起来效率可能稍高一些(因为它可以直接更新索引),但效果完全一样。
回答by doctorless
You need to use git's mv: http://www.kernel.org/pub/software/scm/git/docs/git-mv.html
你需要使用git的mv:http: //www.kernel.org/pub/software/scm/git/docs/git-mv.html
git mv old_dir new_dir
So you'll need to move the new dir back to the old, and re-move it with mv.
因此,您需要将新目录移回旧目录,然后使用 mv 重新移动它。
EDIT:To answer the responses to my answer:
编辑:要回答我的回答:
I decided to test this out myself. I created two files with distinct text, and used git mv
on one, and mv file file2
, git add file2
, git add -u
on the other. Commit message indicated that both were tracked as renames. Therefore, all my advice does is save a step, as others were saying.
我决定自己测试一下。我创建了两个具有不同文本的文件,并git mv
在一个文件中使用,而mv file file2
, git add file2
, 则git add -u
用于另一个文件。提交消息表明两者都被跟踪为重命名。因此,正如其他人所说,我的所有建议只是节省一步。
回答by VonC
Git 2.18 (Q2 2018) should to detect "that it's the same directory, just a different name", because "git status
" learned to pay attention to UI related diff configuration variables such as diff.renames
.
Git 2.18(2018 年第二季度)应该检测到“它是同一个目录,只是名称不同”,因为“ git status
”学会了关注 UI 相关的 diff 配置变量,例如diff.renames
.
See commit dc6b1d9(04 May 2018) by Eckhard S. Maa? (``).
(Merged by Junio C Hamano -- gitster
--in commit 1e174fd, 23 May 2018)
请参阅Eckhard S. Maa 的commit dc6b1d9(2018 年 5 月 4 日)?(``)。
(由Junio C gitster
Hamano合并-- --在commit 1e174fd,2018 年 5 月 23 日)
wt-status
: use settings fromgit_diff_ui_config
If you do something like:
wt-status
:使用设置git_diff_ui_config
如果您执行以下操作:
- git add .
- git status
- git commit
- git show (or git diff HEAD)
one would expect to have analogous output from
git status
andgit show
(or similar diff-related programs).
This is generally not the case, asgit status
has hard coded values for diff related options.With this commit the hard coded settings are dropped from the status command in favour for values provided by
git_diff_ui_config
.What follows are some remarks on the concrete options which were hard coded in
git status
:`diffopt.detect_rename`
Since the very beginning of git status in a3e870f("Add "commit" helper script", 2005-05-30, Git v0.99),
git status
always used rename detection, whereas with commands like show and log one had to activate it with a command line option.
After 5404c11("diff: activatediff.renames
by default", 2016-02-25, Git v2.9.0) the default behaves the same by coincidence, but changingdiff.renames
to other values can break the consistency betweengit status
and other commands again.
With this commit one control the same default behaviour withdiff.renames
.`diffopt.rename_limit`
Similarly one has the option diff.renamelimit to adjust this limit for all commands but git status. With this commit git status will also honor those.
人们期望从
git status
和git show
(或类似的与差异相关的程序)有类似的输出。
通常情况并非如此,git status
差异相关选项的硬编码值也是如此。通过此提交,硬编码设置将从 status 命令中删除,以支持
git_diff_ui_config
.以下是对硬编码的具体选项的一些评论
git status
:`diffopt.detect_rename`
自从a3e870f 中的 git status ("Add "commit" helper script", 2005-05-30, Git v0.99) 一开始就
git status
一直使用重命名检测,而像 show 和 log 这样的命令必须用命令行选项。
在5404c11("diff: activatediff.renames
by default", 2016-02-25, Git v2.9.0) 之后,巧合的是默认行为相同,但更改diff.renames
为其他值会git status
再次破坏与其他命令之间的一致性 。
通过此提交,可以使用diff.renames
.`diffopt.rename_limit`
同样,有一个选项 diff.renamelimit 来调整除 git status 之外的所有命令的此限制。有了这个提交 git status 也将尊重那些。
And the same Git 2.18 offer status.renames
, which could be useful for those who want to do so without disabling the default rename detection done by the
"git diff
" command.
和相同的 Git 2.18 提供status.renames
,这对于那些想要在不禁用“ git diff
”命令完成的默认重命名检测的情况下这样做的人可能很有用。
See commit e8b2dc2(11 May 2018) by Ben Peart (benpeart
).
(Merged by Junio C Hamano -- gitster
--in commit 5da4847, 30 May 2018)
请参阅Ben Peart ( )提交的 e8b2dc2(2018 年 5 月 11 日)。(由Junio C Hamano合并-- --在提交 5da4847 中,2018 年 5 月 30 日)benpeart
gitster
add status config and command line options for rename detection
After performing a merge that has conflicts
git status
will, by default, attempt to detect renames which causes many objects to be examined.
In a virtualized repo, those objects do not exist locally so the rename logic triggers them to be fetched from the server. This results in the status call taking hours to complete on very large repos vs seconds with this patch.Add a new config
status.renames
setting to enable turning off rename detection during status and commit.
This setting will default to the value of diff.renames.Add a new config
status.renamelimit
setting to to enable bounding the time spent finding out inexact renames during status and commit.
This setting will default to the value ofdiff.renamelimit
.Add
--no-renames
command line option to status that enables overriding the config setting from the command line.
Add--find-renames[=<n>]
command line option to status that enables detecting renames and optionally setting the similarity index.
添加状态配置和命令行选项以进行重命名检测
git status
默认情况下,执行有冲突的合并后,将尝试检测导致检查许多对象的重命名。
在虚拟化存储库中,这些对象在本地不存在,因此重命名逻辑会触发它们从服务器获取。这导致状态调用需要数小时才能在非常大的 repos 上完成,而不是使用此补丁进行数秒。添加新的配置
status.renames
设置以启用在状态和提交期间关闭重命名检测。
此设置将默认为 diff.renames 的值。添加一个新的配置
status.renamelimit
设置以启用在状态和提交期间找出不准确重命名所花费的时间。
此设置将默认为 的值diff.renamelimit
。将
--no-renames
命令行选项添加到状态,以便从命令行覆盖配置设置。
将--find-renames[=<n>]
命令行选项添加到状态,以启用检测重命名并可选择设置相似性索引。
回答by Philip Oakley
The problem is a User interface / User experience problem, rather than a 'real' problem for git. I've asked the same question how-to-work-with-subdirectory-renames-in-gitand an underlying question how-does-git-record-or-more-likely-represent-file-paths-and-names-for-its-blob
问题是用户界面/用户体验问题,而不是 git 的“真正”问题。我问了同样的问题how-to-work-with-subdirectory-renames-in-git和一个基本问题how-does-git-record-or-more-likely-represent-file-paths-and-names-为它的斑点
In fact Git doesn't actually care. All the messages you (we) get are about what 'diff' thinks might have happened. With other options the messages will be different but the repository won't be any different (it's the same snapshot!).
事实上,Git 实际上并不关心。您(我们)收到的所有消息都是关于“差异”认为可能发生的事情。使用其他选项,消息会有所不同,但存储库不会有任何不同(它是相同的快照!)。
One option style is the subtree
option for diff (though it is for a different purpose), as is --patience
.
一种选项样式是subtree
diff的选项(尽管它用于不同的目的),就像--patience
.
There is a need for a better UI/UX option that would more easily detect pathchanges (based on the trees rather than the blobs). Part of the problem is the subtle mistakein Linus's argument. He is right that the Git repo should notstore the rename (pathchange) explicitly, rather we need an option to allow it's proper discovery.
需要一个更好的 UI/UX 选项来更容易地检测路径变化(基于树而不是 blob)。部分问题在于Linus 论证中的微妙错误。他是对的,Git存储库不应该显式存储重命名(路径更改),而是我们需要一个选项来允许它正确发现。