Skip to content

Commit 95de376

Browse files
committed
Merge branch 'jk/bundle-use-dash-for-stdfiles'
"git bundle" learned that "-" is a common way to say that the input comes from the standard input and/or the output goes to the standard output. It used to work only for output and only from the root level of the working tree. * jk/bundle-use-dash-for-stdfiles: parse-options: use prefix_filename_except_for_dash() helper parse-options: consistently allocate memory in fix_filename() bundle: don't blindly apply prefix_filename() to "-" bundle: document handling of "-" as stdin bundle: let "-" mean stdin for reading operations
2 parents 12201fd + 0bbe103 commit 95de376

File tree

11 files changed

+82
-19
lines changed

11 files changed

+82
-19
lines changed

Documentation/git-bundle.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ create [options] <file> <git-rev-list-args>::
6666
Used to create a bundle named 'file'. This requires the
6767
'<git-rev-list-args>' arguments to define the bundle contents.
6868
'options' contains the options specific to the 'git bundle create'
69-
subcommand.
69+
subcommand. If 'file' is `-`, the bundle is written to stdout.
7070

7171
verify <file>::
7272
Used to check that a bundle file is valid and will apply
@@ -77,19 +77,21 @@ verify <file>::
7777
Finally, information about additional capabilities, such as "object
7878
filter", is printed. See "Capabilities" in linkgit:gitformat-bundle[5]
7979
for more information. The exit code is zero for success, but will
80-
be nonzero if the bundle file is invalid.
80+
be nonzero if the bundle file is invalid. If 'file' is `-`, the
81+
bundle is read from stdin.
8182

8283
list-heads <file>::
8384
Lists the references defined in the bundle. If followed by a
8485
list of references, only references matching those given are
85-
printed out.
86+
printed out. If 'file' is `-`, the bundle is read from stdin.
8687

8788
unbundle <file>::
8889
Passes the objects in the bundle to 'git index-pack'
8990
for storage in the repository, then prints the names of all
9091
defined references. If a list of references is given, only
9192
references matching those in the list are printed. This command is
9293
really plumbing, intended to be called only by 'git fetch'.
94+
If 'file' is `-`, the bundle is read from stdin.
9395

9496
<git-rev-list-args>::
9597
A list of arguments, acceptable to 'git rev-parse' and

abspath.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,3 +280,10 @@ char *prefix_filename(const char *pfx, const char *arg)
280280
#endif
281281
return strbuf_detach(&path, NULL);
282282
}
283+
284+
char *prefix_filename_except_for_dash(const char *pfx, const char *arg)
285+
{
286+
if (!strcmp(arg, "-"))
287+
return xstrdup(arg);
288+
return prefix_filename(pfx, arg);
289+
}

builtin/archive.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ static int run_remote_archiver(int argc, const char **argv,
8181
int cmd_archive(int argc, const char **argv, const char *prefix)
8282
{
8383
const char *exec = "git-upload-archive";
84-
const char *output = NULL;
84+
char *output = NULL;
8585
const char *remote = NULL;
8686
struct option local_opts[] = {
8787
OPT_FILENAME('o', "output", &output,
@@ -106,5 +106,6 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
106106

107107
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
108108

109+
UNLEAK(output);
109110
return write_archive(argc, argv, prefix, the_repository, output, 0);
110111
}

builtin/bundle.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static int parse_options_cmd_bundle(int argc,
5959
PARSE_OPT_STOP_AT_NON_OPTION);
6060
if (!argc)
6161
usage_msg_opt(_("need a <file> argument"), usagestr, options);
62-
*bundle_file = prefix_filename(prefix, argv[0]);
62+
*bundle_file = prefix_filename_except_for_dash(prefix, argv[0]);
6363
return argc;
6464
}
6565

@@ -108,6 +108,23 @@ static int cmd_bundle_create(int argc, const char **argv, const char *prefix) {
108108
return ret;
109109
}
110110

111+
/*
112+
* Similar to read_bundle_header(), but handle "-" as stdin.
113+
*/
114+
static int open_bundle(const char *path, struct bundle_header *header,
115+
const char **name)
116+
{
117+
if (!strcmp(path, "-")) {
118+
if (name)
119+
*name = "<stdin>";
120+
return read_bundle_header_fd(0, header, "<stdin>");
121+
}
122+
123+
if (name)
124+
*name = path;
125+
return read_bundle_header(path, header);
126+
}
127+
111128
static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) {
112129
struct bundle_header header = BUNDLE_HEADER_INIT;
113130
int bundle_fd = -1;
@@ -119,12 +136,13 @@ static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) {
119136
OPT_END()
120137
};
121138
char *bundle_file;
139+
const char *name;
122140

123141
argc = parse_options_cmd_bundle(argc, argv, prefix,
124142
builtin_bundle_verify_usage, options, &bundle_file);
125143
/* bundle internals use argv[1] as further parameters */
126144

127-
if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0) {
145+
if ((bundle_fd = open_bundle(bundle_file, &header, &name)) < 0) {
128146
ret = 1;
129147
goto cleanup;
130148
}
@@ -135,7 +153,7 @@ static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) {
135153
goto cleanup;
136154
}
137155

