Skip to contentSkip to conversation

copy selected history between repostories

DISCUSSION luisgutz 5 participants 5 messages Jun 15, 2016

lore
Share & tools
lore

luisgutz

author
#0 lore raw

Hi All,

This is something I'm not sure how to do with git, or even if it is possible in git; and because google has not been my friend this time, I though I would ask here.

I have 2 repositories: repoA and repoB.

repoB is massive. lots of history and files. But it has a set of files inside a particular dir with 40-60 files that I just realized are better in repoA.

Is there any way to import that directory into repoA with all it's history, but NOT the history from the other commits?
Another way of putting is this: can I make git forget the history of all other commits but those from this directory?

Signature · 2 lines
View this message in context: http://www.nabble.com/copy-selected-history-between-repostories-tp18533605p18533605.html
Sent from the git mailing list archive at Nabble.com.
#1 lore raw
Quoted 4 lines · luisgutz

Is there any way to import that directory into repoA with all it's history, but NOT the history from the other commits?
Another way of putting is this: can I make git forget the history of all other commits but those from this directory?

I couldn't figure out git-filter-branch, so I did the following, which worked for me:

First, export commits as patches in mbox format:

	git log -p --first-parent --reverse --pretty=email $* > mbox

Second, run the mbox file through a filter which selectively renames files (since almost always I want the files in a different directory in the new repository):

myfilter scripts=bin perllib=lib < mbox > mbox2

Finally, import into new repo:

git-am mbox2

It's a bit slow on the import step but it meets my needs at this time.

Nick.

Filter script follows, for what it's worth ...

#!/usr/bin/perl
# @(#) git-filter-rename.pl
#
# Read an mbox file containing patches on standard input,
# modify the filenames within according to a list of substitutions
# supplied on the command line, and write the modified mbox file
# to standard output.

my @subs;

foreach (@ARGV) {
	if (/(.*)=(.*)/) {
		my $len = length($1);
		push(@subs, [ $1, $2, $len ]);
	} else {
		print STDERR "Unknown arg: $_\n";
	}
}
while (<STDIN>) {
	chomp;
	my $line = $_;

	if ($line =~ /^(---|\+\+\+) ([ab]\/)(.+)$/) {
		my $line_1 = $1;
		my $line_2 = $2;
		my $line_3 = $3;

		subFilename($line_3);

		print "$line_1 $line_2$line_3\n";
		next;
	}

	if ($line =~ /^diff --git ([ab]\/)(\S+) ([ab]\/)(\S+)/) {
		my ($line_1, $line_2, $line_3, $line_4) = ($1, $2, $3, $4);
		subFilename($line_2);
		subFilename($line_4);
		print "diff --git $line_1$line_2 $line_3$line_4\n";
		next;
	}

	print $line, "\n";
}

exit(0);

# ------------------------------------------------------------------------ # Substitute a filename in-place (modifies argument)
# ------------------------------------------------------------------------

sub subFilename {

	foreach my $lr (@subs) {
		my ($lhs, $rhs, $len) = @$lr;
		if (substr($_[0], 0, $len) eq $lhs) {
			print STDERR "Match on $lhs, $_[0]\n";
			substr($_[0], 0, $len) = $rhs;
			last;
		}
	}
}
#2 lore raw
Quoted 11 lines · Nick Andrew

I couldn't figure out git-filter-branch, so I did the following, which worked for me:

First, export commits as patches in mbox format:

	git log -p --first-parent --reverse --pretty=email $* > mbox

[...]

Finally, import into new repo:

git-am mbox2

Note that this will lose any interesting history topology you had, like branching and merging (and it may have trouble applying all patches in that case, too). But if your history was a straight line, it should produce equivalent results.

-Peff

#3 lore raw
In reply to Nick Andrew

Hi,

Quoted 1 line · Nick Andrew

myfilter scripts=bin perllib=lib < mbox > mbox2

Note that if your repository only contains text files, "git fast-export | my-filter | git fast-import --force" would have worked faster, probably.

But I am glad you figured out how to do what you wanted to do.

Ciao,
Dscho

#4 lore raw
In reply to luisgutz
Quoted 4 lines · luisgutz

Is there any way to import that directory into repoA with all it's history, but NOT the history from the other commits?
Another way of putting is this: can I make git forget the history of all other commits but those from this directory?

Try cloning the repository, then running git-filter-branch with the --subdirectory-filter option. It works quite nicely.

Have fun,

Avery