' git rm'出乎意料的行为

时间:2017-08-10 11:22:21

标签: git

给定Git存储库和提交文件System.IO.FilesystemWatcher

我使用操作系统命令删除文件:a

致电$ rm a返回:

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: a no changes added to commit (use "git add" and/or "git commit -a") ,然后调用git rm,产生:

git status

Git的手册页描述命令On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: a

  

从索引中删除文件,或从工作树和索引中删除文件。

根据我的理解,上述命令序列中发生的事情是git rm 删除文件的更改删除到暂存区域(我{&#> 39; m与 index 同义使用,而不是从中删除

我在这里有什么误解?

3 个答案:

答案 0 :(得分:3)

git rm做什么添加对索引的更改从工作目录中删除文件。所以你正在暂停删除文件。这可能听起来有点奇怪,但这是你能想到的最清晰的方式。

提交包含您之前暂停的更改和更改。通常的更改包括新文件和文件更改,还包括文件删除。因此,删除文件被视为更改,通过调用git rm,您更改为索引。

这是顺便说一句。您可以使用git add -u之类的内容来添加所有挂起的更改以及还包含文件删除的原因:文件删除是挂起的更改,因此当您添加它,您要将更改添加到删除文件。

此外,git rm还从工作目录中物理删除文件。因此,如果您没有先使用rm删除文件,Git也会将其从工作目录中删除。如果文件已被删除,那么Git将仅进行删除更改。与此相关的是git rm --cached,它也将暂存文件的删除,但从物理目录中物理删除文件。因此,这将暂存更改以删除文件(尽管该更改尚未实际执行)。

答案 1 :(得分:1)

为了理解git rm的手册页,您需要了解临时区域(即索引)和git status的工作原理。

您可以将工作树,暂存区域和头部引用的提交视为在干净情况下具有相同内容的三个文件夹(即git status显示没有差异):

 Working   Staging   HEAD  
--------- --------- ------ 
 a         a         a     

问题git status检测更改的方式?

  • 非暂停更改:工作和暂存之间的差异
  • 暂存更改:Staging和HEAD之间的差异

当您执行rm a时,您只从工作副本中删除了一个,获取此内容:

 Working   Staging   HEAD  
--------- --------- ------ 
 -         a         a   

git status检测到一个未分级的更改,因为工作和暂存之间存在差异,并且没有分阶段更改,因为暂存和HEAD之间没有区别

当您执行git rm a时,正如文档所述,a也会从暂存区域中删除,从而导致:

 Working   Staging   HEAD  
--------- --------- ------ 
 -         -         a   

允许git status检测一个分阶段的更改,而不允许任何未分阶段的更改。

按照这种思维方式,你可以理解git status本身建议的其他一些命令:

  • git add <file>... - 更新将要提交的内容,即将文件从工作复制到暂存
  • git-commit - 记录对存储库的更改,即将每个文件从登台复制到HEAD(也创建新的提交并移动HEAD)
  • git checkout -- <file>...放弃工作目录中的更改,即从登台复制到工作副本
  • git reset HEAD <file>取消暂停,即从HEAD复制到暂存

作为旁注,git rm --cached a将导致此结果:

 Working   Staging   HEAD  
--------- --------- ------ 
 a         -         a   

Git状态将显示删除a作为提交阶段,因为暂存和头部之间存在差异,但a未跟踪:工作和暂存之间存在差异,但是由于暂存区域中缺少该文件,因此git status将其检测为未跟踪文件而不是未分级更改

答案 2 :(得分:0)

实际上git rm会从本地目录中删除文件,更改将在下次提交时推送到您的存储库。因此,已删除的文件不再在您的存储库中显示。使用rm时,只会从本地存储库中删除该文件,并且不会将更改写入您的原始存储库。因此,您不必在rm之前使用git rm