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
|
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
use Path::Class 'dir';
sub git {
if (!defined wantarray) {
system('git', @_);
}
elsif (wantarray) {
chomp(my @ret = qx{git @_});
return @ret;
}
else {
chomp(my $ret = qx{git @_});
return $ret;
}
}
my $git_dir = dir(scalar(git qw(rev-parse --show-toplevel)))->subdir('.git');
my $state_file = $git_dir->file('rebase-under-state');
my ($continuing, $onto, $branch, @commits);
if ($ARGV[0] eq '--continue') {
die "can't continue: no state file" unless -r $state_file;
($onto, $branch, @commits) = split("\n", $state_file->slurp);
$continuing = 1;
}
else {
$onto = $ARGV[0] // 'master';
$branch = git qw(symbolic-ref -q HEAD);
$branch =~ s+^refs/heads/++;
my $remote_branch = "origin/$branch";
@commits = git 'rev-list', '--reverse', "$remote_branch..$branch";
}
$state_file->openw->print(join("\n", $onto, $branch, @commits));
if ($continuing) {
git 'commit';
}
else {
git 'checkout', $onto;
}
while (@commits) {
my $commit = shift @commits;
$state_file->openw->print(join("\n", $onto, $branch, @commits));
git 'cherry-pick', $commit;
if ($?) {
die <<DIE;
Conflict detected. Fix the conflict, and run `git rebase-under --continue`.
DIE
}
}
git 'checkout', $branch;
git 'rebase', $onto;
$state_file->remove;
|