From patchwork Tue Nov 19 16:48:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Arver via GitGitGadget X-Patchwork-Id: 11252455 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E24591593 for ; Tue, 19 Nov 2019 16:49:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C36B1208CC for ; Tue, 19 Nov 2019 16:49:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jBg+/lgb" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728536AbfKSQtF (ORCPT ); Tue, 19 Nov 2019 11:49:05 -0500 Received: from mail-wm1-f68.google.com ([209.85.128.68]:36240 "EHLO mail-wm1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728362AbfKSQtB (ORCPT ); Tue, 19 Nov 2019 11:49:01 -0500 Received: by mail-wm1-f68.google.com with SMTP id c22so4540398wmd.1 for ; Tue, 19 Nov 2019 08:48:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=1MERttk1qWaqxfrCV4b8uDP13mKag0juDEFZYceBm7s=; b=jBg+/lgbzreERGLwr8mIYK//GkVEzmUhMg53ZZ4r7WDfUMRbZJ05/QD9V38JhcacHO C40AIY9I9kHSBF41UMJ6/2Xcp80igp7BwdQstpx2T4kdDIv9kLS7gxM4zBYmXFITKuqL NgXRSacuJ79LqyDz6GRhR64IGDums/tQXQk1yj0NpTBK5GyyXOd7ASYv6x56+3aeFJOz a+ZbfMJkbQiWwJsclFWDjwplVx3aIS2/xnNYgnRJQCBJVCaaNnfW2p+TIh00XGcE2nGl FSeZpLqA3P4A3Zyl3s9e1x/CP4FR9kUEp2LoKefrjI5KZ3JVXrUbh3cyNTOWN+X+J86e wOmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=1MERttk1qWaqxfrCV4b8uDP13mKag0juDEFZYceBm7s=; b=QdEdtW6Say6LWvqp6IpSe+4DSZjZGgdo48LUlO3tTyeayueB0KA9sttnRbhc9iEZ3Q 19esV86hObjdcGTcU1l3/dXPs1Rx4Mcle9SgB2eG/rWhegg9X0Kwh0K2ZXwjVbcg4278 slwIOyxQQbVj0UGFs83T3vId+MZ0QOaGkte4bik7H7aaDvtdtDAqKarWsZLwt//22xVN DzT7/SCvaWX0tYNj8eaxlq9mH12VkejeEc5BwM/efxW6//z5HAGix3f75kIcIgPMWlj1 EiNB/HyGuolzuxIehooY1koy4DGmzjPQfaljrZ2CKkxphYEcqAET53LaqyQ1FIA52Wvp NDIw== X-Gm-Message-State: APjAAAW8MbontfSCDTNlLw/WaB/PT/FZXoEpFmYc/8aMKU1yZiP7KpKv cYJtEEOMrmwAW4D7eo5Hqyk4x1r23uc= X-Google-Smtp-Source: APXvYqxNIsXnB5AxYjULyh9+U+Z0yKuTyuD5l5NgKt6ImkErcPbwXWNQMMTklTgvPrJrDNf0zjSkdw== X-Received: by 2002:a05:600c:214a:: with SMTP id v10mr6852646wml.102.1574182137583; Tue, 19 Nov 2019 08:48:57 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id z2sm15932101wrs.89.2019.11.19.08.48.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Nov 2019 08:48:57 -0800 (PST) Message-Id: <19b80326ead8bdc44b5d8ca951feb3d6c1f5493c.1574182135.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Alexandr Miloslavskiy via GitGitGadget" Date: Tue, 19 Nov 2019 16:48:50 +0000 Subject: [PATCH v3 1/6] parse-options.h: add new options `--pathspec-from-file`, `--pathspec-file-nul` Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Alexandr Miloslavskiy , Junio C Hamano , Alexandr Miloslavskiy Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Alexandr Miloslavskiy Support for various porcelain commands will arrive via additional patches. `--pathspec-from-file` solves the problem of commandline length limit for UIs built on top of git. Plumbing commands are not always a good fit, for two major reasons: 1) Some UIs show executed commands to user. In this case, porcelain commands are expected. One reason for that is letting user learn git commands by clicking UI buttons. The other reason is letting user study the history of commands in case of any unexpected results. Both of these will lose most of their value if UI uses combinations of arcane plumbing commands. 2) Some UIs have started and grown with porcelain commands. Replacing existing logic with plumbing commands could be cumbersome and prone to various new problems. `--pathspec-from-file` will behave very close to pathspec passed in commandline args, so that switching from one to another is simple. `--pathspec-from-file` will read either a specified file or `stdin` (when file is exactly "-"). Reading from file is a good way to avoid competing for `stdin`, and also gives some extra flexibility. `--pathspec-file-nul` switch mirrors `-z` already used in various places. Some porcelain commands, such as `git commit`, already use `-z`, therefore it needed a new unambiguous name. New options do not have shorthands to avoid shorthand conflicts. It is not expected that they will be typed in console. Signed-off-by: Alexandr Miloslavskiy --- parse-options.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/parse-options.h b/parse-options.h index 38a33a087e..c6cc01e715 100644 --- a/parse-options.h +++ b/parse-options.h @@ -330,5 +330,7 @@ int parse_opt_passthru_argv(const struct option *, const char *, int); #define OPT_WITH(v, h) _OPT_CONTAINS_OR_WITH("with", v, h, PARSE_OPT_HIDDEN | PARSE_OPT_NONEG) #define OPT_WITHOUT(v, h) _OPT_CONTAINS_OR_WITH("without", v, h, PARSE_OPT_HIDDEN | PARSE_OPT_NONEG) #define OPT_CLEANUP(v) OPT_STRING(0, "cleanup", v, N_("mode"), N_("how to strip spaces and #comments from message")) +#define OPT_PATHSPEC_FROM_FILE(v) OPT_FILENAME(0, "pathspec-from-file", v, N_("read pathspec from file")) +#define OPT_PATHSPEC_FILE_NUL(v) OPT_BOOL(0, "pathspec-file-nul", v, N_("with --pathspec-from-file, pathspec elements are separated with NUL character")) #endif From patchwork Tue Nov 19 16:48:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Arver via GitGitGadget X-Patchwork-Id: 11252447 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3F6061871 for ; Tue, 19 Nov 2019 16:49:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2095D208CC for ; Tue, 19 Nov 2019 16:49:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="eCqTx74F" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728513AbfKSQtA (ORCPT ); Tue, 19 Nov 2019 11:49:00 -0500 Received: from mail-wm1-f67.google.com ([209.85.128.67]:56081 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728287AbfKSQtA (ORCPT ); Tue, 19 Nov 2019 11:49:00 -0500 Received: by mail-wm1-f67.google.com with SMTP id b11so3939243wmb.5 for ; Tue, 19 Nov 2019 08:48:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=HjSBzc0rGvd4vC7CgPBj9hyIis2u+fMfIGl4JldqIGg=; b=eCqTx74FxLEy52x4JdfDmTP7Z/7vZlprN4oY9oyVDi6hL0jn5emUckaO4w10FieON5 uUfbIzkVED2i+Ay0fcISDjtIhtcdnOST0ykNWF9F3LBzhFtdJQOTcn1mSl2NgszCajPi iEMJoM+JEF51CbIGgi6YzbeG8bxy6XbgErNSuR2wxZc0IQ20cONI5lZiz2ffe51Vlb4I XdXp9CCAOr8SbXHRvIfEQ8MjBR8dESqM1BCBJY5uaKZ28IUWiL3pDdlvUAAUqdEQL7SJ OAfto8WhqisF33ORMN9w++XzL7kskdVHtOwKdiKYwM1a91k6DiBgjMpbvzyTCZrvnkri /S6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=HjSBzc0rGvd4vC7CgPBj9hyIis2u+fMfIGl4JldqIGg=; b=HpQBxPWtF+CCoSD2cWrWM7T+jDPX6WHpoTWHvpDLGQWOMH7W6+ySFkTrd5QogUFWXh RrHGCSMPWY/eQ0Q0LO3LQd5zpBxsUxSmNe1suCy1LpruNV+ALtJYROp6BJOdT2MCugpe bdy1q9W7VcnpfF8R7agk6hfMPOU/adCPeOnK71xabplJ+37K8KpddiloBureZFUHE8PN dJouDXZhmGiownSST+AGNZwuRoaMS7ErD+iqg9gSkeLpVgmhwqc/fc82VsAqYnCm35Bh Jy+ooEFvIoO2LYJWLZhX0YKpvOWFDHH1G8b7m3U0S5+wC3+23w1cvHMac0bRkJVBUcZ0 6pdA== X-Gm-Message-State: APjAAAXrtB3hZwY9tR/DtuQHCE7aRbcLZuOSb6cGC+U9rEIlpcfoHP0r KQxUXZV/7mpOi45K/vjvjbSJmu6pQiA= X-Google-Smtp-Source: APXvYqw84RwjglP1f2fJXOzs9iLOnG2ePqWmo60EODfgLqUQMQ+dkaCrJFsOKC2VL/w0oRwPkb66qg== X-Received: by 2002:a7b:c411:: with SMTP id k17mr6611816wmi.119.1574182138279; Tue, 19 Nov 2019 08:48:58 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id r25sm3671189wmh.6.2019.11.19.08.48.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Nov 2019 08:48:57 -0800 (PST) Message-Id: <55a7c6ec3cebd46b8650ad8116923676fa0e2b3a.1574182135.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Alexandr Miloslavskiy via GitGitGadget" Date: Tue, 19 Nov 2019 16:48:51 +0000 Subject: [PATCH v3 2/6] pathspec: add new function to parse file Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Alexandr Miloslavskiy , Junio C Hamano , Alexandr Miloslavskiy Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Alexandr Miloslavskiy This will be used to support the new option '--pathspec-from-file' in `git add`, `git-commit`, `git reset` etc. Note also that we specifically handle CR/LF line endings to support Windows better. To simplify code, file is first parsed into `argv_array`. This allows to avoid refactoring `parse_pathspec()`. I considered adding `nul_term_line` to `flags` instead, but decided that it doesn't fit there. The new code is mostly taken from `cmd_update_index()` and `split_mail_conv()`. Co-authored-by: Johannes Schindelin Signed-off-by: Alexandr Miloslavskiy --- pathspec.c | 38 ++++++++++++++++++++++++++++++++++++++ pathspec.h | 10 ++++++++++ 2 files changed, 48 insertions(+) diff --git a/pathspec.c b/pathspec.c index 12c2b322b3..128f27fcb7 100644 --- a/pathspec.c +++ b/pathspec.c @@ -3,6 +3,8 @@ #include "dir.h" #include "pathspec.h" #include "attr.h" +#include "argv-array.h" +#include "quote.h" /* * Finds which of the given pathspecs match items in the index. @@ -613,6 +615,42 @@ void parse_pathspec(struct pathspec *pathspec, } } +void parse_pathspec_file(struct pathspec *pathspec, unsigned magic_mask, + unsigned flags, const char *prefix, + const char *file, int nul_term_line) +{ + struct argv_array parsed_file = ARGV_ARRAY_INIT; + strbuf_getline_fn getline_fn = nul_term_line ? strbuf_getline_nul : + strbuf_getline; + struct strbuf buf = STRBUF_INIT; + struct strbuf unquoted = STRBUF_INIT; + FILE *in; + + if (!strcmp(file, "-")) + in = stdin; + else + in = xfopen(file, "r"); + + while (getline_fn(&buf, in) != EOF) { + if (!nul_term_line && buf.buf[0] == '"') { + strbuf_reset(&unquoted); + if (unquote_c_style(&unquoted, buf.buf, NULL)) + die(_("line is badly quoted: %s"), buf.buf); + strbuf_swap(&buf, &unquoted); + } + argv_array_push(&parsed_file, buf.buf); + strbuf_reset(&buf); + } + + strbuf_release(&unquoted); + strbuf_release(&buf); + if (in != stdin) + fclose(in); + + parse_pathspec(pathspec, magic_mask, flags, prefix, parsed_file.argv); + argv_array_clear(&parsed_file); +} + void copy_pathspec(struct pathspec *dst, const struct pathspec *src) { int i, j; diff --git a/pathspec.h b/pathspec.h index 1c18a2c90c..a27dc81ba2 100644 --- a/pathspec.h +++ b/pathspec.h @@ -85,6 +85,16 @@ void parse_pathspec(struct pathspec *pathspec, unsigned flags, const char *prefix, const char **args); +/* + * Same as parse_pathspec() but uses file as input. + * When 'file' is exactly "-" it uses 'stdin' instead. + */ +void parse_pathspec_file(struct pathspec *pathspec, + unsigned magic_mask, + unsigned flags, + const char *prefix, + const char *file, + int nul_term_line); void copy_pathspec(struct pathspec *dst, const struct pathspec *src); void clear_pathspec(struct pathspec *); From patchwork Tue Nov 19 16:48:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Arver via GitGitGadget X-Patchwork-Id: 11252445 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BD6F0109A for ; Tue, 19 Nov 2019 16:49:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9D49F20885 for ; Tue, 19 Nov 2019 16:49:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="h4/sfycv" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728523AbfKSQtC (ORCPT ); Tue, 19 Nov 2019 11:49:02 -0500 Received: from mail-wm1-f54.google.com ([209.85.128.54]:53576 "EHLO mail-wm1-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728387AbfKSQtB (ORCPT ); Tue, 19 Nov 2019 11:49:01 -0500 Received: by mail-wm1-f54.google.com with SMTP id u18so3966170wmc.3 for ; Tue, 19 Nov 2019 08:48:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=/uK7BgEr7oMW5g58dt51M2VtdlmyVxFS9orGRLslvD0=; b=h4/sfycvl6thCdM8GHBst2wuTExThGYpJqMC7TUV2IlQmZLLOIUAY2Pn2SVqBrkK3Y 92NlSvGaH0syQ5BlQFm5o2OzTVgZKS4T18cCBqIo2kG6/xnf/ZnIgtFBs0+CdxdgVymd osMaO/UGteepSlfjCdFBC0aCmhvNqrQ2WqkwgJ7xK+w1uaOmx97eu7M2dtcftpg3idfz qCGXc+7Dg84U3uzUAZzOA100OSm6Tz5qknjUIiuXUiGd/0P7LttGNTZTCj0UgAztOYqi VnxzXOtnjIklO6/TGTxnmweuVx7a5stM9AzlvgK2bTk4kVFXcdgjIq+ulO+mjpqr4XXq H+8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=/uK7BgEr7oMW5g58dt51M2VtdlmyVxFS9orGRLslvD0=; b=fnGRn6DQC3VqpHhRMLq1rgUByyVkYzV0A/lLUmGWduK9FmH/qEW1j5FWa6uuo69W+S YDZeeA3f+Dy+w0LRy/3dXf7boiUuNVTQTmoq6Fx1zgkCWOOboflGtSwnFrQhweHsLxOH Z/1vW4OpPIVIo6mMMpRNQGEf+QDNXQxWbQlff7v543kFsL7wuXQbl+Y8VGT7JUSZh3ip iVpJ87SjZmNmtihiBFqkniZ17dyciEP36kK0xD2ADgODsM8KIBnS4nbM19DIG4sJRzir sqa752yIRrY/SM0Yzt6ACDctFVQTGX8Cq+oMmddUvceXTPJSve7hmNu08EESfHiU4Qq+ RHdw== X-Gm-Message-State: APjAAAXzPIx54DhJsUbmw3mB4iC5T0eBd9hMgOSxBhCltMbE2dkshZz4 OuS91JxDAmw2wgVDdw7pGLKRTCfgU1o= X-Google-Smtp-Source: APXvYqwhNfC/mMbrndQKFW7dS38WOVZquJysWJZW46sIZbMB40FYuk77fKVSXoT40e0QZgsbwNJCZw== X-Received: by 2002:a1c:2155:: with SMTP id h82mr6667706wmh.94.1574182139047; Tue, 19 Nov 2019 08:48:59 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id n65sm3811164wmf.28.2019.11.19.08.48.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Nov 2019 08:48:58 -0800 (PST) Message-Id: In-Reply-To: References: From: "Alexandr Miloslavskiy via GitGitGadget" Date: Tue, 19 Nov 2019 16:48:52 +0000 Subject: [PATCH v3 3/6] doc: reset: synchronize description Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Alexandr Miloslavskiy , Junio C Hamano , Alexandr Miloslavskiy Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Alexandr Miloslavskiy `git add` shows an example of good writing, follow it. Signed-off-by: Alexandr Miloslavskiy --- Documentation/git-reset.txt | 29 ++++++++++++++++++----------- builtin/reset.c | 4 ++-- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt index 97e0544d9e..d517a43e73 100644 --- a/Documentation/git-reset.txt +++ b/Documentation/git-reset.txt @@ -8,8 +8,8 @@ git-reset - Reset current HEAD to the specified state SYNOPSIS -------- [verse] -'git reset' [-q] [] [--] ... -'git reset' (--patch | -p) [] [--] [...] +'git reset' [-q] [] [--] ... +'git reset' (--patch | -p) [] [--] [...] 'git reset' [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [] DESCRIPTION @@ -19,23 +19,23 @@ In the third form, set the current branch head (`HEAD`) to ``, optionally modifying index and working tree to match. The ``/`` defaults to `HEAD` in all forms. -'git reset' [-q] [] [--] ...:: - This form resets the index entries for all `` to their - state at ``. (It does not affect the working tree or - the current branch.) +'git reset' [-q] [] [--] ...:: + This form resets the index entries for all paths that match the + `` to their state at ``. (It does not affect + the working tree or the current branch.) + -This means that `git reset ` is the opposite of `git add -`. This command is equivalent to -`git restore [--source=] --staged ...`. +This means that `git reset ` is the opposite of `git add +`. This command is equivalent to +`git restore [--source=] --staged ...`. + -After running `git reset ` to update the index entry, you can +After running `git reset ` to update the index entry, you can use linkgit:git-restore[1] to check the contents out of the index to the working tree. Alternatively, using linkgit:git-restore[1] and specifying a commit with `--source`, you can copy the contents of a path out of a commit to the index and to the working tree in one go. -'git reset' (--patch | -p) [] [--] [...]:: +'git reset' (--patch | -p) [] [--] [...]:: Interactively select hunks in the difference between the index and `` (defaults to `HEAD`). The chosen hunks are applied in reverse to the index. @@ -101,6 +101,13 @@ OPTIONS `reset.quiet` config option. `--quiet` and `--no-quiet` will override the default behavior. +\--:: + Do not interpret any more arguments as options. + +...:: + Limits the paths affected by the operation. ++ +For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. EXAMPLES -------- diff --git a/builtin/reset.c b/builtin/reset.c index fdd572168b..9291c0fd72 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -30,8 +30,8 @@ static const char * const git_reset_usage[] = { N_("git reset [--mixed | --soft | --hard | --merge | --keep] [-q] []"), - N_("git reset [-q] [] [--] ..."), - N_("git reset --patch [] [--] [...]"), + N_("git reset [-q] [] [--] ..."), + N_("git reset --patch [] [--] [...]"), NULL }; From patchwork Tue Nov 19 16:48:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Arver via GitGitGadget X-Patchwork-Id: 11252451 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2EF471871 for ; Tue, 19 Nov 2019 16:49:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 06C81208CC for ; Tue, 19 Nov 2019 16:49:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VXf1+VSm" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728533AbfKSQtE (ORCPT ); Tue, 19 Nov 2019 11:49:04 -0500 Received: from mail-wm1-f65.google.com ([209.85.128.65]:35713 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728443AbfKSQtC (ORCPT ); Tue, 19 Nov 2019 11:49:02 -0500 Received: by mail-wm1-f65.google.com with SMTP id 8so4543095wmo.0 for ; Tue, 19 Nov 2019 08:49:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=+buHZ51n44LNLRAp/5N82/ndSWJeE5B71CXkIfxwgzQ=; b=VXf1+VSmIJe9kz7jhyQfLbw2yrdhyIBcfQUTjwZgg9SG6/fJYXhUu/VTdimR37c3qw CKpObJZjvrtC0UGJ21JlaGRJ/0eC9b0Yjwa9UXjxKGHTW3pm+ct6dQxqvpDHTfc7EWT6 /wi2XLS8iWcy+72c15sOQsvSoCdH6Y8dGfzlrAdTHSVNR3RK3Gi2eIDEr2kKx//Pk7S6 aOAi0hS42lYU1JmPBPaLiFJOd7Y+auA+XOt/0fLfOl2OrJrvvHOOyIwF78lQt0Icbi9/ yantfQkDNoFtJ1gelYlMtxjxPTb+4r9oFuJQGcxVPxMtOUsQTDAhI2afT/EwjuK5U7VW 3xHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=+buHZ51n44LNLRAp/5N82/ndSWJeE5B71CXkIfxwgzQ=; b=VU8NH8Az51MVSoTcRB+MWOAlNcLIzsJEWMW5irVC+ZJX864rPkFK/iyVvRy3jpAz7X /O1GUfCq7vVm9d80ItDVIPS4/ZPHNYD4siRdmm4fxT5EILyMk4kaKg7bky8Hel78HcUv qnWsgk4O0xTzxMINUYA1uCvJ6TaOJ6FnMy0vM3mRm398UEc0F0B06ogThXrTRXdQJ4FS HGKbhYwq/9igk4PqXhM/AoU3WBMdYasa+nnong/hxuWYWH/FCMXbPQnQvUqaRmepHpeD y8TSzvl4haoUxWp7FMsMy0hhoe3Yima/2FU8tkszRDFq5+WH2fXRF+IKdM1tuAuQiXUS Y3pg== X-Gm-Message-State: APjAAAVqlMNc5d/rZdGhc9mc/OIyAhkMtrSl6OyNcLCE0btdKGePNlkK ydkWelrFL9VnAIU5ynwA+NDFFvWm2f0= X-Google-Smtp-Source: APXvYqxYR7gb8W2vCaWkNWSaw3RNB1CFGwkBugUP1kWJoXpolP2LUqBTydwXAiVu2PXqfjKCrNNQuQ== X-Received: by 2002:a1c:16:: with SMTP id 22mr7306978wma.0.1574182139814; Tue, 19 Nov 2019 08:48:59 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id b2sm2269041wrr.76.2019.11.19.08.48.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Nov 2019 08:48:59 -0800 (PST) Message-Id: <8a10ff881b01ff22517d46a94dd53a46481af9c7.1574182135.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Alexandr Miloslavskiy via GitGitGadget" Date: Tue, 19 Nov 2019 16:48:53 +0000 Subject: [PATCH v3 4/6] reset: support the `--pathspec-from-file` option Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Alexandr Miloslavskiy , Junio C Hamano , Alexandr Miloslavskiy Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Alexandr Miloslavskiy Decisions taken for simplicity: 1) For now, `--pathspec-from-file` is declared incompatible with `--patch`, even when is not `stdin`. Such use case it not really expected. Also, it is harder to support in `git commit`, so I decided to make it incompatible in all places. 2) It is not allowed to pass pathspec in both args and file. Co-authored-by: Johannes Schindelin Signed-off-by: Alexandr Miloslavskiy --- Documentation/git-reset.txt | 21 ++++- builtin/reset.c | 21 ++++- t/t7107-reset-pathspec-file.sh | 155 +++++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+), 5 deletions(-) create mode 100755 t/t7107-reset-pathspec-file.sh diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt index d517a43e73..932080c55d 100644 --- a/Documentation/git-reset.txt +++ b/Documentation/git-reset.txt @@ -9,18 +9,20 @@ SYNOPSIS -------- [verse] 'git reset' [-q] [] [--] ... +'git reset' [-q] [--pathspec-from-file= [--pathspec-file-nul]] [] 'git reset' (--patch | -p) [] [--] [...] 'git reset' [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [] DESCRIPTION ----------- -In the first and second form, copy entries from `` to the index. -In the third form, set the current branch head (`HEAD`) to ``, +In the first three forms, copy entries from `` to the index. +In the last form, set the current branch head (`HEAD`) to ``, optionally modifying index and working tree to match. The ``/`` defaults to `HEAD` in all forms. 'git reset' [-q] [] [--] ...:: - This form resets the index entries for all paths that match the +'git reset' [-q] [--pathspec-from-file= [--pathspec-file-nul]] []:: + These forms reset the index entries for all paths that match the `` to their state at ``. (It does not affect the working tree or the current branch.) + @@ -101,6 +103,19 @@ OPTIONS `reset.quiet` config option. `--quiet` and `--no-quiet` will override the default behavior. +--pathspec-from-file=:: + Pathspec is passed in `` instead of commandline args. If + `` is exactly `-` then standard input is used. Pathspec + elements are separated by LF or CR/LF. Pathspec elements can be + quoted as explained for the configuration variable `core.quotePath` + (see linkgit:git-config[1]). See also `--pathspec-file-nul` and + global `--literal-pathspecs`. + +--pathspec-file-nul:: + Only meaningful with `--pathspec-from-file`. Pathspec elements are + separated with NUL character and all other characters are taken + literally (including newlines and quotes). + \--:: Do not interpret any more arguments as options. diff --git a/builtin/reset.c b/builtin/reset.c index 9291c0fd72..246bf9d737 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -31,6 +31,7 @@ static const char * const git_reset_usage[] = { N_("git reset [--mixed | --soft | --hard | --merge | --keep] [-q] []"), N_("git reset [-q] [] [--] ..."), + N_("git reset [-q] [--pathspec-from-file [--pathspec-file-nul]] []"), N_("git reset --patch [] [--] [...]"), NULL }; @@ -284,8 +285,8 @@ static int git_reset_config(const char *var, const char *value, void *cb) int cmd_reset(int argc, const char **argv, const char *prefix) { int reset_type = NONE, update_ref_status = 0, quiet = 0; - int patch_mode = 0, unborn; - const char *rev; + int patch_mode = 0, pathspec_file_nul = 0, unborn; + const char *rev, *pathspec_from_file = NULL; struct object_id oid; struct pathspec pathspec; int intent_to_add = 0; @@ -306,6 +307,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix) OPT_BOOL('p', "patch", &patch_mode, N_("select hunks interactively")), OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that removed paths will be added later")), + OPT_PATHSPEC_FROM_FILE(&pathspec_from_file), + OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul), OPT_END() }; @@ -316,6 +319,20 @@ int cmd_reset(int argc, const char **argv, const char *prefix) PARSE_OPT_KEEP_DASHDASH); parse_args(&pathspec, argv, prefix, patch_mode, &rev); + if (pathspec_from_file) { + if (patch_mode) + die(_("--pathspec-from-file is incompatible with --patch")); + + if (pathspec.nr) + die(_("--pathspec-from-file is incompatible with pathspec arguments")); + + parse_pathspec_file(&pathspec, 0, + PATHSPEC_PREFER_FULL, + prefix, pathspec_from_file, pathspec_file_nul); + } else if (pathspec_file_nul) { + die(_("--pathspec-file-nul requires --pathspec-from-file")); + } + unborn = !strcmp(rev, "HEAD") && get_oid("HEAD", &oid); if (unborn) { /* reset on unborn branch: treat as reset to empty tree */ diff --git a/t/t7107-reset-pathspec-file.sh b/t/t7107-reset-pathspec-file.sh new file mode 100755 index 0000000000..6b1a731fff --- /dev/null +++ b/t/t7107-reset-pathspec-file.sh @@ -0,0 +1,155 @@ +#!/bin/sh + +test_description='reset --pathspec-from-file' + +. ./test-lib.sh + +test_tick + +test_expect_success setup ' + echo A >fileA.t && + echo B >fileB.t && + echo C >fileC.t && + echo D >fileD.t && + git add . && + git commit --include . -m "Commit" && + git tag checkpoint +' + +restore_checkpoint () { + git reset --hard checkpoint +} + +verify_expect () { + git status --porcelain -- fileA.t fileB.t fileC.t fileD.t >actual && + test_cmp expect actual +} + +test_expect_success '--pathspec-from-file from stdin' ' + restore_checkpoint && + + git rm fileA.t && + echo fileA.t | git reset --pathspec-from-file=- && + + cat >expect <<-\EOF && + D fileA.t + EOF + verify_expect +' + +test_expect_success '--pathspec-from-file from file' ' + restore_checkpoint && + + git rm fileA.t && + echo fileA.t >list && + git reset --pathspec-from-file=list && + + cat >expect <<-\EOF && + D fileA.t + EOF + verify_expect +' + +test_expect_success 'NUL delimiters' ' + restore_checkpoint && + + git rm fileA.t fileB.t && + printf "fileA.t\0fileB.t\0" | git reset --pathspec-from-file=- --pathspec-file-nul && + + cat >expect <<-\EOF && + D fileA.t + D fileB.t + EOF + verify_expect +' + +test_expect_success 'LF delimiters' ' + restore_checkpoint && + + git rm fileA.t fileB.t && + printf "fileA.t\nfileB.t\n" | git reset --pathspec-from-file=- && + + cat >expect <<-\EOF && + D fileA.t + D fileB.t + EOF + verify_expect +' + +test_expect_success 'no trailing delimiter' ' + restore_checkpoint && + + git rm fileA.t fileB.t && + printf "fileA.t\nfileB.t" | git reset --pathspec-from-file=- && + + cat >expect <<-\EOF && + D fileA.t + D fileB.t + EOF + verify_expect +' + +test_expect_success 'CRLF delimiters' ' + restore_checkpoint && + + git rm fileA.t fileB.t && + printf "fileA.t\r\nfileB.t\r\n" | git reset --pathspec-from-file=- && + + cat >expect <<-\EOF && + D fileA.t + D fileB.t + EOF + verify_expect +' + +test_expect_success 'quotes' ' + restore_checkpoint && + + git rm fileA.t && + printf "\"file\\101.t\"" | git reset --pathspec-from-file=- && + + cat >expect <<-\EOF && + D fileA.t + EOF + verify_expect +' + +test_expect_success 'quotes not compatible with --pathspec-file-nul' ' + restore_checkpoint && + + git rm fileA.t && + printf "\"file\\101.t\"" >list && + # Note: "git reset" has not yet learned to fail on wrong pathspecs + git reset --pathspec-from-file=list --pathspec-file-nul && + + cat >expect <<-\EOF && + D fileA.t + EOF + test_must_fail verify_expect +' + +test_expect_success '--pathspec-from-file is not compatible with --soft or --hard' ' + restore_checkpoint && + + git rm fileA.t && + echo fileA.t >list && + test_must_fail git reset --soft --pathspec-from-file=list && + test_must_fail git reset --hard --pathspec-from-file=list +' + +test_expect_success 'only touches what was listed' ' + restore_checkpoint && + + git rm fileA.t fileB.t fileC.t fileD.t && + printf "fileB.t\nfileC.t\n" | git reset --pathspec-from-file=- && + + cat >expect <<-\EOF && + D fileA.t + D fileB.t + D fileC.t + D fileD.t + EOF + verify_expect +' + +test_done From patchwork Tue Nov 19 16:48:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Arver via GitGitGadget X-Patchwork-Id: 11252449 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7D758109A for ; Tue, 19 Nov 2019 16:49:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5E3BC20885 for ; Tue, 19 Nov 2019 16:49:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="eLDjodH7" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728419AbfKSQtD (ORCPT ); Tue, 19 Nov 2019 11:49:03 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:36246 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728353AbfKSQtC (ORCPT ); Tue, 19 Nov 2019 11:49:02 -0500 Received: by mail-wm1-f66.google.com with SMTP id c22so4540627wmd.1 for ; Tue, 19 Nov 2019 08:49:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=jFwdsXIw10GWaJMKJTmYGPbaQki7xSpz/S6SI98raT0=; b=eLDjodH7rQMbR9PNdeLYJwnxRNQyGPOjkST1omy6TTK49jKcwyPG2R4m/uy9ChbvvX Ca1TCsT8zFeoAbakC0uw7oW80/u7KuwdKjp5Etmdo1Lp9vC7qhogAdDuXiv3Zjz2KfZb Fz2xhO86Zw+J7St/9TWwQmYAgyM12mUVqDMU1mg8tu88V4tuu3nU1yQLGw0Ulnak/DUE 1jN0+neUKyMZvjAKQcaRXXigZXz+YO0P25lWUxh7wKM0JpPcHZ2Z31GHhHV5etlvobqI 7cFEh5QQK4L6JV5P6cuAbo0cwbxCcebakuOT6nMOBmVd96RrSlTNn/UyUjk0IrjP6Uri HpAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=jFwdsXIw10GWaJMKJTmYGPbaQki7xSpz/S6SI98raT0=; b=CoDuQ18HWM3tx33hZPkayf9sxP7djcoW58i5CWaRnQ+ba0xvqGgunmbMDS5Bge8X88 s5+66zkVhQWSJYrpiE2Z+MCz73OZgR2PfL36qmiOMuV2pcvRR3HWogw0A00zl1iLdbXZ mxx+5TyYAWZis9x+LN4jrbtMFR7Kj/Ke6gzoEPHwt/FSlBwEvcVeC0hrwh9tIItkIoYB T08DYEfYveioyYse3QRGAjht17z6uNdaXuvFOLdPn0iuOLte9wv6QGTr/BKcK4GqIcBa kWjwEFYyQkxzdUl/L273DILgG7h7i3Q9/Ei4gejb2lepc8D5HiIbZgIP+PMPRysTFG6G 6lWg== X-Gm-Message-State: APjAAAWuiaP0Ztovkamfnms7iawK2oZrLhtDsDoZzHqOxWMfG1B1a/YL h2gCbgdNMEsaBx32HZWrfAiQgYLH/nQ= X-Google-Smtp-Source: APXvYqyswOz7iCJCybpHr2/0XxOoN4GhWkj4NkY48DX/059k/pNunrrnFEnnXMweFkRh6gJjY7S9SQ== X-Received: by 2002:a1c:2dd0:: with SMTP id t199mr6692705wmt.58.1574182140649; Tue, 19 Nov 2019 08:49:00 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id j66sm3447075wma.19.2019.11.19.08.49.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Nov 2019 08:49:00 -0800 (PST) Message-Id: <0b79797e772b25c6caa22bd9761837062e7265de.1574182135.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Alexandr Miloslavskiy via GitGitGadget" Date: Tue, 19 Nov 2019 16:48:54 +0000 Subject: [PATCH v3 5/6] doc: commit: synchronize description Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Alexandr Miloslavskiy , Junio C Hamano , Alexandr Miloslavskiy Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Alexandr Miloslavskiy `git add` shows an example of good writing, follow it. This also better disambiguates ... header. Signed-off-by: Alexandr Miloslavskiy --- Documentation/git-commit.txt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index afa7b75a23..a0c44978ee 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -13,7 +13,7 @@ SYNOPSIS [-F | -m ] [--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=] [--date=] [--cleanup=] [--[no-]status] - [-i | -o] [-S[]] [--] [...] + [-i | -o] [-S[]] [--] [...] DESCRIPTION ----------- @@ -345,12 +345,13 @@ changes to tracked files. \--:: Do not interpret any more arguments as options. -...:: - When files are given on the command line, the command - commits the contents of the named files, without - recording the changes already staged. The contents of - these files are also staged for the next commit on top - of what have been staged before. +...:: + When pathspec is given on the command line, commit the contents of + the files that match the pathspec without recording the changes + already added to the index. The contents of these files are also + staged for the next commit on top of what have been staged before. ++ +For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. :git-commit: 1 include::date-formats.txt[] From patchwork Tue Nov 19 16:48:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Arver via GitGitGadget X-Patchwork-Id: 11252457 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AF6FC1593 for ; Tue, 19 Nov 2019 16:49:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 87A7520885 for ; Tue, 19 Nov 2019 16:49:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="HrNQMZ2N" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728538AbfKSQtI (ORCPT ); Tue, 19 Nov 2019 11:49:08 -0500 Received: from mail-wr1-f68.google.com ([209.85.221.68]:41154 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728387AbfKSQtD (ORCPT ); Tue, 19 Nov 2019 11:49:03 -0500 Received: by mail-wr1-f68.google.com with SMTP id b18so23253253wrj.8 for ; Tue, 19 Nov 2019 08:49:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=2qJ2JnwHuR1ld5PUIj6mq6uqSoUsP0jupdV9js+upsU=; b=HrNQMZ2Nw50/+lhVSC+E1hfc5dTDkS+kqfkvBA3nObrPonI161hY8ZNI1x2+zxyscs CimZO5lTYEaXvaxs2/jTCX4w8GqKM84H1z/TFGBVy8B7k/2ziN+MahPwuLCnAHzit5ck KJqqCWBfWO0f3nHG+m1rR9yTNlFubVNbPg72qoRJZx0WTo/b/Ag5GX10xgcupDIfR0q9 XkEaH6VpL407T7VZpJ7Rgc05Ls+9OJphpKVBt5uTe9EQ3aVRHAqiijrE3msmT0T5TR0t Fv7ODCqkDQ2PIrp7gi3Tjn9etd9nQNJsQM48CfOu7vlnFQOS9ycjY/NXejgp163FjLLi GMqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=2qJ2JnwHuR1ld5PUIj6mq6uqSoUsP0jupdV9js+upsU=; b=d0MRtJcglIRyVxYt8a27iuM8fg66gzJD7wOcaXebqwN906n8CPRNJBZesUtNBFODfh vcXH5pdsESuTXkuKTidZSixIr2j0SI1Cn6H+y3OmsSn+3Wv4c12FOED5R3zVofWS//eW qUV4xXJjZHHV/QoFpXkfoyRX6z30S8joE9clVhOAtsGY6EX2dL9ECTEagdVHk9+Nb4zY AkxaZGmT9Qp+/HaaiLcTWD2j3aPvQyY5i/uTLlqNSWrYmZWMdkHMGop1YwZRHXAsz/i3 cdV/X9bGldaXMk5wSYOV7qpaKpCosb1ysRTE9im2m6fUW37twMT6gLtt/ebV355Anvoy QWRQ== X-Gm-Message-State: APjAAAV/v85+0iNvjo5j2NfTrMwiGg9qs/grvM4ZoTdzL8oArtkxZ39v bTd17ml/sBHVcVgx5sia2HrXr+FbuJA= X-Google-Smtp-Source: APXvYqw+M4+C29q2YhTG7F3eeEJPE2CxeWjZbWJkCKfIMozKRfQwAcvL61oefxmGA/pRwa9sC+XUAw== X-Received: by 2002:adf:ea8d:: with SMTP id s13mr38481662wrm.366.1574182141462; Tue, 19 Nov 2019 08:49:01 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id a206sm3811989wmf.15.2019.11.19.08.49.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Nov 2019 08:49:00 -0800 (PST) Message-Id: <7e482120020faf403daf8fbd517fbf27cebe452c.1574182135.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Alexandr Miloslavskiy via GitGitGadget" Date: Tue, 19 Nov 2019 16:48:55 +0000 Subject: [PATCH v3 6/6] commit: support the --pathspec-from-file option Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Alexandr Miloslavskiy , Junio C Hamano , Alexandr Miloslavskiy Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Alexandr Miloslavskiy Decisions taken for simplicity: 1) For now, `--pathspec-from-file` is declared incompatible with `--interactive/--patch`, even when is not `stdin`. Such use case it not really expected. Also, it would require changes to `interactive_add()`. 2) It is not allowed to pass pathspec in both args and file. Signed-off-by: Alexandr Miloslavskiy --- Documentation/git-commit.txt | 16 +++- builtin/commit.c | 25 +++++- t/t7526-commit-pathspec-file.sh | 130 ++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+), 5 deletions(-) create mode 100755 t/t7526-commit-pathspec-file.sh diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index a0c44978ee..ced5a9beab 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -13,7 +13,8 @@ SYNOPSIS [-F | -m ] [--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=] [--date=] [--cleanup=] [--[no-]status] - [-i | -o] [-S[]] [--] [...] + [-i | -o] [--pathspec-from-file= [--pathspec-file-nul]] + [-S[]] [--] [...] DESCRIPTION ----------- @@ -278,6 +279,19 @@ FROM UPSTREAM REBASE" section in linkgit:git-rebase[1].) already been staged. If used together with `--allow-empty` paths are also not required, and an empty commit will be created. +--pathspec-from-file=:: + Pathspec is passed in `` instead of commandline args. If + `` is exactly `-` then standard input is used. Pathspec + elements are separated by LF or CR/LF. Pathspec elements can be + quoted as explained for the configuration variable `core.quotePath` + (see linkgit:git-config[1]). See also `--pathspec-file-nul` and + global `--literal-pathspecs`. + +--pathspec-file-nul:: + Only meaningful with `--pathspec-from-file`. Pathspec elements are + separated with NUL character and all other characters are taken + literally (including newlines and quotes). + -u[]:: --untracked-files[=]:: Show untracked files. diff --git a/builtin/commit.c b/builtin/commit.c index e588bc6ad3..ed40729355 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -107,9 +107,9 @@ static int all, also, interactive, patch_interactive, only, amend, signoff; static int edit_flag = -1; /* unspecified */ static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship; static int config_commit_verbose = -1; /* unspecified */ -static int no_post_rewrite, allow_empty_message; +static int no_post_rewrite, allow_empty_message, pathspec_file_nul; static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg; -static char *sign_commit; +static char *sign_commit, *pathspec_from_file; /* * The default commit message cleanup mode will remove the lines @@ -343,6 +343,23 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix PATHSPEC_PREFER_FULL, prefix, argv); + if (pathspec_from_file) { + if (interactive) + die(_("--pathspec-from-file is incompatible with --interactive/--patch")); + + if (pathspec.nr) + die(_("--pathspec-from-file is incompatible with pathspec arguments")); + + parse_pathspec_file(&pathspec, 0, + PATHSPEC_PREFER_FULL, + prefix, pathspec_from_file, pathspec_file_nul); + } else if (pathspec_file_nul) { + die(_("--pathspec-file-nul requires --pathspec-from-file")); + } + + if (!pathspec.nr && (also || (only && !amend && !allow_empty))) + die(_("No paths with --include/--only does not make sense.")); + if (read_cache_preload(&pathspec) < 0) die(_("index file corrupt")); @@ -1198,8 +1215,6 @@ static int parse_and_validate_options(int argc, const char *argv[], if (also + only + all + interactive > 1) die(_("Only one of --include/--only/--all/--interactive/--patch can be used.")); - if (argc == 0 && (also || (only && !amend && !allow_empty))) - die(_("No paths with --include/--only does not make sense.")); cleanup_mode = get_cleanup_mode(cleanup_arg, use_editor); handle_untracked_files_arg(s); @@ -1535,6 +1550,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix) OPT_BOOL(0, "amend", &amend, N_("amend previous commit")), OPT_BOOL(0, "no-post-rewrite", &no_post_rewrite, N_("bypass post-rewrite hook")), { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, N_("mode"), N_("show untracked files, optional modes: all, normal, no. (Default: all)"), PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, + OPT_PATHSPEC_FROM_FILE(&pathspec_from_file), + OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul), /* end commit contents options */ OPT_HIDDEN_BOOL(0, "allow-empty", &allow_empty, diff --git a/t/t7526-commit-pathspec-file.sh b/t/t7526-commit-pathspec-file.sh new file mode 100755 index 0000000000..a06b683534 --- /dev/null +++ b/t/t7526-commit-pathspec-file.sh @@ -0,0 +1,130 @@ +#!/bin/sh + +test_description='commit --pathspec-from-file' + +. ./test-lib.sh + +test_tick + +test_expect_success setup ' + test_commit file0 && + git tag checkpoint && + + echo A >fileA.t && + echo B >fileB.t && + echo C >fileC.t && + echo D >fileD.t && + git add fileA.t fileB.t fileC.t fileD.t +' + +restore_checkpoint () { + git reset --soft checkpoint +} + +verify_expect () { + git diff-tree --no-commit-id --name-status -r HEAD >actual && + test_cmp expect actual +} + +test_expect_success '--pathspec-from-file from stdin' ' + restore_checkpoint && + + echo fileA.t | git commit --pathspec-from-file=- -m "Commit" && + + cat >expect <<-\EOF && + A fileA.t + EOF + verify_expect +' + +test_expect_success '--pathspec-from-file from file' ' + restore_checkpoint && + + echo fileA.t >list && + git commit --pathspec-from-file=list -m "Commit" && + + cat >expect <<-\EOF && + A fileA.t + EOF + verify_expect +' + +test_expect_success 'NUL delimiters' ' + restore_checkpoint && + + printf "fileA.t\0fileB.t\0" | git commit --pathspec-from-file=- --pathspec-file-nul -m "Commit" && + + cat >expect <<-\EOF && + A fileA.t + A fileB.t + EOF + verify_expect +' + +test_expect_success 'LF delimiters' ' + restore_checkpoint && + + printf "fileA.t\nfileB.t\n" | git commit --pathspec-from-file=- -m "Commit" && + + cat >expect <<-\EOF && + A fileA.t + A fileB.t + EOF + verify_expect +' + +test_expect_success 'no trailing delimiter' ' + restore_checkpoint && + + printf "fileA.t\nfileB.t" | git commit --pathspec-from-file=- -m "Commit" && + + cat >expect <<-\EOF && + A fileA.t + A fileB.t + EOF + verify_expect +' + +test_expect_success 'CRLF delimiters' ' + restore_checkpoint && + + printf "fileA.t\r\nfileB.t\r\n" | git commit --pathspec-from-file=- -m "Commit" && + + cat >expect <<-\EOF && + A fileA.t + A fileB.t + EOF + verify_expect +' + +test_expect_success 'quotes' ' + restore_checkpoint && + + printf "\"file\\101.t\"" | git commit --pathspec-from-file=- -m "Commit" && + + cat >expect <<-\EOF && + A fileA.t + EOF + verify_expect expect +' + +test_expect_success 'quotes not compatible with --pathspec-file-nul' ' + restore_checkpoint && + + printf "\"file\\101.t\"" >list && + test_must_fail git commit --pathspec-from-file=list --pathspec-file-nul -m "Commit" +' + +test_expect_success 'only touches what was listed' ' + restore_checkpoint && + + printf "fileB.t\nfileC.t\n" | git commit --pathspec-from-file=- -m "Commit" && + + cat >expect <<-\EOF && + A fileB.t + A fileC.t + EOF + verify_expect +' + +test_done