Hi Junio & Rubén, On Tue, 16 Aug 2022, Johannes Schindelin wrote: > On Mon, 8 Aug 2022, Junio C Hamano wrote: > > > Johannes Schindelin <Johannes.Schindelin@xxxxxx> writes: > > > > > @@ -1420,6 +1420,12 @@ static int interpret_nth_prior_checkout(struct repository *r, > > > const char *brace; > > > char *num_end; > > > > > > + if (namelen == 1 && *name == '-') { > > > + brace = name; > > > + nth = 1; > > > + goto find_nth_checkout; > > > + } > > > + > > > if (namelen < 4) > > > return -1; > > > if (name[0] != '@' || name[1] != '{' || name[2] != '-') > > > > If a solution along this line works, it would be far cleaner design > > than the various hacks we have done in the past, noticing "-" and > > replacing with "@{-1}". > > Indeed, but it does not work as-is: `interpret_nth_prior_checkout()` is > used on prefixes of a rev, and for the special handling of `-` we cannot > have that. > > [...] > > One thing we could do, however, would be to patch only > `repo_interpret_branch_name()`, i.e. only allow `-` to imply the > previous branch name in invocations where a branch name is asked for > _explicitly_. I.e. not any random revision, but specifically a branch > name. This patch does that: -- snip -- diff --git a/object-name.c b/object-name.c index 4d2746574cd..a2732be3b71 100644 --- a/object-name.c +++ b/object-name.c @@ -1616,6 +1616,20 @@ int repo_interpret_branch_name(struct repository *r, if (!namelen) namelen = strlen(name); + if (namelen == 1 && *name == '-') { + struct grab_nth_branch_switch_cbdata cb = { + .remaining = 1, + .sb = buf + }; + + if (refs_for_each_reflog_ent_reverse(get_main_ref_store(r), + "HEAD", + grab_nth_branch_switch, + &cb) <= 0) + return -1; + return namelen; + } + if (!options->allowed || (options->allowed & INTERPRET_BRANCH_LOCAL)) { len = interpret_nth_prior_checkout(r, name, namelen, buf); if (!len) { diff --git a/t/t3204-branch-name-interpretation.sh b/t/t3204-branch-name-interpretation.sh index 993a6b5eff7..5acbef95913 100755 --- a/t/t3204-branch-name-interpretation.sh +++ b/t/t3204-branch-name-interpretation.sh @@ -67,6 +67,22 @@ test_expect_success 'delete branch via @{-1}' ' expect_deleted previous-del ' +test_expect_success 'delete branch via -' ' + git checkout -b previous-del && + git checkout - && + + git branch -d - && + expect_deleted previous-del && + + git branch previous-del2 && + git checkout -b previous-del && + git checkout - && + + git branch -d previous-del2 - && + expect_deleted previous-del && + expect_deleted previous-del2 +' + test_expect_success 'delete branch via local @{upstream}' ' git branch local-del && git branch --set-upstream-to=local-del && -- snap -- This adds support for things like `git branch -d -`, and it even verifies that that works. What does not work with this patch is `git show -`. I am not sure whether we want to make that work, although I have to admit that I would use it. Often. And this patch would make it work, the test suite even passes with it: -- snip -- diff --git a/revision.c b/revision.c index f4eee11cc8b..207b554aef1 100644 --- a/revision.c +++ b/revision.c @@ -2802,7 +2802,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s revarg_opt |= REVARG_CANNOT_BE_FILENAME; for (left = i = 1; i < argc; i++) { const char *arg = argv[i]; - if (!seen_end_of_options && *arg == '-') { + if (!seen_end_of_options && *arg == '-' && arg[1]) { int opts; opts = handle_revision_pseudo_opt( -- snap -- That latter patch obviously needs at least one accompanying test case, and the patch series would then need to drop the special-casings we already have for "-". Rubén, do you want to take this a bit further? Ciao, Dscho P.S.: For convenient fetching, I opened a draft PR here: https://github.com/gitgitgadget/git/pull/1329