git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Trying to sync two svn repositories with git-svn (repost)

From
Avery Pennarun <apenwarr@gmail.com>
Date
Apr 30, 2009, 22:59 UTC
Message-ID
<32541b130904301559w329bdd4bo6f2736a505b7235f@mail.gmail.com>
In-Reply-To
<20090430222808.GH15420@raven.wolf.lan>
On Thu, Apr 30, 2009 at 6:28 PM, Josef Wolf <jw@raven.inka.de> wrote:
Show 8 quoted lines
>  # cherry-pick from second-svn to first-svn
>  #
>  git svn checkout first-svn
>  git cherry-pick sha1-from-second-svn # repeat as needed
>  git checkout first-svn/trunk
>  git merge --no-ff first-svn
>  git diff first-svn/trunk first-svn >changes.diff
>  git svn dcommit
[...]
Show 7 quoted lines
> But I am still somewhat confused:
>
>  git log -1 first-svn/trunk
>
> says "Merge branch first-svn into HEAD".  But this does not reflect
> what I've actually done: I've picked _from_ second-svn and committed
> that _to_ first-svn.

The most recent commit to first-svn/trunk was "git merge --no-ff first-svn", which creates the merge commit you're seeing here. (HEAD == first-svn/trunk). So this sounds right to me.

"git log -1 first-svn" would give you the first cherry-pick. But remember, it's a completely different branch.

Show 11 quoted lines
>> What you probably thought you should do, given that the existing
>> git-svn documentation says to do it, is more like this:
>>
>>    # WRONG
>>    git checkout first-svn
>>    git cherry-pick some stuff
>>    git merge [perhaps -s ours] second-svn/trunk
>>    git svn dcommit
>
> Almost... In addition, I was trying to "git svn rebase" before the
> dcommit
'git svn dcommit' implies 'git svn rebase' first anyway, so it's the same.
> What would happen if somebody else creates a new commit just after I
> "git svn fetch" but before I dcommit?  Guess, svn will not accept this
> commit, because it is based on an outdated revision.  How would I
> get out from this situation?

AFAIK, it will attempt to do "git svn rebase" first, and if that succeeds, it will do the commit.

In such a case, the rebase should be okay, because it's only changing commits (in fact, just one commit: the merge commit) that don't exist on any other branch. Thus it won't mangle any other merges.

Show 5 quoted lines
>> As it happens, I wrote the git-svn chapter for the
>> very-nearly-available new O'Reilly book "Version Control with Git."  I
>> gave the complicated solution there too.
>
> Interesting.  Do you have any information when it will be available?
Mid-May, as I understand it.
Show 6 quoted lines
> Ummm, no.. I have _two_ branches:
>
>  first-svn:  contains the cherries that I picked from second-svn. This
>              branch looks the way first-svn/trunk should be
>  second-svn: contains the cherries that I picked from first-svn. This
>              looks the way second-svn/trunk should be

Okay, if you want to end up with two different remote branches, it makes sense to have two different local branches.

> Don't I need to rebase at least one of them if I want to "merge" those
> two branches into a single one?
I don't think so.  If you merge them together, what do you *want* it
to look like?  And what do you want to do with that branch afterwards?
 It's hard for me to guess, but it seems unlikely that rebasing things
will get you there.

If what you want is "one central branch that currently looks like first-svn/trunk or second-svn/trunk or maybe something else, but we'll be merging future changes to first-svn and second-svn into it in the future", then you would do:

   git checkout -b one-true-branch
   ...make it look however you want...
   # now mark it as up-to-date with svn, but don't change anything
   git merge -s ours first-svn/trunk
   git merge -s ours second-svn/trunk

And then in the future, whenever first-svn/trunk or second-svn/trunk change, you would do:

   git merge first-svn/trunk
   git merge second-svn/trunk
etc.
> I have a hard time to adopt my mental model to the one-branch method for
> some reason.  OTOH, I can easily understand the multiple-branch method:
> for every remote branch, I have a local branch on which I collect the
> commits that should go to this remote.

