我们做了一些不好的事情。
在合并冲突期间,我们运行了git stash save
,现在我们无法恢复我们的工作。
我们尝试过的方法:
git pull -Xours origin master
git stash apply --index
而且:
git pull origin master
git stash save --keep-index "merge conflicts"
git stash apply stash@{1}
请帮忙!
我们做了一些不好的事情。
在合并冲突期间,我们运行了git stash save
,现在我们无法恢复我们的工作。
我们尝试过的方法:
git pull -Xours origin master
git stash apply --index
而且:
git pull origin master
git stash save --keep-index "merge conflicts"
git stash apply stash@{1}
请帮忙!
git stash
没有保存您尝试合并的分支的引用。在合并期间,此引用存储在一个名为MERGE_HEAD
的引用中。MERGE_HEAD
:git stash apply --index
git update-ref MERGE_HEAD d7a9884a380f81b2fbf002442ee9c9eaf34ff68d
.git/MERGE_MSG
不存在,我创建了一个带有自定义合并消息的文件,然后提交了。我担心我会被标记为合并中所有更改的作者,但似乎一切都按照应该的方式进行了。其他作者得到了适当的认可。谢谢 :) - Eldamir今天我也做了同样的事情,并采用了不同的方法(经过试错)来回到之前存储状态,以便我可以继续解决冲突并完成合并。
首先,在目标分支中取消存储部分合并后,我捕获了剩余冲突文件的列表(文本文件或编辑器选项卡)。这只是取消存储后未暂存文件的列表,因为已解决冲突的文件在存储之前已被暂存。
$ git status
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: myproject/src/main/java/com/acme/package3/Class3.java
# modified: myproject/src/main/java/com/acme/package3/Class4.java
#
接下来,我创建了一个补丁并将分支重置回合并前的状态:
$ git diff HEAD > ~/merge-with-resolved-conflicts.patch
$ git reset --hard HEAD
然后我创建了一个临时分支(派生自合并目标分支),并应用了补丁:
$ git checkout -b my-temp-branch
$ git apply ~/merge-with-resolved-conflicts.patch
$ git commit -a -m "Merge with resolved conflicts"
现在,我的临时分支(my-temp-branch)的HEAD包含了所有已经合并的内容,包括冲突已解决的文件和仍然存在冲突的文件。
然后我切换回原始分支,再次进行合并,并查看git状态。
$ git checkout my-branch
$ git merge other-branch
$ git status
# Unmerged paths:
# (use "git add <file>..." to mark resolution)
#
# both modified: myproject/src/main/java/com/acme/package1/Class1.java
# both modified: myproject/src/main/java/com/acme/package2/Class2.java
# both modified: myproject/src/main/java/com/acme/package3/Class3.java
# both modified: myproject/src/main/java/com/acme/package3/Class4.java
#
现在我需要比较这两个文件列表。第二个列表中的任何文件,但不在第一个列表中,已经被解决了(在这个示例中,Class1.java和Class2.java)。因此,对于每个这样的文件,我从临时分支中获取了已解决冲突的版本(类似于cherry-pick,但是针对单个文件而不是整个提交):
$ git checkout my-temp-branch myproject/src/main/java/com/acme/package1/Class1.java
$ git checkout my-temp-branch myproject/src/main/java/com/acme/package2/Class2.java
你已经解决了所有的冲突,然后你执行了git stash
。这将重置你的工作树到合并前的状态,并将所有的解决方案放入一个stash中。
所以,你需要做的就是重新执行合并,然后将stash中的所有内容(-- .
)检出到工作树中。注意,在你的仓库根目录下运行此命令。
git merge conflict-branch
cd "$(git rev-parse --show-toplevel)"
git checkout stash@{0} -- .
git commit
顺便提一下,当进行合并操作时,你可以使用git worktree add
代替git stash
。
当你处于冲突状态(索引和工作目录),你将无法执行 git stash
- 它会报错说存在未合并的条目。
确保你确实已经进行了存储。查看 git status
和 git stash show
的输出。
git stash
之前,我已经解决了冲突并继续使用了git add
。在我使用git add
后,我进行了进一步的编辑,然后执行了git stash save msg
。所以这是成功的。 - steven_moygit stash save
确实会中止,而不会将有冲突的文件存储。因此,这是正确的,不是错误的。 - user456814我解决(在合并冲突期间 git stash pop)的方法是:
创建并检出一个新的(本地)分支 mytemporarybranch
git branch mytemporarybranch && git checkout mytemporarybranch
提交到这个 mytemporarybranch
git commit -m "我的混乱合并和压缩"
检出 myoriginalbranch
git checkout myoriginalbranch
正确合并(这次不要 squash pop/apply!)
squash 合并 mytemporarybranch 到 myoriginal 分支
git merge --squash mytemporarybranch
git stash megre --no-commit <branch>
git reset #to remove the "conflicts" flags
git checkout <initial commit> -- ./ #to revert everything to the previous working state,
git stash apply #apply your changes
一旦所有东西都处于期望的状态,git commit
git checkout <tree-ish>
和git checkout <tree-ish> -- <files>
之间实际上有很大的区别。git checkout
:
git checkout <branch>
:此形式通过更新索引、工作树和HEAD来切换分支,以反映指定的分支或提交。
git checkout [-p|--patch] <tree-ish> -- <pathspec>
:当给出<paths>或--patch时,git checkout不会切换分支。它会从索引文件或命名的<tree-ish>(通常是提交)中更新工作树中的命名路径。
git checkout <initial commit>
确实会丢弃合并信息。
git checkout <initial commit> -- ./
(注意额外的-- ./
),另一方面,将保留合并信息,并将每个已跟踪文件恢复到其在<initial commit>
中的状态。
git checkout
会取消合并状态,对吗?这样我最终将得到一个正常的提交,其中包含了 master 中的所有更改。 - bukzorgit stash apply
命令还清除了合并状态,按照 Evan 的回答中建议的方式明确设置 MERGE_HEAD
引用即可解决我的问题。 - Robert Byrne
stash save
清除索引而stash apply
不修改它,因此您最终会得到常规的未暂存更改,而不是合并。我想在合并过程中应用这些更改,但不知道如何做。 - bukzor