通过 GIT 使用(不同的)SVN 远程存储库的正确方法是什么

发布于 2024-10-12 16:24:07 字数 4916 浏览 5 评论 0原文

环境:

  • 一个名为 svn+ssh://yourserver/svn/prj 的附近
  • SVN 存储库 一个名为 svn+ssh://theirserver/svn/prj 的外部
  • SVN 存储库 一个名为“myrep”的本地 git 存储库,它是一个 git-svn附近的克隆
    • 使用:git svn clone -R附近svn -s svn+ssh://yourserver/svn/prj所以有一个主干和一些分支(都是从主干r3分叉/复制的。< /里>
$ git branch -a
* master
 remotes/b1
 remotes/b2
 remotes/trunk

我们来了。

在我的 master(这是来自远程/主干的分支)中进行的简单更改被添加,然后提交,然后通过 git svn dcommit“推送”到 SVN

。远的。 树现在看起来像这样:

$ git log --graph --oneline --all
* 1e6277f change 3 in b2
* 7623755 two new branches
| * 7901fad change3 in b1
| * e83f135 two new branches
|/  
| * 6fac7ad change 3
| * 5858495 new file test3
| * 4cdf2ed change2
| * 511ed7a change1
|/  
* d5c68ab init

结论 1:

git svn dcommit 将本地 master 分支中所做的所有更改发送到远程/主干 SVN,然后对其进行变基 输出和树如下所示:

$ git add test

$ git ci
[master 8a03901] modified test via git for SVN trunk
 1 files changed, 1 insertions(+), 1 deletions(-)

$ git svn dcommit
Committing to svn+ssh://yourserver/svn/prj/trunk ...
    M   test
Committed r9
    M   test
r9 = 542eb78f841fc1a4d12f4a72f68e40e3069f3309 (refs/remotes/trunk)
No changes between current HEAD and refs/remotes/trunk
Resetting to the latest refs/remotes/trunk

$ git log --graph --oneline --all
* 542eb78 modified test via git for SVN trunk
* 6fac7ad change 3
* 5858495 new file test3
* 4cdf2ed change2
* 511ed7a change1
| * 1e6277f change 3 in b2
| * 7623755 two new branches
|/  
| * 7901fad change3 in b1
| * e83f135 two new branches
|/  
* d5c68ab init

问题 1:

  • 为什么 init 是 b1 和 b2 的父级?
  • 为什么我的主人与“init”树相同,它不应该是远程树的“分支”吗?合并状态仍然是“未合并”,因为只完成了变基

问题2:

修补远程/b1某些更改的正确/最佳方法是什么

我的方式:使用git checkout -b myb1创建本地分支myb1 Remotes/b1 然后 $ git diff master^..master | patch -p1 then add, ci, dcommit

问题 3:

如何获取有关我的分支所属/分叉的远程路径的信息?配置没有告诉我任何有关它的信息:

$ git config --get-regexp svn-remote
svn-remote.nearbysvn.url svn+ssh://yourserver/svn/prj
svn-remote.nearbysvn.fetch trunk:refs/remotes/trunk
svn-remote.nearbysvn.branches branches/:refs/remotes/
svn-remote.nearbysvn.tags tags/:refs/remotes/tags/

问题4:

这有点棘手: 第二个(外部)SVN 现在是第一个 SVN 的“副本”,但有一个例外:外部也可能被其他人使用。 目前,在“附近”中所做的所有更改都必须在外部更改中再次完成(修补第二个工作副本中的文件,依此类推...

如果此删除 SVN 现在是第二个远程 SVN 存储库,那么最佳实践是什么“通过 git 合并优化”?

是的,有一些很棒的人会使用 BeyondCompare 等(参见 如何比较 Git 存储库中的源代码与 SVN 存储库中的源代码)。但这不是我最喜欢的“合并”方式,

我建议我需要: * 本地分支,如 myb1、master、master2 * 为我的工作创建分支/分支,例如 master-taskX (git checkout -b master-taskX) * 然后我可以使用合并将我的更改返回到主版本,然后提交它们?

我很快就会很高兴收到一些 git-svn 专家的来信;)

谨致问候, ~Marcel

附录:

仅供参考:这是“附近”的初始 SVN 历史记录:

------------------------------------------------------------------------
r8 | konqi | 2011-01-19 17:48:51 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /branches/b2/test3

