如何告诉Git两个提交在不相交的历史中实际上是相同的?

RSF*_*on7 12 git version-control git-svn

我有一个Git repo,它是来自另一个Git repo的克隆,它是来自巨型SVN repo的克隆.我们可以从SVN更新其他Git repo并从它提交到SVN,但是与另一个用户一起提交.

我想用我自己的用户直接将我的本地提交发布到SVN repo.

这就是我尝试过的:我手动创建了git-svn分支,将其添加到.git/config

[branch "master"]
[svn-remote "svn"]
        url = https://url/to/svn/trunk/repo_name
        fetch = :refs/remotes/git-svn
Run Code Online (Sandbox Code Playgroud)

然后git svn fetch,下载了32k提交.

但我最终得到了两个不相关的历史:

  1. 一个来自Git:
    1. 从提交开始674c35a,表示原始克隆点处的SVN repo的状态.
    2. 分支master始终与SVN同步(通过其他Git仓库).
    3. 该分支dev有我们目前的发展,应该合并master(通常被压扁),然后回到SVN回购.
  2. 一个用于SVN回购:
    1. 从正确的初始提交开始.
    2. 它有30k +提交.
    3. Git最初从SVN [ fb1b9c7] 克隆的提交(但只有前一次提交的diff,而不是整个repo作为开始提交).
    4. 然后应该是共同的提交(100+)git/origin/master.

我如何告诉Git启动commit(674c35a)实际上与SVN commit(fb1b9c7)相同?那么Git可以以某种方式理解master克隆之后的提交实际上是一样的git-svn吗?

我试图改变--onto,如这里所解释的那样,但这不是我想要的(提交不在分支的顶部).

Sco*_*don 0

你的历史可能是这样的:

*--*--*--fb1b9c7--*--*--* [git-svn] (version of master from SVN)

         674c35a--*--*--* [master] (version of master from Git)
                         \
                          *--*--*--* [dev]
Run Code Online (Sandbox Code Playgroud)

看起来您有两个问题:您的 Git 历史记录不包含完整 SVN 历史记录中的 30k+ 提交,并且dev基于(不完整的)Git 历史记录而不是 SVN 版本。

由于fb1b9c7== 674c35a,您应该能够执行以下操作:

git rebase --onto git-svn master dev
Run Code Online (Sandbox Code Playgroud)

我的实验表明,git rebase并不关心目标分支 ( git-svn) 与基础分支 ( ) 没有相同的历史记录master。SVN 仅存储差异也没关系,因为 git-svn 会在获取期间将这些差异转换为真正的 Git 提交。

由于历史包含相同的内容,您甚至应该能够执行以下操作:

git checkout dev
git rebase git-svn
Run Code Online (Sandbox Code Playgroud)

之后,您可以删除master该树并让其稍后被垃圾收集。(如果您仍然需要单独的分支,请在删除原始分支后master执行。)git checkout -b master git-svnmaster

当你说:

(提交不在分支顶部)

我假设您指的是提交fb1b9c7674c35a. 然而,这些提交被埋在历史中并不重要,因为我们将选择一个 ( fb1b9c7) 使用,并让另一个被垃圾收集,如上所述。