summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
authorLibravatar Johannes Schindelin <johannes.schindelin@gmx.de>2016-09-09 12:10:50 +0200
committerLibravatar Junio C Hamano <gitster@pobox.com>2016-09-11 14:48:15 -0700
commit7bcf341453572a227036afec76bdab451b798870 (patch)
tree44bf23805839bd2af79a0f33ede751b15821c217 /builtin
parentcat-file: introduce the --filters option (diff)
downloadtgif-7bcf341453572a227036afec76bdab451b798870.tar.xz
cat-file --textconv/--filters: allow specifying the path separately
There are circumstances when it is relatively easy to figure out the object name for a given path, but not the name of the containing tree. For example, when looking at a diff generated by Git, the object names are recorded, but not the revision. As a matter of fact, the revisions from which the diff was generated may not even exist locally. In such a case, the user would have to generate a fake revision just to be able to use --textconv or --filters. Let's simplify this dramatically, because we do not really need that revision at all: all we care about is that we know the path. In the scenario described above, we do know the path, and we just want to specify it separately from the object name. Example usage: git cat-file --textconv --path=main.c 0f1937fd Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin')
-rw-r--r--builtin/cat-file.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 96007cb1a0..51f4c546ee 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -20,6 +20,8 @@ struct batch_options {
const char *format;
};
+static const char *force_path;
+
static int filter_object(const char *path, unsigned mode,
const unsigned char *sha1,
char **buf, unsigned long *size)
@@ -53,6 +55,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
struct object_info oi = {NULL};
struct strbuf sb = STRBUF_INIT;
unsigned flags = LOOKUP_REPLACE_OBJECT;
+ const char *path = force_path;
if (unknown_type)
flags |= LOOKUP_UNKNOWN_OBJECT;
@@ -60,6 +63,11 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
if (get_sha1_with_context(obj_name, 0, sha1, &obj_context))
die("Not a valid object name %s", obj_name);
+ if (!path)
+ path = obj_context.path;
+ if (obj_context.mode == S_IFINVALID)
+ obj_context.mode = 0100644;
+
buf = NULL;
switch (opt) {
case 't':
@@ -84,21 +92,22 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
return !has_sha1_file(sha1);
case 'w':
- if (!obj_context.path[0])
+ if (!path[0])
die("git cat-file --filters %s: <object> must be "
"<sha1:path>", obj_name);
- if (filter_object(obj_context.path, obj_context.mode,
+ if (filter_object(path, obj_context.mode,
sha1, &buf, &size))
return -1;
break;
case 'c':
- if (!obj_context.path[0])
+ if (!path[0])
die("git cat-file --textconv %s: <object> must be <sha1:path>",
obj_name);
- if (textconv_object(obj_context.path, obj_context.mode, sha1, 1, &buf, &size))
+ if (textconv_object(path, obj_context.mode,
+ sha1, 1, &buf, &size))
break;
case 'p':
@@ -472,7 +481,7 @@ static int batch_objects(struct batch_options *opt)
}
static const char * const cat_file_usage[] = {
- N_("git cat-file (-t [--allow-unknown-type]|-s [--allow-unknown-type]|-e|-p|<type>|--textconv|--filters) <object>"),
+ N_("git cat-file (-t [--allow-unknown-type]|-s [--allow-unknown-type]|-e|-p|<type>|--textconv|--filters) [--path=<path>] <object>"),
N_("git cat-file (--batch | --batch-check) [--follow-symlinks]"),
NULL
};
@@ -520,6 +529,8 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
N_("for blob objects, run textconv on object's content"), 'c'),
OPT_CMDMODE(0, "filters", &opt,
N_("for blob objects, run filters on object's content"), 'w'),
+ OPT_STRING(0, "path", &force_path, N_("blob"),
+ N_("use a specific path for --textconv/--filters")),
OPT_BOOL(0, "allow-unknown-type", &unknown_type,
N_("allow -s and -t to work with broken/corrupt objects")),
OPT_BOOL(0, "buffer", &batch.buffer_output, N_("buffer --batch output")),
@@ -562,6 +573,11 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
usage_with_options(cat_file_usage, options);
}
+ if (force_path && opt != 'c' && opt != 'w') {
+ error("--path=<path> needs --textconv or --filters");
+ usage_with_options(cat_file_usage, options);
+ }
+
if (batch.buffer_output < 0)
batch.buffer_output = batch.all_objects;