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

[RFC/PATCH] status: Add a new NUL separated output format

From
Julian Phillips <julian@quantumfyre.co.uk>
Date
Apr 10, 2010, 19:25 UTC
Message-ID
<20100410192529.23731.79803.julian@quantumfyre.co.uk>
In-Reply-To
<9c7e1f33b7ec0dab68a92aa8f067989e@212.159.54.234>

Add a new output format option to git-status that is a more extreme form of the -z output that places a NUL between all parts of the record, and always has three entries per record, even when only two are relevant. This make the parsing of --porcelain output much simpler for the consumer.

Signed-off-by: Julian Phillips <julian@quantumfyre.co.uk>
---
On Sat, 10 Apr 2010, Julian Phillips wrote:
Show 12 quoted lines
> Not true.  If the second form was used, then you _can_ split on \0.  It
> will tokenise the data for you, and then you consume ether two or three
> tokens depending on the status flags.  So it would make the parsing
> simpler.  But to make it even easier, how about adding a -Z that makes the
> output format "XY\0file1\0[file2]\0" (i.e. always three tokens per record,
> with the third token being empty if there is no second filename)?  Though
> if future expandability was wanted you could end each record with \0\0 and
> then parsing would be a two stages of split on \0\0 for records and then
> split on \0 for entries?  The is already precedence for the -z option to
> change the output format, so a second similar switch should be ok?  Then
> the updated documentation could recommend --porcelain -Z for new users
> without affecting old ones.

Something like this for the first variant (fixed three entries per record) perhaps ... (though a proper patch would probably want some tests too)

 builtin/commit.c |    6 ++++--
 wt-status.c      |   19 ++++++++++++++-----
 2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/builtin/commit.c b/builtin/commit.c
index c5ab683..acbcefc 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1025,8 +1025,10 @@ int cmd_status(int argc, const char **argv, const char *prefix)
 		OPT_SET_INT(0, "porcelain", &status_format,
 			    "show porcelain output format",
 			    STATUS_FORMAT_PORCELAIN),
-		OPT_BOOLEAN('z', "null", &null_termination,
-			    "terminate entries with NUL"),
+		OPT_SET_INT('z', "null", &null_termination,
+			    "terminate entries with NUL", 1),
+		OPT_SET_INT('Z', "intense-null", &null_termination,
+			    "use NUL for all seperators, including absent values", 2),
 		{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg,
 		  "mode",
 		  "show untracked files, optional modes: all, normal, no. (Default: all)",
diff --git a/wt-status.c b/wt-status.c
index 8ca59a2..9f23ec6 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -663,7 +663,9 @@ static void wt_shortstatus_unmerged(int null_termination, struct string_list_ite
 	case 7: how = "UU"; break; /* both modified */
 	}
 	color_fprintf(s->fp, color(WT_STATUS_UNMERGED, s), "%s", how);
-	if (null_termination) {
+	if (null_termination == 2) {
+		fprintf(stdout, "%c%s%c%c", 0, it->string, 0, 0);
+	} else if (null_termination) {
 		fprintf(stdout, " %s%c", it->string, 0);
 	} else {
 		struct strbuf onebuf = STRBUF_INIT;
@@ -687,14 +689,19 @@ static void wt_shortstatus_status(int null_termination, struct string_list_item
 		color_fprintf(s->fp, color(WT_STATUS_CHANGED, s), "%c", d->worktree_status);
 	else
 		putchar(' ');
-	putchar(' ');
-	if (null_termination) {
-		fprintf(stdout, "%s%c", it->string, 0);
+	if (null_termination == 2) {
+		char *file2 = "";
+		if (d->head_path)
+			file2 = d->head_path;
+		fprintf(stdout, "%c%s%c%s%c", 0, it->string, 0, file2, 0);
+	} else if (null_termination) {
+		fprintf(stdout, " %s%c", it->string, 0);
 		if (d->head_path)
 			fprintf(stdout, "%s%c", d->head_path, 0);
 	} else {
 		struct strbuf onebuf = STRBUF_INIT;
 		const char *one;
+		putchar(' ');
 		if (d->head_path) {
 			one = quote_path(d->head_path, -1, &onebuf, s->prefix);
 			printf("%s -> ", one);
@@ -709,7 +716,9 @@ static void wt_shortstatus_status(int null_termination, struct string_list_item
 static void wt_shortstatus_untracked(int null_termination, struct string_list_item *it,
 			    struct wt_status *s)
 {
-	if (null_termination) {
+	if (null_termination == 2) {
+		fprintf(stdout, "??%c%s%c%c", 0, it->string, 0, 0);
+	} else if (null_termination) {
 		fprintf(stdout, "?? %s%c", it->string, 0);
 	} else {
 		struct strbuf onebuf = STRBUF_INIT;
-- 
1.7.0.4
Previous: Jon SeymourNext: Eric Raymond
Message 15 of 19 in “git status --porcelain is a mess that needs fixing”
  1. Eric RaymondApr 9, 2010
  2. Junio C HamanoApr 9, 2010
  3. Jeff KingApr 10, 2010
  4. Jonathan NiederApr 10, 2010
  5. Jonathan NiederApr 10, 2010
  6. Jeff KingApr 10, 2010
  7. Jonathan NiederApr 10, 2010
  8. Jeff KingApr 10, 2010
  9. Eric RaymondApr 10, 2010
  10. Julian PhillipsApr 10, 2010
  11. Eric RaymondApr 10, 2010
  12. Jon SeymourApr 10, 2010
  13. Julian PhillipsApr 10, 2010
  14. Jon SeymourApr 10, 2010
  15. status: Add a new NUL separated output formatJulian Phillips, Apr 10, 2010
  16. Eric RaymondApr 10, 2010
  17. Julian PhillipsApr 10, 2010
  18. Eric RaymondApr 10, 2010
  19. status: Add json output formatJulian Phillips, Apr 10, 2010

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.