如何在git pull时暂时忽略未跟踪的文件?

6

我有一些新文件还没有添加到git中,我还不确定是否要添加,我还在犹豫。但是我想获取服务器上最新的内容。

然而,当我执行git pull时,会出现错误error: Your local changes to 'XXXX' would be overwritten by merge. Aborting.,其中XXXX是我的新文件。

我怎样才能告诉git从服务器下载更改和新文件,并告诉我可能存在的冲突,同时又不会因为我有新文件而中止操作?

我不想将它们添加到.gitignore中,因为我经常遇到这种情况,我不想为琐碎的事情不断地添加和删除文件...特别是因为我不想忘记某个文件,最终决定将其添加到仓库中,所以我希望git status继续告诉我这些文件。有时候我运行git status -uno来忽略新文件,然后有时候我运行git status来查看新文件并决定保留哪些文件和丢弃哪些文件。但我找不到git pull的等效选项。

我的尝试都是搜索那些想要用仓库中的内容覆盖本地更改的人,或其他类似的场景。:( 在阅读文档后,我发现我可以使用git fetch将本地仓库更新到最新状态,这没有出现任何错误,但也没有将更改带到我的工作副本中。我无法找到下一步该怎么做。:-/ 无论如何,一个没有错误的pull是理想的...


提交你的修改,然后拉取(pull),再运行 git reset origin/master 命令来撤销本地的提交(但是会保留工作目录中的文件)。这是一种非常安全和简单的方法。 - Dietrich Epp
这可能会导致合并冲突,并且可能不是OP想要的东西。 - Ru Chern Chong
嗯...建议是暂时提交所有内容以便能够拉取,然后将事情重置为之前的状态?是的,这似乎不是我想要的东西。如果我理解正确,我会失去对代码所做的任何未提交更改。 - msb
这不是重复问题,因为我遇到的核心问题并不是丢失不属于(本地或远程)仓库的文件,而这在其他问题中甚至没有提到。我不知道如何编辑我的帖子以使这更清晰,因为它已经在标题和第一段中了。 - msb
也许有趣:https://dev59.com/TGYr5IYBdhLWcg3wuciw#26549583 - djvg
2个回答

7

在从远程仓库拉取代码之前,你需要将修改内容先进行储藏(stash),或者重置当前分支到最近的提交(commit)。重置分支会导致你失去未提交的修改。

git stash

// after you have pulled from remote
git stash apply 
// OR
git stash pop

关于applypop之间的区别,这里有一个非常好的解释,可以在这里找到。


您还可以选择使用以下命令重置当前分支。

git reset --hard

重置意味着我会失去本地文件和更改,对吗?如果我藏起来,我该如何将藏起来的东西与拉取的东西合并? - msb
4
当我询问时,没有提供链接。 :P - msb
1
让我看看是否理解正确。首先,我会进行存储(stash),这意味着我将我的代码更改和新文件保存在某个临时位置。然后我进行拉取(pull),这样就不会出现任何错误。接下来,我弹出存储(pop the stash),这将把我的代码更改和新文件恢复到我的工作副本中,并覆盖最新拉取的代码。是这样吗? - msb
1
@RémyHosseinkhanBoucher 那是两年前的事了,但如果我没记错的话,它是有效的。如果你不想冒险,可以在执行所有操作之前备份你的更改,尝试后你就会知道结果。;) 自那以后我再也没有需要过它了。哈哈 :/ - msb
为了以后参考,对于新的未跟踪样本,取消暂存工作正常;然而,对于有本地更改的文件,取消暂存过程尝试合并,当出现冲突时会弄乱,保留两个版本,并标记哪个是仓库的,哪个是本地的。我还没有找到如何只保留本地版本,以便我可以执行 git diff 并查看本地和仓库之间的差异... - msb
显示剩余3条评论

6

你可能已经知道,git pull 基本上就是 git fetch 然后接着 git merge

出现问题的步骤不是 git fetch,而是 git merge

... overwritten by merge
请注意这里的最后一个单词是“merge”。这意味着你的犹豫不决已经被别人决定了,至少对于其中的一个文件而言:那个特定的文件现在已经添加了,在另一个提交中。这就是Git将要覆盖的文件。
现在你有各种选择:
- 不合并(或者暂时不合并):你可以让文件保持未跟踪状态。我认为这很清楚,但它并没有解决问题。最终你可能需要合并。 - 合并:文件将会被跟踪。然后你有一些子选项,关于Git应该如何处理你现有的未跟踪文件: - 添加并提交。Git将合并你基于原始版本所做的更改和他们基于原始版本所做的更改。假设两个更改都是“添加此文件”,也就是说该文件不在合并基础中。这意味着冲突将是“添加/添加”冲突,有点麻烦。 - 将你的文件版本保存在其他地方,删除未跟踪的文件。让Git合并(作为快进合并或真正的合并,无论哪种方式)。手动合并你自己的更改,添加并创建你自己的新提交。 - 另一个人是错的,这个文件不应该被跟踪:将你的文件版本保存在其他地方。让Git合并。删除文件并提交,提交删除操作。然后你可以把自己的未跟踪文件放回去。
还有一些其他选项(例如重新设置而不是合并),但它们最终都会出现相同的情况:要么文件被跟踪(就像你告诉Git要合并的提交中那样),要么你必须更新到那个提交,删除文件,并再次提交以创建一个不跟踪该文件的提交。
“将文件保存在其他位置”的方式由你决定:例如,你可以完全将其移出工作树,或者你可以使用git stash来创建一个包含该文件的提交。
git stash正常工作时,它非常方便。但是,由于它实际上会创建两到三个提交,这些提交不属于任何分支,因此它变得相当复杂。当它出现问题时,处理起来非常困难。所以对于任何可能很复杂的情况,我喜欢避免使用git stash。请注意,默认情况下,git stash只存储已跟踪的文件,因此您必须git add它,以将其放入git stash通常创建的两个提交中。您可以使用git stash -u来明确地创建第三个提交,其中包含未跟踪的文件,但这会使存储更加难以处理。

“已经被别人决定了(...):那个特定的文件现在已经被添加到另一个提交中”,但是没有其他提交和其他人。:-/” - msb
肯定有另一个提交,否则就没有合并的内容了。无论是谁创建了那个另一个提交,在这里都称作“其他人”,即使那个人是你。 :-) - torek
哦天啊......你说得对!嗯,有点。确实没有其他提交。:$ 但是我半年前git add了一个文件,但从未提交。在git status中报告为“新”的所有内容都会干扰操作。我git reset了那个文件,提交了其他新的东西,现在git pull可以工作了!你错了,有另一个提交干扰了事情,但你说对了,有另一个待处理的操作。谢谢! - msb
嗯,既然已经完成了拉取请求的合并,请尝试使用 git ls-files --stage 命令(请注意,这将生成大量输出,每个跟踪文件一行)。如果您曾经使用 git add 命令添加过该文件,则会将其复制到索引/暂存区,并且自那时以来,除了通过首先将其从索引/暂存区中取出而进行的任何提交之外,它已经存在于您所做的每个提交中。请记住,每个提交都是每个文件的完整快照:例如,使用 git ls-tree -r <commit> 命令查看它们所有。 (如果您使用 git commit <paths> 命令,则会得到一个临时的索引/暂存区;我假设您没有这样做。) - torek
感谢@torek提供的有关未跟踪文件的-u提示 :-) - Kieran Ryan
显示剩余4条评论

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