【问题标题】:How to fix and merge this git tree?如何修复和合并这个 git 树?
【发布时间】:2012-03-02 10:25:24
【问题描述】:

这是我的 gitk(我认为从这个问题得到了改进,谢谢@amber:Merging commits from branch to master -> odd-looking tree):

分支frontend 在左侧。你可以在右下角看到masterremotes/origin/master的提示为黄色。


我需要做两件事,我已经经历了大约 36 小时的麻烦:

  1. 如何开始将frontend 的提交添加到master(一个接一个,先“添加延迟”)以便我可以推送它们?我不想合并整个分支,因为涉及大量代码,而且两个分支都有工作树,我不想打扰。
  2. 我似乎在frontend 周围有两个相同的“批量更新”条目,顶部/左侧没有分支。我怎样才能摆脱顶部的无分支 bulk update 东西,所以有 2 个干净的分支?我希望它看起来像这样:

    |  # frontend
    |  # Bulk update.
    |  # ...commits...
    |  # move this frontend commit to master
    |  |  #master's changes
    |  |  #master, remotes/origin/master, remotes/staging/master
    

我真的很想自己做这件事,但最后一天半的挣扎表明,我输入的内容中最轻微的不准确往往会导致更加混乱。

【问题讨论】:

    标签: git git-branch


    【解决方案1】:

    您应该将问题拆分为两个单独的 SO 问题,以遵循问答格式。话虽这么说:

    1. 结帐主并使用git cherry-pick -e <sha>,其中<sha> 是对您要添加到masterfrontend 中的每个签入的引用。所以你会首先使用git cherry-pick -e <sha of 'adding delay'>。您可以按照您想要的任何顺序进行挑选,以便您可以从frontend 以与master 不同的顺序安排您想要的签到。见http://technosophos.com/content/git-cherry-picking-move-small-code-patches-across-branches

      另一种方法是变基,但如果您不习惯该机制,这可能比使用cherry-pick 更令人困惑。我建议你先在你的 repo 的克隆上尝试这种方法。您可以随时撤消我所说的,但如果您已经时间紧迫,您不想浪费时间弄清楚如何做到这一点。

      首先结帐frontend,然后创建一个新分支tmp(因为您不想实际删除前端)。

      然后执行git rebase -i --onto master master tmp。这将打开一个编辑器来删除和重新排列将在主签入之后以您希望在前端分支中的任何顺序提交的签入。

      当你完成 tmp 将是你想要掌握的地方,所以检查 master 并执行 git reset --hard tmp 并删除 tmp 分支 git branch -d tmp

      Pro Git 这本书有很好的关于 rebase 的信息,但是我已经将这些概念应用到了您的用例中。 http://progit.org/book/ch3-6.html

    2. 首先确保列出的批量更改实际上是重复的。您可以通过git diff <sha of bulk1> <sha of bulk2> 来查看差异。如果它相同或不同,从列表中删除它的关键是删除你在某个时候给 git 的存储。如果它不是重复的,请确保在删除存储之前决定如何处理差异。

      在分支中执行 git stash pop,如果您真的不想要保存在 stash 中的内容,请执行 git reset --hard HEAD。那时,如果您重新运行 gitk(刷新不会显示此内容),您将看到左上角的那些条目已删除。您的 gitk 图表显示 stash 是从 master 索引的,因此我将在其中使用 stash,但您最清楚在哪个分支,masterfrontend,您可能想要使用它。

      您也可以只使用git stash pop 并提交您正在保存的更改,它就会消失。 gitk 中存在分支历史的唯一原因是显示 git 如何知道如何重新创建存储中的差异。一旦您弹出该存储区,它就会忘记该存储区的任何祖先,这就像将存储区重新定位到您弹出它的位置。

      @Jefromi 有一种更简洁的方法,如果您不需要它们的任何东西,只需删除它们,这些不是他的确切词,而是他的建议:

      使用git stash clear 删除所有存储。您可以使用git stash drop stash@{n} 来删除那个。使用 git stash list 查看 n 应该是什么。

    【讨论】:

    • 这几乎都是正确的。不过,你对第二个问题有点偏离。提交不仅仅是快照——它们还包括元数据。这两个提交可能有相同的树,但不同的消息(和时间戳)。而且你遗漏了一件重要的事情:该提交的第二个版本几乎肯定是由git commit --amend 创建的;重要的是要知道修改一个提交会创建一个新的提交,而旧的提交是悬空的。在这种情况下,它被基于它的 stash 固定在那里。
    • 至于弹出存储:您可能不想在 master 上执行此操作,因为您可能隐藏了在前端分支上下文中有意义的工作。如果它的内容很重要,您可能需要在弹出它之前检查前端。如果你想扔掉它,你可以使用git stash clear 删除所有存储,或使用git stash drop stash@{n} 删除那个(使用git stash list 查看n 应该是什么)。
    • @Jefromi 谢谢,我不记得还有什么其他事情可能会改变提交的唯一性。我更新了我的答案。
    • @Jefromi 存储日志图表明存储已被推送到主服务器上,因此我不清楚他们可能想在哪里弹出它。我编辑了答案以表明他们应该知道他们想要弹出任何更改的分支。我还添加了清除和删除特定存储的命令。
    猜你喜欢
    • 2018-09-19
    • 1970-01-01
    • 2017-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多