From ce6eee9d419bcac712d3ddbb084619d3c02681bd Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 23 Oct 2016 00:09:22 +0100 Subject: [PATCH] Automatically calculate which .origs are required * Spot if any of our .origs have different hashes to the archive's * Update the .changes to have the set of .origs that the archive doesn't Signed-off-by: Ian Jackson --- debian/changelog | 2 + dgit | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ dgit.1 | 9 ++++- 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 5c72474e..4ff91b9d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,8 @@ dgit (2.9~) unstable; urgency=low * Split brain mode: Fix --new. Closes:#842354. + * During push, automatically calculate which .origs are required, + so user never needs [--ch:]-sa or [--ch:]-sd. Closes:#829116. -- diff --git a/dgit b/dgit index db03cfbd..79618d90 100755 --- a/dgit +++ b/dgit @@ -1615,6 +1615,101 @@ sub is_orig_file_of_vsn ($$) { return 1; } +sub changes_update_origs_from_dsc ($$$$) { + my ($dsc, $changes, $upstreamvsn, $changesfile) = @_; + my %changes_f; + printdebug "checking origs needed ($upstreamvsn)...\n"; + $_ = getfield $changes, 'Files'; + m/^\w+ \d+ (\S+ \S+) \S+$/m or + fail "cannot find section/priority from .changes Files field"; + my $placementinfo = $1; + my %changed; + printdebug "checking origs needed placement '$placementinfo'...\n"; + foreach my $l (split /\n/, getfield $dsc, 'Files') { + $l =~ m/\S+$/ or next; + my $file = $&; + printdebug "origs $file | $l\n"; + next unless is_orig_file_of_vsn $file, $upstreamvsn; + printdebug "origs $file is_orig\n"; + my $have = archive_query('file_in_archive', $file); + if (!defined $have) { + print STDERR <{$archivefield}; + $_ = $dsc->{$fname}; + next unless defined; + m/^(\w+) .* \Q$file\E$/m or + fail ".dsc $fname missing entry for $file"; + if ($h->{$archivefield} eq $1) { + $same++; + } else { + push @differ, + "$archivefield: $h->{$archivefield} (archive) != $1 (local .dsc)"; + } + } + die "$file ".Dumper($h)." ?!" if $same && @differ; + $found_same++ + if $same; + push @found_differ, "archive $h->{filename}: ".join "; ", @differ + if @differ; + } + print "origs $file f.same=$found_same #f._differ=$#found_differ\n"; + if (@found_differ && !$found_same) { + fail join "\n", + "archive contains $file with different checksum", + @found_differ; + } + # Now we edit the changes file to add or remove it + foreach my $csumi (@files_csum_info_fields) { + my ($fname, $module, $method, $archivefield) = @$csumi; + next unless defined $changes->{$fname}; + if ($found_same) { + # in archive, delete from .changes if it's there + $changed{$file} = "removed" if + $changes->{$fname} =~ s/^.* \Q$file\E$(?:)\n//m; + } elsif ($changes->{$fname} =~ m/^.* \Q$file\E$(?:)\n/m) { + # not in archive, but it's here in the .changes + } else { + my $dsc_data = getfield $dsc, $fname; + $dsc_data =~ m/^(.* \Q$file\E$)\n/m or die "$dsc_data $file ?"; + my $extra = $1; + $extra =~ s/ \d+ /$&$placementinfo / + or die "$fname $extra >$dsc_data< ?" + if $fname eq 'Files'; + $changes->{$fname} .= "\n". $extra; + $changed{$file} = "added"; + } + } + } + if (%changed) { + foreach my $file (keys %changed) { + progress sprintf + "edited .changes for archive .orig contents: %s %s", + $changed{$file}, $file; + } + my $chtmp = "$changesfile.tmp"; + $changes->save($chtmp); + if (act_local()) { + rename $chtmp,$changesfile or die "$changesfile $!"; + } else { + progress "[new .changes left in $changesfile]"; + } + } else { + progress "$changesfile already has appropriate .orig(s) (if any)"; + } +} + sub make_commit ($) { my ($file) = @_; return cmdoutput @git, qw(hash-object -w -t commit), $file; @@ -3356,6 +3451,10 @@ END files_compare_inputs($dsc, $changes) unless forceing [qw(dsc-changes-mismatch)]; + # Perhaps adjust .dsc to contain right set of origs + changes_update_origs_from_dsc($dsc, $changes, $upstreamversion, + $changesfile); + # Checks complete, we're going to try and go ahead: responder_send_file('changes',$changesfile); diff --git a/dgit.1 b/dgit.1 index cc10695a..f7f8dad5 100644 --- a/dgit.1 +++ b/dgit.1 @@ -155,6 +155,9 @@ the built source package not being identical to the git tree. In more detail: dgit push checks that the current HEAD corresponds to the .dsc. It then pushes the HEAD to the suite's dgit-repos branch, +adjusts the .changes to include any .origs which the archive lacks +and exclude .origs which the archive has +(so -sa and -sd are not needed when building for dgit push), makes a signed git tag, edits the .dsc to contain the dgit metadata field, runs debsign to sign the upload (.dsc and .changes), pushes the signed tag, and finally uses dput to upload the .changes to the @@ -591,7 +594,11 @@ Specifies a single additional option to pass, eventually, to dpkg-genchanges. Options which are safe to pass include -.BR "-si -sa -sd -C" . +.BR -C +(and also +.BR "-si -sa -sd" +although these should never be necessary with Debian since dgit +automatically calculates whether .origs need to be uploaded.) For other options the caveat below applies. .TP -- 2.30.2