cat-file: add --follow-symlinks to --batch

This wires the in-repo-symlink following code through to the cat-file
builtin.  In the event of an out-of-repo link, cat-file will print
the link in a new format.

Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
David Turner
2015-05-20 13:03:40 -04:00
committed by Junio C Hamano
parent c4ec96774b
commit 122d53464b
3 changed files with 348 additions and 7 deletions

View File

@ -8,6 +8,7 @@
#include "parse-options.h"
#include "userdiff.h"
#include "streaming.h"
#include "tree-walk.h"
static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
{
@ -224,6 +225,7 @@ static void print_object_or_die(int fd, struct expand_data *data)
struct batch_options {
int enabled;
int follow_symlinks;
int print_contents;
const char *format;
};
@ -232,12 +234,44 @@ static int batch_one_object(const char *obj_name, struct batch_options *opt,
struct expand_data *data)
{
struct strbuf buf = STRBUF_INIT;
struct object_context ctx;
int flags = opt->follow_symlinks ? GET_SHA1_FOLLOW_SYMLINKS : 0;
enum follow_symlinks_result result;
if (!obj_name)
return 1;
if (get_sha1(obj_name, data->sha1)) {
printf("%s missing\n", obj_name);
result = get_sha1_with_context(obj_name, flags, data->sha1, &ctx);
if (result != FOUND) {
switch (result) {
case MISSING_OBJECT:
printf("%s missing\n", obj_name);
break;
case DANGLING_SYMLINK:
printf("dangling %"PRIuMAX"\n%s\n",
(uintmax_t)strlen(obj_name), obj_name);
break;
case SYMLINK_LOOP:
printf("loop %"PRIuMAX"\n%s\n",
(uintmax_t)strlen(obj_name), obj_name);
break;
case NOT_DIR:
printf("notdir %"PRIuMAX"\n%s\n",
(uintmax_t)strlen(obj_name), obj_name);
break;
default:
die("BUG: unknown get_sha1_with_context result %d\n",
result);
break;
}
fflush(stdout);
return 0;
}
if (ctx.mode == 0) {
printf("symlink %"PRIuMAX"\n%s\n",
(uintmax_t)ctx.symlink_path.len,
ctx.symlink_path.buf);
fflush(stdout);
return 0;
}
@ -324,7 +358,7 @@ static int batch_objects(struct batch_options *opt)
static const char * const cat_file_usage[] = {
N_("git cat-file (-t | -s | -e | -p | <type> | --textconv) <object>"),
N_("git cat-file (--batch | --batch-check) < <list-of-objects>"),
N_("git cat-file (--batch | --batch-check) [--follow-symlinks] < <list-of-objects>"),
NULL
};
@ -342,9 +376,8 @@ static int batch_option_callback(const struct option *opt,
{
struct batch_options *bo = opt->value;
if (unset) {
memset(bo, 0, sizeof(*bo));
return 0;
if (bo->enabled) {
return 1;
}
bo->enabled = 1;
@ -375,6 +408,8 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
{ OPTION_CALLBACK, 0, "batch-check", &batch, "format",
N_("show info about objects fed from the standard input"),
PARSE_OPT_OPTARG, batch_option_callback },
OPT_BOOL(0, "follow-symlinks", &batch.follow_symlinks,
N_("follow in-tree symlinks (used with --batch or --batch-check)")),
OPT_END()
};
@ -402,6 +437,10 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
usage_with_options(cat_file_usage, options);
}
if (batch.follow_symlinks && !batch.enabled) {
usage_with_options(cat_file_usage, options);
}
if (batch.enabled)
return batch_objects(&batch);