summaryrefslogtreecommitdiffstats
path: root/svn-commit-git-patch
blob: 54b345d4b141652fbef7cee20ecd6313de910067 (plain)
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
#!/usr/bin/perl

use strict;
use warnings;

use MIME::Words;

=head1 DESCRIPTION

Take a patch made by git-format-patch (e.g. against a git-svn clone of a
repository) and apply it to an svn repository. Tries to keep the commit subject
and message. The git commit author and the git commmit date are put into the
svn commmit message.

This could probably also be done by using `git svn dcommit`, but then I'd have
to set up/learn git-svn. Doing it like this is easier for such a simple
usecase. Also, writing short scripts is fun!

=cut

if (@ARGV < 1) {
	print "usage: svn-commit-git-patch <patchfile>\n";
	exit 1;
}

my $patchfile = $ARGV[0] // die "<patchfile> not set";

my $subject;
my $message = '';

open my $fh, '<', $patchfile;
while (my $line = <$fh>) {
	last if $line =~ /^---$/;

	# TODO: does this need the whole message or is it enough to pass a single
	# line? what about potential multiline headers? no idea if git creates
	# those
	$line = MIME::Words::decode_mimewords($line);

	# TODO: parse multiline subject "headers" correctly. no idea if git creates those
	if ($line =~ /^Subject: (?:\[PATCH \d+\/\d+\] )?(.*)$/) {
		$subject = $1;
	} elsif ($line =~ /^From [a-f0-9]{40} Mon Sep 17 00:00:00 2001$/) {
		next;
	} else {
		$message .= $line;
	}
}

$message = "$subject\n\n$message";

system(qw(svn patch --strip 1), $patchfile);
system(qw(svn commit -m), $message);