Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git 重定基址以更改合并提交的父级_Git_Git Rebase - Fatal编程技术网

Git 重定基址以更改合并提交的父级

Git 重定基址以更改合并提交的父级,git,git-rebase,Git,Git Rebase,假设我有下面的历史记录,上面的一行是主分支,下面的一行是一个功能分支,它在一个点上与主分支合并,而D只是恢复C(这意味着B和D中的工作目录是相同的) 我想在F合并之前,将C及其还原D添加到历史记录中,如下所示: A---B---C---D master \ \ E-----------F'--G' feature $ git checkout <sha1> # Use D or E's sha-1 here.

假设我有下面的历史记录,上面的一行是主分支,下面的一行是一个功能分支,它在一个点上与主分支合并,而
D
只是恢复
C
(这意味着
B
D
中的工作目录是相同的)

我想在
F
合并之前,将
C
及其还原
D
添加到历史记录中,如下所示:

A---B---C---D           master
 \           \
  E-----------F'--G'    feature
$ git checkout <sha1>  # Use D or E's sha-1 here.
                       # Note: whichever you use will
                       # be the first parent of our new
                       # merge; choose based on that.
$ git merge --no-commit <sha1>  # use the remaining sha-1 here
[ignore resulting stuff]
$ git rm -rf .         # Note: assumes you're in top dir of work tree
$ git checkout <sha1-of-F> -- .
$ git commit           # Create merge commit F'
我不想更改
E
(这实际上是一系列的提交)

git-rebase--D B上的
(如建议)会导致合并冲突(有或没有
--保留合并


有什么方法可以实现我想要的吗?

大多数方法都会有些痛苦。使用
git filter branch
,除了filter branch本身是痛苦的之外,还有一个中等程度的无痛版本。:-)(您需要筛选提交
F
G
,并编写一个提交筛选器,用于替换
F'
所需的新父级,并让筛选器分支操作替换
G
的父级)

我认为不使用低级命令的最简单方法就是创建一个新的合并,然后将
G
重设为新合并的基础。新合并可能有冲突,但我们不在乎,我们只想获取旧合并的树,我们可以这样做:

A---B---C---D           master
 \           \
  E-----------F'--G'    feature
$ git checkout <sha1>  # Use D or E's sha-1 here.
                       # Note: whichever you use will
                       # be the first parent of our new
                       # merge; choose based on that.
$ git merge --no-commit <sha1>  # use the remaining sha-1 here
[ignore resulting stuff]
$ git rm -rf .         # Note: assumes you're in top dir of work tree
$ git checkout <sha1-of-F> -- .
$ git commit           # Create merge commit F'
$git checkout#在这里使用D或E的sha-1。
#注意:无论您使用哪一种,都将
#成为我们新家庭的第一个家长
#合并;基于此进行选择。
$git merge--不提交#在此处使用剩余的sha-1
[忽略结果]
$git rm-rf.#注意:假设您位于工作树的顶部目录中
$git结帐--。
$git提交#创建合并提交F'
第一个
checkout
使用一个SHA-1使您处于分离状态,
merge--no commit
启动与另一个SHA-1的合并过程,
git rm-rf。
丢弃合并树和任何冲突,
git checkout--。
填充上一次合并的索引和工作树。最后的
git提交
创建了merge
F'
,其树与merge
F
相同,但父级不同

此时(仍然具有分离的头部),您可以重新设置基址(或樱桃选择)提交
G
(或多个提交
G
),然后强制分支指向新图形的顶端。我建议使用
git-rebase--在头部
上,但我没有用分离的头部进行测试,至少有一种方法可能出错(将
头部
解析为ID太晚)

低级别的
git commit tree
命令实际上可能更简单,尽管您必须使用
git update ref
拼写分支名称。[编辑:可能不太正确,你想要的两个父母是
D
E
,而不是
D
B
。同样,把你想要的一个作为第一个父母放在第一位。]


使用更熟悉的命令的优点是它们更熟悉。

类似于
git update ref feature\u branch$(git commit tree-pe-p B-m“fakeout merge”F^{tree})
然后
git cherry pick G
应该work@AndrewC复制提交消息
git show-s--pretty=%B F
|git提交树等`。非常感谢!我能够让这两种方法非常直接地工作(只需对
G
提交使用
cherry pick
)。是的,哎呀,从错误的图表中提取了家长。无论如何,谢谢@Andrew C-我明白你的意思了。