+ if (check_for_git()) {
+ git_fetch_us();
+ }
+ fetch_from_archive() or die;
+}
+
+sub pull () {
+ fetch();
+ runcmd_ordryrun @git, qw(merge -m),"Merge from $suite [dgit]",
+ lrref();
+}
+
+sub dopush () {
+ runcmd @git, qw(diff --quiet HEAD);
+ my $clogp = parsechangelog();
+ $package = $clogp->{Source};
+ my $dscfn = "${package}_$clogp->{Version}.dsc";
+ stat "../$dscfn" or die "$dscfn $!";
+ $dsc = parsecontrol("../$dscfn");
+ prep_ud();
+ chdir $ud or die $!;
+ print "checking that $dscfn corresponds to HEAD\n";
+ runcmd qw(dpkg-source -x --), "../../../../$dscfn";
+ my ($tree,$dir) = mktree_in_ud_from_only_subdir();
+ chdir '../../../..' or die $!;
+ runcmd @git, qw(diff --exit-code), $tree;
+#fetch from alioth
+#do fast forward check and maybe fake merge
+# if (!is_fast_fwd(mainbranch
+# runcmd @git, qw(fetch -p ), "$alioth_git/$package.git",
+# map { lref($_).":".rref($_) }
+# (uploadbranch());
+ $dsc->{$ourdscfield} = rev_parse('HEAD');
+ $dsc->save("../$dscfn.tmp") or die $!;
+ if (!$dryrun) {
+ rename "../$dscfn.tmp","../$dscfn" or die "$dscfn $!";
+ } else {
+ print "[new .dsc left in $dscfn.tmp]\n";
+ }
+ if (!$changesfile) {
+ my $pat = "../${package}_$clogp->{Version}_*.changes";
+ my @cs = glob $pat;
+ die "$pat ?" unless @cs==1;
+ ($changesfile) = @cs;
+ }
+ my $tag = debiantag($dsc->{Version});
+ if (!check_for_git()) {
+ create_remote_git_repo();
+ }
+ runcmd_ordryrun @git, qw(push),access_giturl(),"HEAD:".rrref();
+ if ($sign) {
+ my @tag_cmd = (@git, qw(tag -s -m),
+ "Release $dsc->{Version} for $suite [dgit]");
+ push @tag_cmd, qw(-u),$keyid if defined $keyid;
+ push @tag_cmd, $tag;
+ runcmd_ordryrun @tag_cmd;
+ my @debsign_cmd = @debsign;
+ push @debsign_cmd, "-k$keyid" if defined $keyid;
+ push @debsign_cmd, $changesfile;
+ runcmd_ordryrun @debsign_cmd;
+ }
+ runcmd_ordryrun @git, qw(push),access_giturl(),"refs/tags/$tag";
+ my $host = access_cfg('upload-host');
+ my @hostarg = defined($host) ? ($host,) : ();
+ runcmd_ordryrun @dput, @hostarg, $changesfile;
+}
+
+sub cmd_clone {
+ parseopts();
+ my $dstdir;
+ die if defined $package;
+ if (@ARGV==1) {
+ ($package) = @ARGV;
+ } elsif (@ARGV==2 && $ARGV[1] =~ m#^\w#) {
+ ($package,$suite) = @ARGV;
+ } elsif (@ARGV==2 && $ARGV[1] =~ m#^[./]#) {
+ ($package,$dstdir) = @ARGV;
+ } elsif (@ARGV==3) {
+ ($package,$suite,$dstdir) = @ARGV;
+ } else {
+ die;
+ }
+ $dstdir ||= "$package";
+ clone($dstdir);
+}
+
+sub branchsuite () {
+ my $branch = cmdoutput_errok @git, qw(symbolic-ref HEAD);
+ chomp $branch;
+ if ($branch =~ m#$lbranch_re#o) {
+ return $1;
+ } else {
+ return undef;
+ }
+}
+
+sub fetchpullargs () {
+ if (!defined $package) {
+ my $sourcep = parsecontrol('debian/control');
+ $package = $sourcep->{Source};
+ }
+ if (@ARGV==0) {
+ $suite = branchsuite();
+ if (!$suite) {
+ my $clogp = parsechangelog();
+ $suite = $clogp->{Distribution};
+ }
+ canonicalise_suite();
+ print "fetching from suite $suite\n";
+ } elsif (@ARGV==1) {
+ ($suite) = @ARGV;
+ canonicalise_suite();
+ } else {
+ die;
+ }
+}
+
+sub cmd_fetch {
+ parseopts();
+ fetchpullargs();
+ fetch();
+}
+
+sub cmd_pull {
+ parseopts();
+ fetchpullargs();
+ pull();
+}
+
+sub cmd_push {
+ parseopts();
+ die if defined $package;
+ my $clogp = parsechangelog();
+ $package = $clogp->{Source};
+ if (@ARGV==0) {
+ $suite = $clogp->{Distribution};
+ if ($new_package) {
+ local ($package) = 'dpkg';
+ canonicalise_suite();
+ }
+ } else {
+ die;
+ }
+ if (fetch_from_archive()) {
+ is_fast_fwd(lrref(), 'HEAD') or die;
+ } else {
+ die unless $new_package;
+ }
+ dopush();
+}
+
+sub cmd_build {
+ # we pass further options and args to git-buildpackage
+ die if defined $package;
+ my $clogp = parsechangelog();
+ $suite = $clogp->{Distribution};
+ $package = $clogp->{Source};
+ canonicalise_suite();
+ runcmd_ordryrun
+ qw(git-buildpackage -us -uc --git-no-sign-tags),
+ '--git-builder=dpkg-buildpackage -i\.git/ -I.git',
+ "--git-debian-branch=".lbranch(),
+ @ARGV;
+}
+
+sub parseopts () {
+ my $om;
+ while (@ARGV) {
+ last unless $ARGV[0] =~ m/^-/;
+ $_ = shift @ARGV;
+ last if m/^--?$/;
+ if (m/^--/) {
+ if (m/^--dry-run$/) {
+ $dryrun=1;
+ } elsif (m/^--no-sign$/) {
+ $sign=0;
+ } elsif (m/^--new$/) {
+ $new_package=1;
+ } elsif (m/^--(\w+)=(.*)/s && ($om = $opts_opt_map{$1})) {
+ $om->[0] = $2;
+ } elsif (m/^--(\w+):(.*)/s && ($om = $opts_opt_map{$1})) {
+ push @$om, $2;
+ } else {
+ die "$_ ?";
+ }
+ } else {
+ while (m/^-./s) {
+ if (s/^-n/-/) {
+ $dryrun=1;
+ } elsif (s/^-D/-/) {
+ open DEBUG, ">&STDERR" or die $!;
+ $debug++;
+ } elsif (s/^-N/-/) {
+ $new_package=1;
+ } elsif (s/^-c(.*=.*)//s) {
+ push @git, '-c', $1;
+ } elsif (s/^-C(.*)//s) {
+ $changesfile = $1;
+ } elsif (s/^-k(.*)//s) {
+ $keyid=$1;
+ } else {
+ die "$_ ?";
+ }
+ }
+ }
+ }
+}
+
+parseopts();
+die unless @ARGV;
+my $cmd = shift @ARGV;
+
+{ no strict qw(refs); &{"cmd_$cmd"}(); }