如何使git标记删除,并将新文件作为文件移动?
我已经手动移动了一个文件,然后修改了它。 根据Git,这是一个新的文件和一个删除的文件。 有没有办法强迫Git把它当作文件移动?
如果您的修改不太严重,Git会自动检测移动/重命名。 只是git add
新文件,并git rm
旧文件。 git status
会显示是否检测到重命名。
此外,为了在目录周围移动,您可能需要:
- cd到该目录结构的顶部。
- 运行
git add -A .
- 运行
git status
来validation“新文件”现在是“重命名”文件
如果git的状态仍然显示“新文件”,而不是“重命名”,你需要按照汉克盖伊的build议,并做两个单独的提交移动和修改。
在单独的提交中进行移动和修改。
这都是一种感性的东西。 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 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(-)
git帮助日志
-M Detect renames. -C Detect copies as well as renames. See also --find-copies-harder.
git diff -M
或者git log -M
应该自动检测这样的变化 ,只要它们确实是小的变化就可以重命名 。 如果你的微小变化不小,你可以减less相似度,例如
$ git log -M20 -p --stat
将其从默认的50%降低到20%。
以下是一个或几个未提交的重命名和修改的文件的快速和肮脏的解决scheme。
假设这个文件被命名为foo
,现在它被命名为bar
:
-
将
bar
重命名为临时名称:mv bar side
-
结帐
foo
:git checkout HEAD foo
-
重命名
foo
与Git:git mv foo bar
-
现在重命名你的临时文件
bar
。mv side bar
最后一步是将更改后的内容重新放入文件中。
虽然这可以工作,但如果移动的文件内容与原始git的内容太不相同,则认为决定这是一个新的对象会更有效率。 让我来certificate一下:
$ 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.
如果你使用的是TortoiseGit,注意到Git的自动重命名检测是在提交过程中发生的,但事实上这种情况并不总是显示在软件上。 我已经将两个文件移动到不同的目录并进行了一些轻微的修改。 我使用TortoiseGit作为我的提交工具,更改列表显示文件被删除和添加,而不是移动。 从命令行运行git status显示了类似的情况。 但是在提交这些文件之后,它们显示为在日志中被重命名。 所以对于你的问题的回答是,只要你没有做太大的动作,Git应该自动select重命名。
编辑:显然,如果您添加新的文件,然后从命令行中执行git状态,重命名应提交之前提交。
编辑2:另外,在TortoiseGit中,在提交对话框中添加新文件,但不要提交它们。 然后,如果进入Show Log命令并查看工作目录,则会看到Git在提交之前是否检测到重命名。
在这里提出了同样的问题: https : //tortoisegit.org/issue/1389 ,并被logging为一个错误在这里修复: https : //tortoisegit.org/issue/1440事实certificate这是TortoiseGit的提交显示问题对话框,如果你还没有添加新的文件,也可以使用git状态。
如果你在谈论没有显示重命名的git status
,请尝试git commit --dry-run -a
当移动(但不修改)某些文件时,我最近遇到了这个问题。
问题是,当我移动文件,Git改变了一些行结束,然后不能够告诉文件是相同的。
使用git mv
解决了这个问题,但是它只能在单个文件/目录下工作,并且在存储库的根目录中有很多文件要做。
解决这个问题的一种方法是使用一些bash /批量魔术。
另一种方法是以下
- 移动文件和
git commit
。 这更新了行尾。 - 将文件移回到原来的位置,现在他们有新的行结束,
git commit --amend
- 再次移动文件,
git commit --amend
。 这次没有改变,所以Git很开心
使用git mv
命令移动文件,而不是操作系统移动命令: https : //git-scm.com/docs/git-mv
请注意, git mv
命令只存在于Git 1.8.5及更高版本中。 所以你可能不得不更新你的Git来使用这个命令。
对我来说,在提交之前保存所有更改并将其重新popup。 这使得git重新分析添加/删除的文件,并正确标记为移动。
有一个更好的“命令行”方式来做到这一点,我知道这是一个黑客,但我从来没有find一个好的解决scheme。
使用TortoiseGIT:如果你有一个GIT提交,其中一些文件移动操作显示为加载/删除而不是重命名的负载,即使这些文件只有很小的变化,那么这样做:
- 检查你在本地完成了什么
- 在第二次提交中检查一个小的单行更改
- 去GITlogin龟git
- select两个提交,单击右键,然后select“合并到一个提交”
新的提交现在将正确显示文件重命名…这将有助于保持适当的文件历史logging。
当我编辑,重命名,并在同一时间移动文件,这些解决scheme都没有工作。 解决的办法是在两个提交(编辑和重命名/移动分开),然后通过git rebase -i
fixup
第二个提交,在一个提交。