我试图运行'git rm -rf --cached'。以及'git add'。删除现在列在.gitignore中的缓存文件。我在Windows计算机上使用Visual Studio,并且更喜欢在这种特定情况下保留行结尾。
我尝试使用git config命令将core.autocrlf设置为false。我尝试使用'* -text'行创建一个.gitattributes,运行.git / index,然后运行git reset。到目前为止,每次我添加文件时,我都会得到一个庞大的修改文件列表。
编辑:文件中的更改实际上不是行结尾,它是文件权限的更改,我没有请求。
编辑:剩下的问题是文件模式显然没有在Windows系统中正确存储(另请参阅What is git's "filemode"?)。要保存和恢复它们,需要一个脚本和原始数据:
git ls-files --stage > /tmp/original
要恢复模式,这个相当粗糙的管道应该工作:
< /tmp/original \
awk -F$'\t' '/^100755 / { print "git update-index --chmod=+x \"" $2 "\"" }' |
sh
这将尝试通过以下序列删除的chmod +x
文件,因此如果有任何此类文件,您可能会遇到一些错误消息。 (它还假设没有文件名称中有双引号。)
假设您还没有.gitattributes
文件,这是一个应该工作的六步过程:
.gitattributes
文件rm .git/index
git checkout HEAD -- .
git rm -r --cached .
git add .
git rm .gitattributes
(你可以保留这个,直到验证它一切正常)。之后运行git commit
。我没有(也没有使用)Windows因此无法测试这一点,但这里有理由为什么它应该工作,因此为什么有这些步骤。
Git的实际数据存储格式是一种特殊的,仅限Git,压缩(有时是高度压缩)的格式。以这种格式存储的文件主要仅对Git本身有用。这种格式存储原始的,未解释的字节流:文件不必分成“文本”和“数据”等等,它们只是原始字节流(因此被视为“数据”/“非文本”)。数据一旦存储,就是只读的,并被分配一个哈希ID(当前是SHA-1,虽然未来的Git可能使用SHA-256)。 Git调用以这种方式存储的文件blob,即a term stolen from the database world。
您的计算机的有用文件存储格式当然是不同的,并且可能(并且在Windows上)区分“文本”和“数据”。文本可能有编码(例如ISO-8859-1,UTF-8,UTF-16等)。这些文件通常都是可读写的,计算机上的任何文件都可以处理它们(在某种程度上,取决于编码)。
Git必须从提交中提取文件,将它们从blob转换为可以使用的文件。这些文件存在于您的工作树中。你和他们一起工作,然后git add
他们让Git有机会重新给他们带来斑点。
在这些特殊的Git-blob和工作树之间,Git需要一个存储blobbed数据的地方,这与commit-write不同,但是就像提交一样,文件采用特殊的Git格式。这个“介于两者之间”的地方是Git的索引。各种Git文档有时将其称为暂存区域或缓存。
Git使用每个文件的索引副本(或blob,真的)来进行新的提交。运行git add
时,Git会读取工作树文件,将其编码为blob格式,然后将其井号ID保存在索引中。运行git commit
时,Git只是将索引副本冻结为已提交的副本。
当您运行git checkout
以切换到某个提交时,Git会将提交提取到索引中(填充所有blob哈希ID),并将blob提取到工作树中,以便它们处于有用的格式并且您可以处理它们。当您运行git add
时,Git会将工作树文件压缩为其blob格式并替换该文件的索引条目。
将blob转换为工作树文件(反之亦然)是Git进行所需转换的理想场所,例如将换行符转换为CRLF行结尾。这就是Git所做的事情:git checkout
填充索引并扩展并转换为工作树,git add
压缩 - 取消 - 从工作树转换为索引,为下一个git commit
做好准备。 (任何你不接触的文件,保持压缩状态并准备就绪,安全地隐藏在索引中。)
您已经知道跟踪文件是索引中的文件,而未跟踪文件是工作树中但不在索引中的文件。你的目标是使用现有的.gitignore
来使当前在索引中的文件远离索引,如果它们是.gitignore
-ed。您正在使用的过程是:
git rm -r --cached .
:从索引中删除所有内容,以便整个工作树不被跟踪git add .
:从工作树中的任何内容生成索引中的所有新blob,同时忽略.gitignore
中列出的任何文件。这里的问题是工作树中的内容已经被“blob转换为工作树”转换,并且将被“工作树转换为blob”转换为“未转换”。用.gitattributes
创建一个* -text
文件告诉Git:要做的转换根本就没有转换。“
不幸的是,现在为时已晚:你先前运行的git checkout
,将这个提交到工作树中,已经进行了一些转换。
所以在这里,我们使用第1步创建一个.gitattributes
文件,表示不进行转换。第2步,rm .git/index
,完全删除索引。 Git现在不知道工作树中究竟是什么。这个步骤可能是不必要的,但我用它来强制Git在第3步中执行,它告诉Git:将HEAD
提交中的每个文件提取到索引和工作树中。这会重新创建索引,并重新填充工作树,这次不进行转换。
步骤4和5与以前一样,但这次,工作树文件都与HEAD
提交中的blob匹配,因为步骤3使用.gitattributes
指令进行操作。第6步是确保您不提交“do no conversions”指令。