我弹出了一个存储,但出现了合并冲突。与重复的问题不同,我已经在目录中有一些未提交的更改需要保留。我不仅想让合并冲突消失,还要将目录恢复到弹出之前的状态。
我尝试了git merge --abort
,但是git声称没有进行任何合并。有没有一种简单的方法可以中止“stash pop”操作而不破坏我最初在目录中所做的更改?
我一直在使用
git reset --merge
我不记得它曾经失败过。
注: git reset --merge
将放弃任何已暂存的更改。另外,正如评论中@Saroopashree Kumaraguru所指出的,备份内容不会丢失并且可以在以后重新应用。
git stash pop
命令时因为合并冲突而导致操作不成功时,存储的内容将被自动保存在stash中,而不是被删除。 - Saroopashree Kumaraguru我的使用情况:刚尝试切换到错误的分支并出现了冲突。我只需要撤销切换但保留在存储列表中,以便在正确的分支上弹出它。我做了这个:
git reset HEAD --hard
git checkout my_correct_branch
git stash pop
简单。
stash pop
回目录之前,我无法想象我有未提交的更改的情况,因为那听起来像是灾难的配方。 - Shadoninja好的,我认为我已经理解了"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
现在你只剩下非stash更改了,它们在索引中。如果需要,可以使用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)
git stash apply
命令不会丢弃存储的内容,当合并失败时,使用 git stash pop
命令也会保留存储的内容。 - xeruf编辑:来自git help stash
文档中的pop部分:
如果应用状态时出现冲突,则此操作可能会失败,并且此时该状态不会从隐藏列表中被移除。您需要手动解决冲突,并在之后手动调用git stash drop。
如果使用了--index选项,则尝试恢复工作树和索引的更改。但是,当存在冲突时(这些冲突存储在索引中,因此您无法像最初那样应用更改),这将失败。
尝试将你所有的repo复制到一个新的目录中(这样你就有了一个副本),然后运行:
git stash show
并将其输出保存在某个地方,如果您关心它的话。
然后:git stash drop
以删除具有冲突的stash
然后:git reset HEAD
这将使您的repo恢复到先前的状态。(希望如此,我仍然无法重现您的问题)
===
我正在尝试重现您的问题,但是当使用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 reset .
git checkout .
git clean -f
好的,我想我已经找到了一个工作流程,可以让你回到你需要的地方(就像你没有执行过弹出操作一样)。
在此之前,请备份!!我不知道这是否适用于你,所以为了万无一失,请复制整个repo。
1)解决合并问题,并通过选择来自补丁的所有更改(在tortoisemerge中,这会显示为one.REMOTE(theirs))来解决所有冲突。
git mergetool
2) 提交这些更改(它们已经通过合并工具命令添加了)。给它一个提交消息,例如“merge”或您记得的其他内容。
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^^^
从中删除包含“merge”和“reversed patch”的两行。
7)取回未暂存的更改并撤销“本地更改”提交。
git reset HEAD^
我用一个简单的例子演示了一遍,它可以让你回到想要的位置——正好在弹出stash之前,保留了你的本地更改并且stash仍然可用于弹出。
git stash show -p | git apply -R
如果git stash apply
进行了实际合并,则无法正常工作。请参见我的回答... - Ben Jackson我用了一种稍微不同的方法解决了这个问题,以下是我的做法。
首先,我切错了分支并遇到了冲突。储藏区保持不变,但索引处于冲突解决状态,阻止了许多命令。
简单的git reset HEAD
中止了冲突解决并留下了未提交(且不需要的)更改。
几次git co <文件名>
将索引还原回初始状态。最后,我使用git co <分支名称>
切换到目标分支,并运行新的git stash pop
,顺利地解决了问题,没有冲突发生。
一些想法:
使用git mergetool
将合并文件拆分为原始部分和新部分。希望其中之一是包含您非存储更改的文件。
反向应用储藏的差异,仅撤消这些更改。您可能需要手动拆分具有合并冲突的文件(希望上述技巧适用于此)。
我没有测试过这两个方法,所以我不确定它们是否有效。
git merge --abort
git reset --merge
git stash pop
的操作。这种情况下,您可以简单地使用git reset --hard
,而您的存储仍然完好无损。(这更或多或少是@BradKoch链接主题所建议的)。 - Steven Lu