git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jiang Xin <worldhello.net@gmail.com>
To: Junio C Hamano <gitster@pobox.com>, Johannes Sixt <j6t@kdbg.org>
Cc: Git List <git@vger.kernel.org>, Jiang Xin <worldhello.net@gmail.com>
Subject: [PATCH v15 03/16] quote.c: substitute path_relative with relative_path
Date: Tue, 25 Jun 2013 23:53:44 +0800	[thread overview]
Message-ID: <e1aa7e7d2e9ec1cd021ceffa7fd5cc4e858dd30b.1372175282.git.worldhello.net@gmail.com> (raw)
In-Reply-To: <cover.1372175282.git.worldhello.net@gmail.com>
In-Reply-To: <cover.1372175282.git.worldhello.net@gmail.com>

Substitute the function path_relative in quote.c with the function
relative_path. Function relative_path can be treated as an enhanced
and robust version of path_relative.

Outputs of path_relative and it's replacement (relative_path) are the
same for the following cases:

    path      prefix     output of path_relative  output of relative_path
    ========  =========  =======================  =======================
    /a/b/c/   /a/b/      c/                       c/
    /a/b/c    /a/b/      c                        c
    /a/       /a/b/      ../                      ../
    /         /a/b/      ../../                   ../../
    /a/c      /a/b/      ../c                     ../c
    /x/y      /a/b/      ../../x/y                ../../x/y
    a/b/c/    a/b/       c/                       c/
    a/        a/b/       ../                      ../
    x/y       a/b/      ../../x/y                 ../../x/y
    /a/b      (empty)    /a/b                     /a/b
    /a/b      (null)     /a/b                     /a/b
    a/b       (empty)    a/b                      a/b
    a/b       (null)     a/b                      a/b

But if both of the path and the prefix are the same, or the returned
relative path should be the current directory, the outputs of both
functions are different. Function relative_path returns "./", while
function path_relative returns empty string.

    path      prefix     output of path_relative  output of relative_path
    ========  =========  =======================  =======================
    /a/b/     /a/b/      (empty)                  ./
    a/b/      a/b/       (empty)                  ./
    (empty)   (null)     (empty)                  ./
    (empty)   (empty)    (empty)                  ./

But not panic, the callers of path_relative can handle such cases, or
never encounter this issue at all. E.g.

 * In function quote_path_relative, if the output of path_relative is
   empty, append "./" to it, like:

       if (!out->len)
           strbuf_addstr(out, "./");

 * Another caller is write_name_quoted_relative, which is only used by
   builtin/ls-files.c. git-ls-files only show files, so path of files
   will never be identical with the prefix of a directory.

The following differences show that path_relative can not handle
extra slashes properly.

    path      prefix     output of path_relative  output of relative_path
    ========  =========  =======================  =======================
    /a//b//c/ //a/b//    ../../../../a//b//c/     c/
    a/b//c    a//b       ../b//c                  c

And if prefix has no trailing slash, path_relative can not work properly
either. But since prefix always has a trailing slash, so it's not a
problem.

    path      prefix     output of path_relative  output of relative_path
    ========  =========  =======================  =======================
    /a/b/c/   /a/b       b/c/                     c/
    /a/b      /a/b       b                        ./
    /a/b/     /a/b       b/                       ./
    /a        /a/b/      ../../a                  ../
    a/b/c/    a/b        b/c/                     c/
    a/b/      a/b        b/                       ./
    a         a/b        ../a                     ../
    x/y       a/b/       ../x/y                   ../../x/y
    a/c       a/b        c                        ../c
    /a/       /a/b       (empty)                  ../
    (empty)   /a/b       ../../                   ./

Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
---
 builtin/ls-files.c |  7 +++++--
 quote.c            | 55 ++----------------------------------------------------
 2 files changed, 7 insertions(+), 55 deletions(-)

diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 3a410c..d100 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -48,8 +48,11 @@ static const char *tag_resolve_undo = "";
 
 static void write_name(const char* name, size_t len)
 {
-	write_name_quoted_relative(name, len, prefix, prefix_len, stdout,
-			line_terminator);
+	/* Since prefix_len is ignored in write_name_quoted_relative, we
+	 * should turn off prefix here in case of running "git ls-files"
+	 * with "--full-name" option */
+	write_name_quoted_relative(name, len, prefix_len ? prefix : NULL,
+			prefix_len, stdout, line_terminator);
 }
 
 static void show_dir_entry(const char *tag, struct dir_entry *ent)
diff --git a/quote.c b/quote.c
index 91122..64ff3 100644
--- a/quote.c
+++ b/quote.c
@@ -312,75 +312,24 @@ void write_name_quotedpfx(const char *pfx, size_t pfxlen,
 	fputc(terminator, fp);
 }
 