change 3 in b2

------------------------------------------------------------------------
r7 | konqi | 2011-01-19 17:48:42 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /branches/b1/test3

change3 in b1

------------------------------------------------------------------------
r6 | konqi | 2011-01-19 17:46:07 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /trunk/test3

change 3

------------------------------------------------------------------------
r5 | konqi | 2011-01-19 17:36:13 +0100 (Mi, 19 Jan 2011) | 3 lines
Changed paths:
   A /branches/b1 (from /trunk:1)
   R /branches/b1/test (from /trunk/test:2)
   R /branches/b1/test2 (from /trunk/test2:3)
   A /branches/b1/test3 (from /trunk/test3:4)
   A /branches/b2 (from /trunk:1)
   R /branches/b2/test (from /trunk/test:2)
   R /branches/b2/test2 (from /trunk/test2:3)
   A /branches/b2/test3 (from /trunk/test3:4)

two new branches


------------------------------------------------------------------------
r4 | konqi | 2011-01-19 17:30:05 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   A /trunk/test3

new file test3

------------------------------------------------------------------------
r3 | konqi | 2011-01-19 17:28:46 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /trunk/test2

change2

------------------------------------------------------------------------
r2 | konqi | 2011-01-19 17:28:34 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /trunk/test

change1

------------------------------------------------------------------------
r1 | konqi | 2011-01-19 17:28:10 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   A /branches
   A /tags
   A /trunk
   A /trunk/test
   A /trunk/test2

init

------------------------------------------------------------------------

The environnement:

  • A nearby SVN Repository called svn+ssh://yourserver/svn/prj
  • An external SVN Repository called svn+ssh://theirserver/svn/prj
  • A local git repository that called "myrep" which is a git-svn clone of the nearby one
    • made with: git svn clone -R nearbysvn -s svn+ssh://yourserver/svn/prj so there is a trunk and some branches (both forked / copied from trunk r3.
$ git branch -a
* master
 remotes/b1
 remotes/b2
 remotes/trunk

Here we come.

Simple changes made in my master (which is a branch from the remotes/trunk) are added, then committed, then "pushed" to the SVN via git svn dcommit.

So good, so far.
The tree now looks like this:

$ git log --graph --oneline --all
* 1e6277f change 3 in b2
* 7623755 two new branches
| * 7901fad change3 in b1
| * e83f135 two new branches
|/  
| * 6fac7ad change 3
| * 5858495 new file test3
| * 4cdf2ed change2
| * 511ed7a change1
|/  
* d5c68ab init

Conclusion 1:

git svn dcommit sends all changes made in my local master branch to the remotes/trunk SVN, then rebase it
The output and tree looks like this:

$ git add test

$ git ci
[master 8a03901] modified test via git for SVN trunk
 1 files changed, 1 insertions(+), 1 deletions(-)

$ git svn dcommit
Committing to svn+ssh://yourserver/svn/prj/trunk ...
    M   test
Committed r9
    M   test
r9 = 542eb78f841fc1a4d12f4a72f68e40e3069f3309 (refs/remotes/trunk)
No changes between current HEAD and refs/remotes/trunk
Resetting to the latest refs/remotes/trunk

$ git log --graph --oneline --all
* 542eb78 modified test via git for SVN trunk
* 6fac7ad change 3
* 5858495 new file test3
* 4cdf2ed change2
* 511ed7a change1
| * 1e6277f change 3 in b2
| * 7623755 two new branches
|/  
| * 7901fad change3 in b1
| * e83f135 two new branches
|/  
* d5c68ab init

Question 1:

  • why is init the parent for b1 and b2?
  • why is my master the same as the "init" tree, shouldn't it be a "branch" from the remote one? The merge status is still "unmerged" cause only a rebase was done

Question 2:

what is the correct / best way to patch some changes to the remote/b1

my way: create a local branch myb1 with git checkout -b myb1 remotes/b1 then $ git diff master^..master | patch -p1 then add, ci, dcommit

Question 3:

how can I get informations about my branches to which remote paths they belong to / are forked from? config doesn't tell me anything about it:

