在Git中取消隐藏stream行
我popup一个藏匿,并发生了合并冲突。 与被列为重复的问题不同,我已经在我想保留的目录中有一些未提交的更改。 我不只是想让合并冲突消失,还要让我的目录恢复到popup之前的状态。
我试过git merge --abort
,但git声称没有合并进行中。 有没有一个简单的方法来中止stream行而不破坏我最初在目录中的变化?
好的,我想我已经搞定了“git stash unapply”。 这比git apply --reverse
更复杂,因为你需要反向合并动作,以防git stash apply
任何合并git stash apply
。
反向合并要求将所有当前更改推入索引:
-
git add -u
然后颠倒由git stash apply
完成的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)
我的用例:刚试过popup错误的分支,并发生冲突。 我所需要的只是撤消popup窗口,但将其保存在存储列表中,以便可以将其popup到正确的分支上。 我做到了这一点:
git reset HEAD --hard git checkout my_correct_branch git stash pop
简单。
编辑:从popup部分的git help stash
文档:
应用状态可能会因冲突而失败; 在这种情况下,它不会从存储列表中删除。 您需要手动解决冲突,然后手动调用git stash drop。
如果使用–index选项,则不仅尝试恢复工作树的更改,而且还尝试恢复索引的更改。 但是,如果发生冲突(存储在索引中,因此不能再像原来那样应用更改),这可能会失败。
试着把所有的回购拷贝到一个新的目录(所以你有一个副本)并运行:
git stash show
并保存输出的地方,如果你关心它。
然后: git stash drop
放置冲突的藏匿然后: git reset HEAD
这应该使您的回购在以前的状态(希望,我仍然无法重现您的问题)
===
我想repro你的问题,但所有我得到时,使用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试图合并我的更改,它只是失败。 你有任何我们可以遵循的repro步骤来帮助你吗?
好吧,我想我已经设法find了一个能让你回到你需要的地方的工作stream程(就好像你还没有完成stream行)。
采取备份之前! 我不知道这是否适合你,所以为了防止它不起作用,请复制你的整个回购。
1)修复合并问题,并通过select所有来自修补程序的更改(在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)摆脱补丁/ unpatch提交
git rebase -i HEAD^^^
从中删除两行,其中“合并”和“反向修补”。
7)取回你的未知变化并撤销“本地变更”提交
git reset HEAD^
我已经通过一个简单的例子来解决它,它让你回到你想要的地方 – 直接存储在popup窗口之前,用你的本地修改和存储仍然可以popup。
一些想法:
-
使用
git mergetool
将合并文件分成原始和新的部分。 希望其中的一个是你的非隐藏的变化的文件。 -
以相反的方式应用藏匿的差异,以仅撤消这些变化。 你可能不得不手动拆分合并冲突的文件(希望上面的技巧会起作用)。
我没有testing这两个,所以我不知道他们会工作。
使用git reflog
列出在你的git历史logging中所做的所有更改。 复制一个操作ID并inputgit reset ACTION_ID
我可以在“脏”目录中重现干净的git stash pop
,未提交的更改,但尚未popup,产生合并冲突。
如果合并冲突,你试图申请的--ours
不会消失,你可以尝试检查git show stash@{0}
(可选用--ours
或--theirs
),并与git statis
--theirs
和git diff HEAD
。 您应该能够看到应用存储的更改。
如果DavidG是正确的,因为合并冲突没有popup存储,那么你只需要清理你的工作目录。 快速git commit
你关心的一切。 (如果你还没有完成,你可以reset
或squash
提交。)然后,在你关心的所有事情都安全的情况下,把git reset
所有东西都git reset
git stash pop
把它们转储到工作目录中。
如果您不必担心您所做的任何其他更改,而您只想返回上次提交,则可以执行以下操作:
git reset . git checkout . git clean -f
如果在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 stash
: The working directory must match the index.
其中@DavidG指出,如果任何目前未分离的修改文件发生冲突,则隐藏stash pop
将失败。 因此,我们不应该担心除了回到HEAD
之外,解决合并冲突。 任何剩余的修改后的文件都与存储无关,并在stash pop
之前被修改
如果有变化,我不清楚我们是否可以依靠相同的命令,你可能想尝试@Ben Jackson的技术。 build议感激..
这里是所有各种情况的testing设置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
我以一种不同的方式解决了这个问题。 这是发生了什么事。
首先,我popup错误的分支,并发生冲突。 藏匿处保持完好,但索引处于解决冲突状态,阻止了许多命令。
一个简单的git reset HEAD
中止了冲突解决方法,并且保留了未提交的(和UNWANTED )更改。
几个git co <filename>
将索引恢复到初始状态。 最后,我用git co <branch-name>
切换了分支,并运行了一个新的git stash pop
,它解决了没有冲突的问题。