From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11087 invoked by alias); 5 Dec 2009 12:43:06 -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: 27460 Received: (qmail 5785 invoked from network); 5 Dec 2009 12:43:03 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.5 Received-SPF: none (ns1.primenet.com.au: domain at altlinux.org does not designate permitted sender hosts) Date: Sat, 5 Dec 2009 15:42:58 +0300 From: "Alexey I. Froloff" To: zsh-workers@zsh.org Subject: Re: [PATCH] _git: offer changed files relative to current directory Message-ID: <20091205124258.GC3344@altlinux.org> References: <1259973163-20919-1-git-send-email-raorn@altlinux.org> <20091205120753.GA21684@headley> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="6WlEvdN9Dv0WHSBl" Content-Disposition: inline In-Reply-To: <20091205120753.GA21684@headley> User-Agent: Mutt/1.5.20 (2009-06-23) --6WlEvdN9Dv0WHSBl Content-Type: multipart/mixed; boundary="aT9PWwzfKXlsBJM1" Content-Disposition: inline --aT9PWwzfKXlsBJM1 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Sat, Dec 05, 2009 at 01:07:54PM +0100, ??t??p??n N??mec wrote: > No, this is wrong as far as I recall. At least this is better than current behavior. > I was solving the same problem before some time. Your solution (i.e. > git-diff-index --relative) only displays the changed files under a > subdirectory, which is incorrect when not in the repository root. Same problem exists for __git_*_files (__git_files). > I solved the problem by writing a 50 line or so "ueberfunction" which > manually relativizes the paths returned by git-diff-index to the correct > form required by git-commit You can get current subdirectory with "git rev-parse --show-prefix", then all "absolute" paths must be turned into relative. On my system there is "relative" program (comes with rpm-build package), so the code would look like: local -a rawfiles files local f prefix prefix=3D$(_call_program gitprefix git rev-parse --show-prefix 2>/dev/null) __git_command_successful || return rawfiles=3D( ... git ls-files or git diff-index call ... ) for f in $rawfiles; do files+=3D( $(relative /$prefix /$f) ) done _wanted ... Just need pure-zsh "relative" implementation. relative.c attached. P.S. I don't like this for loop. Can this be done with single expansion expression? --=20 Regards, Sir Raorn. --aT9PWwzfKXlsBJM1 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="relative.c" /* Copyright (C) 2001 Dmitry V. Levin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include static void * xmalloc(size_t size) { void *r = malloc(size); if (!r) error(EXIT_FAILURE, errno, "malloc: allocating %lu bytes", (unsigned long) size); return r; } static char * xstrdup(const char *s) { size_t len = strlen(s); char *r = xmalloc(len + 1); memcpy(r, s, len + 1); return r; } static void __attribute__ ((noreturn)) result(const char *str) { puts(str); exit(0); } static const char * normalize(char *str) { char *p; size_t len; for (p = strstr(str, "//"); p; p = strstr(str, "//")) memmove(p, p + 1, strlen(p)); for (p = strstr(str, "/./"); p; p = strstr(str, "/./")) memmove(p, p + 2, strlen(p + 1)); len = strlen(str); if ((len >= 2) && ('/' == str[len - 2]) && ('.' == str[len - 1])) str[len - 1] = '\0'; return str; } static void strip_trailing(char *str, const char sym) { char *p; for (p = strrchr(str, sym); p && (p >= str) && (sym == *p); --p) *p = '\0'; } static const char * base_name(const char *name) { const char *p = strrchr(name, '/'); if (p) return p + 1; else return name; } static char * lookup_back(const char *str, const char sym, const char *pos) { for (; pos >= str; --pos) if (sym == *pos) return (char *) pos; return 0; } int main(int ac, char *av[]) { const char *orig_what; char *what_p, *to_p, *res; char *what, *to; if (ac < 3) { fprintf(stderr, "Usage: %s \n", program_invocation_short_name); return 1; } what = xstrdup(av[1]); to = xstrdup(av[2]); orig_what = normalize(av[1]); normalize(av[2]); what = xstrdup(av[1]); to = xstrdup(av[2]); if ('/' != *what) result(what); if ('/' != *to) error(EXIT_FAILURE, 0, "destination must be absolute filename"); strip_trailing(what, '/'); strip_trailing(to, '/'); for (what_p = what, to_p = to; *what_p && *to_p; ++what_p, ++to_p) if (*what_p != *to_p) break; if (!*what_p && !*to_p) result(base_name(orig_what)); res = xmalloc(strlen(what) + strlen(to) * 3 / 2 + 3); if (('/' == *what_p) && !*to_p) result(orig_what + (++what_p - what)); if ('/' != *to_p || *what_p) { what_p = lookup_back(what, '/', what_p - 1); strcpy(res, ".."); } else { res[0] = '\0'; } for (; *to_p; ++to_p) { if ('/' == *to_p) { if (*res) strcat(res, "/.."); else strcpy(res, ".."); } } strcat(res, orig_what + (what_p - what)); result(res); } --aT9PWwzfKXlsBJM1-- --6WlEvdN9Dv0WHSBl Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iEYEARECAAYFAksaVU0ACgkQVqT7+fkT8wptEwCeP3fYIv4D/acS0lNHFqUBCVyW zTYAoJkwOxFkavjcDyVcNH+6FRiICw80 =0Qer -----END PGP SIGNATURE----- --6WlEvdN9Dv0WHSBl--