zsh-workers
 help / color / mirror / code / Atom feed
From: Robbie Gates <robbie@m8s.org>
To: zsh-workers@zsh.org
Subject: git checkout @... completion
Date: Tue, 31 Mar 2015 22:10:42 +1100	[thread overview]
Message-ID: <CAH6YsRe33+_Y6O5WSq_DjP=AouXVJ8=QGDHwM+mb6=1301=aVw@mail.gmail.com> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 1454 bytes --]

Hi All,

  i've modified the git completions in _git to complete git checkout's
@{-n} syntax for recent branches. I'm pretty sure the way i've done it is
somewhat ugly, because my understanding of the completion system is
primitive. I've attached a patch (against a local copy) - please let me
know if it's better to submit changes as a PR and i'll do that.

  More importantly, any review comments before the patch is usable are most
welcome. In particular, it just offers the first for each unique amongst
the most recent 9 branches. This is done by parsing the output of git log
--walk-reflogs using the same logic as git uses to interpret the @...
syntax according to my reading of sha1_name.c
<https://github.com/git/git/blob/e80e85a52adfda053cafc3b23058a86aff35404f/sha1_name.c#L930>
in
the git source using a bit of awkery. Although simplistic, i think this is
useful in practice.

  In particular, it could be rewritten to loop over git check-ref-format
--branch "@{-$i}" for increasing i until a given (by completion style
maybe, or environment variable) number of unique previous branches was
found. This felt a bit more rounadabout (and effort) than the quick version
here, but if it's more likely to be acceptable that this patch please let
me know and i'll rework it. Any pointers to completions with a configurable
depth / length that i could use to glean the right way to do this kind of
thing welcome.

  Thanks for your time,

 - Robbie

[-- Attachment #1.2: Type: text/html, Size: 1661 bytes --]

[-- Attachment #2: _git.patch --]
[-- Type: application/octet-stream, Size: 2379 bytes --]

diff --git a/functions/_git b/functions/_git
index c4e386b..884756c 100644
--- a/functions/_git
+++ b/functions/_git
@@ -463,27 +463,37 @@ _git-checkout () {
         local branch_arg='branches::__git_revisions' \
               remote_branch_noprefix_arg='remote branches::__git_remote_branch_names_noprefix' \
               tree_ish_arg='tree-ishs::__git_tree_ishs' \
-              file_arg='modified-files::__git_modified_files'
+              file_arg='modified-files::__git_modified_files' \
+              previous_arg='previous-branches::__git_previous_branches'
 
         if [[ -n ${opt_args[(I)-b|-B|--orphan|--detach]} ]]; then
           remote_branch_noprefix_arg=
           tree_ish_arg=
           file_arg=
+          previous_arg=
         elif [[ -n $opt_args[(I)--track] ]]; then
           branch_arg='remote-branches::__git_remote_branch_names'
           remote_branch_noprefix_arg=
           tree_ish_arg=
           file_arg=
+          previous_arg=
         elif [[ -n ${opt_args[(I)--ours|--theirs|-m|--conflict|--patch]} ]]; then
           branch_arg=
           remote_branch_noprefix_arg=
+          previous_arg=
+        elif [[ $line[CURRENT] = @* ]]; then
+          branch_arg=
+          remote_branch_noprefix_arg=
+          tree_ish_arg=
+          file_arg=
         fi
 
         _alternative \
           $branch_arg \
           $remote_branch_noprefix_arg \
           $tree_ish_arg \
-          $file_arg && ret=0
+          $file_arg \
+          $previous_arg && ret=0
       elif [[ -n ${opt_args[(I)-b|-B|-t|--track|--orphan|--detach]} ]]; then
         _nothing
       elif [[ -n $line[1] ]] && __git_is_treeish $line[1]; then
@@ -5769,6 +5779,14 @@ __git_notes_refs () {
   _wanted notes-refs expl 'notes ref' compadd $* - $notes_refs
 }
 
+(( $+functions[__git_previous_branches] )) ||
+__git_previous_branches () {
+  declare -a previous_branches
+  # We don't need to escape : in branch names, because they can't be there (see git help check-ref-format)
+  previous_branches=(${(f)"$(_call_program previous-branches "git log --max-count=9 --walk-reflogs --grep-reflog '^checkout: moving from .* to' --format='%gs' 2>/dev/null" | awk '{if (!seen[$4]) { seen[$4]=1 ; print "@{-" NR "}:" $4 } }')"})
+  _describe "previous branch" previous_branches
+}
+
 # File Argument Types
 
 (( $+functions[__git_files_relative] )) ||

             reply	other threads:[~2015-03-31 11:10 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-31 11:10 Robbie Gates [this message]
2015-04-01  9:41 ` Daniel Shahaf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAH6YsRe33+_Y6O5WSq_DjP=AouXVJ8=QGDHwM+mb6=1301=aVw@mail.gmail.com' \
    --to=robbie@m8s.org \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).