git-缓存并在分支之间移动后,Git删除工作树中的一些文件

时间:2018-12-21 03:50:03

标签: git commit gitignore checkout rm

当我按照这些步骤进行操作时,将删除工作树中的文件,而这应该不会发生:

来自新的本地仓库

git init

我创建了一些文件

touch file1.txt | touch file2.txt

我想忽略file1

echo file1.txt > .gitignore

我上演并提交

git add .
git commit -m "Initial commit"

我创建了一个新分支(退出结帐)

git branch dev

我错了,我也想忽略file2!所以我取消暂存file2

git rm --cached file2.txt

我将file2放入gitignore

echo file2.txt >> .gitignore

我上演并提交

git add .
git commit -m "file2 in gitignore"

我转到开发分支(什么都不做)

git checkout dev

我回到大师那里(别无所求)

git checkout master

file2.txt已在我的工作树中删除!

我做错了什么? :(

由于我从.gitignore是不同的分支中检出,因此file2.txt是否被删除?

2 个答案:

答案 0 :(得分:1)

看起来很奇怪吧?

git rm具有两个不同的级别,

rm --cached仅将文件标记为在暂存索引中已删除。它将文件保持在工作目录中。See more here

然后神奇的事情就是命令git checkout

根据官方文档here。 它说

  

更新工作树中的文件以匹配索引中的版本

这意味着它将用working directory的内容更新staging index。由于已使用命令git rm --cached从登台索引中删除了文件,因此工作目录将被替换为staging index命令git checkout master的内容。

答案 1 :(得分:1)

由于您已忽略file2.txt,因此我认为您的预期行为是git在切换分支时不会删除它。

但是在您要离开的分支上,file2.txt不会被忽略;实际上不可能,因为它已被索引。从那里移到master时,更改之一是删除file2.txt

这是一种极端情况,其中“正确”的行为值得商bat。有时,一个人可能期望(或至少想要)一件事,而其他时候一个人可能期望另一件事。

但是您正在观察的是git的记录行为。

请注意,如果您还file2.txt删除dev

git checkout dev
git rm --cached file2.txt
git echo file2.txt >> .gitignore
git add .
git commit 

然后在分支之间进行切换,使file2.txt保持不变。而且,如果首先犯错file2.txt是一个错误,那么从所有分支中删除它至少是有道理的。

该建议的问题在于,取决于每个分支上发生的其他事情,它可能导致合并冲突。解决起来很简单,但是仍然很烦人。由于这个原因(或其他原因),您实际上可能要考虑进行历史记录编辑,尤其是在尚未推送/与其他开发人员共享这些提交的情况下。

注意,如果您执行此操作,则要确保已恢复file2.txt的工作树副本。 (如果您不这样做,以后仍然可以(一段时间)恢复它们,但并非如此简单。)因此,一旦您安全地恢复了这些文件

git filter-branch --index-filter 'git rm --cached --ignore-unmatch :/:file2.txt' -- --all