git 隐藏未解决的合并冲突

git stash unresolved merge conflicts

我正在解决合并冲突,需要回到旧的代码库来弄清楚它以前是如何工作的。 我凭直觉隐藏了我的工作副本,检查了我想要的内容并应用了隐藏。 现在我遇到了很多麻烦,因为我的代码已保存,但我不再在终端中的分支名称旁边看到 |MERGING 并且我丢失了来自另一个分支的所有提交。 git 它看起来不再像合并提交,而只是一个新的代码更改。

我做错了什么,以后如何避免同样的问题?

注意:按原样提交它不是一种选择,因为我们正在处理 2 个不同的回购协议,我们需要不时将一个合并到另一个。如果我们在一次合并期间更改校验和,我们将面临大量冲突,因为在下一次合并时 git 将无法识别先前合并的代码。一遍又一遍地合并相同的 repo 看起来就像多次合并同一个分支。校验和应保持不变。

有些事情并没有完全加起来,因为 git stash 通过提交来工作。你说:

I was resolving merge conflicts ... I intuitively stashed my working copy

如果您正在进行有冲突的合并,则无法提交,因此您无法使用 git stash:

... [set up some conflicts; get onto branch b2, with b1 ready to conflict]

$ git add README && git commit -m 'b2-readme'
[b2 c548973] b2-readme
 1 file changed, 1 insertion(+)
$ git merge b1
Auto-merging README
CONFLICT (content): Merge conflict in README
Automatic merge failed; fix conflicts and then commit the result.
$ git status
On branch b2
You have unmerged paths.
  (fix conflicts and run "git commit")

Changes to be committed:

    new file:   file1

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified:   README
$ git stash
README: needs merge
README: needs merge
README: unmerged (af8a7b1af61c4d6a71415c41d0f19a418d5a1e3c)
README: unmerged (1eafc235a9f2cb59959d554ba9b9e11877c88349)
README: unmerged (7616840fd1336b8bcae3f33e2c6c69890e563121)
fatal: git-write-tree: error building trees
Cannot save the current index state

要真正实现存储,您必须解决冲突。 Git 不关心你如何解决它们,当然:

$ cat README 
We put a dummy README file into the base,
to get an initial commit.
<<<<<<< HEAD
conflicting b2 change
||||||| merged common ancestors
=======
conflicting change in b1
>>>>>>> b1
$ git add README    # Yuck! "resolve" conflicts by leaving markers
$ git status --short
M  README
A  file1
$ git stash
Saved working directory and index state WIP on b2: c548973 b2-readme
HEAD is now at c548973 b2-readme

如果这是你所做的——也许是在对冲突做一些明智的事情,而不是我在这里的愚蠢例子——然后你这样做了:

$ git stash pop   # NB: better to "git stash apply" really
On branch b2
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   file1

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:   README

Dropped refs/stash@{0} (8a947fcd34b3259fbb2fbf667bc0b99cc139a88c)

你有点麻烦,但不是太多。问题是,您现在在索引和工作树中拥有执行(这次成功)git stash 时的状态,但是您丢失了合并状态文件(.git/MERGE_HEAD.git/MERGE_MSG).

NOTE: Committing it as is is not an option, because we are working on 2 different repos and we need to merge one into another from time to time.

承诺和失败一样,是always an option!例如,在这种情况下,诀窍是现在提交结果,然后返回并重新开始合并。

由于 Git 中分支的混乱性质,现在可以在 b2 上提交此代码,然后使 b2(名称)不再包含 提交。但首先创建一个 new 分支名称同样容易,甚至更容易,而且绝对不会造成混淆。然后你可以在那里提交,而不是 b2.

$ git checkout -b save-merge-result
M   README
A   file1
Switched to a new branch 'save-merge-result'

# NOTE: use "git status" (not shown here) to see what you
# still need to "git add" (which is `README` in my case)

$ git add README
$ git commit -m 'save merge result on temp branch'
[save-merge-result f8b2251] save merge result on temp branch
 Date: Tue Oct 18 05:58:14 2016 -0700
 2 files changed, 20 insertions(+)
 create mode 100644 file1

现在您可以返回 b2 并重做 git merge,这当然会再次因冲突而失败:1

$ git checkout b1
Switched to branch 'b1'
$ git merge b2
Auto-merging README
CONFLICT (content): Merge conflict in README
Automatic merge failed; fix conflicts and then commit the result.

现在您可以从临时合并中提取结果。例如:

$ git checkout save-merge-result -- .
$ git status
On branch b1
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

    modified:   README
    new file:   file2

此时你可以修改git add个文件为needed/desired.

请注意,如果您还没有对您创建的存储执行 git pop,您可以使用 git stash branch 将存储转换为它自己的一个分支,一步完成。由于 git stash save 只是简单地进行提交,您永远 不需要 使用 git stash:只需创建一个分支并在那里提交。 git stash 所做的只是为您提供由名称 stash 而不是分支名称记住的提交。

(顺便说一句,不要将分支命名为 stash 并开始使用 git stashGit 不会有任何问题这个,但是你会混淆你自己。:-))


1假设您没有启用git rerere.