git - 设置提交的父级而不使用 rebase

问题描述 投票:0回答:3

我使用

git-svn
创建了 SVN 存储库的 git 镜像。 SVN 内部的结构有点不标准,因此 git 创建了一个与
master
分支没有共同提交的分支。

      A---B---C topic

D---E---F---G master

我知道提交

A
是基于提交
E
并且我非常肯定我已经解决了导致git无法识别这一事实的问题(使用
filter-branch
)。我想要做的是将
topic
重新附加到
master
分支,将
E
设置为
A
的父级:

      A---B---C topic
     /
D---E---F---G master

git-rebase
似乎对我不起作用,因为提交
A
的差异列出了
master
中已存在的大量文件的创建,导致大量冲突。
根据我对 git 的理解,只需将
E
设置为
A
的父级应该足以解决所有问题。
这可能吗?如果是的话我该怎么办?

git rebase
3个回答
29
投票

看看移植物(移植物文件可以在

.git/info/grafts
中找到)。格式非常简单:

<commit sha1> <parent1 sha1> <parent2 sha1> … <parentN sha1>

这使得 git 相信提交具有与实际不同的父级。

在较新版本的 Git 中,您希望使用 replace 机制 将历史移植到一起:

git 替换 --graft …

无论选择哪种方法(移植文件或替换参考),都使用过滤器分支使移植永久化(因此可以删除移植文件):

git filter-branch --tag-name-filter cat -- --all

请注意,这重写了存储库的历史记录,因此不应在共享存储库上使用!


例如,如果您只想重写正在嫁接到 master 分支上的提交的历史记录,请使用以下命令:

git filter-branch --tag-name-filter cat -- master..

8
投票

根据你的图表(尽管我担心你的意思是“我非常肯定我已经解决了导致 git 无法识别这一事实的问题(使用

filter-branch
)。”),你应该能够执行如下操作。

# checkout A
git checkout A

# Reset the branch pointer to E so that E is the parent of the next commit
# --soft ensures that the index stays the same
git reset --soft E

# Remake the commit with the E as the parent, re-using the old commit metadata
git commit -C HEAD@{1}

# Rebase the topic branch onto the modified A commit (current HEAD)
git rebase --onto HEAD A topic

7
投票

您所需要的就是这个:

git rebase --root --onto master^^ topic^^ topic

root 选项可让您包含 A。

更新:

如果您想保留要变基的部分的分支和合并,请添加

--preserve-merges
选项。

© www.soinside.com 2019 - 2024. All rights reserved.