138-
fprintf(stderr, _("%s is okay\n"), bundle_file);
156+
fprintf(stderr, _("%s is okay\n"), name);
139157
ret = 0;
140158
cleanup:
141159
free(bundle_file);
@@ -156,7 +174,7 @@ static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix
156174
builtin_bundle_list_heads_usage, options, &bundle_file);
157175
/* bundle internals use argv[1] as further parameters */
158176

159-
if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0) {
177+
if ((bundle_fd = open_bundle(bundle_file, &header, NULL)) < 0) {
160178
ret = 1;
161179
goto cleanup;
162180
}
@@ -186,7 +204,7 @@ static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix)
186204
builtin_bundle_unbundle_usage, options, &bundle_file);
187205
/* bundle internals use argv[1] as further parameters */
188206

189-
if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0) {
207+
if ((bundle_fd = open_bundle(bundle_file, &header, NULL)) < 0) {
190208
ret = 1;
191209
goto cleanup;
192210
}

builtin/checkout.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ struct checkout_opts {
7676
const char *ignore_unmerged_opt;
7777
int ignore_unmerged;
7878
int pathspec_file_nul;
79-
const char *pathspec_from_file;
79+
char *pathspec_from_file;
8080

8181
const char *new_branch;
8282
const char *new_branch_force;
@@ -1890,6 +1890,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
18901890
options, checkout_usage, &new_branch_info);
18911891
branch_info_release(&new_branch_info);
18921892
clear_pathspec(&opts.pathspec);
1893+
free(opts.pathspec_from_file);
18931894
FREE_AND_NULL(options);
18941895
return ret;
18951896
}

builtin/reset.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
318318
int reset_type = NONE, update_ref_status = 0, quiet = 0;
319319
int no_refresh = 0;
320320
int patch_mode = 0, pathspec_file_nul = 0, unborn;
321-
const char *rev, *pathspec_from_file = NULL;
321+
const char *rev;
322+
char *pathspec_from_file = NULL;
322323
struct object_id oid;
323324
struct pathspec pathspec;
324325
int intent_to_add = 0;
@@ -496,5 +497,6 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
496497

497498
cleanup:
498499
clear_pathspec(&pathspec);
500+
free(pathspec_from_file);
499501
return update_ref_status;
500502
}

builtin/tag.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
429429
int create_reflog = 0;
430430
int annotate = 0, force = 0;
431431
int cmdmode = 0, create_tag_object = 0;
432-
const char *msgfile = NULL, *keyid = NULL;
432+
char *msgfile = NULL;
433+
const char *keyid = NULL;
433434
struct msg_arg msg = { .buf = STRBUF_INIT };
434435
struct ref_transaction *transaction;
435436
struct strbuf err = STRBUF_INIT;
@@ -639,5 +640,6 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
639640
strbuf_release(&reflog_msg);
640641
strbuf_release(&msg.buf);
641642
strbuf_release(&err);
643+
free(msgfile);
642644
return ret;
643645
}

cache.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,9 @@ char *prefix_path_gently(const char *prefix, int len, int *remaining, const char
610610
*/
611611
char *prefix_filename(const char *prefix, const char *path);
612612

613+
/* Likewise, but path=="-" always yields "-" */
614+
char *prefix_filename_except_for_dash(const char *prefix, const char *path);
615+
613616
int check_filename(const char *prefix, const char *name);
614617
void verify_filename(const char *prefix,
615618
const char *name,

parse-options.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ static enum parse_opt_result get_arg(struct parse_opt_ctx_t *p,
5959
return 0;
6060
}
6161

62-
static void fix_filename(const char *prefix, const char **file)
62+
static void fix_filename(const char *prefix, char **file)
6363
{
64-
if (!file || !*file || !prefix || is_absolute_path(*file)
65-
|| !strcmp("-", *file))
66-
return;
67-
*file = prefix_filename(prefix, *file);
64+
if (!file || !*file)
65+
; /* leave as NULL */
66+
else
67+
*file = prefix_filename_except_for_dash(prefix, *file);
6868
}
6969

7070
static enum parse_opt_result opt_command_mode_error(
@@ -177,7 +177,7 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
177177
err = get_arg(p, opt, flags, (const char **)opt->value);
178178

179179
if (!err)
180-
fix_filename(p->prefix, (const char **)opt->value);
180+
fix_filename(p->prefix, (char **)opt->value);
181181
return err;
182182

183183
case OPTION_CALLBACK:

t/helper/test-parse-pathspec-file.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
int cmd__parse_pathspec_file(int argc, const char **argv)
77
{
88
struct pathspec pathspec;
9-
const char *pathspec_from_file = NULL;
9+
char *pathspec_from_file = NULL;
1010
int pathspec_file_nul = 0, i;
1111

1212
static const char *const usage[] = {
@@ -29,5 +29,6 @@ int cmd__parse_pathspec_file(int argc, const char **argv)
2929
printf("%s\n", pathspec.items[i].original);
3030

3131
clear_pathspec(&pathspec);
32+
free(pathspec_from_file);
3233
return 0;
3334
}

0 commit comments

Comments
 (0)