Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: [PATCH] _git: offer changed files relative to current directory
- X-seq: zsh-workers 27462
- From: ÅtÄpÃn NÄmec <stepnem@xxxxxxxxx>
- To: "Alexey I. Froloff" <raorn@xxxxxxxxxxxx>
- Subject: Re: [PATCH] _git: offer changed files relative to current directory
- Date: Sat, 5 Dec 2009 18:00:53 +0100
- Cc: zsh-workers@xxxxxxx
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:date:from:to:cc:subject :message-id:mail-followup-to:references:mime-version:content-type :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=pft3gfjtjBhmxJytK7yXq1bS4O5NJwQdH34ShelUstw=; b=sfzjHLAF2DWIYE+im/I4dvLhgJnJFrdXg86YeyrePERgvY1fGOp5kW9OVhKKkz4aLf cyh6y8LNQn757nwCqECd3plisaawrn2WduIgNVRobp/3kvGxGrdEKAvG85r64/EpA8Pg jI/WV7r6HynEGgSv84XGuB+3IKImM5WzUCCk0=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=date:from:to:cc:subject:message-id:mail-followup-to:references :mime-version:content-type:content-disposition :content-transfer-encoding:in-reply-to:user-agent; b=Iezt4NiLr0/A8VTC4UTQPwv3DiUgvGWhYUh0X9BCfjGhM4wjRmd7lJ449ELZvtWoSi G1PKDXacRoxt7cvdJfDQnB6BIYLElZbsBMEdrfho8kun0hbe3J8DuKzrooDGH7ey5f78 Yh92fVqkYL0Il0o5BCfPHDKiZaZra7XPJrdws=
- In-reply-to: <20091205151202.GE3344@xxxxxxxxxxxx>
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mail-followup-to: "Alexey I. Froloff" <raorn@xxxxxxxxxxxx>, zsh-workers@xxxxxxx
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
- References: <1259973163-20919-1-git-send-email-raorn@xxxxxxxxxxxx> <20091205120753.GA21684@headley> <20091205124258.GC3344@xxxxxxxxxxxx> <20091205151202.GE3344@xxxxxxxxxxxx>
On Sat, Dec 05, 2009 at 06:12:03PM +0300, Alexey I. Froloff wrote:
> On Sat, Dec 05, 2009 at 03:42:58PM +0300, Alexey I. Froloff wrote:
> > Just need pure-zsh "relative" implementation.
> Here's my quick'n'dirty code:
>
I'm not sure about the exact purpose of this function, but it doesn't
seem correct to me:
> relate()
> {
> local -a what to res
>
> what=( ${(ps:/:)"${${${${1//\/\///}//\/.\///}%%/.}%%/}"} )
> to=( ${(ps:/:)"${${${${2//\/\///}//\/.\///}%%/.}%%/}"} )
>
> while (( $#what > 0 )) && (( $#to > 0 )) && [[ $what[1] == $to[1] ]]; do
> what[1]=()
> to[1]=()
> done
It is not unlikely to have more same-named directories in different
parts of directory tree. IIUC, the code above won't always work
correctly in such situation (i.e. it will remove the directory from the
path, wrongly assuming it is the same directory for both paths).
I believe the only correct way to solve the path relativization problem
for arbitrary input is to use the *absolute* paths.
In any case, it would be more useful/comprehensible (to me at least) if
you included the solution with the former patch to solve the actual
problem.
Anyway, here is what I've been succesfully using for some time; don't
laugh your teeth off:
------- 8< -------
From: ÅtÄpÃn NÄmec <stepnem@xxxxxxxxx>
Date: Sat, 5 Dec 2009 17:42:56 +0100
Subject: [PATCH] _git: Fix commit path completion.
Paths returned by git-diff-index are relative to repository root; make
them relative to the current directory (i.e. how git-commit requires
them), using a `munge_paths' monsterfunction.
Signed-off-by: ÅtÄpÃn NÄmec <stepnem@xxxxxxxxx>
---
_git | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 54 insertions(+), 1 deletions(-)
diff --git a/_git b/_git
index e483133..b426612 100644
--- a/_git
+++ b/_git
@@ -2824,12 +2824,65 @@ __git_unmerged_files () {
#this is for git-commit which can take files both git-added and not
(( $+functions[__git_changed_files] )) ||
__git_changed_files () {
+ # this function is needed to transform paths relative to the repo base dir
+ # (as returned by diff-index) into the form relative to the current directory
+ # :|
+ munge_paths () {
+ # SN FIXME is this needed? How come I don't see emulate -R anywhere in this file?
+ emulate -LR zsh
+ local cwd scnt scnta scntc
+ local -a abs paths
+ cwd=${"$(pwd)":a}
+ base=${${"$(git rev-parse --git-dir)":a}%.git}
+ abs=($base${^files})
+ scntc=${#${cwd//[^\/]}}
+ for ((i=1; i <= $#abs; i++)); do
+ scnta=${#${abs[$i]//[^\/]}}
+ scnt=$(($scntc - $scnta))
+ if ((scnt >= 0)); then
+ paths[$i]="$abs[$i]:t"
+ for ((j=0; j <= $scnt; j++)); do
+ paths[$i]="../$paths[$i]"
+ done
+ else
+ if [[ $abs[$i] == $cwd* ]]; then
+ paths[$i]="${${abs[$i]}#$cwd/}"
+ else
+ # longest common prefix
+ lcp () {
+ local lcp
+ for ((i=1; i<=$#1; i++)); do
+ if [[ ${1[i]} == ${2[i]} ]]; then
+ lcp+=${1[i]}
+ else
+ break
+ fi
+ done
+ echo "$lcp"
+ }
+ local common="$(lcp $cwd $abs[$i])"
+ local prefix=""
+ paths[$i]="${${abs[$i]}#$common}"
+ local cwdr="${${cwd}#$common}"
+ scntcr=${#${cwdr//[^\/]}}
+ for ((j=0; j <= $scntcr; j++)); do
+ prefix="../$prefix"
+ done
+ paths[$i]="$prefix$paths[$i]"
+ fi
+ fi
+ done
+ print ${(pj:\0:)paths}
+ }
+
local -a files
files=(${(ps:\0:)"$(_call_program files git diff-index -z --name-only --no-color HEAD 2>/dev/null)"})
__git_command_successful || return
+ files=(${(ps:\0:)"$(munge_paths)"})
- _wanted files expl 'index file' _multi_parts $@ - / files
+ _description files expl 'Changed files'
+ compadd "$expl[@]" - "$files[@]"
}
(( $+functions[__git_tree_files] )) ||
--
Messages sorted by:
Reverse Date,
Date,
Thread,
Author