临时提交复杂合并 [英] temporary commit on complex merge

查看:82
本文介绍了临时提交复杂合并的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个分支 master ,它是主分支, feature_branch_1 这是非常古老的,主。我需要将 feature_branch_1 合并到master中,所以我做了:

  git pull --rebase origin master 

正如预期的那样,有很多冲突,不久之后就需要在新的 feature_branch_2 上开发另一个功能,这是针对master的 HEAD ,并且肯定需要在 feature_branch_1 。或多或少处于复杂的合并过程中,我如何在 feature_branch_1 上进行临时提交,以便稍后再回来。我知道我可以做一个:

  git add<事情完成> 
git commit -m'合并之间的中介提交'
...稍后再回来
git checkout'that-temp-commit-hash'
...完成后
git add。
git commit -m'with feature_branch_1'
git rebase --interactive HEAD〜1



$ p
$ b

这是处理这个问题的最好方法吗?

解决方案

Git不会让您对包含未合并条目的索引进行提交。 使用 git add 会解决未合并的条目,以便您可以提交,但由于以下几个原因,此方法可能不令人满意。没有太多细节:


  • 未使用索引插槽1至3而不是插槽0指示未解决的路径。文件的合并版本和双方( - 我们的 - 他们的),虽然在从工作树到插槽0的副本,clobbering中的
  • git add 副本插槽1-3,以便现在解析文件(即使工作树文件仍充满冲突标记)。
  • 撤消( REUC )条目在此处也记录在索引中,以便您可以 git checkout -m 重新创建冲突的路径(擦除slot 0条目并恢复1-3条目)。
  • 实际上,提交合并结果永久失去undo状态。


  • 这意味着如果你做了部分合并,然后又想回到它并想完成它,一些信息 - 特别是没有合并的状态,即使它被移动到撤消条目 - 也缺少。您可以最近找出哪些文件仍然需要合理地合并,以便搜索冲突标记。 (如果你没有问题,这种方法毕竟可能是令人满意的。)



    除此之外,rebase会复制多个提交,并且您拥有没有提到这种特殊的合并冲突是否发生在最后一次这样的提交。在进行其他操作之前,您需要完成或中止rebase。 (在技术上可以在rebase中间做一些事情,但这很棘手。)



    至于这部分:


      ...稍后回来
    git checkout'that-temp-commit-hash'
    。 ..完成
    git add后。
    git commit -m'with feature_branch_1'
    git rebase --interactive HEAD〜1




    因为这个特定的非合并状态(你很快就解决了错误的目的以便做其他事情并在以后回来)是由于重新组合而不是合并的结果,该序列可以工作。尽管如此,使用 git commit --amend 取代最后两个步骤会更简单,更普遍适用。 - 修改选项告诉 git commit 使用当前提交的父级进行新的提交,而不是当前提交本身。这适用于正常(单亲,非合并)提交和实际合并(两个或更多父母)。



    替代品



    最好的办法是让这个工作树一个人留下,然后再处理其他问题。



    最简单的方法是,它始终与每个版本的Git一起工作,就是制作另一个克隆。



    您可以通过克隆正在进行的rebase来制作额外的克隆。在具有硬链接的敏感系统上,如果使用本地路径( git clone work / repo work / new-clone-for-fast-fix )将您的存储库克隆到同一文件系统上的另一个存储库,例如code>,从你工作的地方开始,Git将使用硬链接到底层的包和对象,这样你只需要工作树空间。



    如果你的Git比较新(我推荐至少使用Git 2.6,尽管这个功能在2.5版本中),你可以使用 git worktree add 来创建一个新的链接工作树。链接的工作树会记住它的源存储库(反之亦然),但也有一个专用的索引/分段区域。你可以把它放在你想要的任何分支上,做你喜欢的任何分支,包括创建其他分支或者做其他分支,所有这些都不会干扰你的主要工作树和主要索引。

    I have two branches master which is the main branch and feature_branch_1 which is very old and many commits behind the master. I need to merge feature_branch_1 into master, so I did:

    git pull --rebase origin master
    

    As expected there are tons of conflicts, soon after there was a need to develop another feature on a new feature_branch_2 and this is against the HEAD of master and definitely needs to be worked on before feature_branch_1. Being more or less in the middle of the complex merge, how do I do a temporary commit on feature_branch_1 so I can come back to it later. I know I can just do a:

    git add <things-that-are-done>
    git commit -m 'intermediary commit between merges'
    ... come back to it later
    git checkout 'that-temp-commit-hash'
    ... after finishing
    git add .
    git commit -m 'done with feature_branch_1'
    git rebase --interactive HEAD~1
    

    making a temporary commit then rebasing to squash it afterward.

    is this the best way to handle this?

    解决方案

    Git will not let you make a commit with an index that contains unmerged entries.

    Using git add will resolve away the unmerged entries, so that you can then commit, but this approach may be unsatisfactory for several reasons. Without going into too much detail:

    • Unresolved paths are indicated by the use of index slots 1-3 instead of slot 0. These hold the merge-base version of the file, and both "sides" (--ours and --theirs, although during a rebase the roles are kind of swapped) of the merge.
    • git add copies from the work-tree to slot 0, clobbering slots 1-3, so that the file is now resolved (even if the work-tree file is still full of conflict markers).
    • An "undo" (REUC) entry is recorded in the index at this point as well, so that you can git checkout -m the path to re-create the conflict (wiping away the slot 0 entry and restoring the 1-3 entries).
    • Actually committing the merge result loses the undo state permanently.

    This means that if you do commit a partial merge, and then want to go back to it and want to finish it, some information—specifically the unmerged state, even if it was moved to an undo entry—is missing. The closest you can get to figuring out, later, which files you still need to merge properly, is to search for conflict markers. (If that's OK with you, this method may be satisfactory after all.)

    Besides this, a rebase copies multiple commits, and you have not mentioned whether this particular merge conflict has occurred on the very last such commit. You need to either finish or abort the rebase before going on to other operations. (It's technically possible to do some things in the middle of a rebase, but this is tricky.)

    As for this part:

    ... come back to it later
    git checkout 'that-temp-commit-hash'
    ... after finishing
    git add .
    git commit -m 'done with feature_branch_1'
    git rebase --interactive HEAD~1
    

    Because this particular unmerged-state (which you quickly resolved "wrong" on purpose so as to do something else and come back later) was the result of a rebase rather than a merge, that sequence could work. It would be simpler, and more generally applicable, to replace the last two steps with git commit --amend, though. The --amend option tells git commit to make its new commit using the current commit's parent(s), instead of the current commit itself. This works for both normal (single-parent, non-merge) commits and actual merges (two or more parents).

    Alternatives

    Your best bet is probably to leave this work-tree alone and make another one where you handle the other issues.

    The simplest way to do that, which always works with every version of Git, is to make another clone.

    You can make the extra clone by cloning the in-progress rebase. On sensible systems that have hard links, if you clone your repository to another repository on the same file system, using local paths (git clone work/repo work/new-clone-for-fast-fix for instance, from one level up from where you have been working), Git will use hard links to the underlying packs and objects, so that you need only work-tree space.

    If your Git is relatively new (I recommend at least Git 2.6 although the feature was there in 2.5), you can use git worktree add to create a new "linked work-tree". A linked work-tree remembers its origin repository (and vice versa), but also has a private index / staging-area. You can put it on whatever branch you want and do anything you like there, including creating other branches or doing other rebases, all without disturbing your "main" work-tree and "main" index.

    这篇关于临时提交复杂合并的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