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

时间:2011-10-13 08:46:55

标签: git git-stash

作为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相同的内容。

11 个答案:

答案 0 :(得分:335)

不要跟随其他答案

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

清洁解决方案

以下解决方案对我来说似乎更清晰,而且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在冲突时不会这样做。
  4. 转换为命令行:

    $ git stash pop
    
    # ...resolve conflict(s)
    
    $ git reset
    
    $ git stash drop
    

    默认行为的说明

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

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

    合并工具

    我强烈建议您使用3-way merge tools中的任何一个来解决冲突,例如KDiff3Meld等,而不是手动执行。它通常自动解决所有或大多数冲突。它的巨大节省时间!

答案 1 :(得分:290)

假设您有这种情况,您可以隐藏更改以从原点拉出。可能是因为您的本地更改在某些设置文件中只是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,因为如果您的存储中有自动合并的文件,它们会自动暂存,因此您最终会在{{1}之后再次暂存这些文件}。)

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

git stash drop

完成了。

答案 2 :(得分:82)

您可以使用git reset HEAD file来解决冲突,而不是添加为解决冲突而进行的更改,而不是添加您所做的更改。

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

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

答案 3 :(得分:18)

git checkout stash -- .

为我工作。

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

答案 4 :(得分:4)

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

git stash apply --index

这里有完整的解释:

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

答案 5 :(得分:4)

git add .
git reset

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

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

答案 6 :(得分:2)

git stash branch将起作用,为您创建一个新的分支,检查出来 当你把你的工作藏起来,在那里重新申请你的工作,你所做的承诺,以及 如果成功应用,则删除存储。检查this

答案 7 :(得分:2)

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

答案 8 :(得分:2)

没有问题。您正在寻找简单的git reset HEAD,因为它使文件像没有冲突的git stash pop一样被修改。

唯一的问题是您的冲突文件仍将具有冲突标记,而git不会再将其报告为与“ both_modified”标志发生冲突了。

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

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

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

我认为这很干净……

答案 9 :(得分:1)

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

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

答案 10 :(得分:-1)

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

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