X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=dgit.git;a=blobdiff_plain;f=dgit;h=079e5dec7c212c0c4ea1be9ecb76f4891af75cfb;hp=265978ea53cd0841de791d9aae3e409110caf4ac;hb=9ee62540f7477f10c404f06ce7e53133f8a8fcd7;hpb=b02532fd7d3c82864c76eecbfd99a1abc7e2c1b2 diff --git a/dgit b/dgit index 265978ea..079e5dec 100755 --- a/dgit +++ b/dgit @@ -111,7 +111,7 @@ sub lref () { return "refs/heads/".lbranch(); } sub lrref () { return "refs/remotes/$remotename/".server_branch($csuite); } sub rrref () { return server_ref($csuite); } -sub lrfetchrefs () { return "refs/dgit-fetch/$isuite"; } +sub lrfetchrefs () { return "refs/dgit-fetch/$csuite"; } sub stripepoch ($) { my ($vsn) = @_; @@ -448,6 +448,7 @@ our %defcfg = ('dgit.default.distro' => 'debian', 'dgit-distro.debian.git-user-force' => 'dgit', 'dgit-distro.debian.git-proto' => 'git+ssh://', 'dgit-distro.debian.git-path' => '/dgit/debian/repos', + 'dgit-distro.debian.git-create' => 'true', 'dgit-distro.debian.git-check' => 'ssh-cmd', 'dgit-distro.debian.archive-query-url', 'https://api.ftp-master.debian.org/', # 'dgit-distro.debian.archive-query-tls-key', @@ -1020,7 +1021,7 @@ sub check_for_git () { my ($usedistro,) = access_distros(); $instead_distro= cfg("dgit-distro.$usedistro.diverts.$divert"); $instead_distro =~ s{^/}{ access_basedistro()."/" }e; - printdebug "diverting $divert so using distro $instead_distro\n"; + progress "diverting to $divert (using config for $instead_distro)"; return check_for_git(); } failedcmd @cmd unless $r =~ m/^[01]$/; @@ -1343,12 +1344,33 @@ sub ensure_we_have_orig () { } sub git_fetch_us () { - runcmd_ordryrun_local @git, qw(fetch),access_giturl(),fetchspec(); - if (deliberately_not_fast_forward) { - runcmd_ordryrun_local @git, qw(fetch -p), access_giturl(), - map { "+refs/$_/*:".lrfetchrefs."/$_/*" } - qw(tags heads); - } + my @specs = (fetchspec()); + push @specs, + map { "+refs/$_/*:".lrfetchrefs."/$_/*" } + qw(tags heads); + runcmd_ordryrun_local @git, qw(fetch -p -n -q), access_giturl(), @specs; + + my %here; + my $tagpat = debiantag('*',access_basedistro); + + git_for_each_ref("refs/tags/".$tagpat, sub { + my ($objid,$objtype,$fullrefname,$reftail) = @_; + printdebug "currently $fullrefname=$objid\n"; + $here{$fullrefname} = $objid; + }); + git_for_each_ref(lrfetchrefs."/tags/".$tagpat, sub { + my ($objid,$objtype,$fullrefname,$reftail) = @_; + my $lref = "refs".substr($fullrefname, length lrfetchrefs); + printdebug "offered $lref=$objid\n"; + if (!defined $here{$lref}) { + my @upd = (@git, qw(update-ref), $lref, $objid, ''); + runcmd_ordryrun_local @upd; + } elsif ($here{$lref} eq $objid) { + } else { + print STDERR \ + "Not updateting $lref from $here{$lref} to $objid.\n"; + } + }); } sub fetch_from_archive () { @@ -1455,6 +1477,38 @@ END return 1; } +sub set_local_git_config ($$) { + my ($k, $v) = @_; + runcmd @git, qw(config), $k, $v; +} + +sub setup_mergechangelogs () { + my $driver = 'dpkg-mergechangelogs'; + my $cb = "merge.$driver"; + my $attrs = '.git/info/attributes'; + ensuredir '.git/info'; + + open NATTRS, ">", "$attrs.new" or die "$attrs.new $!"; + if (!open ATTRS, "<", $attrs) { + $!==ENOENT or die "$attrs: $!"; + } else { + while () { + chomp; + next if m{^debian/changelog\s}; + print NATTRS $_, "\n" or die $!; + } + ATTRS->error and die $!; + close ATTRS; + } + print NATTRS "debian/changelog merge=$driver\n" or die $!; + close NATTRS; + + set_local_git_config "$cb.name", 'debian/changelog merge driver'; + set_local_git_config "$cb.driver", 'dpkg-mergechangelogs -m %O %A %B %A'; + + rename "$attrs.new", "$attrs" or die "$attrs: $!"; +} + sub clone ($) { my ($dstdir) = @_; canonicalise_suite(); @@ -1465,7 +1519,7 @@ sub clone ($) { runcmd @git, qw(init -q); my $giturl = access_giturl(1); if (defined $giturl) { - runcmd @git, qw(config), "remote.$remotename.fetch", fetchspec(); + set_local_git_config "remote.$remotename.fetch", fetchspec(); open H, "> .git/HEAD" or die $!; print H "ref: ".lref()."\n" or die $!; close H or die $!; @@ -1484,6 +1538,7 @@ sub clone ($) { $vcsgiturl =~ s/\s+-b\s+\S+//g; runcmd @git, qw(remote add vcs-git), $vcsgiturl; } + setup_mergechangelogs(); runcmd @git, qw(reset --hard), lrref(); printdone "ready for work in $dstdir"; } @@ -1768,7 +1823,6 @@ sub dopush ($) { my $tag_obj_hash = cmdoutput @git, qw(hash-object -w -t tag), $tagobjfn; runcmd_ordryrun @git, qw(verify-tag), $tag_obj_hash; runcmd_ordryrun_local @git, qw(update-ref), "refs/tags/$tag", $tag_obj_hash; - runcmd_ordryrun @git, qw(tag -v --), $tag; if (!check_for_git()) { create_remote_git_repo(); @@ -1897,10 +1951,12 @@ sub cmd_push { if ($new_package) { local ($package) = $existing_package; # this is a hack canonicalise_suite(); - } - if (defined $specsuite && $specsuite ne $isuite) { + } else { canonicalise_suite(); - $csuite eq $specsuite or + } + if (defined $specsuite && + $specsuite ne $isuite && + $specsuite ne $csuite) { fail "dgit push: changelog specifies $isuite ($csuite)". " but command line specifies $specsuite"; } @@ -2579,6 +2635,8 @@ sub clean_tree () { runcmd_ordryrun_local @dpkgbuildpackage, qw(-T clean); } elsif ($cleanmode eq 'git') { runcmd_ordryrun_local @git, qw(clean -xdf); + } elsif ($cleanmode eq 'git-ff') { + runcmd_ordryrun_local @git, qw(clean -xdff); } elsif ($cleanmode eq 'none') { } else { die "$cleanmode ?"; @@ -2697,7 +2755,7 @@ sub cmd_sbuild { changedir ".."; my $pat = "${package}_".(stripepoch $version)."_*.changes"; if (act_local()) { - stat_exist $dscfn or fail "$dscfn (in parent directory): $!"; + stat_exists $dscfn or fail "$dscfn (in parent directory): $!"; stat_exists $sourcechanges or fail "$sourcechanges (in parent directory): $!"; foreach my $cf (glob $pat) { @@ -2746,6 +2804,11 @@ sub cmd_clone_dgit_repos_server { exec @cmd or fail "exec git clone: $!\n"; } +sub cmd_setup_mergechangelogs { + badusage "no arguments allowed to dgit setup-mergechangelogs" if @ARGV; + setup_mergechangelogs(); +} + #---------- argument parsing and main program ---------- sub cmd_version { @@ -2810,7 +2873,7 @@ sub parseopts () { } elsif (m/^--build-products-dir=(.*)/s) { push @ropts, $_; $buildproductsdir = $1; - } elsif (m/^--clean=(dpkg-source|git|none)$/s) { + } elsif (m/^--clean=(dpkg-source|git|git-ff|none)$/s) { push @ropts, $_; $cleanmode = $1; } elsif (m/^--clean=(.*)$/s) { @@ -2882,6 +2945,9 @@ sub parseopts () { } elsif (s/^-wg$//s) { push @ropts, $&; $cleanmode = 'git'; + } elsif (s/^-wgf$//s) { + push @ropts, $&; + $cleanmode = 'git-ff'; } elsif (s/^-wd$//s) { push @ropts, $&; $cleanmode = 'dpkg-source';