git - 设置一个没有rebase的commit的父级

Mar*_*ing 23 git rebase

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

      A---B---C topic

D---E---F---G master
Run Code Online (Sandbox Code Playgroud)

我知道提交A是基于提交的E,我非常肯定我已经解决了导致git无法识别该事实(使用filter-branch)的问题.我想要做的是重新连接topicmaster分支,设置E为以下的父代A:

      A---B---C topic
     /
D---E---F---G master
Run Code Online (Sandbox Code Playgroud)

git-rebase似乎对我没有用,因为提交的差异A列出了已经存在的大量文件的创建master,导致了大量的冲突.
从我对git的理解只是设置E为父母A应该足以解决所有问题.
这可能吗?如果是,我该怎么办?

kni*_*ttl 29

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

<commit sha1> <parent1 sha1> <parent2 sha1> … <parentN sha1>
Run Code Online (Sandbox Code Playgroud)

这使得git相信提交的父母与实际拥有的不同.使用filter-branch使移植物永久化(因此可以移除移植物文件):

git filter-branch --tag-name-filter cat -- --all
Run Code Online (Sandbox Code Playgroud)

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


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

git filter-branch --tag-name-filter cat -- master..
Run Code Online (Sandbox Code Playgroud)

  • Grafts在你需要它们时非常有用,但是像git中的其他一些功能一样,它们应该在你共享repo之前使用(或者你需要让其他人重新克隆).正如答案所说,只需创建grafts文件(hash-of-A,space,hash-of-E,newline)并使用"git filter-branch --tag-name-filter cat - --all"来重写历史而不更改其他提交数据 (3认同)

CB *_*ley 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
Run Code Online (Sandbox Code Playgroud)


Ada*_*ruk 6

你需要的只是这个:

git rebase --root --onto master^^ topic^^ topic
Run Code Online (Sandbox Code Playgroud)

root选项允许你包括A.

更新:

--preserve-merges如果要保留要变基的零件的分支和合并,请添加该选项.