382

我弹出了一个存储,并且发生了合并冲突。与列为重复的问题不同,我已经在我想要保留的目录中进行了一些未提交的更改。我不仅想让合并冲突消失,还想让我的目录恢复到弹出之前的状态。

我试过git merge --abort了,但 git 声称没有进行合并。有没有一种简单的方法可以在不破坏我最初在目录中所做的更改的情况下中止弹出?

4

15 回答 15

355

我的用例:刚刚尝试弹出错误的分支并发生冲突。我所需要的只是撤消弹出但将其保留在存储列表中,以便我可以将其弹出到正确的分支上。我这样做了:

git reset HEAD --hard
git checkout my_correct_branch
git stash pop

简单的。

于 2015-04-07T16:16:48.903 回答
350

简单的一班轮

我一直用

git reset --merge

我不记得它曾经失败过。


注意:git reset --merge将丢弃任何分阶段的更改

于 2020-02-28T02:52:30.183 回答
65

好的,我想我已经解决了“git stash unapply”。它比git apply --reverse您需要反向合并操作更复杂,以防git stash apply.

反向合并要求将所有当前更改推送到索引中:

  • git add -u

然后反转通过以下merge-recursive方式完成的操作git stash apply

  • git merge-recursive stash@{0}: -- $(git write-tree) stash@{0}^1

现在您将只剩下非存储更改。他们将在索引中。如果您愿意,可以使用git reset取消暂存更改。

鉴于您原来的git stash apply失败,我认为反向也可能失败,因为它想要撤消的一些事情没有完成。

这是一个示例,显示了工作副本(通过git status)如何再次干净:

 $ git status
# On branch trunk
nothing to commit (working directory clean)
 $ git stash apply
Auto-merging foo.c
# On branch trunk
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   foo.c
#
no changes added to commit (use "git add" and/or "git commit -a")
 $ git add -u
 $ git merge-recursive stash@{0}: -- $(git write-tree) stash@{0}^1
Auto-merging foo.c
 $ git status
# On branch trunk
nothing to commit (working directory clean)
于 2013-01-22T01:32:04.750 回答
50

编辑:从git help stash弹出部分的文档中:

应用状态可能会因冲突而失败;在这种情况下,它不会从存储列表中删除。您需要手动解决冲突,然后手动调用 git stash drop。

如果使用 --index 选项,则不仅尝试恢复工作树的更改,还尝试恢复索引的更改。但是,当您有冲突时,这可能会失败(这些冲突存储在索引中,因此您不能再像原来那样应用更改)。

尝试将所有 repo 硬拷贝到一个新目录中(这样你就有了它的副本)并运行:

git stash show如果您关心它,请将其保存在某处。

然后:git stash drop删除冲突的存储然后:git reset HEAD

那应该使您的回购处于以前的状态(希望我仍然无法重现您的问题)

===

我正在尝试重现您的问题,但使用时我得到的git stash pop只是:

error: Your local changes to the following files would be overwritten by merge:
...
Please, commit your changes or stash them before you can merge.
Aborting

在干净的目录中:

git init
echo hello world > a
git add a & git commit -m "a"
echo hallo welt >> a
echo hello world > b
git add b & git commit -m "b"
echo hallo welt >> b
git stash
echo hola mundo >> a
git stash pop

我没有看到 git 试图合并我的更改,它只是失败了。您有任何我们可以遵循的复制步骤来帮助您吗?

于 2012-11-12T05:23:57.370 回答
6

如果您不必担心所做的任何其他更改并且只想返回上一次提交,那么您可以执行以下操作:

git reset .
git checkout .
git clean -f
于 2015-03-26T13:24:40.537 回答
4

好的,我想我已经设法找到了一个工作流程,可以让你回到你需要的地方(就好像你没有完成弹出一样)。

提前备份!!我不知道这是否对你有用,所以复制你的整个回购,以防万一它不起作用。

1)通过选择来自补丁的所有更改来修复合并问题并修复所有冲突(在tortoisemerge中,这显示为one.REMOETE(他们的))。

git mergetool

2) 提交这些更改(它们已经通过 mergetool 命令添加)。给它一个“合并”的提交信息或你记得的东西。

git commit -m "merge"

3) 现在,您仍将拥有最初开始的本地未暂存更改,并带有来自补丁的新提交(我们可以稍后摆脱它)。现在提交您未暂存的更改

git add .
git add -u .
git commit -m "local changes"