-static const char *path_relative(const char *in, int len,
-				 struct strbuf *sb, const char *prefix,
-				 int prefix_len);
-
 void write_name_quoted_relative(const char *name, size_t len,
 				const char *prefix, size_t prefix_len,
 				FILE *fp, int terminator)
 {
 	struct strbuf sb = STRBUF_INIT;
 
-	name = path_relative(name, len, &sb, prefix, prefix_len);
+	name = relative_path(name, prefix, &sb);
 	write_name_quoted(name, fp, terminator);
 
 	strbuf_release(&sb);
 }
 
-/*
- * Give path as relative to prefix.
- *
- * The strbuf may or may not be used, so do not assume it contains the
- * returned path.
- */
-static const char *path_relative(const char *in, int len,
-				 struct strbuf *sb, const char *prefix,
-				 int prefix_len)
-{
-	int off, i;
-
-	if (len < 0)
-		len = strlen(in);
-	if (prefix_len < 0) {
-		if (prefix)
-			prefix_len = strlen(prefix);
-		else
-			prefix_len = 0;
-	}
-
-	off = 0;
-	i = 0;
-	while (i < prefix_len && i < len && prefix[i] == in[i]) {
-		if (prefix[i] == '/')
-			off = i + 1;
-		i++;
-	}
-	in += off;
-	len -= off;
-
-	if (i >= prefix_len)
-		return in;
-
-	strbuf_reset(sb);
-	strbuf_grow(sb, len);
-
-	while (i < prefix_len) {
-		if (prefix[i] == '/')
-			strbuf_addstr(sb, "../");
-		i++;
-	}
-	strbuf_add(sb, in, len);
-
-	return sb->buf;
-}
-
 /* quote path as relative to the given prefix */
 char *quote_path_relative(const char *in, int len,
 			  struct strbuf *out, const char *prefix)
 {
 	struct strbuf sb = STRBUF_INIT;
-	const char *rel = path_relative(in, len, &sb, prefix, -1);
+	const char *rel = relative_path(in, prefix, &sb);
 	strbuf_reset(out);
 	quote_c_style_counted(rel, strlen(rel), out, NULL, 0);
 	strbuf_release(&sb);
-- 
1.8.3.1.756.g2e9b71f

  parent reply	other threads:[~2013-06-25 15:54 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-25 15:53 [PATCH v15 00/16] Interactive git clean Jiang Xin
2013-06-25 15:53 ` [PATCH v15 01/16] test: add test cases for relative_path Jiang Xin
2013-06-26 17:44   ` Junio C Hamano
2013-06-27  1:00     ` Jiang Xin
2013-06-25 15:53 ` [PATCH v15 02/16] path.c: refactor relative_path(), not only strip prefix Jiang Xin
2013-06-26 17:44   ` Junio C Hamano
2013-06-27  3:31     ` Jiang Xin
2013-06-25 15:53 ` Jiang Xin [this message]
2013-06-26 17:44   ` [PATCH v15 03/16] quote.c: substitute path_relative with relative_path Junio C Hamano
2013-06-25 15:53 ` [PATCH v15 04/16] Refactor quote_path_relative, remove unused params Jiang Xin
2013-06-26 17:47   ` Junio C Hamano
2013-06-27  1:47     ` Jiang Xin
2013-06-25 15:53 ` [PATCH v15 05/16] Refactor write_name_quoted_relative, " Jiang Xin
2013-06-25 15:53 ` [PATCH v15 06/16] git-clean: refactor git-clean into two phases Jiang Xin
2013-06-25 15:53 ` [PATCH v15 07/16] git-clean: add support for -i/--interactive Jiang Xin
2013-06-25 15:53 ` [PATCH v15 08/16] git-clean: show items of del_list in columns Jiang Xin
2013-06-25 15:53 ` [PATCH v15 09/16] git-clean: add colors to interactive git-clean Jiang Xin
2013-06-25 15:53 ` [PATCH v15 10/16] git-clean: use a git-add-interactive compatible UI Jiang Xin
2013-06-25 15:53 ` [PATCH v15 11/16] git-clean: add filter by pattern interactive action Jiang Xin
2013-06-25 15:53 ` [PATCH v15 12/16] git-clean: add select by numbers " Jiang Xin
2013-06-25 15:53 ` [PATCH v15 13/16] git-clean: add ask each " Jiang Xin
2013-06-25 15:53 ` [PATCH v15 14/16] git-clean: add documentation for interactive git-clean Jiang Xin
2013-06-25 15:53 ` [PATCH v15 15/16] test: add t7301 for git-clean--interactive Jiang Xin
2013-06-25 15:53 ` [PATCH v15 16/16] test: run testcases with POSIX absolute paths on Windows Jiang Xin
2013-06-26 18:03 ` [PATCH v15 00/16] Interactive git clean Junio C Hamano

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=e1aa7e7d2e9ec1cd021ceffa7fd5cc4e858dd30b.1372175282.git.worldhello.net@gmail.com \
    --to=worldhello.net@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=j6t@kdbg.org \
    /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).