奇'混帐mv`行为(Odd `git mv` behaviour)

2019-09-29 23:09发布

上个月我开始通过派生相应的回购协议,创建一个特性分支,然后提交pull请求贡献一份GitHub的仓库。 虽然重复这个过程了几天,我重命名与预装Linux命令文件时遇到了一个奇怪的问题mv ,并与Git的命令git mv

实际的问题是,这取决于当你移动/重命名上一个文件git mv ,当你git add它在什么时候你编辑重命名的文件,你要么得到:

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        renamed:    somethingelse -> something

或这个:

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   something
        deleted:    somethingelse

为了证明这一点,我已经写了测试 :

#!/bin/bash

# To my knowledge, this “problem” only occurs with new files in a Git repo
printf "COMMAND: mkdir -v gitrepo\n\n"
mkdir -v gitrepo

printf "\nCOMMAND: cd gitrepo\n\n"
cd gitrepo

printf "\nCOMMAND: git init\n\n"
git init

printf "\nCOMMAND: git status\n\n"
git status

printf "\nCOMMAND: touch something\n\n"
touch something

printf "\nCOMMAND: git status\n\n"
git status

printf "\nCOMMAND: git add something\n\n"
git add something

printf "\nCOMMAND: git status\n\n"
git status

printf '\nCOMMAND: git commit -m "Added something"\n\n'
git commit -m "Added something"

printf "\nCOMMAND: git status\n\n"
git status

printf "\nCOMMAND: git mv something somethingelse\n\n"
git mv something somethingelse

printf "\nCOMMAND: git status\n\n"
git status

# Type in the following on line 1: First line of code
printf "\nCOMMAND: vim somethingelse\n\n"
vim somethingelse

printf "\nCOMMAND: git status\n\n"
git status

printf "\nCOMMAND: git add somethingelse\n\n"
git add somethingelse

printf "\nCOMMAND: git status\n\n"
git status

printf '\nCOMMAND: git commit -m "Renamed something to somethingelse and edited somethingelse"\n\n'
git commit -m "Renamed something to somethingelse and edited somethingelse"

printf "\nCOMMAND: git status\n\n"
git status

printf "\nCOMMAND: git mv somethingelse something\n\n"
git mv somethingelse something

printf "\nCOMMAND: git status\n\n"
git status

# If you add something to the first line, the rename will not be detected by Git
# However, if you instead create 2 newlines and fill line 3 with new code,
# the rename gets detected for whatever reason
printf "\nCOMMAND: vim something\n\n"
vim something

printf "\nCOMMAND: git status\n\n"
git status

printf "\nCOMMAND: git add something\n\n"
git add something

printf "\nCOMMAND: git status\n\n"
git status

printf '\nCOMMAND: git commit -m "Renamed somethingelse to something and edited something"\n\n'
git commit -m "Renamed somethingelse to something and edited something"

printf "\nCOMMAND: git status\n\n"
git status

cd .. && rm -fr gitrepo && printf "\nREMOVED gitrepo folder\n"
printf "\nDONE.\n"

出于某种原因,这主要影响“新文件”,而不是它已经在的存储库中存在的人。 如果克隆的我的叉勺,刀库与git clone https://github.com/christianheinrichs/Spoon-Knife.git例如,然后应用链接的测试脚本的工作流程,你会看到,在大多数情况下,你将可以重命名文件README.md自述例如,编辑它,它仍然将计为重命名,而不是一个新的文件/删除拆分。

虽然我可能重现上克隆勺刀叉回购新的文件/删除的行为,我并不很清楚我是怎么做的,相信我,当我说我想弄明白。

那么究竟是怎么回事在这里,我不明白?

请参阅: https://gist.github.com/christianheinrichs/e50bfdd5eec70a606fa6ce4a88c5951b#file-git_mv-test-sh-L65

Answer 1:

git不保留一个标志说:“这newname文件最初被称为oldname文件”:

git mv oldname newname

# is exactly equivalent to :  

mv oldname newname
git rm oldname
git add newname

当显示文件的状态, git试图猜测,如果它是一个renamedelete + add通过比较文件的内容,并看到他们是多么相似。

所以:如果通过启动git mv文件,然后编辑该文件,根据文件多少修改,混帐可能会或可能无法看到它一切都始于一个mv

又见这个问题的答案: 混帐如何知道文件改名?



文章来源: Odd `git mv` behaviour