4)反转补丁。这可以使用以下命令完成:

git stash show -p | git apply -R

5)提交这些更改:

git commit -a -m "reversed patch"

6)摆脱补丁/取消补丁提交

git rebase -i HEAD^^^

从中删除带有“合并”和“反转补丁”的两行。

7) 取回您的未更改更改并撤消“本地更改”提交

git reset HEAD^

我已经用一个简单的例子来完成它,它会让你回到你想去的地方——就在存储库被弹出之前,你的本地更改和存储库仍然可以弹出。

于 2013-01-22T17:08:05.583 回答
3

我以不同的方式解决了这个问题。这就是发生的事情。

首先,我跳错了分支并发生了冲突。存储保持不变,但索引处于冲突解决状态,阻止了许多命令。

一个简单git reset HEAD的中止冲突解决并留下未提交(和UNWANTED)的更改。

有几个git co <filename>将索引恢复到初始状态。最后,我切换了分支git co <branch-name>并运行了一个新的git stash pop,它没有冲突地解决。

于 2017-01-20T16:08:14.270 回答
2

一些想法:

  • 用于git mergetool将合并文件拆分为原始部分和新部分。希望其中之一是其中包含您的非存储更改的文件。

  • 反向应用存储的差异,以撤消这些更改。您可能必须手动拆分具有合并冲突的文件(希望上述技巧适用)。

我没有测试其中任何一个,所以我不确定它们是否会起作用。

于 2012-11-15T10:29:52.223 回答
1

我可以在“脏”目录上复制干净git stash pop,但未提交更改,但尚未弹出会产生合并冲突。

如果在合并冲突时,您尝试应用的存储没有消失,您可以尝试检查git show stash@{0}(可选用--oursor --theirs)并与 and 进行git statis比较git diff HEAD。您应该能够看到哪些更改来自应用存储。

于 2013-01-18T19:32:16.333 回答
1

如果 DavidG 是正确的,因为合并冲突它没有弹出存储,那么你只需要清理你的工作目录。快速git commit完成您关心的一切。(如果您还没有完成,您可以resetsquash稍后提交。)然后,您关心的所有内容都是安全的,git reset其他所有内容都git stash pop转储到您的工作目录中。

于 2013-01-19T19:32:42.010 回答
1

如果 之前没有阶段性更改git stash pop,如问题所示,那么以下两个命令应该可以工作。

git diff --name-only --cached | xargs git checkout --ours HEAD
git ls-tree stash@{0}^3 --name-only | xargs rm

第一个反转存储中的任何合并,无论成功与否。第二个删除存储引入的任何未跟踪文件。

From man git stashThe working directory must match the index. @DavidG 指出,stash pop如果任何当前未暂存的修改文件发生冲突,则将失败。因此,除了回到HEAD. 任何剩余的修改文件都与存储无关,并且在stash pop

如果有分阶段的更改,我不清楚我们是否可以依赖相同的命令,您可能想尝试@Ben Jackson 的技术。建议赞赏..

这是针对所有各种情况的测试设置https://gist.github.com/here/4f3af6dafdb4ca15e804

# Result:
# Merge succeeded in m (theirs)
# Conflict in b
# Unstaged in a
# Untracked in c and d

# Goal:
# Reverse changes to successful merge m
# Keep our version in merge conflict b
# Keep our unstaged a
# Keep our untracked d
# Delete stashed untracked c
于 2014-07-24T02:06:57.270 回答
1

如果您只有隐藏的更改,请尝试使用此 1 班轮。它会删除所有存在的本地更改。

git 结帐 -f

于 2022-02-09T10:40:18.477 回答
0

用于git reflog列出您的 git 历史记录中所做的所有更改。复制操作 ID 并键入git reset ACTION_ID

于 2011-12-16T01:43:15.527 回答
0

尝试使用 if tracked 文件。

git rm <path to file>
git reset  <path to file>
git checkout <path to file>
于 2020-08-17T10:22:41.150 回答
-2

我在这里发帖希望其他人发现我的回答有帮助。当我尝试在与我存储的分支不同的分支上进行存储弹出时,我遇到了类似的问题。在我的情况下,我没有未提交或索引中的文件,但仍然进入合并冲突情况(与@pid 相同的情况)。正如其他人之前指出的那样,失败的 git stash pop 确实保留了我的存储,然后快速 git reset HEAD 加上回到我原来的分支并从那里进行存储确实解决了我的问题。

于 2018-08-14T22:47:37.110 回答