如何在没有提交的情况下解决git stash冲突?

问题描述 投票:405回答:10

作为asked in this question,我也想知道如何解决冲突的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

git git-stash
10个回答
382
投票

Don't follow other answers

好吧,你可以关注他们:)。但我不认为执行提交然后重置分支以删除该提交和其他答案中建议的类似解决方法是解决此问题的干净方法。

Clean solution

以下解决方案似乎对我来说更清晰,Git本身也提出了这一点 - 尝试在存储库中执行git status并发生冲突:

Unmerged paths:
  (use "git reset HEAD <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

那么让我们做Git建议的事情(不做任何无用的提交):

  1. 手动(或使用一些合并工具,见下文)解决冲突。
  2. 使用git reset将冲突标记为已解决并取消更改。您可以在没有任何参数的情况下执行它,Git将从索引中删除所有内容。您之前不必执行git add
  3. 最后,使用git stash drop删除存储,因为Git在冲突时不会这样做。

转换为命令行:

$ git stash pop

# ...resolve conflict(s)

$ git reset

$ git stash drop

Explanation of the default behavior

将冲突标记为已解决的方法有两种:git addgit reset。虽然git reset将冲突标记为已解决并从索引中删除文件,但git add也将冲突标记为已解决,但将文件保留在索引中。

解决冲突后将文件添加到索引是故意的。这样,您可以区分更改与先前存储的更改以及解决冲突后所做的更改。如果您不喜欢它,您可以随时使用git reset从索引中删除所有内容。

Merge tools

我强烈建议使用任何3-way merge tools来解决冲突,例如: KDiff3Meld等,而不是手动完成。它通常自动解决所有或大多数冲突。节省大量时间!


-1
投票

它不是最好的方法,但它的工作原理:

$ git stash apply
$ >> resolve your conflict <<
$ >> do what you want to do with your code <<
$ git checkout HEAD -- file/path/to/your/file

292
投票

假设您有这种情况,您可以隐藏更改以从原点拉出。可能是因为您的本地更改只是某些设置文件中的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

并做了。


84
投票

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

但是,您可能必须运行此命令两次。一旦将冲突标记为已解决并且一次取消暂停冲突解决例程所发生的更改。

有可能应该有一个同时完成这两件事的重置模式,尽管现在还没有。


21
投票
git checkout stash -- .

为我工作。

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


6
投票
git add .
git reset

git add .将播放所有告诉git您已解决冲突的文件

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


4
投票

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

git stash apply --index

这是完整的解释:

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


2
投票

git stash branch将工作,它会为您创建一个新分支,检查您在保存工作时所处的提交,在那里重新应用您的工作,然后在成功应用时删除存储。检查this


2
投票

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


1
投票

根据git stash questions的说法,在解决冲突之后,git add <file>是正确的行动方针。

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

© www.soinside.com 2019 - 2024. All rights reserved.