Permalink
Browse files

Merge branch 'git-ff'

  • Loading branch information...
2 parents e4874f4 + 2ac3558 commit 719e580697ef88ba6fd7093b997ab6342b8bd676 @mjdominus committed Mar 25, 2012
Showing with 62 additions and 0 deletions.
  1. +62 −0 git-ff
View
62 git-ff
@@ -0,0 +1,62 @@
+#!/usr/bin/perl
+#
+# Usage:
+# git-ff (fast-forward HEAD to corresponding remote tracking branch)
+# git-ff refname (fast-forward ref to corresponding remote tracking branch)
+# git-ff refname [target] (fast-forward ref to target)
+# git-ff -r remote (fast-forward all heads that track this remote)
+
+use strict;
+use Getopt::Std;
+sub error;
+
+my %opt = (v => 0, r => undef);
+getopts('vr:', \%opt) or usage();
+$ENV{GIT_GET_NO_NEWLINE} = 1;
+my $HEAD = qx{git get current-branch-name};
+
+my $remote_name = $opt{r};
+if ($remote_name) {
+ system("git get is-remote '$remote_name'") == 0
+ or error "Unknown remote '$remote_name'";
+ for my $head (qx{git get heads}) {
+ chomp $head;
+ my $tracking = qx{git-get branch-remote '$head'};
+ next unless $tracking eq $remote_name;
+ my $remote_branch = qx{git-get branch-remote-branch '$head'};
+ ff_ref($head, $remote_branch);
+ }
+} else {
+ my ($refname, $target) = @ARGV;
+ $refname ||= qx{git get current-branch-name}
+ or error "Can't fast-forward detached HEAD";
+ $refname or usage();
+ $target ||= qx{git get branch-remote-branch '$refname'}
+ or error "Can't find upstream branch for '$refname'";
+ ff_ref($refname, $target, "die on failure");
+}
+
+sub ff_ref {
+ my ($ref, $target, $die_on_failure) = @_;
+ if ($HEAD && $HEAD eq $ref) {
+ if (system("git get is-working-tree-dirty") == 0) {
+ error("Won't update current branch '$ref' with dirty working tree");
+ exit 1 if $die_on_failure;
+ return;
+ }
+ }
+ unless (system("git", "get", "is-ancestor-of", $ref, $target) == 0) {
+ die "Can't fast-forward $ref to $target\n" if $die_on_failure;
+ return;
+ }
+ return if system("git", "get", "is-same-object", $ref, $target) == 0;
+ chomp($ref = qx{git rev-parse --symbolic-full-name '$ref'});
+ $ref || die "Can't find symbolic-full-name of '$ref'\n";
+ exit 2 unless system("git", "update-ref", "-m", "merge $target: Fast-forward", $ref, $target) == 0;
+ warn "$ref -> $target\n" if $opt{v};
+}
+
+sub error {
+ warn @_, "\n";
+ exit 1;
+}

0 comments on commit 719e580

Please sign in to comment.