我手动移动了一个文件,然后修改了它。根据Git,它是一个新文件和一个已删除的文件。有什么方法可以强制Git将其视为文件移动吗?
当前回答
其他的答案已经涵盖了,你可以简单地git添加新&& git rm OLD,以使git识别移动。
然而,如果你已经在工作目录中修改了文件,add+rm方法将把修改添加到索引中,这在某些情况下可能是不希望的(例如,在大量修改的情况下,Git可能不再识别它是一个文件重命名)。
让我们假设您想要将重命名添加到索引,而不是任何修改。显而易见的方法来实现这一点,是做一个来回重命名mv NEW OLD && git mv OLD NEW。
但是也有一种(稍微复杂一点的)方法可以直接在索引中做这件事,而不需要在工作树中重命名文件:
info=$(git ls-files -s -- "OLD" | cut -d' ' -f-2 | tr ' ' ,)
git update-index --add --cacheinfo "$info,NEW" &&
git rm --cached "$old"
这也可以放在~/.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"
其他回答
如果你说git状态不显示重命名,试试git commit——dry-run -a
这都是感性的事情。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(-)
git撒谎
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(-)
Git帮助日志
-M
Detect renames.
-C
Detect copies as well as renames. See also --find-copies-harder.
使用git mv命令来移动文件,而不是操作系统的移动命令: https://git-scm.com/docs/git-mv
请注意,git mv命令只存在于git 1.8.5及以上版本。因此,您可能必须更新Git才能使用此命令。
我最近在移动(但不是修改)一些文件时遇到了这个问题。
问题是,当我移动文件时,Git更改了一些行结束符,然后无法判断文件是否相同。
使用git mv解决了这个问题,但它只能在单个文件/目录上工作,而且我在存储库的根目录下有很多文件要做。
解决这个问题的一种方法是使用bash /批处理魔法。
另一种方法如下
移动文件,git提交。这将更新行结束符。 将文件移回原来的位置,现在它们有了新的行结束符,git提交—修改 再次移动文件,git提交—修改。这次行结束符没有变化,所以Git很高兴
对于一个或几个未提交的重命名和修改文件,这里有一个快速而简单的解决方案。
假设文件的名字是foo,现在它的名字是bar:
将工具条重命名为临时名称: Mv横边 结帐foo: git结帐头foo 用Git将foo重命名为bar: Git mv foo bar 现在将临时文件重命名为bar。 毫伏侧杆
最后一步是将更改后的内容返回到文件中。
虽然这可以工作,但如果移动的文件与原始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.
推荐文章
- 为什么我需要显式地推一个新分支?
- 如何撤消最后的git添加?
- Rubymine:如何让Git忽略Rubymine创建的.idea文件
- Gitignore二进制文件,没有扩展名
- Git隐藏错误:Git隐藏弹出并最终与合并冲突
- 了解Git和GitHub的基础知识
- 没有。Git目录的Git克隆
- Git与Mercurial仓库的互操作性
- 忽略git中修改(但未提交)的文件?
- “git restore”命令是什么?“git restore”和“git reset”之间有什么区别?
- Git合并与强制覆盖
- Git拉另一个分支
- 在Bash命令提示符上添加git分支
- 如何更改Git日志日期格式
- git pull -rebase和git pull -ff-only之间的区别