[PATCH/RFC v3 0/6] N-th last checked out branch
From: Thomas Rast <hidden>
Date: 2016-06-15 22:45:58
Junio C Hamano [off-list ref] writes:
"cd -" is a very good analogy why your "-" shortcut is a short-sighted convenience feature that is too narrow and not well designed. "cd -" can go back, but you cannot say "ls -" to list the contents of the previous directory.
True.
Another reason is the one level limitation.
It shares that limitation with my mind ;-) But well, since you all seem to want a more general solution, here's a draft. I started poking around in refs.c for the backwards search, but the two reflog functions had a lot of functionality implemented very differently. So 1-4 are just cleanup and adding that backwards iterator. Note that 3/6 changes for_each_reflog_ent() to die() when it finds a format error, unlike the previous behaviour. No tests seemed to care, but maybe someone out there relies on having broken reflogs? ;-)
* The code read the reflog twice, first to count how many branch switching there are and then to locate the N-th entry we are interested in, because I was lazy. We may want an API to enumerate reflog entries in reverse.
So this might be settled.
* The reflog parser only parses "checkout" and not rebase action. It also does not notice "git checkout HEAD^" is not switching to a real branch.
I don't handle this, but I'm not sure how much of a problem it is. It can correctly detach and re-attach even in cases such as HEAD^. Ok, now that you mention it, it will probably put you on the parent of whatever you happened to be on, instead of the earlier value of HEAD^.
$ git checkout @{-1}
One problem with the syntax is that the assumption that there can only
be a single @{} construct is quite entrenched in sha1_name.c. So if
we want to support @{-1}@{1}, that'll need some extra work.
@{-1}~2 and similar work fine though.
Other things of note:
I changed the semantics to really only look at checkouts that "did
something". If you keep saying 'git checkout master' over and over,
those will not count towards the N.
I changed the parser to read the 'checkout: moving from $old' instead
of the 'to $new'. The above semantics introduced too many extra
conditions for my taste if we wanted to support the pre-1.5.3 reflog
comment format. (You'd have to check if the $to was changed from the
last [newer] entry, but then there's another border case when you do
'git init; git checkout -b side; git checkout -' because you never
moved to master.)
The @{date} syntax will be marginally slower after the refactoring
because the old parser carefully avoided parsing numbers where it
could. (I guess it could actually be done as a bisection for an extra
order of magnitude.)
It's far too early here to be sending mail.
Interactive rebase needs a "move hunk" feature.
Thomas Rast (6):
reflog: refactor parsing and checking
reflog: refactor log open+mmap
reflog: make for_each_reflog_ent use mmap
reflog: add backwards iterator
sha1_name: implement @{-N} syntax for N-th last checked out
checkout: implement '@{-N}' and '-' special abbreviations
Documentation/git-checkout.txt | 4 +
Documentation/git-rev-parse.txt | 3 +
builtin-checkout.c | 15 ++-
cache.h | 1 +
refs.c | 285 +++++++++++++++++++++++----------------
refs.h | 1 +
sha1_name.c | 79 +++++++++++-
t/t1505-rev-parse-last.sh | 71 ++++++++++
t/t2012-checkout-last.sh | 50 +++++++
9 files changed, 387 insertions(+), 122 deletions(-)
create mode 100755 t/t1505-rev-parse-last.sh
create mode 100755 t/t2012-checkout-last.sh