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

Re: [PATCH] contrib/svn-fe: Fast script to remap svn history

From
Jonathan Nieder <jrnieder@gmail.com>
Date
Nov 21, 2010, 05:17 UTC
Message-ID
<20101121051734.GA11856@burratino>
In-Reply-To
<1286431561-24126-1-git-send-email-david.barr@cordelta.com>
Hi David,
David Barr wrote:
> This python script walks the commit sequence imported by svn-fe.
> For each commit, it tries to identify the branch that was changed.
> Commits are rewritten to be rooted according to the standard layout.
I like the idea and especially that the heuristics are simple.

Maybe this could be made git-agnostic using the new ls-tree command you are introducing in fast-import? Though it would need to get a revision list from somewhere. Alternatively, do you think it would make sense for something like this to be implemented as a filter or observer of the fast-import stream as it is generated during an import?

> A basic heuristic of matching trees is used to find parents for the
> first commit in a branch and for tags.
More precisely, the rule used is:
Show 9 quoted lines
> +    # Find a common path prefix in the changes for the revision
> +    subroot = ""
> +    changes = Popen(["git","diff","--name-only",parent,git_commit], stdout=PIPE)
> +    for path in changes.stdout:
> +        match = subroot_re.match(path)
> +        if match:
> +            subroot = match.group()
> +            changes.terminate()
> +            break
The first change lying in one of
	trunk
	branch/*
	tags/*

determines the branch. When a branch is renamed, this has a 50/50 chance of choosing the right branch.

Show 7 quoted lines
> +        # Choose a parent for the rewritten commit
> +        if ref in ref_commit:
> +            parent = ref_commit[ref]
> +        elif subtree in tree_commit:
> +            parent = tree_commit[subtree]
> +        else:
> +            parent = ""

If this is a live branch, the parent is the last commit from that branch. Otherwise, we take the last commit whose resulting tree looked like this one. Or...

> +            # Default to trunk if the branch is new
> +            if parent == "" and "refs/heads/trunk" in ref_commit:
> +                parent = ref_commit["refs/heads/trunk"]
... if all else fails, we take the tip commit on the trunk.
For comparison, here's the git-svn rule:
> 	# look for a parent from another branch:
> 	my @b_path_components = split m#/#, $self->{path};

Among the paths above this commit's base directory [if this is branches/foo, examine first branches/foo, then branches, then /]:

Show 6 quoted lines
> 	while (@b_path_components) {
> 		$i = $paths->{'/'.join('/', @b_path_components)};
> 		last if $i && defined $i->{copyfrom_path};
> 		unshift(@a_path_components, pop(@b_path_components));
> 	}
> 	return undef unless defined $i && defined $i->{copyfrom_path};

Find the first one with copyfrom information (i.e., that was renamed or copied from another rev in this revision).

Show 6 quoted lines
> 	my $branch_from = $i->{copyfrom_path};
> 	if (@a_path_components) {
> 		print STDERR "branch_from: $branch_from => ";
> 		$branch_from .= '/'.join('/', @a_path_components);
> 		print STDERR $branch_from, "\n";
> 	}

Build back up the URL (so if branches was renamed to Branches but branches/foo had no copyfrom information, we look for Branches/foo).

[...]
> 	my $gs = $self->other_gs($new_url, $url,
> 		                 $branch_from, $r, $self->{ref_id});
> 	my ($r0, $parent) = $gs->find_rev_before($r, 1);
Find the last revision that changed that path and record it.

Maybe we could benefit from including the copyfrom information in the fast-import stream output by svn-fe somehow? The simplest way to do this would be some specially formatted comments. An alternative (in the spirit of Sam's earlier suggestions) might be to represent it in the tree svn-fe creates, for example by introducing dummy

	foo.copiedfrom
symlinks.

Thanks, that was interesting. Jonathan

Previous: Jonathan NiederNext: Stephen Bash
Message 5 of 7 in “contrib/svn-fe: Fast script to remap svn history”
  1. contrib/svn-fe: Fast script to remap svn historyDavid Barr, Oct 7, 2010
  2. Sverre RabbelierOct 7, 2010
  3. David Michael BarrOct 7, 2010
  4. Jonathan NiederOct 7, 2010
  5. Jonathan NiederNov 21, 2010
  6. Stephen BashNov 22, 2010
  7. Jonathan NiederNov 22, 2010

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.