在Git中删除一个藏匿的流行音乐

时间:2011-12-15 05:54:28

标签: git git-stash

我突然出现了一个合并冲突。与列为重复的问题不同,我已经在目录中保留了一些未提交的更改。我不只是想让合并冲突消失,而且还要让我的目录恢复到流行之前的状态。

我试过git merge --abort,但是git声称没有合并正在进行中。是否有一种简单的方法可以在不破坏我最初在目录中进行的更改的情况下中止流行音乐?

15 个答案:

答案 0 :(得分:219)

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

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

易。

答案 1 :(得分:51)

简单的单缸纸

我一直都用

git reset --merge

我不记得它曾经失败过。

答案 2 :(得分:43)

好吧,我想我已经解决了“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)

答案 3 :(得分:42)

编辑:来自pop部分的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试图合并我的更改,它只是失败了。你有任何我们可以遵循的重复步骤来帮助你吗?

答案 4 :(得分:6)

如果您不必担心自己所做的任何其他更改,而您只想回到最后一次提交,那么您可以这样做:

git reset .
git checkout .
git clean -f

答案 5 :(得分: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^^^

从中删除两行,其中包含'merge'和'reverse patch'。

7)获取您的不明确的更改并撤消“本地更改”提交

git reset HEAD^

我通过一个简单的例子来完成它,它会让你回到你想要的地方 - 直接在藏匿处出现之前,你的本地更改以及仍然可以弹出的藏匿处。

答案 6 :(得分:3)

我以一种不同的方式解决了这个问题。发生了什么事。

首先,我弹出错误的分支并发生冲突。藏匿处保持不变,但索引处于冲突解决状态,阻止了许多命令。

一个简单的git reset HEAD中止了冲突解决方案,并保留了未提交的(以及 UNWANTED )更改。

多个git co <filename>将索引恢复为初始状态。最后,我使用git co <branch-name>切换了分支并运行了一个新的git stash pop,该解析没有冲突。

答案 7 :(得分:2)

一些想法:

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

  • 反向应用stash的diff,以撤消这些更改。你可能不得不手动拆分出合并冲突的文件(希望上面的技巧可以用于)。

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

答案 8 :(得分:1)

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

答案 9 :(得分:1)

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

如果合并冲突,您尝试申请的藏匿条件并未消失,您可以尝试检查git show stash@{0}(可选择--ours--theirs)并与git statisgit diff HEAD进行比较。您应该能够看到应用存储的更改。

答案 10 :(得分:1)

如果DavidG是正确的,因为合并冲突没有弹出存储,那么你只需要清理你的工作目录。快速git commit你关心的一切。 (如果你没有完成,你可以resetsquash提交。)然后,在你关心的一切安全的情况下,git reset git stash pop所有其他{{1}}转入你的工作。目录

答案 11 :(得分:0)

如果在问题之前git stash pop之前没有分阶段的更改,则以下两个命令应该有效。

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

第一个是从存储中撤消任何合并,成功与否。第二个删除存储引入的任何未跟踪文件。

来自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

答案 12 :(得分:0)

我在这里发布,希望其他人对我的回答有所帮助。当我尝试在与我藏身的分支不同的分支上进行藏匿弹出时,我遇到了类似的问题。就我而言,我没有未提交或在索引中的文件,但仍然陷入合并冲突情况(与@pid相同)。正如其他人以前指出的那样,失败的git stash pop确实确实保留了我的stash,然后快速git reset HEAD再返回到我的原始分支并从那里进行隐藏确实解决了我的问题。

答案 13 :(得分:0)

首先提交所有内容

藏匿处的第一个高峰

git diff stash@{0} HEAD

如果您想使用该存储库,请保留您的git存储库,但看看如果应用该存储库会发生什么情况

git stash apply

偷看隐藏之前的真相与现在已应用隐藏的真实之间的区别

git diff HEAD

快乐之路:喜欢你所看到的吗?

git add .
git commit -m "before stash or some other commit message"

然后清理您已应用的存储区

git stash drop stash@{0}

对所应用的隐藏物不满意?您可以选择!

1。不喜欢藏匿处提供的任何更改吗?

在本地应用存储之前返回状态

git checkout .

2。喜欢一些文件,但是不喜欢吗?

删除所有不需要的文件

git checkout path/to/file

添加此提交中所需的任何文件

git add path/to/file

现在只需提交并推送

git add .
git commit -m "your commit message here"
git push 

然后清理您已应用的存储区

git stash drop stash@{0}

答案 14 :(得分:0)

尝试使用是否跟踪文件。

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