我在Windows上使用Git版本2.12.2.windows.2。
我有一个最初从Subversion转换的Git历史记录。我最近意识到存储库中有一个文件foo.txt~1~
。 (这一定是来自过去的编辑。)我意识到这一点,因为每次我克隆存储库时,Git会立即告诉我foo.txt
已被修改。显然,foo.txt~1~
文件的某些内容使Git认为foo.txt
已被修改。
所以我想通过删除foo.txt~1~
并使用日志消息“删除备份文本文件”进行提交来解决问题。我们称之为提交01234
然后提交了一些提交,我决定完全删除文本文件,所以我做了:
git filter-branch --tree-filter "rm -f foo.txt~1~" --prune-empty HEAD
所以现在我认为我有foo.txt~1~
的历史。奇怪的是,01234的差异表示我删除了foo.txt
的所有行并添加了foo.txt
的所有行。
在任何情况下,我都希望从历史记录中删除提交01234,因为没有提及无意义提交说我删除了不再存在的备份文本文件,所以我做了git rebase -i 01234~
并选择drop
来摆脱提交。
不幸的是,Git突然停下来说道:
Cannot rebase: You have unstaged changes.
Git表明foo.txt
已被修改;它表明该文件的所有行都已删除并替换为......使用相同的行。
Git说我可以使用git checkout -- foo.txt
来放弃我的更改,但在执行此操作后,git status
仍会显示foo.txt
已被修改。
Git还说我可以使用git add foo.txt
更新将要提交的内容。所以我使用git add foo.txt
添加文件。它告诉我,我已经上演了变化。所以我使用git commit -m "Added non-modified text file."
来提交“更改”。然后我又做了git rebase --continue
。
成功了 - 但是当然现在我在历史记录中有一个“添加了未修改的文本文件”提交。所以我再次尝试git rebase -i 01234~
,然后再提交drop
......整个周期再次启动:
Cannot rebase: You have unstaged changes.
有时候我想摆脱Git。
我该如何解决这个问题?
P.S。在我尝试使用foo.txt~1~
从历史记录中删除git filter-branch
之前,我有原始存储库的单个副本,如果这有帮助的话。但是在添加单个提交删除foo.txt~1~
(提交01234)之前,我没有存储库的副本,并且该提交不是最后一次提交。
P.P.S。我认为这可能与Windows和文件名中的~
有关,所以我在Linux上使用Git 2.12.2尝试了这个。完全相同的事情发生了。
答案 0 :(得分:1)
事实证明,这与文件名中的波浪号~
字符无关;这样的文件(foo.txt~1~
)出现在" sidecar" Git认为被修改的文件(foo.txt
)仅仅是巧合。
问题确实归结为行结尾。我早已用.gitattributes
文件解决了行结束问题,但是当我从Subversion转换此存储库时,我有一个脚本将文件从CRLF转换为LF。此脚本附带了一长串文件,其中包含要转换的结尾。我没有包含这个特定的文件扩展名(它实际上是jsp
而不是txt
,但是我会使用txt
来保持一致性,这显然意味着我所有的{ {1}}文件卡在Git存储库中的CRLF结尾。
我想因为我的时髦新.txt
文件(实际上确实包含.gitattributes
),在做rebase时Git使用CRLF结尾检出.txt
文件但是在索引中它使用了LF,它与存储库本身的CRLF不同。 (或者那种效果; Git很复杂。)
所以我的目标是首先规范新行,然后处理foo.txt
文件。这是我最终如何去做的。我切换到一台Linux机器(只是因为它有foo.txt~1~
方便)并在我更改任何内容之前启动了存储库(它仍然在我擦除的中间提交dos2unix
,认为这是问题):
foo.txt~1~
#normalize EOLs on `*.txt` and `*.txt~1~`
git filter-branch --tree-filter '/path/to/normalize-eol.sh' -- --all
#drop the commit which deleted the `.txt~1~` file
git rebase -i 01234~ #and specify "drop"
#then do the magic from https://stackoverflow.com/a/43961960/421049
# to rejoin some tail branches
#now delete the `*.txt~1~` files throughout history
git filter-branch --index-filter 'git rm --cached --ignore-unmatch -r *.*~*' HEAD
脚本看起来像这样:
normalize-eol.sh
(这段代码是在几年前第一次进行转换时从Stack Overflow搜索中收集的。)
这可能是我最糟糕的Git噩梦,而且(又一次)来自线路结尾这样一个愚蠢的小事。
答案 1 :(得分:-1)
这意味着您的提交实际上已经发生了变化。它可能类似于你看不到的行尾。
不要摆脱git。不要讨厌玩家,讨厌游戏。