Git在拉取时无法删除文件 - 我该如何解决代码库不一致的状态?

7
在执行“git pull”时,因为我忘记关闭锁定这些文件的应用程序,导致git无法解除链接它想要覆盖的文件而中止了操作。
当我关闭应用程序并尝试重新执行“git pull”时,会收到以下错误消息:
"Error: Your local changes to the following files would be overwritten by merge: ..."

and

"Error: The following untracked working tree files would be overwritten by merge: ..."

显然,git在没有做回滚的情况下中止了拉取操作,现在它认为刚刚拉取的更改是我本地的更改。

我该如何摆脱这种状态?我们谈论的是很多文件,在执行“git revert”之前,我必须手动检查每个文件,以确定是否存在来自我的本地更改。

注意:我们在一个客户端-服务器式的设置中使用git,分布式开发人员经常向中央bitbucket仓库“拉取”和“推送&提交”。


嗯,有人回答了这个问题(1月25日),现在答案呢?建议使用stash -> pull的解决方案不可行吗? - Stiefel
1
git merge --abort 怎么样? - Vorac
我找到了一个可接受的解决方案(请参见下面的答案),但是我也愿意接受更好的解决方案。另外:您认为这是 Git 的一个 bug 吗? - Stiefel
你在评论和回答中提到的“服务器”,是直接从你在这里拉取的检出工作树中运行吗?阅读你在评论和回答中所说的内容,与阅读你的问题所得到的情况并不相同,你能否请澄清一下这个服务器在这里的角色是什么? - jthill
@jthill:这是一个类似于客户端-服务器设置的GIT,其中bitbucket.org扮演服务器的角色。开发人员是客户端,定期进行“pull”和“commit&push”。 - Stiefel
3个回答

4

由于以上方法都对我无效,因此我使用了一种不完全自动化但可以将工作量减少到手动选择几个文件的过程(在我的情况下只需要2个文件而不是50个)。

首先,使用以下命令将所有文件(包括未跟踪和忽略的文件)进行存储:

git stash save --all             

然后重新执行之前失败的拉取操作,使用

git pull                         

现在从存储中取出以覆盖所有在第一次拉取时更改的文件(无需尝试合并):
git checkout stash -- .         

现在还有一个问题:在失败的拉取和第二次拉取之间在服务器上所做的更改现在被覆盖了。但是这些应该只是一些文件(如果两次“拉取”之间的时间很短),而且在您自己进行的工作更改列表中更容易识别。在最终提交之前,只需“还原”它们即可(我使用了Tortoise GIT提交对话框)。
git commit
git stash drop

2
git reset --hard

这将会重置所有被跟踪的文件为它们所提交的状态。

git clean -df

这将清除所有剩余的未跟踪、未忽略的文件。

然后您可以重新进行pull操作。普通合并就可以了,因为您已经执行了fetch操作。


我相当确定这种行为是由于Windows希望文件工作方式的差异所致。在Unix领域,一旦您打开了一个文件,目录条目就会被释放。您看到的错误在Unix系统上根本不会发生;打开的文件将成为临时文件,只要它仍然对某个进程保持打开状态,它就会存在。Unix的方式也有缺点,您正在看到Windows方式的缺点。解决方法很容易,重置和清理几乎是您的工地清理工。这是一项光荣的工作,请认识他们,他们知道自己在做什么。


但是使用“git reset --hard”命令,我会失去所有本地未提交的更改,对吗? - Stiefel
而 git clean 将删除所有未跟踪的文件。如果我理解正确,这个答案与我试图实现的相反。 - Stiefel
澄清一下:在对所有文件进行提交之前执行“git pull”可能是我们的错误和不良习惯。 - Stiefel
1
就是这样的大小。Git是为在存储库中进行开发工作而设置的,您关心的更改正在被跟踪,其他一切都是垃圾或缓存。我仍然觉得我漏掉了什么,但对我来说,似乎在这里使用一个单独的分支可能是正确的选择,而不是每次都使用stash。此外,请查看add、reset和checkout命令的“--patch”选项。 - jthill

0

尝试

git reset --merge
git fetch --all
git reset --hard origin/master

或者,如果你在其他分支上

git reset --hard origin/your_branch

说明:

git fetch 从远程下载最新版本,而不尝试合并或变基任何内容。

然后,git reset 将主分支重置为你刚刚获取的内容。--hard 选项会将工作树中的所有文件更改为匹配 origin/master 中的文件。

需要注意的是,在重置之前可以通过从 master 创建分支来保留当前的本地提交记录:

git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/master

我尝试了前三个命令 - 我本地的(未提交的)更改消失了。 - Stiefel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接