$ git config --get-regexp svn-remote
svn-remote.nearbysvn.url svn+ssh://yourserver/svn/prj
svn-remote.nearbysvn.fetch trunk:refs/remotes/trunk
svn-remote.nearbysvn.branches branches/:refs/remotes/
svn-remote.nearbysvn.tags tags/:refs/remotes/tags/

Question 4:

This is some more tricky:
The second (external) SVN is now a "duplicate" of the first one, with one exception: external might be used by others too.
Currently all changes made in "nearby" has to be done again in the external one (patching files in a second working copy, and so on...

If this remove SVN is now a second remote SVN repository, what is best practice to "optimize" this with merges via git?

Yes, there are some great guy'S who will use BeyondCompare, etc (see How to compare source in Git repository between source in SVN repository). But this is NOT my favorite way to "merge"

I propose I need:
* local branches like myb1, master, master2
* forks / branches of this for my work like master-taskX (git checkout -b master-taskX)
* then I might use merge to get my changes back to master and then dcommit them??

I'll be glad to hear from some git-svn experts soon ;)

With kind regards,
~Marcel

Appendix:

FYI: here is the inital SVN history for "nearby":

------------------------------------------------------------------------
r8 | konqi | 2011-01-19 17:48:51 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /branches/b2/test3

change 3 in b2

------------------------------------------------------------------------
r7 | konqi | 2011-01-19 17:48:42 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /branches/b1/test3

change3 in b1

------------------------------------------------------------------------
r6 | konqi | 2011-01-19 17:46:07 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /trunk/test3

change 3

------------------------------------------------------------------------
r5 | konqi | 2011-01-19 17:36:13 +0100 (Mi, 19 Jan 2011) | 3 lines
Changed paths:
   A /branches/b1 (from /trunk:1)
   R /branches/b1/test (from /trunk/test:2)
   R /branches/b1/test2 (from /trunk/test2:3)
   A /branches/b1/test3 (from /trunk/test3:4)
   A /branches/b2 (from /trunk:1)
   R /branches/b2/test (from /trunk/test:2)
   R /branches/b2/test2 (from /trunk/test2:3)
   A /branches/b2/test3 (from /trunk/test3:4)

two new branches


------------------------------------------------------------------------
r4 | konqi | 2011-01-19 17:30:05 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   A /trunk/test3

new file test3

------------------------------------------------------------------------
r3 | konqi | 2011-01-19 17:28:46 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /trunk/test2

change2

------------------------------------------------------------------------
r2 | konqi | 2011-01-19 17:28:34 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   M /trunk/test

change1

------------------------------------------------------------------------
r1 | konqi | 2011-01-19 17:28:10 +0100 (Mi, 19 Jan 2011) | 2 lines
Changed paths:
   A /branches
   A /tags
   A /trunk
   A /trunk/test
   A /trunk/test2

init

------------------------------------------------------------------------

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

稀香 2024-10-19 16:24:07
  • 为什么 init 是 b1 和 b2 的父级?
    • 因为在 svn 的历史中,init 创建了“branches”文件夹,并且 git-svn 将其视为所有分支提交的父级。最后,这只是一个约定,对于任何功能来说并不是特别重要。
  • 为什么我的主人与“init”树相同,它不应该是远程树的“分支”吗?
    • 它是来自远程的分支,但 git 提交不是分支的一部分,这不是 git 的想法。对于 git 来说,“分支”是指向提交的指针,它隐含地包括所有父提交。提交本身不知道也不关心它们属于哪个分支。
  • 合并状态仍然是“未合并”,因为只完成了变基
    • (不知道你在说什么)

问题 2:

  • 修补远程/b1 的某些更改的正确/最佳方法是什么
    • 如果您没有进行完全合并,请尝试 gitcherry-pick (请参阅 githelpcherry-pick);这或多或少是一种更简单、更可靠的方式来完成您已经在做的事情

问题3:

  • 我如何获取有关它们所属/分叉的远程路径的分支的信息?
    • 您可以检查它们并运行 git svn info,或者对提交消息底部的 svn 行使用 git log 和 grep,其中列出了源的路径和版本。后者是 git-svn 的 svn 提交来源的权威来源。

问题 4:

  • 这有点棘手:第二个(外部)SVN 现在是第一个 SVN 的“重复”,但有一个例外:外部也可能被其他人使用。目前,在“附近”中所做的所有更改都必须在外部更改中再次完成(在第二个工作副本中修补文件,等等......

    如果此删除 SVN 现在是第二个远程 SVN 存储库,那么通过 git 合并来“优化”此存储库的最佳实践是什么?

    是的,有一些很棒的人会使用 BeyondCompare 等(请参阅如何在 SVN 存储库中的源之间比较 Git 存储库中的源)。但这不是我最喜欢的“合并”方式

    我建议我需要: * 本地分支,如 myb1、master、master2 * 为我的工作分叉/分支,如 master-taskX (git checkout -b master-taskX) * 然后我可能会使用合并来取回我的更改掌握然后提交它们?

    • 我在同一台机器上有两个 git 存储库,其中一个(我们称其为 A 和 B)设置为跟踪每个 svn 存储库。在 A 上进行开发,设置跟踪附近的存储库。在 git svn clone 之后,让 B 将 A 注册为常规 git“remote”(git remote add /path/to/repo/A)。一旦您准备好在 A 上进行提交,就可以在 B 中使用 git fetch -f 将它们带到那里。然后在A中git svn dcommit;在 B 中使用类似 git checkout -b temp A/master 的东西; git rebase --onto trunk HEAD^; git svn dcommit; git checkout 大师; gitbranch -D temp 将更改提交到存储库 B。要提交多个版本,您需要调整 rebase 命令中的克拉数。

请注意,根据我的经验,git merge 与 git-svn 配合得不好,因此您可能希望坚持使用上述技术,这些技术不会在 git 历史记录中创建双父提交。

  • why is init the parent for b1 and b2?
    • Because in svn's history, init creates the 'branches' folder, and git-svn regards it as the parent of all branch commits. In the end it's just a convention and not particularly important to any functionality.
  • why is my master the same as the "init" tree, shouldn't it be a "branch" from the remote one?
    • It is a branch from the remote, but git commits aren't part of branches, that's not how git thinks. To git, a "branch" is a pointer to a commit, that includes by implication all parent commits. The commits themselves don't know or care what branch(es) they are part of.
  • The merge status is still "unmerged" cause only a rebase was done
    • (no idea what you're talking about here)

Question 2:

  • what is the correct / best way to patch some changes to the remote/b1
    • If you aren't doing a full merge, try git cherry-pick (see git help cherry-pick); it's more or less an easier and more reliable way of doing what you are doing already

Question 3:

  • how can I get informations about my branches to which remote paths they belong to / are forked from?
    • You could check them out and run git svn info, or use git log and grep for the svn line at the bottom of the commit message that lists the path and rev of the source. The latter is git-svn's authoritative source for where svn commits come from.

Question 4:

  • This is some more tricky: The second (external) SVN is now a "duplicate" of the first one, with one exception: external might be used by others too. Currently all changes made in "nearby" has to be done again in the external one (patching files in a second working copy, and so on...

    If this remove SVN is now a second remote SVN repository, what is best practice to "optimize" this with merges via git?

    Yes, there are some great guy'S who will use BeyondCompare, etc (see How to compare source in Git repository between source in SVN repository). But this is NOT my favorite way to "merge"

    I propose I need: * local branches like myb1, master, master2 * forks / branches of this for my work like master-taskX (git checkout -b master-taskX) * then I might use merge to get my changes back to master and then dcommit them??

    • I'd have two git repositories on the same machine, one (let's call them A and B) set to track each svn repo. Do your dev on A, set to track the nearby repo. Have B register the A as a regular git "remote" (git remote add /path/to/repo/A) after you git svn clone. Once you have got your commits ready to dcommit on A, use git fetch -f in B to bring them there. Then git svn dcommit in A; in B use something like git checkout -b temp A/master; git rebase --onto trunk HEAD^; git svn dcommit; git checkout master; git branch -D temp to commit the changes to repo B. To dcommit multiple revs you will neat to adjust the number of carats in the rebase command.

Note generally that in my experience git merge doesn't play well with git-svn, so you probably want to stick to techniques like the above which do not create two-parent commits in the git history.

浪漫之都 2024-10-19 16:24:07

我会为 2 个 svn 存储库创建 2 个单独的 git 存储库。然后,通过变基等方式在 Git 存储库之一中协调更改。

I would make 2 separate git repos for the 2 svn repos. Then, coordinate changes via rebasing, etc. in one of the Git repositories.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文