From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS31976 209.132.180.0/23 X-Spam-Status: No, score=-4.3 required=3.0 tests=AWL,BAYES_00, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD shortcircuit=no autolearn=ham autolearn_force=no version=3.4.0 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by dcvr.yhbt.net (Postfix) with ESMTP id 965461F6C1 for ; Thu, 18 Aug 2016 12:48:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752429AbcHRMsP (ORCPT ); Thu, 18 Aug 2016 08:48:15 -0400 Received: from mout.gmx.net ([212.227.17.22]:53560 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1945898AbcHRMsI (ORCPT ); Thu, 18 Aug 2016 08:48:08 -0400 Received: from virtualbox ([37.24.141.212]) by mail.gmx.com (mrgmx102) with ESMTPSA (Nemesis) id 0MDn8s-1bOmf33fRe-00H5bS; Thu, 18 Aug 2016 14:46:23 +0200 Date: Thu, 18 Aug 2016 14:46:23 +0200 (CEST) From: Johannes Schindelin X-X-Sender: virtualbox@virtualbox To: git@vger.kernel.org cc: Junio C Hamano Subject: [PATCH 3/4] cat-file --textconv/--filters: allow specifying the path separately In-Reply-To: Message-ID: <787224ce9a382ddd1180a408e784ca26993e5603.1471524357.git.johannes.schindelin@gmx.de> References: User-Agent: Alpine 2.20 (DEB 67 2015-01-07) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Provags-ID: V03:K0:7/shNIOqUzeeOyvHUJBhq46EHAD47rcSR0uYEhePjkJ+yvDWB9k MM4JCc+RsLSdaryiXl2HJr5vTCPD3L45BbizZr6i2ZgUfNZpDjKKZJmFpjgBBnRJuiQlvRt fCQbfm0+Q7qOMoeCw3UyA2TLozdN50shXj7g+lXgwwnAO0ooCQVt0bOIjaBh0unTgsWSeSB JAvfpZ5mmdbFaIIgDCHuw== X-UI-Out-Filterresults: notjunk:1;V01:K0:y68pzysJJ1c=:fXaMGt9CWAOznk7tlTk7bd kcimKsaPDG1t292fHUyTrxC0rMr4wbxqPL/G9PPi4JrvQ2wCdB92oY4kVq7VhQDWzgGgr0D+m pNSYRPAhyScLDDzXRupxMZXrcv8jD1gv94Ag8hI5c8T6eFr84EKZ++0k67mKx+xKkojODwN2t XlGmW2QzdSU3Leszxn5kFZ94w9KNVTVy4GZ0o/u3H5UPBppAJ745ogIpSHp/IkrSt8VCdUGdA nc2WdP3G+MziDNfv9Rj6qM5iotAoiis8nXoIlJOTK+yxOwR9xFKZkwR0ktbvl6toYGa9sP992 amx2PMhNlymmSkJOa4TEmMI13abUMstX8YvQs8Iw5/XVTg/mqKC2rRYsQFZ7XspqsxV+YGFc2 ZLXXiYhO9g4hxBM41lPeCH31+mP7tQ4zLqh+pPsPQm0LagGCz8bLXNeSbvIhjeLeWTRV+pZgG 0JRDy2J1kcp32D4jnTsNKHpgVHLuESuIBlP8besbEatq35Mb8o6YIYjv4ytprA+x7CbMXBt5t mtpSEaP2tagZAhwnXNc8r50cGUgkkJKGQ3JloDpK/hU2B8sk9lZ9wYQF4KidnH4KlonntkQaW /zZV305xR8O+7Qj9XCdl0g3pFFbB0zABnoB592yyadf/diB2uftOf7WBOX+t9Y6yp9RYnMY+Y dJphYxr2WmJ2BL0YPbIzqVi8MmrubFZH8QmZRlddU/d93xC2VT3MOiJqpuJNyDTotPSImnfLx KoBORZGzDD9t9oC36DKtu1oEmm2Cv/WXeSSxo1Bz/COv2b49bNOwlkCFpcBVNMzvxuAUybbhs ah0GS0a Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org There are circumstances when it is relatively easy to figure out the object name for a given path, but not the revision. 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 --use-path=main.c 0f1937fd Signed-off-by: Johannes Schindelin --- Documentation/git-cat-file.txt | 7 ++++++- builtin/cat-file.c | 22 +++++++++++++++++----- t/t8010-cat-file-filters.sh | 13 +++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt index 7d48735..59a3c37 100644 --- a/Documentation/git-cat-file.txt +++ b/Documentation/git-cat-file.txt @@ -9,7 +9,7 @@ git-cat-file - Provide content or type and size information for repository objec SYNOPSIS -------- [verse] -'git cat-file' (-t [--allow-unknown-type]| -s [--allow-unknown-type]| -e | -p | | --textconv | --filters ) +'git cat-file' (-t [--allow-unknown-type]| -s [--allow-unknown-type]| -e | -p | | --textconv | --filters ) [--use-path=] 'git cat-file' (--batch | --batch-check) [--follow-symlinks] DESCRIPTION @@ -64,6 +64,11 @@ OPTIONS end-of-line conversion, etc). In this case, has to be of the form :, or :. +--use-path=:: + For use with --textconv or --filters, to allow specifying an object + name and a path separately, e.g. when it is difficult to figure out + the revision from which the blob came. + --batch:: --batch=:: Print object information and contents for each object provided diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 0b74afa..5ff58b3 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) @@ -89,21 +91,24 @@ 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 (!force_path && !obj_context.path[0]) die("git cat-file --filters %s: must be " "", obj_name); - if (filter_object(obj_context.path, obj_context.mode, + if (filter_object(force_path ? force_path : obj_context.path, + force_path ? 0100644 : obj_context.mode, sha1, &buf, &size)) return -1; break; case 'c': - if (!obj_context.path[0]) + if (!force_path && !obj_context.path[0]) die("git cat-file --textconv %s: must be ", obj_name); - if (textconv_object(obj_context.path, obj_context.mode, sha1, 1, &buf, &size)) + if (textconv_object(force_path ? force_path : obj_context.path, + force_path ? 0100644 : obj_context.mode, + sha1, 1, &buf, &size)) break; case 'p': @@ -477,7 +482,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||--textconv|--filters) "), + N_("git cat-file (-t [--allow-unknown-type]|-s [--allow-unknown-type]|-e|-p||--textconv|--filters) [--use-path=] "), N_("git cat-file (--batch | --batch-check) [--follow-symlinks]"), NULL }; @@ -525,6 +530,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, "use-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")), @@ -567,6 +574,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("--use-path= needs --textconv or --filters"); + usage_with_options(cat_file_usage, options); + } + if (batch.buffer_output < 0) batch.buffer_output = batch.all_objects; diff --git a/t/t8010-cat-file-filters.sh b/t/t8010-cat-file-filters.sh index e466634..fd17159 100755 --- a/t/t8010-cat-file-filters.sh +++ b/t/t8010-cat-file-filters.sh @@ -31,4 +31,17 @@ test_expect_success 'cat-file --filters converts to worktree version' ' has_cr actual ' +test_expect_success 'cat-file --filters --use-path= works' ' + sha1=$(git rev-parse -q --verify HEAD:world.txt) && + git cat-file --filters --use-path=world.txt $sha1 >actual && + has_cr actual +' + +test_expect_success 'cat-file --textconv --use-path= works' ' + sha1=$(git rev-parse -q --verify HEAD:world.txt) && + test_config diff.txt.textconv "tr A-Za-z N-ZA-Mn-za-m <" && + git cat-file --textconv --use-path=hello.txt $sha1 >rot13 && + test uryyb = "$(cat rot13 | remove_cr)" +' + test_done -- 2.9.2.691.g78954f3