use File::Path;
use File::Basename;
use Dpkg::Control::Hash;
+use Debian::Dgit::ExitStatus;
+use Debian::Dgit::I18n;
BEGIN {
use Exporter ();
git_check_unmodified
git_reflog_action_msg git_update_ref_cmd
make_commit_text
+ reflog_cache_insert reflog_cache_lookup
$package_re $component_re $deliberately_re
$distro_re $versiontag_re $series_filename_re
$orig_f_comp_re $orig_f_sig_re $orig_f_tail_re
our $printdebug_when_debuglevel = 1;
our $debugcmd_when_debuglevel = 1;
+# these three all go together, only valid after record_maindir
+our $maindir;
+our $maindir_gitdir;
+our $maindir_gitcommon;
+
# policy hook exit status bits
# see dgit-repos-server head comment for documentation
# 1 is reserved in case something fails with `exit 1' and to spot
sub shellquote {
my @out;
local $_;
- defined or confess 'internal error' foreach @_;
+ defined or confess __ 'internal error' foreach @_;
foreach my $a (@_) {
$_ = $a;
if (!length || m{[^-=_./:0-9a-z]}i) {
}
sub failmsg {
- my $s = "error: @_\n";
+ my $s = f_ "error: %s\n", "@_";
$s =~ s/\n\n$/\n/g;
my $prefix = _us().": ";
$s =~ s/^/$prefix/gm;
sub must_getcwd () {
my $d = getcwd();
- defined $d or fail "getcwd failed: $!";
+ defined $d or fail f_ "getcwd failed: %s\n", $!;
return $d;
}
sub waitstatusmsg () {
if (!$?) {
- return "terminated, reporting successful completion";
+ return __ "terminated, reporting successful completion";
} elsif (!($? & 255)) {
- return "failed with error exit status ".WEXITSTATUS($?);
+ return f_ "failed with error exit status %s", WEXITSTATUS($?);
} elsif (WIFSIGNALED($?)) {
my $signum=WTERMSIG($?);
- return "died due to fatal signal ".
+ return f_ "died due to fatal signal %s",
($signames[$signum] // "number $signum").
($? & 128 ? " (core dumped)" : ""); # POSIX(3pm) has no WCOREDUMP
} else {
- return "failed with unknown wait status ".$?;
+ return f_ "failed with unknown wait status %s", $?;
}
}
sub failedcmd_report_cmd {
my $intro = shift @_;
- $intro //= "failed command";
+ $intro //= __ "failed command";
{ local ($!); printcmd \*STDERR, _us().": $intro:", @_ or die $!; };
}
sub failedcmd_waitstatus {
if ($? < 0) {
- return "failed to fork/exec: $!";
+ return f_ "failed to fork/exec: %s", $!;
} elsif ($?) {
- return "subprocess ".waitstatusmsg();
+ return f_ "subprocess %s", waitstatusmsg();
} else {
- return "subprocess produced invalid output";
+ return __ "subprocess produced invalid output";
}
}
my ($dctrl,$field) = @_;
my $v = $dctrl->{$field};
return $v if defined $v;
- fail "missing field $field in ".$dctrl->get_option('name');
+ fail f_ "missing field %s in %s", $field, $dctrl->get_option('name');
}
sub parsechangelog_loop ($$$) {
return $h;
}
+sub reflog_cache_insert ($$$) {
+ my ($ref, $cachekey, $value) = @_;
+ # you must call this in $maindir
+ # you must have called record_maindir
+
+ # When we no longer need to support squeeze, use --create-reflog
+ # instead of this:
+ my $parent = $ref; $parent =~ s{/[^/]+$}{};
+ ensuredir "$maindir_gitcommon/logs/$parent";
+ my $makelogfh = new IO::File "$maindir_gitcommon/logs/$ref", '>>'
+ or die $!;
+
+ my $oldcache = git_get_ref $ref;
+
+ if ($oldcache eq $value) {
+ my $tree = cmdoutput qw(git rev-parse), "$value:";
+ # git update-ref doesn't always update, in this case. *sigh*
+ my $authline = (ucfirst _us()).
+ ' <'._us().'@example.com> 1000000000 +0000';
+ my $dummy = make_commit_text <<END;
+tree $tree
+parent $value
+author $authline
+committer $authline
+
+Dummy commit - do not use
+END
+ runcmd qw(git update-ref -m), _us()." - dummy", $ref, $dummy;
+ }
+ runcmd qw(git update-ref -m), $cachekey, $ref, $value;
+}
+
+sub reflog_cache_lookup ($$) {
+ my ($ref, $cachekey) = @_;
+ # you may call this in $maindir or in a playtree
+ # you must have called record_maindir
+ my @cmd = (qw(git log -g), '--pretty=format:%H %gs', $ref);
+ debugcmd "|(probably)",@cmd;
+ my $child = open GC, "-|"; defined $child or die $!;
+ if (!$child) {
+ chdir $maindir or die $!;
+ if (!stat "$maindir_gitcommon/logs/$ref") {
+ $! == ENOENT or die $!;
+ printdebug ">(no reflog)\n";
+ finish 0;
+ }
+ exec @cmd; die $!;
+ }
+ while (<GC>) {
+ chomp;
+ printdebug ">| ", $_, "\n" if $debuglevel > 1;
+ next unless m/^(\w+) (\S.*\S)$/ && $2 eq $cachekey;
+ close GC;
+ return $1;
+ }
+ die $! if GC->error;
+ failedcmd unless close GC;
+ return undef;
+}
+
# ========== playground handling ==========
# terminology:
# ----- maindir -----
-# these three all go together
-our $maindir;
-our $maindir_gitdir;
-our $maindir_gitcommon;
-
our $local_git_cfg;
sub record_maindir () {