Git fork

rev-list: support NUL-delimited --missing option

The `--missing={print,print-info}` option for git-rev-list(1) prints
missing objects found while performing the object walk in the form:

$ git rev-list --missing=print-info <rev>
?<oid> [SP <token>=<value>]... LF

Add support for printing missing objects in a NUL-delimited format when
the `-z` option is enabled.

$ git rev-list -z --missing=print-info <rev>
<oid> NUL missing=yes NUL [<token>=<value> NUL]...

In this mode, values containing special characters or spaces are printed
as-is without being escaped or quoted. Instead of prefixing the missing
OID with '?', a separate `missing=yes` token/value pair is appended.

Signed-off-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Justin Tobler and committed by
Junio C Hamano
340e7523 1c3c1ab3

+56 -11
+3 -2
Documentation/rev-list-options.adoc
··· 380 380 <OID> NUL 381 381 <OID> NUL path=<path> NUL 382 382 <OID> NUL boundary=yes NUL 383 + <OID> NUL missing=yes NUL [<token>=<value> NUL]... 383 384 ----------------------------------------------------------------------- 384 385 + 385 - This mode is only compatible with the `--objects` and `--boundary` output 386 - options. 386 + This mode is only compatible with the `--objects`, `--boundary`, and 387 + `--missing` output options. 387 388 endif::git-rev-list[] 388 389 389 390 History Simplification
+22 -9
builtin/rev-list.c
··· 136 136 { 137 137 struct strbuf sb = STRBUF_INIT; 138 138 139 + if (line_term) 140 + printf("?%s", oid_to_hex(&entry->entry.oid)); 141 + else 142 + printf("%s%cmissing=yes", oid_to_hex(&entry->entry.oid), 143 + info_term); 144 + 139 145 if (!print_missing_info) { 140 - printf("?%s\n", oid_to_hex(&entry->entry.oid)); 146 + putchar(line_term); 141 147 return; 142 148 } 143 149 144 150 if (entry->path && *entry->path) { 145 - struct strbuf path = STRBUF_INIT; 151 + strbuf_addf(&sb, "%cpath=", info_term); 152 + 153 + if (line_term) { 154 + struct strbuf path = STRBUF_INIT; 146 155 147 - strbuf_addstr(&sb, " path="); 148 - quote_path(entry->path, NULL, &path, QUOTE_PATH_QUOTE_SP); 149 - strbuf_addbuf(&sb, &path); 156 + quote_path(entry->path, NULL, &path, QUOTE_PATH_QUOTE_SP); 157 + strbuf_addbuf(&sb, &path); 150 158 151 - strbuf_release(&path); 159 + strbuf_release(&path); 160 + } else { 161 + strbuf_addstr(&sb, entry->path); 162 + } 152 163 } 153 164 if (entry->type) 154 - strbuf_addf(&sb, " type=%s", type_name(entry->type)); 165 + strbuf_addf(&sb, "%ctype=%s", info_term, type_name(entry->type)); 166 + 167 + fwrite(sb.buf, sizeof(char), sb.len, stdout); 168 + putchar(line_term); 155 169 156 - printf("?%s%s\n", oid_to_hex(&entry->entry.oid), sb.buf); 157 170 strbuf_release(&sb); 158 171 } 159 172 ··· 783 796 if (revs.graph || revs.verbose_header || show_disk_usage || 784 797 info.show_timestamp || info.header_prefix || bisect_list || 785 798 use_bitmap_index || revs.edge_hint || revs.left_right || 786 - revs.cherry_mark || arg_missing_action) 799 + revs.cherry_mark) 787 800 die(_("-z option used with unsupported option")); 788 801 } 789 802
+31
t/t6022-rev-list-missing.sh
··· 198 198 ' 199 199 done 200 200 201 + test_expect_success "-z nul-delimited --missing" ' 202 + test_when_finished rm -rf repo && 203 + 204 + git init repo && 205 + ( 206 + cd repo && 207 + git commit --allow-empty -m first && 208 + 209 + path="foo bar" && 210 + echo foobar >"$path" && 211 + git add -A && 212 + git commit -m second && 213 + 214 + oid=$(git rev-parse "HEAD:$path") && 215 + type="$(git cat-file -t $oid)" && 216 + 217 + obj_path=".git/objects/$(test_oid_to_path $oid)" && 218 + 219 + git rev-list -z --objects --no-object-names \ 220 + HEAD ^"$oid" >expect && 221 + printf "%s\0missing=yes\0path=%s\0type=%s\0" "$oid" "$path" \ 222 + "$type" >>expect && 223 + 224 + mv "$obj_path" "$obj_path.hidden" && 225 + git rev-list -z --objects --no-object-names \ 226 + --missing=print-info HEAD >actual && 227 + 228 + test_cmp expect actual 229 + ) 230 + ' 231 + 201 232 test_done