File: git-deconstruct

package info (click to toggle)
hxtools 20231224-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,640 kB
  • sloc: ansic: 4,825; perl: 3,463; sh: 1,629; cpp: 353; makefile: 149
file content (92 lines) | stat: -rwxr-xr-x 2,180 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/perl
# SPDX-License-Identifier: MIT
#
#	reverses the entire git history, producing new commits
#

use IPC::Open2;
use strict;

my $rev_array = [];
my $rev_ptr   = {};
my $rev_new   = {};
if (!open(FH, "git log '--pretty=format:%H %P' |")) {
	die();
}
while (defined(my $line = <FH>)) {
	chomp($line);
	my($commit, @parents) = split(/\s+/, $line);

	push(@$rev_array, $commit);
	if (!exists($rev_ptr->{$commit})) {
		$rev_ptr->{$commit} = [];
	}

	foreach my $p (@parents) {
		my $q;

		if (!exists($rev_ptr->{$p})) {
			$q = [];
			$rev_ptr->{$p} = $q;
		} else {
			$q = $rev_ptr->{$p};
		}
		push(@$q, $commit);
	}
}
close FH;

sub split_commit
{
	my($author_name, $author_email, $author_date);
	my($cmit_name, $cmit_email, $cmit_date);

	while (defined(my $line = shift @_)) {
		chomp $line;
		my($type) = ($line =~ /^(\w+)/);

		if ($type eq "author") {
			($author_name, $author_email, $author_date) =
				($line =~ /^author (.*) <(.*?)> (.*)/);
		} elsif ($type eq "committer") {
			($cmit_name, $cmit_email, $cmit_date) =
				($line =~ /^committer (.*) <(.*?)> (.*)/);
		} elsif (!defined($type)) {
			last;
		}
	}

	return ($author_name, $author_email, $author_date,
		$cmit_name, $cmit_email, $cmit_date, join("", @_));
}

foreach my $commit (@$rev_array) {
	my($an, $ae, $ad, $cn, $ce, $cd, $log) =
		split_commit(`git cat-file commit $commit`);

	my @cmd = ("git", "commit-tree", "$commit^{tree}");
	foreach my $parent (@{$rev_ptr->{$commit}}) {
		push(@cmd, "-p", $rev_new->{$parent});
	}

#	print "GIT_AUTHOR_NAME=\"$an\" GIT_AUTHOR_DATE=\"$ad\" ";
#	print "GIT_AUTHOR_EMAIL=\"$ae\" ";
#	print "GIT_COMMITER_NAME=\"$cn\" ";
#	print "GIT_COMMITTER_EMAIL=\"$ce\" CIT_COMMITTER_DATE=\"$cd\" ";
	print join(" ", @cmd), "\n";
	my($k_out, $k_in);
	$ENV{GIT_AUTHOR_NAME}     = $an;
	$ENV{GIT_AUTHOR_EMAIL}    = $ae;
	$ENV{GIT_AUTHOR_DATE}     = $ad;
	$ENV{GIT_COMMITTER_NAME}  = $cn;
	$ENV{GIT_COMMITTER_EMAIL} = $ce;
	$ENV{GIT_COMMITTER_DATE}  = $cd;
	my $pid = open2($k_in, $k_out, @cmd);
	print $k_out $log;
	close $k_out;
	chomp(my $new_commit = <$k_in>);
	close $k_in;
	waitpid($pid, 0);
	$rev_new->{$commit} = $new_commit;
	print "Created $new_commit\n";
}