Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort list of git refs in most recently used (committed) order #8767

Closed
thomaseizinger opened this issue Mar 24, 2020 · 4 comments
Closed

Sort list of git refs in most recently used (committed) order #8767

thomaseizinger opened this issue Mar 24, 2020 · 4 comments
Labels
Feature New feature or request Topic: completion Pull Request or issue regarding completion

Comments

@thomaseizinger
Copy link

Is your feature request related to a particular plugin or theme? If so, specify it.

gitfast

Is your feature request related to a problem? Please describe.

Having to exactly remember branch names is cumbersome, I would much more prefer if the result of gco <TAB> would list branches I (or possible someone else if remote branches are included) recently committed to.

Describe the solution you'd like

Make use of the --sort option of git-for-each-ref command to sort by committer date. (Source: https://stackoverflow.com/a/5188364/2489334) I think, the following function would need to be changed:

__git_refs ()
{
local i hash dir track="${2-}"
local list_refs_from=path remote="${1-}"
local format refs
local pfx="${3-}" cur_="${4-$cur}" sfx="${5-}"
local match="${4-}"
local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers
__git_find_repo_path
dir="$__git_repo_path"
if [ -z "$remote" ]; then
if [ -z "$dir" ]; then
return
fi
else
if __git_is_configured_remote "$remote"; then
# configured remote takes precedence over a
# local directory with the same name
list_refs_from=remote
elif [ -d "$remote/.git" ]; then
dir="$remote/.git"
elif [ -d "$remote" ]; then
dir="$remote"
else
list_refs_from=url
fi
fi
if [ "$list_refs_from" = path ]; then
if [[ "$cur_" == ^* ]]; then
pfx="$pfx^"
fer_pfx="$fer_pfx^"
cur_=${cur_#^}
match=${match#^}
fi
case "$cur_" in
refs|refs/*)
format="refname"
refs=("$match*" "$match*/**")
track=""
;;
*)
for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD REBASE_HEAD; do
case "$i" in
$match*)
if [ -e "$dir/$i" ]; then
echo "$pfx$i$sfx"
fi
;;
esac
done
format="refname:strip=2"
refs=("refs/tags/$match*" "refs/tags/$match*/**"
"refs/heads/$match*" "refs/heads/$match*/**"
"refs/remotes/$match*" "refs/remotes/$match*/**")
;;
esac
__git_dir="$dir" __git for-each-ref --format="$fer_pfx%($format)$sfx" \
"${refs[@]}"
if [ -n "$track" ]; then
# employ the heuristic used by git checkout
# Try to find a remote branch that matches the completion word
# but only output if the branch name is unique
__git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
--sort="refname:strip=3" \
"refs/remotes/*/$match*" "refs/remotes/*/$match*/**" | \
uniq -u
fi
return
fi
case "$cur_" in
refs|refs/*)
__git ls-remote "$remote" "$match*" | \
while read -r hash i; do
case "$i" in
*^{}) ;;
*) echo "$pfx$i$sfx" ;;
esac
done
;;
*)
if [ "$list_refs_from" = remote ]; then
case "HEAD" in
$match*) echo "${pfx}HEAD$sfx" ;;
esac
__git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
"refs/remotes/$remote/$match*" \
"refs/remotes/$remote/$match*/**"
else
local query_symref
case "HEAD" in
$match*) query_symref="HEAD" ;;
esac
__git ls-remote "$remote" $query_symref \
"refs/tags/$match*" "refs/heads/$match*" \
"refs/remotes/$match*" |
while read -r hash i; do
case "$i" in
*^{}) ;;
refs/*) echo "$pfx${i#refs/*/}$sfx" ;;
*) echo "$pfx$i$sfx" ;; # symbolic refs
esac
done
fi
;;
esac
}

Unfortunately, I have not idea how to write completion scripts or ZSH scripts in general so I couldn't make it work. If I try to add the --sort argument, it just seems to be ignored. The completion values of gco <TAB> seem to be sorted alphabetically.

Describe alternatives you've considered

Setting the branch.sort git config value but it doesn't seem to have an effect.

Additional context

refs are sorted alphabetically:

image

@thomaseizinger thomaseizinger added the Feature New feature or request label Mar 24, 2020
@mcornella mcornella added the Topic: completion Pull Request or issue regarding completion label Apr 13, 2020
@mcornella
Copy link
Member

Two things should change for that:

  • The __git_refs function should echo the refs in MRU order
  • The __gitcomp_direct function should run compadd with -V something to specify unordered display. Otherwise, compadd prints the entries in alphabetical order no matter the order in which the arguments were passed to it.

@thomaseizinger
Copy link
Author

thomaseizinger commented Apr 19, 2020

Do you think it makes sense to change the default behaviour here and make a PR for these changes?

If not, what is your advice on patching these files locally that are compatible with updates?

thomaseizinger added a commit to thomaseizinger/ohmyzsh that referenced this issue Apr 26, 2020
@thomaseizinger
Copy link
Author

@mcornella I submitted a PR here: #8860

@mcornella
Copy link
Member

These should be pushed upstream, i.e. on the git repository. Meanwhile, you can set up a custom plugin, see adding a new plugin.

cc @felipec

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature New feature or request Topic: completion Pull Request or issue regarding completion
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants