On Tue, Aug 18, 2020 at 10:41 AM Jeff King <peff@xxxxxxxx> wrote: > Hmm. I think the behavior we'd want is something like: > > # make sure the other side has three refs > git branch prune/one HEAD > git branch prune/two HEAD > git branch prune/three HEAD > git push dst.git refs/heads/prune/* > > # now drop two of ours, which are eligible for pruning > git branch -d prune/one > git branch -d prune/two > > # push with pruning, omitting "two" > git push --prune dst.git refs/heads/prune/* ^refs/heads/prune/two > > # we should leave "two" but still deleted "one" > test_write_lines one three >expect > git -C dst.git for-each-ref --format='%(refname:lstrip=3)' refs/heads/prune/ >actual > test_cmp expect actual > > I.e., the negative refspec shrinks the space we're considering pruning. > And we'd probably want a similar test for "fetch --prune". > > I just tried that, though, and got an interesting result. The push > actually complains: > > $ git push --prune dst.git refs/heads/prune/* ^refs/heads/prune/two > error: src refspec refs/heads/prune/two does not match any > error: failed to push some refs to 'dst.git' > > For negative refspecs, would we want to loosen the "must-exist" check? > Or really, is this getting into the "are we negative on the src or dst" > thing you brought up earlier? Especially with --prune, what I really > want to say is "do not touch the remote refs/heads/two". > > We can get work around it by using a wildcard: > > $ git push --prune dst.git refs/heads/prune/* ^refs/heads/prune/two* > To dst.git > - [deleted] prune/one > > So it works as I'd expect already with your patch. But I do wonder if > there are corner cases around the src/dst thing that might not behave > sensibly. > Hmm. So this raises a good point. I added a variation of this test where I used separate names for the source and destination. It looks like with the current implementation, negative refspecs always apply to the destination.