Thread (31 messages) flat view 31 messages, 2 authors, 2016-06-15

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

From: Avery Pennarun <hidden>
Date: 2016-06-15 22:46:41
Subsystem: the rest · Maintainer: Linus Torvalds

On Thu, Apr 30, 2009 at 6:28 PM, Josef Wolf [off-list ref] wrote:
 # 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
[...]
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.
quoted
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.
quoted
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.
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.
quoted
quoted
quoted
quoted
quoted
As long as you "git config merge.summary true" (to make the merge
commit list all the commits it's merging)
[...]
quoted
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.
quoted
quoted
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];
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help