#!/usr/bin/env perl
# git-track-remote-branches --- create local branches for all remotes
# Author: Noah Friedman <friedman@splode.com>
# Created: 2014-11-28
# Public domain

# Commentary:

# Usage: git-track-remote-branches {-C dir}
#        git {-C dir} track-remote-branches

# Code:

use strict;
use warnings qw(all);

my @git_cmd = ($ENV{GITPROG} || "git");

# Like `` but avoids shell exec/reparsing.
sub cmd_out
{
  my $pid = open (my $fh, "-|");
  die "fork: $!" unless defined $pid;
  local $/ = wantarray ? $/ : undef;
  return <$fh> if $pid;                          # parent
  exec ({ $_[0] } @_) or die "exec: $_[0]: $!";  # child
}

sub git { return cmd_out (@git_cmd, @_) }

sub git_branch
{
  my %result;
  map { s=^\*?\s*(?:remotes/)?==;
        $result{$_} = undef unless / -> /;
      } split (/[\r\n]+/, git (qw(branch --column=never), @_));
  return %result;
}

sub main
{
  push @git_cmd, (shift, shift) if (@_ > 1 && $_[0] eq '-C');

  my %loc = git_branch ("-l");
  my %rem = git_branch ("-r");

  map { (my $lname = $_) =~ s=^.*?/==;
        if (exists $loc{$lname})
          {
            delete $rem{$_};
          }
        else
          {
            $rem{$_} = $lname;
          }
      } keys %rem;

  map { system (@git_cmd, qw(branch --track), $rem{$_}, $_);
      } sort keys %rem;
}

main (@ARGV);

# eof
