Johannes Schindelin <johannes.schindelin@xxxxxx> writes: > As suggested by its name, the --filters option applies the filters > that are currently configured for the specified path. > > This feature comes in handy when a 3rd-party tool wants to work with > the contents of files from past revisions as if they had been checked > out, but without detouring via temporary files. > > Note that we ensure that symbolic links are unaffected (we know from > looking at the mode whether it refers to a symbolic link or a regular > file). I think you can lose the last paragraph and enrich the first one instead. The text as-given does not even say anything about the new option affecting only blobs. The --filters option applies the convert_to_working_tree() filter for the path when showing the contents of a regular file blob object. or something like that. > +--filters:: > + Show the content as transformed by the filters configured in > + the current working tree for the given <path> (i.e. smudge filters, > + end-of-line conversion, etc). In this case, <object> has to be of > + the form <tree-ish>:<path>, or :<path>. Makes sense. We show the contents as if we are checking the blob out to the given <path>, in other words. > diff --git a/builtin/cat-file.c b/builtin/cat-file.c > index 2dfe626..0b74afa 100644 > --- a/builtin/cat-file.c > +++ b/builtin/cat-file.c > @@ -20,6 +20,33 @@ struct batch_options { > const char *format; > }; > > +static int filter_object(const char *path, unsigned mode, > + const unsigned char *sha1, > + char **buf, unsigned long *size) > +{ > + enum object_type type; > + > + *buf = read_sha1_file(sha1, &type, size); > + if (!*buf) > + return error(_("cannot read object %s '%s'"), > + sha1_to_hex(sha1), path); > + if (type != OBJ_BLOB) { > + free(*buf); > + return error(_("blob expected for %s '%s'"), > + sha1_to_hex(sha1), path); > + } > + if (S_ISREG(mode)) { > + struct strbuf strbuf = STRBUF_INIT; > + if (convert_to_working_tree(path, *buf, *size, &strbuf)) { > + free(*buf); > + *size = strbuf.len; > + *buf = strbuf_detach(&strbuf, NULL); > + } > + } This is just a tangent for future clean-up of the coding convention, but if we used size_t internally throughout the system, we would be able to use strbuf_detach(&strbuf, size) instead. With the current coding convention, all internal sizes are ulong, and this is the best we could do. > @@ -61,6 +88,16 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, > case 'e': > return !has_sha1_file(sha1); > > + case 'w': > + if (!obj_context.path[0]) > + die("git cat-file --filters %s: <object> must be " > + "<sha1:path>", obj_name); > + > + if (filter_object(obj_context.path, obj_context.mode, > + sha1, &buf, &size)) > + return -1; > + break; > + Makes sense. > diff --git a/t/t8010-cat-file-filters.sh b/t/t8010-cat-file-filters.sh > new file mode 100755 > index 0000000..e466634 > --- /dev/null > +++ b/t/t8010-cat-file-filters.sh > @@ -0,0 +1,34 @@ > +#!/bin/sh > + > +test_description='git cat-file filters support' > +. ./test-lib.sh > + > +test_expect_success 'setup ' ' > + echo "*.txt eol=crlf diff=txt" >.gitattributes && > + echo "hello" | append_cr >world.txt && > + git add .gitattributes world.txt && > + test_tick && > + git commit -m "Initial commit" > +' OK, so we ask *.txt in the working tree to be CRLF (and presumably that means the in-repository objects are LF). > +has_cr () { > + tr '\015' Q <"$1" | grep Q >/dev/null > +} > + > +test_expect_success 'no filters with `git show`' ' > + git show HEAD:world.txt >actual && > + ! has_cr actual > + > +' > + > +test_expect_success 'no filters with cat-file' ' > + git cat-file blob HEAD:world.txt >actual && > + ! has_cr actual > +' OK. > +test_expect_success 'cat-file --filters converts to worktree version' ' > + git cat-file --filters HEAD:world.txt >actual && > + has_cr actual > +' OK. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html