summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Jackson <ijackson@chiark.greenend.org.uk>2016-10-23 00:09:22 +0100
committerIan Jackson <ijackson@chiark.greenend.org.uk>2016-10-30 16:36:20 +0000
commitce6eee9d419bcac712d3ddbb084619d3c02681bd (patch)
tree94ae9e3692a9ba47e4e2e352540d63439348e94f
parent261784cf5da5928375f838a13745f82626a6fe10 (diff)
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 <ijackson@chiark.greenend.org.uk>
-rw-r--r--debian/changelog2
-rwxr-xr-xdgit99
-rw-r--r--dgit.19
3 files changed, 109 insertions, 1 deletions
diff --git a/debian/changelog b/debian/changelog
index 5c72474..4ff91b9 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 db03cfb..79618d9 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 <<END;
+archive does not support .orig check; hope you used --ch:--sa/-sd if needed
+END
+ return;
+ }
+ my $found_same = 0;
+ my @found_differ;
+ printdebug "origs $file \$#\$have=$#$have\n";
+ foreach my $h (@$have) {
+ my $same = 0;
+ my @differ;
+ foreach my $csumi (@files_csum_info_fields) {
+ my ($fname, $module, $method, $archivefield) = @$csumi;
+ next unless defined $h->{$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 cc10695..f7f8dad 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