From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26060 invoked by alias); 25 Aug 2016 00:59:32 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 39102 Received: (qmail 10116 invoked from network); 25 Aug 2016 00:59:32 -0000 X-Qmail-Scanner-Diagnostics: from out2-smtp.messagingengine.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1. Clear:RC:0(66.111.4.26):SA:0(0.0/5.0):. Processed in 0.451836 secs); 25 Aug 2016 00:59:32 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.1 X-Envelope-From: d.s@daniel.shahaf.name X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Received-SPF: none (ns1.primenet.com.au: domain at daniel.shahaf.name does not designate permitted sender hosts) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= daniel.shahaf.name; h=cc:date:from:message-id:subject:to :x-sasl-enc:x-sasl-enc; s=mesmtp; bh=xCHP2JbmWl8a1CHnUP62gv2jST0 =; b=0/stvUHnP+eRiVJyN+KQ29Fw3dT9aiD5kRctkXVrhrZv9A9D+GuZCVBcG6c nqPMmwl9FSekCteCIT2hkptoQ9aqEW5wsPmiw+WRaD/94JQKenvnnx0paI4SlAmM lJfX8GzwQWzkLEjBl+F+abXSSgjC+ClEEpt26sF7G46LKsEQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:message-id:subject:to :x-sasl-enc:x-sasl-enc; s=smtpout; bh=xCHP2JbmWl8a1CHnUP62gv2jST 0=; b=o7lcJaEMzwRRlHdzb8mygXYJZwwFy0Wk5YaFv43V1i9BO6DkeDLiRsMpRz 70v8bOfyHINm2xjja/Iy9u265+8iiIWfKeuRA33C6RZI2VQlI5fPrhbYhNxwHjAE NCx5xf3L3mscdTxW9/34LyyMOq8wj06b++OL8YO/YC9lbcA8M= X-Sasl-enc: 6tDTModLj7MQ6uvNbtd2EjKud5ulmwsFBWojzeTj91vP 1472086764 From: Daniel Shahaf To: zsh-workers@zsh.org Cc: Daniel Hahler Subject: [PATCH] __git_recent_branches: Optimise. Date: Thu, 25 Aug 2016 00:59:08 +0000 Message-Id: <1472086748-16738-1-git-send-email-danielsh@fujitsu.shahaf.local2> X-Mailer: git-send-email 2.1.4 This improves performance from 0.6s to 0.04s (+93%) on one of Daniel Hahler's repositories. --- Completion/Unix/Command/_git | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git index 40b2c11..66fc557 100644 --- a/Completion/Unix/Command/_git +++ b/Completion/Unix/Command/_git @@ -6051,35 +6051,39 @@ __git_recent_branches__names() # # See workers/38592 for an equivalent long-hand implementation, and the rest # of that thread for why this implementation was chosen instead. + # + # Note: since we obtain the "from" part of the reflog, we only obtain heads, not tags. reply=(${${(u)${${(0)"$(_call_program reflog git reflog -1000 -z --grep-reflog='\^checkout:\ moving\ from\ ' --pretty='%gs')"}#checkout: moving from }%% *}:#[[:xdigit:]](#c40)}) } (( $+functions[__git_recent_branches] )) || __git_recent_branches() { local -a branches descriptions - local branch description local -a reply + local -aU valid_ref_names_munged=( ${"${(f)"$(_call_program valid-ref-names 'git for-each-ref --format="%(refname)" refs/heads/ refs/tags/')"}"#refs/(heads|tags)/} ) - __git_recent_branches__names \ - ; for branch in $reply - do - # ### We'd want to convert all $reply to $descriptions in one shot, - # ### with this: - # ### array=("${(ps:\0:)"$(_call_program descriptions git --no-pager log --no-walk=unsorted -z --pretty=%s ${(q)reply} --)"}") - # ### , but git croaks if any of the positional arguments is a ref name - # ### that has been deleted. (So does 'git rev-parse'.) - # ### Hence, we resort to fetching the descriptions one-by-one. - # ### This would be costly if fork() is expensive. - description="$(_call_program description git --no-pager log --no-walk=unsorted --pretty=%s ${(q)branch} --)" - - # If the ref has been deleted, $description would be empty. - if [[ -n "$description" ]]; then - branches+=$branch - descriptions+="${branch//:/\:}:${description}" - fi + # 1. Obtain names of recently-checked-out branches from the reflog. + # 2. Remove ref names that that no longer exist from the list. + # (We must do this because #3 would otherwise croak on them.) + __git_recent_branches__names; branches=( ${(@)reply:*valid_ref_names_munged} ) + + # 3. Obtain log messages for all of them in one shot. + descriptions=( ${(f)"$(_call_program all-descriptions git --no-pager log --no-walk=unsorted --pretty=%s ${(q)branches} --)"} ) + + if (( $#branches != $#descriptions )); then + # ### Trouble... + zle -M "__git_recent_branches: \$#branches != \$#descriptions" + return 1 + fi + + # 4. Synthesize the data structure _describe wants. + local -a branches_colon_descriptions + local branch description + for branch description in ${branches:^descriptions} ; do + branches_colon_descriptions+="${branch//:/\:}:${description}" done - _describe -V -t recent-branches "recent branches" descriptions branches + _describe -V -t recent-branches "recent branches" branches_colon_descriptions } (( $+functions[__git_commits_prefer_recent] )) ||