X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=dgit;h=65bc10f01f5c369d29b7d7a069999a8cac2fd78b;hb=0e6fdb25bacae95c16679692426b5ce7c2b150d9;hp=c6a3596605fd9657c17f877ad8f7e733e902f8db;hpb=d3009c4371f9209cd6745caa5e422355ac6692a7;p=dgit.git diff --git a/dgit b/dgit index c6a35966..65bc10f0 100755 --- a/dgit +++ b/dgit @@ -111,6 +111,8 @@ 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 stripepoch ($) { my ($vsn) = @_; $vsn =~ s/^\d+\://; @@ -162,6 +164,12 @@ sub deliberately ($) { return !!grep { $_ eq "--deliberately-$enquiry" } @deliberatelies; } +sub deliberately_not_fast_forward () { + foreach (qw(not-fast-forward fresh-repo)) { + return 1 if deliberately($_) || deliberately("TEST-dgit-only-$_"); + } +} + #---------- remote protocol support, common ---------- # remote push initiator/responder protocol: @@ -667,23 +675,6 @@ sub parsechangelog { return $c; } -sub git_get_ref ($) { - my ($refname) = @_; - my $got = cmdoutput_errok @git, qw(show-ref --), $refname; - if (!defined $got) { - $?==256 or fail "git show-ref failed (status $?)"; - printdebug "ref $refname= [show-ref exited 1]\n"; - return ''; - } - if ($got =~ m/^(\w+) \Q$refname\E$/m) { - printdebug "ref $refname=$1\n"; - return $1; - } else { - printdebug "ref $refname= [no match]\n"; - return ''; - } -} - sub must_getcwd () { my $d = getcwd(); defined $d or fail "getcwd failed: $!"; @@ -1271,20 +1262,13 @@ sub ensure_we_have_orig () { } } -sub is_fast_fwd ($$) { - my ($ancestor,$child) = @_; - my @cmd = (@git, qw(merge-base), $ancestor, $child); - my $mb = cmdoutput_errok @cmd; - if (defined $mb) { - return git_rev_parse($mb) eq git_rev_parse($ancestor); - } else { - $?==256 or failedcmd @cmd; - return 0; - } -} - 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); + } } sub fetch_from_archive () { @@ -1677,11 +1661,12 @@ sub dopush ($) { responder_send_command("param head $head"); responder_send_command("param csuite $csuite"); - if ($forceflag && defined $lastpush_hash) { - git_for_each_tag_referring($lastpush_hash, sub { - my ($objid,$fullrefname,$tagname) = @_; - responder_send_command("supersedes $fullrefname=$objid"); - $supersedes{$fullrefname} = $objid; + if ($forceflag) { + git_for_each_ref(lrfetchrefs, sub { + my ($objid,$objtype,$lrfetchrefname,$reftail) = @_; + my $rrefname= substr($lrfetchrefname, length(lrfetchrefs) + 1); + responder_send_command("supersedes $rrefname=$objid"); + $supersedes{$rrefname} = $objid; }); } @@ -1845,8 +1830,7 @@ sub cmd_push { if (fetch_from_archive()) { if (is_fast_fwd(lrref(), 'HEAD')) { # ok - } elsif (deliberately('not-fast-forward') || - deliberately('TEST-not-fast-forward-dgit-only')) { + } elsif (deliberately_not_fast_forward) { $forceflag = '+'; } else { fail "dgit push: HEAD is not a descendant".