Git重置行为

时间:2015-02-21 17:24:50

标签: git merge rebase

我有以下情况:

分支有一个稳定版本的应用程序。

开发人员A最近创建了一个名为 branch-a 的功能分支,其中有几个提交(让他们 a-1 a-2 a-3 )。此处实现的功能基于 master 的最新代码,目前已经过充分测试。

开发人员B有一个名为 branch-b 的功能分支,有几个提交(例如, b-1 b-2 ,的 b-3 )。出于某种原因,B先生在他的功能分支中有一个过时的版本(基于主人的一周或两个星期的状态)并且根本没有测试代码。

两位开发人员都使用以下方法将其功能分支合并为master:

  1. git checkout master
  2. git pull origin master
  3. git merge branch-X(其中X = a,b)
  4. git push origin master
  5. 没有使用rebase命令。首先,这个序列由B完成,接下来是A。

    当我(开发人员C)从主人那里撤出时,我在 git log 中看到过:

    • a-merge:由开发者A与主人合并
    • A-3
    • A-2
    • A-1
    • b-3(是的,这个提交恰好在合并之后)
    • b-merge-conflicts:由开发人员B与master合并(数千个文件冲突)
    • B-2
    • B-1
    • master-stable:之前的稳定提交

    结果B先生以某种方式迫使旧版本的代码在合并时覆盖稳定版本(导致b-merge-conflicts commit)。

    现在我想重写历史并保存 b-1 + b-3 + a-1 + a- 2 + a-3 更改并撤消 b-2 b-merge-conflicts a-merge < /强>

    我的想法是撤消几个顶级提交,直到 b-1 ,然后使用cherry-pick修补应用 b-3 a-1 < / strong>, a-2 a-3 提交给新主人。

    但是当我尝试时:

    git reset --hard HEAD~7 我可以看到一个只包含旧提交的历史记录(在master-stable之前),而不包含branch-a和branch-b的历史记录。

    当我尝试:

    git reset --hard HEAD~2

    我可以在历史记录中看到顶部只有主稳定提交,但不是我想要的 a-2

    看起来git reset在HEAD之后没有翻译一个数字作为一些重置提交(因为我从文档中得到了不应该),但是作为一些HEAD改变了git pull(在我的例子中有2个) )。

    如何正确撤消前7次提交b-2 .. a-merge并重写从b-1开始的历史记录?

    UPDATE在评论中提到

    我用过(没有--all排除其他信息)

    git log --oneline --decorate --graph

    *   ef7d93f Merge with master by Developer A
    |\
    | * 2b9dd31 b-4
    | * 924a452 b-3
    | * 1f9489d b-2
    | *   e3cd7a6 Merge by Developer B [2]: Merge branch 'master' from https://github.com ....
    | |\
    | * | aece506 Merge by Developer B [1]: merge branch
    | * | 487e7ee b-1
    * | | d9404f8 a-1
    | |/
    |/|
    * | 9b202ce master-stable last commit
    

2 个答案:

答案 0 :(得分:2)

git log骗你。它呈现Git历史,好像它是线性的,它向你显示日期顺序的提交。这不是很有用。通过向您展示提交的树(图表确实),git log --graph --decorate将为您提供更清晰的故事。根据我的工作情况,您的存储库看起来像这样。

                                       a1 - a2 - a3
                                      /            \
origin c1 - c2 - c3 - c4 - b-merge - b3 -------- a-merge [master]
        \                  /
         b1 -------------b2

正如您所看到的,“返回七次提交”可以有多种解释。这就是为什么你应该避免使用这种表示法来移动多个提交,而是引用提交ID。

你想要的是这个。

                  a1 - a2 - a3 [branch-a]
                 /
c1 - c2 - c3 - c4 [master]
                 \
                  b1 - b3 [branch-b]

要到达那里,在c4上创建A和B分支,这样你就可以建立一个地方。

git branch branch-a c4
git branch branch-b c4

             [branch-b]         a1 - a2 - a3
             [branch-a]        /            \
c1 - c2 - c3 - c4 - b-merge - b3 -------- a-merge [master]
  \                  /
   b1 -------------b2

现在检查那些分支机构,樱桃选择适当的更改,解决任何冲突。

                  b1b - b3b [branch B]
                 / 
                |   a1a - a2a - a3a [branch A]
                |  /  
                | /                a1 - a2 - a3
                |/               /            \
c1 - c2 - c3 - c4 - b-merge - b3 -------- a-merge [master]
  \                  /
   b1 -------------b2

这可能看起来像一团糟,但是现在结账大师和git reset --hard c4以及主人在合并时保持活力的所有混乱将会消失(这是一个白色的谎言,起源/主人将保持可见,直到你推,Git也不会实际提出几周的提交。)

                  b1b - b3b [branch B]
                / 
               |  a1a - a2a - a3a [branch A]
               |/
c1 - c2 - c3 - c4 [master]

现在您可以正常合并A和B.当你完成后,你必须push --force,因为主人不是原籍/主人的孩子。

这只是实现目标的一种方式。重要的是能够可视化存储库图形,您希望它在哪里,以及哪些命令将对其进行转换。

答案 1 :(得分:1)

我不确定HEAD~因为我通常使用HEAD^

但您不需要使用该表示法。您只需提供提交的十六进制SHA-1哈希值,或者前七个左右的数字。

git reset --hard 72abfd4