Skip to content

Commit 28c7b1f

Browse files
mhaggergitster
authored andcommitted
fast-import: add a get-mark command
It is sometimes useful for importers to be able to read the SHA-1 corresponding to a mark that they have created via fast-import. For example, they might want to embed the SHA-1 into the commit message of a later commit. Or it might be useful for internal bookkeeping uses, or for logging. Add a "get-mark" command to "git fast-import" that allows the importer to ask for the value of a mark that has been created earlier. Signed-off-by: Michael Haggerty <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3d4a3ff commit 28c7b1f

File tree

3 files changed

+75
-10
lines changed

3 files changed

+75
-10
lines changed

Documentation/git-fast-import.txt

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Options for Frontends
5454
~~~~~~~~~~~~~~~~~~~~~
5555

5656
--cat-blob-fd=<fd>::
57-
Write responses to `cat-blob` and `ls` queries to the
57+
Write responses to `get-mark`, `cat-blob`, and `ls` queries to the
5858
file descriptor <fd> instead of `stdout`. Allows `progress`
5959
output intended for the end-user to be separated from other
6060
output.
@@ -350,6 +350,11 @@ and control the current import process. More detailed discussion
350350
unless the `done` feature was requested using the
351351
`--done` command-line option or `feature done` command.
352352

353+
`get-mark`::
354+
Causes fast-import to print the SHA-1 corresponding to a mark
355+
to the file descriptor set with `--cat-blob-fd`, or `stdout` if
356+
unspecified.
357+
353358
`cat-blob`::
354359
Causes fast-import to print a blob in 'cat-file --batch'
355360
format to the file descriptor set with `--cat-blob-fd` or
@@ -930,6 +935,25 @@ Placing a `progress` command immediately after a `checkpoint` will
930935
inform the reader when the `checkpoint` has been completed and it
931936
can safely access the refs that fast-import updated.
932937

938+
`get-mark`
939+
~~~~~~~~~~
940+
Causes fast-import to print the SHA-1 corresponding to a mark to
941+
stdout or to the file descriptor previously arranged with the
942+
`--cat-blob-fd` argument. The command otherwise has no impact on the
943+
current import; its purpose is to retrieve SHA-1s that later commits
944+
might want to refer to in their commit messages.
945+
946+
....
947+
'get-mark' SP ':' <idnum> LF
948+
....
949+
950+
This command can be used anywhere in the stream that comments are
951+
accepted. In particular, the `get-mark` command can be used in the
952+
middle of a commit but not in the middle of a `data` command.
953+
954+
See ``Responses To Commands'' below for details about how to read
955+
this output safely.
956+
933957
`cat-blob`
934958
~~~~~~~~~~
935959
Causes fast-import to print a blob to a file descriptor previously
@@ -1000,7 +1024,8 @@ Output uses the same format as `git ls-tree <tree> -- <path>`:
10001024
====
10011025

10021026
The <dataref> represents the blob, tree, or commit object at <path>
1003-
and can be used in later 'cat-blob', 'filemodify', or 'ls' commands.
1027+
and can be used in later 'get-mark', 'cat-blob', 'filemodify', or
1028+
'ls' commands.
10041029

10051030
If there is no file or subtree at that path, 'git fast-import' will
10061031
instead report
@@ -1042,9 +1067,11 @@ import-marks-if-exists::
10421067
"feature import-marks-if-exists" like a corresponding
10431068
command-line option silently skips a nonexistent file.
10441069

1070+
get-mark::
10451071
cat-blob::
10461072
ls::
1047-
Require that the backend support the 'cat-blob' or 'ls' command.
1073+
Require that the backend support the 'get-mark', 'cat-blob',
1074+
or 'ls' command respectively.
10481075
Versions of fast-import not supporting the specified command
10491076
will exit with a message indicating so.
10501077
This lets the import error out early with a clear message,
@@ -1124,11 +1151,11 @@ bidirectional pipes:
11241151
git fast-import >fast-import-output
11251152
====
11261153

1127-
A frontend set up this way can use `progress`, `ls`, and `cat-blob`
1128-
commands to read information from the import in progress.
1154+
A frontend set up this way can use `progress`, `get-mark`, `ls`, and
1155+
`cat-blob` commands to read information from the import in progress.
11291156

11301157
To avoid deadlock, such frontends must completely consume any
1131-
pending output from `progress`, `ls`, and `cat-blob` before
1158+
pending output from `progress`, `ls`, `get-mark`, and `cat-blob` before
11321159
performing writes to fast-import that might block.
11331160

