从包含代字号的Git历史记录中删除文件名

时间:2017-05-25 02:10:34

标签: git rebase git-rewrite-history

我在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尝试了这个。完全相同的事情发生了。

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。不要讨厌玩家,讨厌游戏。