git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH REPLACEMENT for 2/2] git status: show relative paths when run in a subdirectory

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Nov 9, 2007, 15:30 UTC
Message-ID
<Pine.LNX.4.64.0711091529570.4362@racer.site>
In-Reply-To
<7v8x593zyv.fsf@gitster.siamese.dyndns.org>

To show the relative paths, the function formerly called quote_crlf() (now called quote_path()) takes the prefix as an additional argument.

While at it, the static buffers were replaced by strbufs.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
	On Thu, 8 Nov 2007, Junio C Hamano wrote:
	> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
	> 
	> > -static const char *quote_crlf(const char *in, char *buf, size_t sz)
	> > +static const char *quote_crlf(const char *in, int len, char *buf, size_t sz,
	> > +	const char *prefix)
	> >  {
	> 
	> This is not quote_*crlf* anymore.
	> 
	> > @@ -118,8 +150,8 @@ static void wt_status_print_filepair(struct wt_status *s,
	> >  	const char *one, *two;
	> >  	char onebuf[PATH_MAX], twobuf[PATH_MAX];
	> >  
	> > -	one = quote_crlf(p->one->path, onebuf, sizeof(onebuf));
	> > -	two = quote_crlf(p->two->path, twobuf, sizeof(twobuf));
	> > +	one = quote_crlf(p->one->path, -1, onebuf, sizeof(onebuf), s->prefix);
	> > +	two = quote_crlf(p->two->path, -1, twobuf, sizeof(twobuf), s->prefix);
	> 
	> I wonder if it makes more sense to use strbuf here...
	Here you are.
 builtin-runstatus.c |    1 +
 t/t7502-status.sh   |   91 +++++++++++++++++++++++++++++++++++++++++++++++++++
 wt-status.c         |   69 ++++++++++++++++++++++++++-------------
 wt-status.h         |    1 +
 4 files changed, 139 insertions(+), 23 deletions(-)
 create mode 100755 t/t7502-status.sh
diff --git a/builtin-runstatus.c b/builtin-runstatus.c
index 2db25c8..8d167a9 100644
--- a/builtin-runstatus.c
+++ b/builtin-runstatus.c
@@ -14,6 +14,7 @@ int cmd_runstatus(int argc, const char **argv, const char *prefix)
 
 	git_config(git_status_config);
 	wt_status_prepare(&s);
+	s.prefix = prefix;
 
 	for (i = 1; i < argc; i++) {
 		if (!strcmp(argv[i], "--color"))
diff --git a/t/t7502-status.sh b/t/t7502-status.sh
new file mode 100755
index 0000000..269b334
--- /dev/null
+++ b/t/t7502-status.sh
@@ -0,0 +1,91 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Johannes E. Schindelin
+#
+
+test_description='git-status'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+	: > tracked &&
+	: > modified &&
+	mkdir dir1 &&
+	: > dir1/tracked &&
+	: > dir1/modified &&
+	mkdir dir2 &&
+	: > dir1/tracked &&
+	: > dir1/modified &&
+	git add . &&
+	test_tick &&
+	git commit -m initial &&
+	: > untracked &&
+	: > dir1/untracked &&
+	: > dir2/untracked &&
+	echo 1 > dir1/modified &&
+	echo 2 > dir2/modified &&
+	echo 3 > dir2/added &&
+	git add dir2/added
+'
+
+cat > expect << \EOF
+# On branch master
+# Changes to be committed:
+#   (use "git reset HEAD <file>..." to unstage)
+#
+#	new file:   dir2/added
+#
+# Changed but not updated:
+#   (use "git add <file>..." to update what will be committed)
+#
+#	modified:   dir1/modified
+#
+# Untracked files:
+#   (use "git add <file>..." to include in what will be committed)
+#
+#	dir1/untracked
+#	dir2/modified
+#	dir2/untracked
+#	expect
+#	output
+#	untracked
+EOF
+
+test_expect_success 'status' '
+
+	git status > output &&
+	git diff expect output
+
+'
+
+cat > expect << \EOF
+# On branch master
+# Changes to be committed:
+#   (use "git reset HEAD <file>..." to unstage)
+#
+#	new file:   ../dir2/added
+#
+# Changed but not updated:
+#   (use "git add <file>..." to update what will be committed)
+#
+#	modified:   ../dir1/modified
+#
+# Untracked files:
+#   (use "git add <file>..." to include in what will be committed)
+#
+#	untracked
+#	../dir2/modified
+#	../dir2/untracked
+#	../expect
+#	../output
+#	../untracked
+EOF
+
+test_expect_success 'status with relative paths' '
+
+	(cd dir1 && git status) > output &&
+	git diff expect output
+
+'
+
+test_done
diff --git a/wt-status.c b/wt-status.c
index 03b5ec4..0d25362 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -82,33 +82,46 @@ static void wt_status_print_trailer(struct wt_status *s)
 	color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "#");
 }
 
-static const char *quote_crlf(const char *in, char *buf, size_t sz)
+static char *quote_path(const char *in, int len,
+		struct strbuf *out, const char *prefix)
 {
-	const char *scan;
-	char *out;
-	const char *ret = in;
+	if (len > 0)
+		strbuf_grow(out, len);
+	strbuf_setlen(out, 0);
+
+	if (prefix) {
+		int off = 0;
+		while (prefix[off] && off < len && prefix[off] == in[off])
+			if (prefix[off] == '/') {
+				prefix += off + 1;
+				in += off + 1;
+				len -= off + 1;
+				off = 0;
+			} else
+				off++;
+
+		for (; *prefix; prefix++)
+			if (*prefix == '/')
+				strbuf_addstr(out, "../");
+	}
 
-	for (scan = in, out = buf; *scan; scan++) {
-		int ch = *scan;
-		int quoted;
+	for (; (len < 0 && *in) || len > 0; in++, len--) {
+		int ch = *in;
 
 		switch (ch) {
 		case '\n':
-			quoted = 'n';
+			strbuf_addstr(out, "\\n");
 			break;
 		case '\r':
-			quoted = 'r';
+			strbuf_addstr(out, "\\r");
 			break;
 		default:
-			*out++ = ch;
+			strbuf_addch(out, ch);
 			continue;
 		}
-		*out++ = '\\';
-		*out++ = quoted;
-		ret = buf;
 	}
-	*out = '\0';
-	return ret;
+
+	return out->buf;
 }
 
 static void wt_status_print_filepair(struct wt_status *s,
@@ -116,10 +129,12 @@ static void wt_status_print_filepair(struct wt_status *s,
 {
 	const char *c = color(t);
 	const char *one, *two;
-	char onebuf[PATH_MAX], twobuf[PATH_MAX];
+	struct strbuf onebuf, twobuf;
 
-	one = quote_crlf(p->one->path, onebuf, sizeof(onebuf));
-	two = quote_crlf(p->two->path, twobuf, sizeof(twobuf));
+	strbuf_init(&onebuf, 0);
+	strbuf_init(&twobuf, 0);
+	one = quote_path(p->one->path, -1, &onebuf, s->prefix);
+	two = quote_path(p->two->path, -1, &twobuf, s->prefix);
 
 	color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
 	switch (p->status) {
@@ -151,6 +166,8 @@ static void wt_status_print_filepair(struct wt_status *s,
 		die("bug: unhandled diff status %c", p->status);
 	}
 	fprintf(s->fp, "\n");
+	strbuf_release(&onebuf);
+	strbuf_release(&twobuf);
 }
 
 static void wt_status_print_updated_cb(struct diff_queue_struct *q,
@@ -205,8 +222,9 @@ static void wt_read_cache(struct wt_status *s)
 static void wt_status_print_initial(struct wt_status *s)
 {
 	int i;
-	char buf[PATH_MAX];
+	struct strbuf buf;
 
+	strbuf_init(&buf, 0);
 	wt_read_cache(s);
 	if (active_nr) {
 		s->commitable = 1;
@@ -215,11 +233,12 @@ static void wt_status_print_initial(struct wt_status *s)
 	for (i = 0; i < active_nr; i++) {
 		color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
 		color_fprintf_ln(s->fp, color(WT_STATUS_UPDATED), "new file: %s",
-				quote_crlf(active_cache[i]->name,
-					   buf, sizeof(buf)));
+				quote_path(active_cache[i]->name, -1,
+					   &buf, s->prefix));
 	}
 	if (active_nr)
 		wt_status_print_trailer(s);
+	strbuf_release(&buf);
 }
 
 static void wt_status_print_updated(struct wt_status *s)
@@ -254,7 +273,9 @@ static void wt_status_print_untracked(struct wt_status *s)
 	const char *x;
 	int i;
 	int shown_header = 0;
+	struct strbuf buf;
 
+	strbuf_init(&buf, 0);
 	memset(&dir, 0, sizeof(dir));
 
 	dir.exclude_per_dir = ".gitignore";
@@ -291,9 +312,11 @@ static void wt_status_print_untracked(struct wt_status *s)
 			shown_header = 1;
 		}
 		color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");
-		color_fprintf_ln(s->fp, color(WT_STATUS_UNTRACKED), "%.*s",
-				ent->len, ent->name);
+		color_fprintf_ln(s->fp, color(WT_STATUS_UNTRACKED), "%s",
+				quote_path(ent->name, ent->len,
+					&buf, s->prefix));
 	}
+	strbuf_release(&buf);
 }
 
 static void wt_status_print_verbose(struct wt_status *s)
diff --git a/wt-status.h b/wt-status.h
index 7744932..f58ebcb 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -23,6 +23,7 @@ struct wt_status {
 	int workdir_untracked;
 	const char *index_file;
 	FILE *fp;
+	const char *prefix;
 };
 
 int git_status_config(const char *var, const char *value);
-- 
1.5.3.5.1645.g1f4df
Previous: Junio C HamanoNext: Michel Marti
Message 43 of 48 in “Inconsistencies with git log”
  1. Jon SmirlNov 7, 2007
  2. Johannes SchindelinNov 7, 2007
  3. Jon SmirlNov 7, 2007
  4. Johannes SchindelinNov 7, 2007
  5. Jon SmirlNov 7, 2007
  6. Johannes SchindelinNov 7, 2007
  7. Jon SmirlNov 7, 2007
  8. Jon SmirlNov 7, 2007
  9. Johannes SchindelinNov 8, 2007
  10. Jon SmirlNov 8, 2007
  11. Andreas EricssonNov 8, 2007
  12. Johannes SchindelinNov 8, 2007
  13. Linus TorvaldsNov 9, 2007
  14. Jon SmirlNov 9, 2007
  15. Linus TorvaldsNov 9, 2007
  16. Linus TorvaldsNov 9, 2007
  17. Jon SmirlNov 9, 2007
  18. Linus TorvaldsNov 9, 2007
  19. Peter BaumannNov 9, 2007
  20. Junio C HamanoNov 9, 2007
  21. Jakub NarebskiNov 9, 2007
  22. Peter BaumannNov 9, 2007
  23. Linus TorvaldsNov 9, 2007
  24. Jakub NarebskiNov 9, 2007
  25. Wincent ColaiutaNov 8, 2007
  26. Daniel BarkalowNov 8, 2007
  27. Brian GernhardtNov 7, 2007
  28. David SymondsNov 7, 2007
  29. Johannes SchindelinNov 8, 2007
  30. David SymondsNov 8, 2007
  31. Brian GernhardtNov 8, 2007
  32. 1/2 Makefile: wt-status.h is also a lib headerJohannes Schindelin, Nov 8, 2007
  33. Andreas EricssonNov 8, 2007
  34. Peter BaumannNov 8, 2007
  35. David SymondsNov 8, 2007
  36. Andreas EricssonNov 8, 2007
  37. Alex RiesenNov 8, 2007
  38. Alex RiesenNov 8, 2007
  39. 2/2 git status: show relative paths when run in a subdirectoryJohannes Schindelin, Nov 8, 2007
  40. David SymondsNov 8, 2007
  41. Johannes SchindelinNov 8, 2007
  42. Junio C HamanoNov 8, 2007
  43. 2/2 git status: show relative paths when run in a subdirectoryJohannes Schindelin, Nov 9, 2007
  44. Michel MartiNov 10, 2007
  45. Johannes SchindelinNov 10, 2007
  46. Wincent ColaiutaNov 8, 2007
  47. Miles BaderNov 10, 2007
  48. David SymondsNov 7, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.