如何在git中向提交添加父级?

时间:2015-01-28 19:11:25

标签: git merge-conflict-resolution

我最近重新绑定 - 也就是说,在master之外创建了一个新分支并合并到一个功能分支中,例如TASK-123,使用新分支TASK-123-b替换已合并到其中的要素分支。只要功能分支与master冲突,这就是我们的git工作流中的常规操作。

当我将TASK-123合并到TASK-123-b时,当然存在合并冲突,我已经解决然后提交了。新分支TASK-123-bTASK-123中的提交合并只有一个父级:master

如何修改提交,以便masterTASK-123都是其父项?我假设将涉及git rebase,但除此之外,我不知道如何在提交中添加父分支/提交。

我的提交历史目前如下:

    master -*---*-----* ...
             \         \
  TASK-123    *---*-*   \
                         \   
TASK-123-b                * ...

我希望我的提交历史记录如下:

    master -*---*-----* ...
             \         \
  TASK-123    *---*-*   \
                     \   \   
TASK-123-b            \---* ...

注意:我还没有把TASK-123-b推到遥控器上,所以对它的改装提交应该不会对我的同事造成任何问题。

2 个答案:

答案 0 :(得分:1)

你需要重新将TASK-123合并到TASK-123-b中,因为看起来它并不像你想要的那样工作。为此,在合并之前在TASK-123-b中找到提交哈希,并在那里重置分支指针:

$ git checkout -B TASK-123-b abc123

然后重复合并:

$ git merge TASK-123

如果重置分支指针,旧的合并提交将变为孤立状态,并且不会显示在日志中,除非您特别提及它作为参数。如果你想把它取回来,哈希将被记录在reflog中,或者你可以将哈希值复制到某个地方并使用checkout -B命令将它放回去,如果你决定需要它。

如果您不想再次解决冲突,请不要重置分支指针,只需再次合并:

$ git checkout TASK-123-b
$ git merge TASK-123

删除旧分支:

$ git branch -d TASK-123

答案 1 :(得分:0)

出于解释目的,假定您的提交是这样标识的:

    master -a---c-----f-----h ...
             \         \
  TASK-123    b---d-e   \
                         \   
TASK-123-b                g---i ...

TL; DR

  1. 重新设置基准,删除合并提交(提交g),并在合并之前编辑提交(提交f)。

  2. 执行git commit --amend而不是对f进行git merge e --no-commit

  3. 使用g从提交git checkout g -- .中检出所有文件。

  4. 提交并继续重新定级过程。


详细答案

如果您的提交树可以这样表示:

首先,在合并提交之前第二次使用提交哈希值进行基准化(合并提交为g,因此将使用<commit-c-sha>作为提交哈希值)

$ git rebase --interactive <commit-c-sha>

这将生成一个待办事项列表,如下所示:

pick <commit-f-sha>  <commit-f-message>   -----> change this to edit
pick <commit-g-sha>  <commit-g-message>   -----> remove this line
pick <commit-i-sha>  <commit-i-message>
...

因此,您的待办事项清单如下:

edit <commit-f-sha>  <commit-f-message>
pick <commit-i-sha>  <commit-i-message>
...

第二,创建一个没有提交的合并。

$ git merge <commit-e-sha> --no-commit

在这里,我们不想真正编辑提交f。相反,我们为替换提交g准备了一个提交。

这为我们提供了合并提交格式,并且可以灵活地对合并提交进行某些工作(例如:修改文件,修改提交属性等)。

第三,我们检出了所有从提交g到当前索引的文件,而没有移动HEAD

$ git checkout <commit-g-sha> -- .

这可以确保要提交的文件与提交g中的文件相同。

第四,继续进行更改并继续进行变基处理。例如:

$ git commit
$ git rebase --continue

您可以添加任何提交选项(但不添加--amend)或将其替换为git commit-tree命令。

此后,提交g将有两个父级,并且g之后的所有提交也将随之发生。

    master -a---c-----f-----h ...
             \         \
  TASK-123    b---d-e   \
                     \   \   
TASK-123-b            \---g---i ... and all of the following commits

注释1:指定时间戳记

进行提交时,默认情况下git使用当前时间设置提交日期。如果要指定时间戳,可以检查GIT_AUTHOR_DATEGIT_COMMITTER_DATE变量以及--date选项

ref:https://git-scm.com/docs/git-commit#_date_formats


注释2:提交树(尚未尝试)

如果您想以更灵活的方式指定提交父对象,则可以执行checkout并使用commit-tree命令而不是merge->创建提交。 checkout-> commit模式。