git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "SZEDER Gábor" <szeder.dev@gmail.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org, "SZEDER Gábor" <szeder.dev@gmail.com>
Subject: [PATCHv2 07/14] completion: don't disambiguate short refs
Date: Thu, 23 Mar 2017 16:29:17 +0100	[thread overview]
Message-ID: <20170323152924.23944-8-szeder.dev@gmail.com> (raw)
In-Reply-To: <20170323152924.23944-1-szeder.dev@gmail.com>

When the completion script lists short refs it does so using the 'git
for-each-ref' format 'refname:short', which makes sure that all listed
refs are unambiguous.  While disambiguating refs is technically
correct in this case, as opposed to the cases discussed in the
previous patch, this disambiguation involves several stat() syscalls
for each ref, thus, unfortunately, comes at a steep cost especially on
Windows and/or when there are a lot of refs to be listed.  A user of
Git for Windows reported[1] 'git checkout <TAB>' taking ~11 seconds in
a repository with just about 4000 refs.

However, it's questionable whether ambiguous refs are really that bad
to justify that much extra cost:

  - Ambiguous refs are not that common,
  - even if a repository contains ambiguous refs, they only hurt when
    the user actually happens to want to do something with one of the
    ambiguous refs, and
  - the issue can be easily circumvented by renaming those ambiguous
    refs.

  - On the other hand, apparently not that many refs are needed to
    make refs completion unacceptably slow on Windows,
  - and this slowness bites each and every time the user attempts refs
    completion, even when the repository doesn't contain any ambiguous
    refs.
  - Furthermore, circumventing the issue might not be possible or
    might be considerably more difficult and requires various
    trade-offs (e.g. working in a repository with only a few selected
    important refs while keeping a separate repository with all refs
    for reference).

Arguably, in this case the benefits of technical correctness are
rather minor compared to the price we pay for it, and we are better
off opting for performance over correctness.

Use the 'git for-each-ref' format 'refname:strip=2' to list short refs
to spare the substantial cost of disambiguating.

This speeds up refs completion considerably.  Uniquely completing a
branch in a repository with 100k local branches, all packed, best of
five:

  On Linux, before:

    $ time __git_complete_refs --cur=maste

    real    0m1.662s
    user    0m1.368s
    sys     0m0.296s

  After:

    real    0m0.831s
    user    0m0.808s
    sys     0m0.028s

  On Windows, before:

    real    0m12.457s
    user    0m1.016s
    sys     0m0.092s

  After:

    real    0m1.480s
    user    0m1.031s
    sys     0m0.060s

[1] - https://github.com/git-for-windows/git/issues/524

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
 contrib/completion/git-completion.bash | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index e129f674e..5ee35d530 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -401,7 +401,7 @@ __git_refs ()
 			for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
 				if [ -e "$dir/$i" ]; then echo $pfx$i; fi
 			done
-			format="refname:short"
+			format="refname:strip=2"
 			refs="refs/tags refs/heads refs/remotes"
 			;;
 		esac
@@ -412,7 +412,7 @@ __git_refs ()
 			# Try to find a remote branch that matches the completion word
 			# but only output if the branch name is unique
 			local ref entry
-			__git for-each-ref --shell --format="ref=%(refname:short)" \
+			__git for-each-ref --shell --format="ref=%(refname:strip=2)" \
 				"refs/remotes/" | \
 			while read -r entry; do
 				eval "$entry"
@@ -437,7 +437,7 @@ __git_refs ()
 	*)
 		if [ "$list_refs_from" = remote ]; then
 			echo "HEAD"
-			__git for-each-ref --format="%(refname:short)" \
+			__git for-each-ref --format="%(refname:strip=2)" \
 				"refs/remotes/$remote/" | sed -e "s#^$remote/##"
 		else
 			__git ls-remote "$remote" HEAD \
-- 
2.12.1.485.g1616aa492


  parent reply	other threads:[~2017-03-23 15:29 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-23 15:29 [PATCHv2 00/14] completion: speed up refs completion SZEDER Gábor
2017-03-23 15:29 ` [PATCHv2 01/14] completion: remove redundant __gitcomp_nl() options from _git_commit() SZEDER Gábor
2017-03-23 15:29 ` [PATCHv2 02/14] completion: wrap __git_refs() for better option parsing SZEDER Gábor
2017-03-23 15:29 ` [PATCHv2 03/14] completion: support completing full refs after '--option=refs/<TAB>' SZEDER Gábor
2017-03-23 15:29 ` [PATCHv2 04/14] completion: support completing fully qualified non-fast-forward refspecs SZEDER Gábor
2017-03-23 15:29 ` [PATCHv2 05/14] completion: support excluding full refs SZEDER Gábor
2017-03-23 15:29 ` [PATCHv2 06/14] completion: don't disambiguate tags and branches SZEDER Gábor
2017-03-23 15:29 ` SZEDER Gábor [this message]
2017-03-24 19:31   ` [PATCHv2 07/14] completion: don't disambiguate short refs Jeff King
2017-03-23 15:29 ` [PATCHv2 08/14] completion: let 'for-each-ref' and 'ls-remote' filter matching refs SZEDER Gábor
2017-03-24 19:42   ` Jeff King
2017-03-28 15:34     ` SZEDER Gábor
2017-03-23 15:29 ` [PATCHv2 09/14] completion: let 'for-each-ref' strip the remote name from remote branches SZEDER Gábor
2017-03-23 15:29 ` [PATCHv2 10/14] completion: let 'for-each-ref' filter remote branches for 'checkout' DWIMery SZEDER Gábor
2017-03-23 15:29 ` [PATCHv2 11/14] completion: let 'for-each-ref' sort " SZEDER Gábor
2017-03-24 19:53   ` Jeff King
2017-03-23 15:29 ` [PATCHv2 12/14] completion: fill COMPREPLY directly when completing refs SZEDER Gábor
2017-03-23 15:29 ` [PATCHv2 13/14] completion: fill COMPREPLY directly when completing fetch refspecs SZEDER Gábor
2017-03-23 15:29 ` [PATCHv2 14/14] completion: speed up branch and tag completion SZEDER Gábor
2017-03-23 15:33 ` [PATCHv2 00/14] completion: speed up refs completion SZEDER Gábor
2017-03-23 18:28 ` Junio C Hamano
2017-03-24 20:01   ` Jeff King

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

  List information: http://vger.kernel.org/majordomo-info.html

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

  git send-email \
    --in-reply-to=20170323152924.23944-8-szeder.dev@gmail.com \
    --to=szeder.dev@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /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://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).