git-设置提交';没有重基的父对象

git-设置提交';没有重基的父对象,git,rebase,Git,Rebase,我使用gitsvn创建svn存储库的git镜像。SVN内部的结构有点不标准,因此git创建了一个分支,该分支与主分支没有公共提交 A---B---C topic D---E---F---G master 我知道commitA是基于commitE的,我很肯定我已经解决了导致git无法识别这一事实的问题(使用过滤器分支)。我要做的是将主题重新附加到主分支,将E设置为A的父级: A---B---C topic / D---E---F---G master git

我使用
gitsvn
创建svn存储库的git镜像。SVN内部的结构有点不标准,因此git创建了一个分支,该分支与
分支没有公共提交

      A---B---C topic

D---E---F---G master
我知道commit
A
是基于commit
E
的,我很肯定我已经解决了导致git无法识别这一事实的问题(使用
过滤器分支
)。我要做的是将
主题
重新附加到
分支,将
E
设置为
A
的父级:

      A---B---C topic
     /
D---E---F---G master
git-rebase
似乎对我不起作用,因为提交的差异
A
列出了在
master
中已经存在的大量文件的创建,导致了大量冲突。
根据我对git的理解,仅仅将
E
设置为
A
的父级就足以解决所有问题。
这可能吗?如果是,我该怎么做呢?

看一下移植物(移植物文件可以在
.git/info/grafts
中找到)。格式非常简单:

<commit sha1> <parent1 sha1> <parent2 sha1> … <parentN sha1>
请注意,此重写存储库的历史记录,因此不应用于共享回购


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

git filter-branch --tag-name-filter cat -- master..
根据您的图表(尽管我很担心您所说的“我很肯定我已经解决了导致git无法识别该事实的问题(使用
过滤器分支
)”),您应该能够执行以下操作

# 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
您所需要的就是:

git rebase --root --onto master^^ topic^^ topic
根选项允许您包含一个

更新:


如果要保留正在重定基址的部件的分支和合并,请添加
--preserve merges
选项。

是否有机会重新初始化将“分支”指向正确目录的svn的git镜像?或者先修复svn结构?实际上回购协议使用了标准的主干/标签/分支布局。然而,我试图修复的分支是通过只复制trunk的一个子路径创建的——我猜这对git svn来说有点太多了,无法处理。rebase有一个
root
选项。如果需要,将其与
上的
保留合并一起使用。另请参见:如果不需要,请不要使用嫁接或过滤分支。嫁接非常有用,因为你需要它们,但与git中的其他一些功能一样,它们应该在共享repo之前使用(或者你需要让其他人重新克隆)。正如答案所说,只需创建grafts文件(hash-of-A、space、hash-of-E、newline)并使用“git filter branch--tag name filter cat--all”重写历史而不更改其他提交data@JodaStephen你应该在答案中加上这个。您知道如果存储库已发布,那么这样做是否可以,但是您正在处理的移植只涉及新的、未发布的提交?直到git grafts。谢谢出于某种原因,最近的合并提交在我的回购中缺少父级。这挽救了这一天。谢谢如果您有一个线性历史记录,如果它有合并提交,您必须使用
--preserve merges
,并且您必须手动重新解决合并冲突,这将非常有用。是的。我会更新答案。还有一次我回答了同样的问题,我包括了这个选项。@AdamDymitruk:关于你的答案的一个问题:你在使用Windows吗?我觉得“^^”这个词很奇怪。这是父级的父级,还是第一个“^”是第二个“^”的DOS转义?(注:如果是后者,那么,
git-rebase-root--to“master^”“topic^”topic
可能是更好的语法。)另一方面,由于使用了
--root
,它可能确实是“祖父母的”。谢谢。在bash中,第一个父对象的第一个父对象几乎可以正常工作,但在该操作之后,topic最终无法跟踪远程源/主题!
git rebase --root --onto master^^ topic^^ topic