Git 避免在数据提交时使用不同的哈希值进行(重复)提交

Git 避免在数据提交时使用不同的哈希值进行(重复)提交,git,version-control,git-svn,Git,Version Control,Git Svn,为这个冗长的问题道歉;我认为最好包括尽可能多的信息 问题: 在使用git-svn-dcommit时,如何使Gitlab托管的repo与(权威的)svn repo保持同步,并避免重复提交 安装程序 我在本地服务器上有一个svn存储库。一个远程团队(无权访问此服务器)正在使用git在存储库中开发软件的子树。出于业务目的,svn存储库在发布等方面被认为是权威的。因此,我使用git svn来保持团队的同步 存储库信息 “本地”svn回购协议svn://project 在Gitlab.mydomain.

为这个冗长的问题道歉;我认为最好包括尽可能多的信息

问题: 在使用
git-svn-dcommit
时,如何使Gitlab托管的repo与(权威的)svn repo保持同步,并避免重复提交

安装程序 我在本地服务器上有一个svn存储库。一个远程团队(无权访问此服务器)正在使用git在存储库中开发软件的子树。出于业务目的,svn存储库在发布等方面被认为是权威的。因此,我使用
git svn
来保持团队的同步

存储库信息
  • “本地”svn回购协议svn://project
  • 在Gitlab.mydomain.com上运行的Gitlab实例
  • 我是唯一同时拥有svn和Gitlab帐户的用户;git用户没有svn帐户(或服务器访问权限),反之亦然
认为上述安排不可更改,因此请不要建议其他安排。我对解决我具体的、较低层次问题的答案感兴趣,我保证很快就会有答案=)

初始克隆 存储库最初是从svn克隆到Gitlab的,如下所示:

git svn clone --prefix=svn --preserve-empty-dirs svn://project gitclone
git remote add origin https://gitlab/me/project.git
git push --set-upstream origin master
问题 当我在git分支上开发一个特性并将其集成回svn存储库时,我最终在git提交历史中发现了大量重复的提交。svn提交历史记录看起来不错。我确定这是因为使用
git svn dcommit
创建的对svn的提交与git端的“原始”提交具有不同的哈希值。以下是一个示例流程:

git开发者 Me(回购同步器) 此时,
git log
在我的(同步器)本地主机上显示与远程主机上相同的提交:

$ git log --format=oneline
commit e84af9ae738d782dfa5499cfb93b3dcb73cbf179 (HEAD -> master, origin/master)
commit 686a513eaf0083ad234e383f7e543df19431eff5
commit dc4d50bd66f36595d539c4f0c2ad70079c277315 (svn/git-svn)
commit 7e330320ac7d36331a8fb525f63fdf60f4ee070f
但是,当我提交
dcommit
时,提交
686a51
e84af9
在我的本地主机上用新的哈希值进行复制(
ed7b23
605348
):

现在,我不再跟踪Gitlab主机,原因很清楚:

$ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 2 and 2 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean

$ git log --graph --format=oneline
* 605348ec24142e2d382b295dbb34aa20c507fad9 (HEAD -> master, svn/git-svn) Update f2
* ed7b23e5abe29c09ff4483d811c1d645916e075b Add f2
* dc4d50bd66f36595d539c4f0c2ad70079c277315 <redacted>
* 7e330320ac7d36331a8fb525f63fdf60f4ee070f <redacted>

$ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 2 and 2 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean

svn日志和历史记录很好,因此我想知道是否有任何方法可以避免在执行
dcommit
时对本地主机进行“新”提交。这似乎可以避免我在这里看到的问题。或者,因为我是git新手,我可能完全错了

简而言之,这是git svn dcommit的机制:
dcommit根据git提交修改svn repo,然后重写git提交

git svn DCOMIT的解释如下所示:

…---A---B---C---D---E  master, origin/master
            |
        svn/git-svn
  • 将当前分支中的每个差异直接提交给SVN 然后重新设置或重置(取决于是否 SVN和head之间存在差异)。这将在中创建修订 Git中每个提交的SVN。该命令将向svn提交更改 基于git提交的repo

  • 这将获取您在Subversion服务器上所做的所有提交 代码,是否为每个提交Subversion,然后重写本地 Git提交以包含唯一标识符。这很重要,因为 这意味着您提交的所有SHA-1校验和都将更改

我们可以通过以下图表来说明:

在repo同步器中从git remote repo提取更改后,在git svn dcommit之前,假设repo中的提交历史记录如下:

…---A---B---C---D---E  master, origin/master
            |
        svn/git-svn
执行
git svn dcommit
时,它将根据
remotes/svn/git svn
之后的新提交
D
E
创建修订。它还将使用新的commit sha-1值重写commit
D
E
(如下图中的commit
D'
E'
)。因此,执行该命令后,提交历史记录将为:

              D'---E'  master
             /
…---A---B---C---D---E  origin/master
            |
        svn/git-svn
…---A---B---C---D'---E'  master, origin/master
            |
        svn/git-svn
因此,
git status
将显示
您的分支和“origin/master”已发生分歧


由于您不想更改排列,您可以通过git push-f origin master在repo同步器中强制推送到GitLab repo。然后提交历史记录将为:

              D'---E'  master
             /
…---A---B---C---D---E  origin/master
            |
        svn/git-svn
…---A---B---C---D'---E'  master, origin/master
            |
        svn/git-svn

简而言之,这是git svn dcommit的机制:
dcommit根据git提交修改svn repo,然后重写git提交

git svn DCOMIT的解释如下所示:

…---A---B---C---D---E  master, origin/master
            |
        svn/git-svn
  • 将当前分支中的每个差异直接提交给SVN 然后重新设置或重置(取决于是否 SVN和head之间存在差异)。这将在中创建修订 Git中每个提交的SVN。该命令将向svn提交更改 基于git提交的repo

  • 这将获取您在Subversion服务器上所做的所有提交 代码,是否为每个提交Subversion,然后重写本地 Git提交以包含唯一标识符。这很重要,因为 这意味着您提交的所有SHA-1校验和都将更改

我们可以通过以下图表来说明:

在repo同步器中从git remote repo提取更改后,在git svn dcommit之前,假设repo中的提交历史记录如下:

…---A---B---C---D---E  master, origin/master
            |
        svn/git-svn
执行
git svn dcommit
时,它将根据
remotes/svn/git svn
之后的新提交
D
E
创建修订。它还将使用新的commit sha-1值重写commit
D
E
(如下图中的commit
D'
E'
)。因此,执行该命令后,提交历史记录将为:

              D'---E'  master
             /
…---A---B---C---D---E  origin/master
            |
        svn/git-svn
…---A---B---C---D'---E'  master, origin/master
            |
        svn/git-svn
因此,
git status
将显示
您的分支和“origin/master”已发生分歧

由于您不想更改排列,因此可以fo