It's indeed pretty complicated. I had much better luck once I finally separated the two concepts in my mind. In general, you want to name local branches after what they *do*; you almost never have a 1:1 mapping between local and remote branches, particularly when using git-svn (at least, when using git-svn with merges instead of rebases).

Maybe think of it like this: you're not "collecting commits." You're simply merging changes from one place to another, and testing them out. Once you're happy with what's on your local branch, you want to merge it (--no-ff) into the remote branch and git svn dcommit it. svn will never see the individual commits; it only sees the merge commits.

>> >> >> As long as you "git config merge.summary true" (to make the merge
>> >> >> commit list all the commits it's merging)
[...]
Show 7 quoted lines
>> In fact, it *only* affects the svn log.  Otherwise svn log ends up
>> with a useless commit that says "Merged from commit (giant hex
>> string)", and you can't actually do anything with the giant hex string
>> because svn doesn't know what it is.
>
> OK.  I just noticed the list is limited to 22 entries.  Can this be
> configured somehow to contain the complete list?

Ah, that. I don't think there's an obvious way. I forgot I did it until now, but my copy of git is patched to "fix" this. My patch is attached below.

Show 12 quoted lines
>> > The people are not uncooperative.  It is just that there's no way to
>> > completely separate the public and private content.
>>
>> There is, if you're willing to do it.  The usual way is two have two
>> branches: public and private.
>
> Well, my plan was to have one (generic) public repository that contains
> templates instead of the localized information.  Separating the
> repositories is a security measure here.
>
> Whether separate repositories or only different branches, conflicts
> _are_ to be expected in this area.

Conflicts are normal. But you can simply resolve them, using normal git mechanisms, when merging from public-svn/trunk to second-svn/trunk, or whatever. At least you shouldn't have to cherry-pick or rebase anything.

Have fun,
Avery
diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c
index df18f40..96c42ff 100644
--- a/builtin-fmt-merge-msg.c
+++ b/builtin-fmt-merge-msg.c
@@ -255,7 +255,7 @@ static void shortlog(const char *name, unsigned char *sha1,
 }

 int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
-       int limit = 20, i = 0, pos = 0;
+       int limit = 2000, i = 0, pos = 0;
        char line[1024];
        char *p = line, *sep = "";
        unsigned char head_sha1[20];
Previous: Josef WolfNext: Josef Wolf
Message 11 of 31 in “Trying to sync two svn repositories with git-svn (repost)”
  1. Josef WolfApr 27, 2009
  2. Josef WolfApr 28, 2009
  3. Avery PennarunApr 28, 2009
  4. Josef WolfApr 28, 2009
  5. Avery PennarunApr 29, 2009
  6. Josef WolfApr 29, 2009
  7. Avery PennarunApr 29, 2009
  8. Josef WolfApr 29, 2009
  9. Avery PennarunApr 30, 2009
  10. Josef WolfApr 30, 2009
  11. Avery PennarunApr 30, 2009
  12. Josef WolfMay 1, 2009
  13. Avery PennarunMay 1, 2009
  14. Josef WolfMay 2, 2009
  15. Avery PennarunMay 4, 2009
  16. Josef WolfMay 4, 2009
  17. Josef WolfMay 6, 2009
  18. Avery PennarunMay 6, 2009
  19. Josef WolfMay 6, 2009
  20. Avery PennarunMay 8, 2009
  21. Josef WolfMay 8, 2009
  22. Josef WolfMay 13, 2009
  23. Avery PennarunMay 13, 2009
  24. Josef WolfMay 13, 2009
  25. Avery PennarunMay 14, 2009
  26. Josef WolfMay 14, 2009
  27. Avery PennarunMay 14, 2009
  28. Josef WolfMay 15, 2009
  29. Avery PennarunMay 15, 2009
  30. Josef WolfMay 17, 2009
  31. Josef WolfMay 20, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.