11341161
Crash Reports

fast-import.c

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,16 +134,17 @@ Format of STDIN stream:
134134
ts ::= # time since the epoch in seconds, ascii base10 notation;
135135
tz ::= # GIT style timezone;
136136
137-
# note: comments, ls and cat requests may appear anywhere
138-
# in the input, except within a data command. Any form
139-
# of the data command always escapes the related input
140-
# from comment processing.
137+
# note: comments, get-mark, ls-tree, and cat-blob requests may
138+
# appear anywhere in the input, except within a data command. Any
139+
# form of the data command always escapes the related input from
140+
# comment processing.
141141
#
142142
# In case it is not clear, the '#' that starts the comment
143143
# must be the first character on that line (an lf
144144
# preceded it).
145145
#
146146
147+
get_mark ::= 'get-mark' sp idnum lf;
147148
cat_blob ::= 'cat-blob' sp (hexsha1 | idnum) lf;
148149
ls_tree ::= 'ls' sp (hexsha1 | idnum) sp path_str lf;
149150
@@ -372,6 +373,7 @@ static volatile sig_atomic_t checkpoint_requested;
372373
static int cat_blob_fd = STDOUT_FILENO;
373374

374375
static void parse_argv(void);
376+
static void parse_get_mark(const char *p);
375377
static void parse_cat_blob(const char *p);
376378
static void parse_ls(const char *p, struct branch *b);
377379

@@ -1907,6 +1909,10 @@ static int read_next_command(void)
19071909
rc->prev->next = rc;
19081910
cmd_tail = rc;
19091911
}
1912+
if (skip_prefix(command_buf.buf, "get-mark ", &p)) {
1913+
parse_get_mark(p);
1914+
continue;
1915+
}
19101916
if (skip_prefix(command_buf.buf, "cat-blob ", &p)) {
19111917
parse_cat_blob(p);
19121918
continue;
@@ -2919,6 +2925,23 @@ static void cat_blob(struct object_entry *oe, unsigned char sha1[20])
29192925
free(buf);
29202926
}
29212927

2928+
static void parse_get_mark(const char *p)
2929+
{
2930+
struct object_entry *oe = oe;
2931+
char output[42];
2932+
2933+
/* get-mark SP <object> LF */
2934+
if (*p != ':')
2935+
die("Not a mark: %s", p);
2936+
2937+
oe = find_mark(parse_mark_ref_eol(p));
2938+
if (!oe)
2939+
die("Unknown mark: %s", command_buf.buf);
2940+
2941+
snprintf(output, sizeof(output), "%s\n", sha1_to_hex(oe->idx.sha1));
2942+
cat_blob_write(output, 41);
2943+
}
2944+
29222945
static void parse_cat_blob(const char *p)
29232946
{
29242947
struct object_entry *oe = oe;
@@ -3243,6 +3266,8 @@ static int parse_one_feature(const char *feature, int from_stream)
32433266
option_import_marks(arg, from_stream, 1);
32443267
} else if (skip_prefix(feature, "export-marks=", &arg)) {
32453268
option_export_marks(arg);
3269+
} else if (!strcmp(feature, "get-mark")) {
3270+
; /* Don't die - this feature is supported */
32463271
} else if (!strcmp(feature, "cat-blob")) {
32473272
; /* Don't die - this feature is supported */
32483273
} else if (!strcmp(feature, "relative-marks")) {

t/t9300-fast-import.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2339,6 +2339,19 @@ test_expect_success !MINGW 'R: in-stream cat-blob-fd not respected' '
23392339
test_cmp expect actual.1
23402340
'
23412341

2342+
test_expect_success !MINGW 'R: print mark for new blob' '
2343+
echo "effluentish" | git hash-object --stdin >expect &&
2344+
git fast-import --cat-blob-fd=6 6>actual <<-\EOF &&
2345+
blob
2346+
mark :1
2347+
data <<BLOB_END
2348+
effluentish
2349+
BLOB_END
2350+
get-mark :1
2351+
EOF
2352+
test_cmp expect actual
2353+
'
2354+
23422355
test_expect_success !MINGW 'R: print new blob' '
23432356
blob=$(echo "yep yep yep" | git hash-object --stdin) &&
23442357
cat >expect <<-EOF &&

0 commit comments

Comments
 (0)