621

正如在这个问题中所问的那样,我还想知道如何在git stash pop不向提交添加所有修改的情况下解决冲突(就像没有冲突的“git stash pop”一样)。

我目前的方法很不酷,因为我是这样做的:

git stash pop  # -> CONFLICT
git stash drop
# [resolve conflict]
# [add conflict files]
git reset HEAD # <all files that are in commit-mode>

如何重现:

mkdir foo; cd foo; git init
echo "1" > one
echo "2" > two
git add -A; git commit -m "first"
echo "1.1" > one
echo "2.1" > two
git stash
echo "2.2" > two
git commit -a -m "second"
echo "Only this file would stay in HEAD without the conflict" > third
git add third
git stash pop
git status

2016-06-27:在示例中添加了一个名为“third”的新文件,以表明像 scy 的解决方案这样的变通办法仅适用于空 HEAD,但不能解决 HEAD 没有相同内容的初始问题,例如对于一个git stash pop没有冲突的。

4

11 回答 11

723

不要跟随其他答案...

好吧,当然,您可以关注他们。但我不认为进行提交然后重置分支以删除您刚刚创建的提交以及其他答案中建议的类似解决方法是解决此问题的干净方法。

清洁溶液

以下解决方案对我来说似乎更干净,而且Git 本身也建议使用它- 尝试git status在有冲突的存储库中执行:

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

注意:restore命令已在 Git版本 2.23.0中引入。旧版本的 Git 建议使用命令git reset HEAD <file>...而不是git restore --staged <file>.... 您还可以使用git reset取消暂存区域(称为索引)中的所有文件。恢复命令的等价物是git restore --staged .(点是必需的,它指定任何文件)。目前,可以使用任何这些命令并且结果是相同的。如果您想了解这些命令之间的区别,请查看文档

所以让我们按照 Git 的建议去做(不要做出和恢复任何毫无意义的提交):

  1. 手动(或理想情况下使用某些合并工具,见下文)解决冲突。
  2. 用于git restore --staged .将冲突标记为已解决并取消暂存区域中的所有文件。如果您只想取消暂存特定文件,请改用该命令git restore --staged <file>。您不必git add之前执行。
  3. 最后,使用 删除存储git stash drop,因为 Git 不会在冲突时自动执行此操作。

翻译成命令行命令:

$ git stash pop

# ...resolve conflict(s)

$ git restore --staged .

$ git stash drop

默认行为的解释

有两种方法可以将冲突标记为已解决:git addgit restore --staged <file>.... 虽然git restore --staged <file>...将冲突标记为已解决并从索引中删除文件git add,但也将冲突标记为已解决,但将文件保留在索引中。

解决冲突后将文件添加到索引是故意的。通过这种方式,您可以将更改与之前的存储区分开来,以及您在冲突解决后所做的更改。如果您不喜欢它,您可以随时使用git restore --staged .从索引中删除所有内容。

合并工具

我强烈建议使用任何3 路合并工具来解决冲突,例如KDiff3Meld等,而不是手动进行。它通常会自动解决所有或大部分冲突。这是巨大的节省时间!

于 2014-12-09T15:09:13.260 回答
306

假设您有这种情况,您将更改存储起来以便从源中提取。可能是因为您的本地更改只是debug: true在某些设置文件中。现在您拉动并且有人在那里引入了新设置,从而产生了冲突。

git status说:

# On branch master
# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#   both modified:      src/js/globals.tpl.js
no changes added to commit (use "git add" and/or "git commit -a")

好的。我决定按照 Git 的建议去做:我解决了冲突并承诺:

vim src/js/globals.tpl.js
# type type type …
git commit -a -m WIP   # (short for "work in progress")

现在我的工作副本处于我想要的状态,但我创建了一个我不想拥有的提交。如何在不修改工作副本的情况下摆脱该提交?等等,有一个流行的命令!

git reset HEAD^

我的工作副本没有更改,但 WIP 提交已消失。这正是我想要的!(请注意,我没有--soft在这里使用,因为如果您的存储中有自动合并的文件,它们是自动暂存的,因此您最终会在之后再次暂存这些文件reset。)

但是还有一件事:手册页git stash pop提醒我们“应用状态可能会因冲突而失败;在这种情况下,它不会从存储列表中删除。您需要手动解决冲突,然后git stash drop手动调用。” 所以这正是我们现在所做的:

git stash drop

并做了。

于 2013-08-13T15:14:44.483 回答
89

无需添加您为解决冲突所做的更改,您可以使用它git reset HEAD file来解决冲突,而无需暂存更改。

但是,您可能必须运行此命令两次。一次将冲突标记为已解决,一次取消暂存由冲突解决例程暂存的更改。

可能应该有一种重置模式可以同时执行这两项操作,尽管现在还没有。

于 2011-10-28T17:49:04.713 回答
38
git checkout stash -- .

为我工作。

注意:这可能很危险,因为它不会尝试将存储中的更改合并到您的工作副本中,而是用隐藏的文件覆盖它。因此,您可能会丢失未提交的更改。

于 2014-09-09T18:09:52.520 回答
28
git add .
git reset

git add .将暂存所有文件,告诉 git 你已经解决了冲突

git reset将取消暂存所有暂存文件而不创建提交

于 2016-09-28T19:16:21.687 回答
10

那里没问题。一个简单git reset HEAD的就是您要寻找的,因为它使您的文件保持修改状态,就像不冲突的git stash pop.

唯一的问题是您的冲突文件仍然会有冲突标签,并且 git 将不再报告它们与有用的“both_modified”标志冲突。

为防止这种情况,只需在运行前解决冲突(编辑和修复冲突的文件)git reset HEAD,您就可以开始了......

在此过程结束时,您的存储将保留在队列中,因此只需执行 agit stash drop将其清除。

这只是发生在我身上并用谷歌搜索了这个问题,因此该解决方案已经过测试。

我认为这就像它得到的一样干净......

于 2020-10-02T05:20:21.880 回答
5

看来这可能是您正在寻找的答案,我还没有亲自尝试过,但它似乎可以解决问题。使用此命令,GIT 将尝试像以前一样应用更改,而不是尝试将所有更改都添加到提交中。

git stash apply --index

这是完整的解释:

http://git-scm.com/book/en/Git-Tools-Stashing

于 2012-03-01T19:16:41.130 回答
2

git stash branchwill works,它会为你创建一个新的分支,检查你在隐藏你的工作时所做的提交,在那里重新应用你的工作,然后如果它成功应用则删除隐藏。检查这个

于 2014-08-12T12:46:39.767 回答
2

我发现最快的方法是解决冲突,然后 do git add -u,然后 do git reset HEAD,这甚至不涉及提交。

于 2015-09-17T21:43:05.573 回答
1

根据git stash questions,在解决冲突之后,git add <file>是正确的做法。

阅读此评论后,我了解到更改会自动添加到索引中(按设计)。这就是git add <file>完成冲突解决过程的原因。

于 2015-01-26T20:11:54.943 回答
-2

它不是最好的方法,但它有效:

$ git stash apply
$ >> resolve your conflict <<
$ >> do what you want to do with your code <<
$ git checkout HEAD -- file/path/to/your/file
于 2017-12-13T10:55:29.980 回答