From: Ryan Anderson <ryan@michonline.com>
To: git@vger.kernel.org
Subject: [RFC] Applying a graft to a tree and "rippling" the changes through the history
Date: Sun, 06 Nov 2005 17:38:18 -0500 [thread overview]
Message-ID: <436E85DA.1080904@michonline.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 3257 bytes --]
I've written a tool that will take a single commit, add it as a parent
of another commit, and recreate the history above that second commit in
a fully compatible manner.
This is mostly useful for creating a fully merged-up repository of the
Linux Historical tree, and the current working tree.
I run this with /graft-ripple.pl linux-history.tmp/ linus origin
Where "origin" is the branch the historical repository is on, and
"linus" is the branch the current repository is on.
Note: This does not end up fixing up HEAD or any branches, it just pulls
all the objects together and recreates the full history.
GPLv2, but I'll redo with a proper patch, signed-off-by, command line
options and help and docs if anyone else feels this is useful as a
general tool.
========= cut here =============
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use IPC::Open2;
sub git_commit_tree {
my ($tree,$comments,@parents) = @_;
my @cparents;
foreach my $p (@parents) {
push @cparents,"-p",$p;
}
my $pid = open2(*Reader, *Writer,
"git-commit-tree",$tree,@cparents);
print Writer $comments;
close(Writer);
my $commit = <Reader>;
waitpid $pid, 0;
close(Reader);
chomp $commit;
return $commit;
}
chdir($ARGV[0]);
open(GRL,"-|","git-rev-list","--parents",$ARGV[1])
or die "Failed to run git-rev-list: " . $!;
my %csets;
my @revs;
while(<GRL>) {
chomp;
my ($commit,@parents) = split /\s+/;
$csets{$commit}{parents} = \@parents;
push @revs, $commit;
open(GCF,"-|","git-cat-file","commit",$commit)
or die "Failed to open git-cat-file: " . $!;
my $in_comments = 0;
while(<GCF>) {
chomp;
if ($in_comments) {
$csets{$commit}{comments} .= $_ . "\n";
} elsif (m/^tree (.+)$/) {
$csets{$commit}{tree} = $1;
#printf("tree = %s\n",$1);
} elsif (m/^parent (.+)$/) {
# Do nothing, we already got
# the parents from rev-list.
} elsif (m/^(author|committer) (.*) <(.*)> (.*)$/) {
#printf("%s = %s <%s> at %s\n",$1, $2,$3,$4);
@{$csets{$commit}{$1}}{qw(name email datetime)}
= ($2,$3,$4);
} elsif (length == 0) {
$in_comments = 1;
$csets{$commit}{comments} = "";
next;
}
}
close(GCF);
}
close(GRL);
@revs = reverse @revs;
push @{$csets{$revs[0]}{parents}},$ARGV[2];
my %newcsets;
foreach my $old (@revs) {
printf("Processing commit %s\n",$old);
$ENV{GIT_AUTHOR_EMAIL} = $csets{$old}{author}{email};
$ENV{GIT_AUTHOR_NAME} = $csets{$old}{author}{name};
$ENV{GIT_AUTHOR_DATE} = $csets{$old}{author}{datetime};
$ENV{GIT_COMMITTER_DATE} = $csets{$old}{committer}{datetime};
$ENV{GIT_COMMITTER_EMAIL} = $csets{$old}{committer}{email};
$ENV{GIT_COMMITTER_NAME} = $csets{$old}{committer}{name};
my @parents = @{$csets{$old}{parents}};
foreach my $p (@{$csets{$old}{parents}}) {
if (exists $newcsets{$p}) {
push @parents, $newcsets{$p}
if exists $newcsets{$p};
printf("Found new csetid %s for %s\n",
$newcsets{$p},$p);
}
}
my $commit = git_commit_tree($csets{$old}{tree},
$csets{$old}{comments},@parents);
$newcsets{$old} = $commit;
printf("Commit for version %s is %s\n",$old,$newcsets{$old});
}
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 256 bytes --]
next reply other threads:[~2005-11-06 22:38 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-11-06 22:38 Ryan Anderson [this message]
2005-11-06 22:43 ` [RFC] Applying a graft to a tree and "rippling" the changes through the history Randal L. Schwartz
2005-11-07 1:45 ` Junio C Hamano
2005-11-07 2:22 ` Ryan Anderson
2005-11-18 8:49 ` Matthias Urlichs
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=436E85DA.1080904@michonline.com \
--to=ryan@michonline.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.