+}
+
+sub fetchpullargs () {
+ if (!defined $package) {
+ my $sourcep = parsecontrol('debian/control','debian/control');
+ $package = getfield $sourcep, 'Source';
+ }
+ if (@ARGV==0) {
+# $isuite = branchsuite(); # this doesn't work because dak hates canons
+ if (!$isuite) {
+ my $clogp = parsechangelog();
+ $isuite = getfield $clogp, 'Distribution';
+ }
+ canonicalise_suite();
+ print "fetching from suite $csuite\n";
+ } elsif (@ARGV==1) {
+ ($isuite) = @ARGV;
+ canonicalise_suite();
+ } else {
+ badusage "incorrect arguments to dgit fetch or dgit pull";
+ }
+}
+
+sub cmd_fetch {
+ parseopts();
+ fetchpullargs();
+ fetch();
+}
+
+sub cmd_pull {
+ parseopts();
+ fetchpullargs();
+ pull();
+}
+
+sub cmd_push {
+ parseopts();
+ badusage "-p is not allowed with dgit push" if defined $package;
+ runcmd @git, qw(diff --quiet HEAD);
+ my $clogp = parsechangelog();
+ $package = getfield $clogp, 'Source';
+ if (@ARGV==0) {
+ $isuite = getfield $clogp, 'Distribution';
+ if ($new_package) {
+ local ($package) = $existing_package; # this is a hack
+ canonicalise_suite();
+ }
+ } else {
+ badusage "incorrect arguments to dgit push";
+ }
+ if (check_for_git()) {
+ git_fetch_us();
+ }
+ if (fetch_from_archive()) {
+ is_fast_fwd(lrref(), 'HEAD') or die;
+ } else {
+ $new_package or
+ fail "package appears to be new in this suite;".
+ " if this is intentional, use --new";
+ }
+ dopush();
+}
+
+our $version;
+our $sourcechanges;
+our $dscfn;
+
+our $fakeeditorenv = 'DGIT_FAKE_EDITOR_QUILT';
+
+sub build_maybe_quilt_fixup () {
+ if (!open F, "debian/source/format") {
+ die $! unless $!==&ENOENT;
+ return;
+ }
+ $_ = <F>;
+ F->error and die $!;
+ chomp;
+ return unless madformat($_);
+ # sigh
+ my $headref = rev_parse('HEAD');
+ my $time = time;
+ my $patchname = "auto-$version-$headref-$time";
+ my $author = cmdoutput @git, qw(log -n1), '--pretty=format:%an <%ae>';
+ my $msg = cmdoutput @git, qw(log -n1), "--pretty=format:%s\n%b";
+ my $descfn = ".git/dgit/quilt-description.tmp";
+ open O, '>', $descfn or die "$descfn: $!";
+ $msg =~ s/\n/\n /g;
+ $msg =~ s/^\s+$/ ./mg;
+ print O <<END or die $!;
+Description: $msg
+ [generated from git commit $headref]
+Author: $author
+
+---
+
+END
+ close O or die $!;
+ {
+ local $ENV{'EDITOR'} = cmdoutput qw(realpath --), $0;
+ local $ENV{'VISUAL'} = $ENV{'EDITOR'};
+ local $ENV{$fakeeditorenv} = cmdoutput qw(realpath --), $descfn;
+ runcmd_ordryrun @dpkgsource, qw(--commit .), $patchname;
+ }
+
+ if (!open P, '>>', ".pc/applied-patches") {
+ $!==&ENOENT or die $!;
+ } else {
+ close P;
+ }
+
+ commit_quilty_patch();
+}
+
+sub quilt_fixup_editor () {
+ my $descfn = $ENV{$fakeeditorenv};
+ my $editing = $ARGV[$#ARGV];
+ open I1, '<', $descfn or die "$descfn: $!";
+ open I2, '<', $editing or die "$editing: $!";
+ unlink $editing or die "$editing: $!";
+ open O, '>', $editing or die "$editing: $!";
+ while (<I1>) { print O or die $!; } I1->error and die $!;
+ my $copying = 0;
+ while (<I2>) {
+ $copying ||= m/^\-\-\- /;
+ next unless $copying;
+ print O or die $!;
+ }
+ I2->error and die $!;
+ close O or die $1;
+ exit 0;
+}
+
+sub cmd_build {
+ # we pass further options and args to git-buildpackage
+ badusage "-p is not allowed with dgit build" if defined $package;
+ badusage "dgit build implies --clean=dpkg-source" if defined $package;
+ my $clogp = parsechangelog();
+ $isuite = getfield $clogp, 'Distribution';
+ $package = getfield $clogp, 'Source';
+ $version = getfield $clogp, 'Version';
+ build_maybe_quilt_fixup();
+ my @cmd =
+ (qw(git-buildpackage -us -uc --git-no-sign-tags),
+ "--git-builder=@dpkgbuildpackage");
+ unless (grep { m/^--git-debian-branch/ } @ARGV) {
+ canonicalise_suite();
+ push @cmd, "--git-debian-branch=".lbranch();
+ }
+ push @cmd, changesopts();
+ runcmd_ordryrun @cmd, @ARGV;
+ printdone "build successful\n";
+}
+
+sub build_source {
+ badusage "-p is not allowed with this action" if defined $package;
+ check_not_dirty();
+ my $clogp = parsechangelog();
+ $package = getfield $clogp, 'Source';
+ $isuite = getfield $clogp, 'Distribution';
+ $version = getfield $clogp, 'Version';
+ $sourcechanges = "${package}_${version}_source.changes";
+ $dscfn = dscfn($version);
+ build_maybe_quilt_fixup();
+ if ($cleanmode eq 'dpkg-source') {
+ runcmd_ordryrun (@dpkgbuildpackage, qw(-us -uc -S)), changesopts();
+ } else {
+ if ($cleanmode eq 'git') {
+ runcmd_ordryrun @git, qw(clean -xdf);
+ } elsif ($cleanmode eq 'none') {
+ } else {
+ die "$cleanmode ?";
+ }
+ my $pwd = cmdoutput qw(env - pwd);
+ my $leafdir = basename $pwd;
+ chdir ".." or die $!;
+ runcmd_ordryrun @dpkgsource, qw(-b --), $leafdir;
+ chdir $pwd or die $!;
+ runcmd_ordryrun qw(sh -ec),
+ 'exec >$1; shift; exec "$@"','x',
+ "../$sourcechanges",
+ @dpkggenchanges, qw(-S), changesopts();
+ }
+}
+
+sub cmd_build_source {
+ badusage "build-source takes no additional arguments" if @ARGV;
+ build_source();
+ printdone "source built, results in $dscfn and $sourcechanges";
+}
+
+sub cmd_sbuild {
+ build_source();
+ chdir ".." or die $!;
+ my $pat = "${package}_${version}_*.changes";
+ if (!$dryrun) {
+ stat $dscfn or fail "$dscfn (in parent directory): $!";
+ stat $sourcechanges or fail "$sourcechanges (in parent directory): $!";
+ foreach my $cf (glob $pat) {
+ next if $cf eq $sourcechanges;
+ unlink $cf or fail "remove $cf: $!";
+ }
+ }
+ runcmd_ordryrun @sbuild, @ARGV, qw(-d), $isuite, $dscfn;
+ runcmd_ordryrun @mergechanges, glob $pat;
+ my $multichanges = "${package}_${version}_multi.changes";
+ if (!$dryrun) {
+ stat $multichanges or fail "$multichanges: $!";
+ }
+ printdone "build successful, results in $multichanges\n" or die $!;
+}
+
+sub cmd_quilt_fixup {
+ badusage "incorrect arguments to dgit quilt-fixup" if @ARGV;
+ my $clogp = parsechangelog();
+ $version = getfield $clogp, 'Version';
+ build_maybe_quilt_fixup();