我手动移动了一个文件,然后我修改了它.根据Git,它是一个新文件和一个删除文件.有没有办法强迫Git将其视为文件移动?
Bom*_*mbe 395
如果您的修改不是太严重,Git会自动检测移动/重命名.只是git add新文件和git rm旧文件.git status然后会显示它是否检测到重命名.
另外,对于目录周围的移动,您可能需要:
git add -A .git status以验证"新文件"现在是"重命名"文件如果git status仍然显示"新文件"而不是"重命名",则需要遵循Hank Gay的建议并执行移动并在两个单独的提交中进行修改.
Han*_*Gay 96
在单独的提交中执行移动和修改.
Ken*_*ric 44
这都是一种感性的东西.Git通常擅长识别移动,因为GIT是一个内容跟踪器
所有这一切真正取决于你的"统计"如何显示它.这里唯一的区别是-M标志.
git log --stat -M
commit 9c034a76d394352134ee2f4ede8a209ebec96288
Author: Kent Fredric
Date: Fri Jan 9 22:13:51 2009 +1300
Category Restructure
lib/Gentoo/Repository.pm | 10 +++++-----
lib/Gentoo/{ => Repository}/Base.pm | 2 +-
lib/Gentoo/{ => Repository}/Category.pm | 12 ++++++------
lib/Gentoo/{ => Repository}/Package.pm | 10 +++++-----
lib/Gentoo/{ => Repository}/Types.pm | 10 +++++-----
5 files changed, 22 insertions(+), 22 deletions(-)
Run Code Online (Sandbox Code Playgroud)
git log --stat
commit 9c034a76d394352134ee2f4ede8a209ebec96288
Author: Kent Fredric
Date: Fri Jan 9 22:13:51 2009 +1300
Category Restructure
lib/Gentoo/Base.pm | 36 ------------------------
lib/Gentoo/Category.pm | 51 ----------------------------------
lib/Gentoo/Package.pm | 41 ---------------------------
lib/Gentoo/Repository.pm | 10 +++---
lib/Gentoo/Repository/Base.pm | 36 ++++++++++++++++++++++++
lib/Gentoo/Repository/Category.pm | 51 ++++++++++++++++++++++++++++++++++
lib/Gentoo/Repository/Package.pm | 41 +++++++++++++++++++++++++++
lib/Gentoo/Repository/Types.pm | 55 +++++++++++++++++++++++++++++++++++++
lib/Gentoo/Types.pm | 55 -------------------------------------
9 files changed, 188 insertions(+), 188 deletions(-)
Run Code Online (Sandbox Code Playgroud)
git帮助日志
-M
Detect renames.
-C
Detect copies as well as renames. See also --find-copies-harder.
Run Code Online (Sandbox Code Playgroud)
小智 33
git diff -M或者git log -M应该自动检测这些更改为重命名,只要它们确实存在微小变化.如果您的微小变化不小,您可以减少相似性,例如
$ git log -M20 -p --stat
Run Code Online (Sandbox Code Playgroud)
将其从默认的50%降低到20%.
小智 31
这是一个快速而又脏的解决方案,用于一个或几个未重命名的已重命名和修改的文件.
假设文件已命名foo,现在命名为bar:
重命名bar为临时名称:
mv bar side
Run Code Online (Sandbox Code Playgroud)结帐foo:
git checkout HEAD foo
Run Code Online (Sandbox Code Playgroud)重命名foo,以bar使用Git:
git mv foo bar
Run Code Online (Sandbox Code Playgroud)现在将您的临时文件重命名为bar.
mv side bar
Run Code Online (Sandbox Code Playgroud)最后一步是将更改的内容恢复到文件中.
虽然这可以工作,但如果移动的文件与原始git的内容太不相同,则会认为确定这是一个新对象更有效.让我来证明:
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
renamed: README -> README.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
modified: work.js
$ git add README.md work.js # why are the changes unstaged, let's add them.
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
deleted: README
new file: README.md
modified: work.js
$ git stash # what? let's go back a bit
Saved working directory and index state WIP on dir: f7a8685 update
HEAD is now at f7a8685 update
$ git status
On branch workit
Untracked files:
(use "git add <file>..." to include in what will be committed)
.idea/
nothing added to commit but untracked files present (use "git add" to track)
$ git stash pop
Removing README
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
new file: README.md
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: README
modified: work.js
Dropped refs/stash@{0} (1ebca3b02e454a400b9fb834ed473c912a00cd2f)
$ git add work.js
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
new file: README.md
modified: work.js
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: README
$ git add README # hang on, I want it removed
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
deleted: README
new file: README.md
modified: work.js
$ mv README.md Rmd # Still? Try the answer I found.
$ git checkout README
error: pathspec 'README' did not match any file(s) known to git.
$ git checkout HEAD README # Ok the answer needed fixing.
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
new file: README.md
modified: work.js
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: README.md
modified: work.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
Rmd
$ git mv README README.md
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
renamed: README -> README.md
modified: work.js
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: work.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
Rmd
$ mv Rmd README.md
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
renamed: README -> README.md
modified: work.js
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
modified: work.js
$ # actually that's half of what I wanted; \
# and the js being modified twice? Git prefers it in this case.
Run Code Online (Sandbox Code Playgroud)
BoD*_*BoD 17
如果您正在谈论git status不显示重命名,请尝试git commit --dry-run -a改为
col*_*fix 11
其他答案已经涵盖了您可以简单地git add NEW && git rm OLD让 git 识别这一举动。
但是,如果您已经修改了工作目录中的文件,add+rm方法会将修改添加到索引中,这在某些情况下可能是不需要的(例如,在进行大量修改的情况下,Git 可能不再识别它是一个文件)改名)。
假设您要将重命名添加到索引,但不进行任何修改。实现此目的的明显方法是来回重命名mv NEW OLD && git mv OLD NEW。
但还有一种(稍微复杂的)方法可以直接在索引中执行此操作,而无需重命名工作树中的文件:
# Step 1.
info=$(git ls-files -s -- "OLD" | cut -d' ' -f-2 | tr ' ' ,)
# Step 2.
git update-index --add --cacheinfo "$info,NEW"
# Step 3.
git rm --cached "$old"
Run Code Online (Sandbox Code Playgroud)
这也可以作为别名放入您的~/.gitconfig:
[alias]
mv-index = "!f() { \
old=\"$1\"; \
new=\"$2\"; \
info=$(git ls-files -s -- \"$old\" | cut -d' ' -f-2 | tr ' ' ,); \
git update-index --add --cacheinfo \"$info,$new\" && \
git rm --cached \"$old\"; \
}; f"
Run Code Online (Sandbox Code Playgroud)
步骤 1:存储 OLD 文件模式和 OLD 文件 sha1 信息,以逗号分隔,以供以后使用(例如info=100644,aa27a98714247db199d86d44d523dddf084a6051)。
为此,
HEAD必须在 OLD 文件存在的提交上进行,并且 OLD 文件的删除甚至不应该暂存(但从文件系统中删除的文件并不重要)。
步骤2:使用所述信息模拟OLD在给定路径添加文件NEW。
警告:此阶段将撤消任何已阶段化的新路径更改。
最后,分阶段删除OLD文件。
全做完了!
Gil*_*rts 10
如果你正在使用TortoiseGit,重要的是要注意Git的自动重命名检测在提交期间发生,但事实上这种情况并不总是由软件预先显示.我已将两个文件移动到另一个目录并执行了一些轻微的编辑.我使用TortoiseGit作为我的提交工具,更改制作列表显示文件被删除和添加,而不是移动.从命令行运行git status显示了类似的情况.但是在提交文件后,它们显示为在日志中重命名.所以你的问题的答案是,只要你没有做过任何太激烈的事情,Git就应该自动获取重命名.
编辑:显然,如果您添加新文件然后从命令行执行git状态,则重命名应在提交之前显示.
编辑2:此外,在TortoiseGit中,在提交对话框中添加新文件但不提交它们.然后,如果您进入Show Log命令并查看工作目录,您将看到Git在提交之前是否检测到重命名.
这里提出了同样的问题:https://tortoisegit.org/issue/1389并且已被记录为修复此处的错误:https://tortoisegit.org/issue/1440 事实证明这是TortoiseGit提交的显示问题如果您尚未添加新文件,则对话框以及存在于git状态的类型.
或者您可以在这里尝试Amber回答这个问题的方法!再次引用:
首先,为手动移动的文件取消分阶段添加:
$ git reset path/to/newfile
$ mv path/to/newfile path/to/oldfile
Run Code Online (Sandbox Code Playgroud)
然后,使用Git移动文件:
$ git mv path/to/oldfile path/to/newfile
Run Code Online (Sandbox Code Playgroud)
当然,如果您已经进行了手动移动,则可能需要在移动之前重置为修订版,然后从那里简单地git mv即可。
使用git mv命令移动文件,而不是操作系统移动命令:https :
//git-scm.com/docs/git-mv
请注意,该git mv命令仅存在于Git 1.8.5及更高版本中。因此,您可能必须更新Git才能使用此命令。