-
Notifications
You must be signed in to change notification settings - Fork 1
/
git-commit-to.pl
104 lines (86 loc) · 2.26 KB
/
git-commit-to.pl
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
93
94
95
96
97
98
99
100
101
102
103
use Getopt::Long;
sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
#
# Parse arguments
#
my $target_branch;
my $message;
my $push;
my $new_branch;
my $rebase;
GetOptions(
"target-branch=s" => \$target_branch,
"message=s" => \$message,
"push+" => \$push,
"new-branch+" => \$new_branch,
"rebase+" => \$rebase,
) or die "Invalid arguments!";
$target_branch = ($target_branch or $ARGV[0]);
$message = ($message or $ARGV[1]);
die "Missing target branch!" unless $target_branch;
die "Missing commit message!" unless $message;
#
# Get working branch name
#
my $working_branch = trim(qx/git rev-parse --abbrev-ref HEAD/);
print "📐 Committing changes in $working_branch to $target_branch\n";
#
# Commit the stashed changes
#
qx/git commit -m "$message"/;
my $commit_hash = trim(qx/git rev-parse HEAD/);
print "📝 Successfully created commit with hash $commit_hash\n";
#
# If there are pending changes, we stash them so as to not have
# problems when switching branches
#
my $modified_files = trim(qx/git status -s -uno/);
if ($modified_files) {
qx/git stash/;
print "👈 Stashed uncommited changes\n";
}
#
# Start a new branch if necessary
#
if ($new_branch) {
qx/git checkout -b $target_branch/;
} else {
qx/git checkout $target_branch/;
}
print "🏃 Moved to branch $target_branch\n";
#
# Cherry pick the commit we created in the working branch
#
qx/git cherry-pick $commit_hash/;
print "🍒 Cherry-picked commit with hash $commit_hash\n";
#
# If push was required, we first pull and rebase the target branch
# and then we push the commit
#
if ($push) {
qx/git pull --rebase origin $target_branch/;
qx/git push/;
print "🙌 Pushed $target_branch to remote\n";
}
#
# Go back to the original branch and stash pop the previous changes
#
qx/git checkout $working_branch/;
print "🏃 Moved back to $working_branch\n";
if ($modified_files) {
qx/git stash pop/;
print "👉 Put back unstashed changes\n"
}
#
# Remove the original commit from the current branch
#
qx/git reset --hard HEAD~1/;
print "🗑 Removed new commit from $working_branch\n";
#
# Perform rebase if requested
#
if ($rebase) {
qx/git rebase $target_branch/;
print "🚜 Rebased commits from $target_branch to branch $working_branch\n";
}
print "🦄 Finished without errors\n"