当我按照这些步骤进行操作时,将删除工作树中的文件,而这应该不会发生:
来自新的本地仓库
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是否被删除?
答案 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