如何中止隐藏pop?

我开了个藏宝箱,合并发生了冲突。与被列为重复的问题不同,我已经在我想保留的目录中有一些未提交的更改。我不只是想让合并冲突消失,还想让我的目录恢复到弹出窗口之前的状态。

我尝试了git merge --abort,但git声称没有合并正在进行中。是否有一种简单的方法来中止弹出,而不破坏我原来在目录中的更改?

192692 次浏览

使用git reflog列出在git历史中所做的所有更改。复制一个动作id并键入git reset ACTION_ID

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

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

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

试着硬拷贝你所有的repo到一个新目录(这样你就有了一个副本),然后运行:

git stash show和保存输出的地方,如果你关心它。

then: git stash drop删除冲突的存储 然后:git reset HEAD < / p >

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

= = =

我试图重现你的问题,但当我使用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试图合并我的更改,它只是失败了。你有什么我们可以帮助你的重现步骤吗?

一些想法:

  • 使用git mergetool将合并文件拆分为原始部分和新部分。希望其中一个是包含你非隐藏更改的文件。

  • 反向应用隐藏的diff来撤销这些更改。您可能必须手动分离合并冲突的文件(希望上面的技巧可以奏效)。

这两个我都没有测试过,所以我不确定它们是否能工作。

我可以在“脏”目录上重新生成干净的git stash pop,具有未提交的更改,但尚未弹出,从而产生合并冲突。

你尝试应用的隐藏没有消失,你可以尝试检查git show stash@{0}(可选使用--ours--theirs)并与git statisgit diff HEAD进行比较。您应该能够看到哪些更改来自应用存储。

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

好吧,我想我已经解决了"git stash unapply"。它比git apply --reverse更复杂,因为如果git stash apply做了任何合并,你需要反向合并操作。

反向合并要求所有当前更改都被推入索引:

  • git add -u

然后反转由git stash apply完成的merge-recursive:

  • 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)

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

事先做个备份!!我不知道这是否适用于你,所以复制你的整个回购以防它不起作用。

1)修复合并问题,并通过选择所有来自补丁的更改来修复所有冲突(在tortoisemerge中,这显示为一个)。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)取消patch/unpatch提交

git rebase -i HEAD^^^

从中删除带有“merge”和“reversed patch”的两行。

7)找回你的unstancing changes,并撤销“local changes”的提交

git reset HEAD^

我已经运行了一个简单的例子,它让你回到你想要的地方-直接在隐藏之前被弹出,与你的本地变化和隐藏仍然可用的弹出。

如果在git stash pop之前没有分阶段的变化,就像问题中那样,那么下面两个命令应该可以工作。

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

第一种方法将从存储中反转任何合并,不管成功与否。第二个删除由隐藏引入的任何未跟踪的文件。

@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

如果你不需要担心你所做的任何其他更改,你只想回到上次提交,那么你可以这样做:

git reset .
git checkout .
git clean -f

我的用例:只是尝试弹出到错误的分支并得到冲突。我所需要的是撤消弹出,但保持它在收藏列表,以便我可以弹出它在正确的分支。我是这样做的:

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

一件容易的事。

我用不同的方法解决了这个问题。事情是这样的。

首先,我碰到了错误的分支,产生了冲突。存储仍然完好无损,但是索引在冲突解决中,阻塞了许多命令。

简单的git reset HEAD终止了冲突解决,并留下了未提交的(和不需要的)更改。

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

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

简单的一行

我总是用

git reset --merge

我不记得它曾经失败过。


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

尝试使用if跟踪文件。

git rm <path to file>
git reset  <path to file>
git checkout <path to file>

如果你只有存储的更改,试试下面的一行。它删除了当前的每个局部更改。

Git checkout -f

合并——只有当你合并其他分支代码并且它有冲突时才会中止。

git merge --abort

如果stash pop有冲突,你可以使用:

git reset --merge