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) = @_;
'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',
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]$/;
}
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 () {
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 (<ATTRS>) {
+ 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();
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 $!;
$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";
}
$package = getfield $clogp, 'Source';
my $cversion = getfield $clogp, 'Version';
- my $tag = debiantag($cversion);
+ my $tag = debiantag($cversion, access_basedistro);
runcmd @git, qw(check-ref-format), $tag;
my $dscfn = dscfn($cversion);
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();
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";
}
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 ?";
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) {
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 {
} 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) {
} 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';