From patchwork Thu Jan 16 16:09:18 2020 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: 11337361 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 EDD87109A for ; Thu, 16 Jan 2020 16:09:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CC2F5207E0 for ; Thu, 16 Jan 2020 16:09:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SxWYR/DT" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726885AbgAPQJa (ORCPT ); Thu, 16 Jan 2020 11:09:30 -0500 Received: from mail-wr1-f65.google.com ([209.85.221.65]:34435 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726653AbgAPQJa (ORCPT ); Thu, 16 Jan 2020 11:09:30 -0500 Received: by mail-wr1-f65.google.com with SMTP id t2so19747671wrr.1 for ; Thu, 16 Jan 2020 08:09:28 -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=lWNe8ZOU5ZJwdci14t4PB6WCJ/g25rTTh2vF6pXDOIc=; b=SxWYR/DTzbm78IaYUzZgl6S2Ow/psmkBiU6myKq/p91BI+PriA8czmTm3GfrYtODT0 h3o/8FHdvzDfJ0HqTV2CQRzQ9IwHtbUdIkvNL6Ud3ZpBUAcY3kXxXiU/CieTroTgnvua Ve6ES/07bqai6gCgwjXaw8DmKxs1rpWpJKjgg55e4CvzJjjMXZwl+OGulJpL6nI9qcSV dYG+0G9P6RNBQ+APHdm6GJaLWhvA97r87TBaayFWfRp5VsK8d4tY3jh1pTQc20hqkKbR Z+b1gfdfkNsqBgemv8KrtynT/cu6XBKx6Qpz3VQX/y595l5mjw9t58Xj0pDr5jneyK7V Gl2A== 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=lWNe8ZOU5ZJwdci14t4PB6WCJ/g25rTTh2vF6pXDOIc=; b=h07luWckvd5EGucgTFPrR57NtI/yebAr7ZAOW+l1jFmHpZwd8CRiWHfNZDqpMy5iYm dgJ2jwTVDsZD+hJ9H6jyzfq4xL8a17vmi5xYdVxZRXIhJ00MSULNlWqDYVbwAa/vgrwq BC4DKnpe+z+51FYFNmoPfEkRs9O9mn6EYz+K+49PPTrO0AF2KKmPtDooIX6TwoKkfD3Y Hx8AeXv1c1hMWcoforo/bDw6GhtgcDtehCX0RjQZmuDmRgthHhpiEYg9aUc1yTGjO2Xp xDnObmO9n4rqEAmDlVVdCpfGx3cABB93/7yqMmT2VwgBSHAy623SUCv4Lf3/RmYq+3Gp CqCg== X-Gm-Message-State: APjAAAWHrV7xN4raHJGYmjbGFC3p80ADJzeWHpMuEFPj7BWgVsxr45i5 jOh8Td5XRDkvFnOQgiwOixc2bOVI X-Google-Smtp-Source: APXvYqzJq5A/dZc01wyXFnCbNFzkbTT+OvaQBrxNTQRUDZUDgLa9I8MbMRm7+6eYfNQ0uIh8aUmLew== X-Received: by 2002:adf:f5cf:: with SMTP id k15mr4234468wrp.182.1579190967691; Thu, 16 Jan 2020 08:09:27 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id b21sm531096wmd.37.2020.01.16.08.09.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jan 2020 08:09:27 -0800 (PST) Message-Id: <23387f83912d1f5aef17a28d466db162f50fd722.1579190965.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Alexandr Miloslavskiy via GitGitGadget" Date: Thu, 16 Jan 2020 16:09:18 +0000 Subject: [PATCH 1/8] doc: rm: synchronize description Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Paul-Sebastian Ungureanu , Alexandr Miloslavskiy , Alexandr Miloslavskiy Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Alexandr Miloslavskiy This patch continues the effort that is already applied to `git commit`, `git reset`, `git checkout` etc. 1) Changed outdated descriptions to mention pathspec instead. 2) Added reference to 'linkgit:gitglossary[7]'. 3) Removed content that merely repeated gitglossary. 4) Merged the remainder of "discussion" into ``. Signed-off-by: Alexandr Miloslavskiy --- Documentation/git-rm.txt | 50 +++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt index b5c46223c4..e02a08e5ef 100644 --- a/Documentation/git-rm.txt +++ b/Documentation/git-rm.txt @@ -8,16 +8,16 @@ git-rm - Remove files from the working tree and from the index SYNOPSIS -------- [verse] -'git rm' [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] ... +'git rm' [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] ... DESCRIPTION ----------- -Remove files from the index, or from the working tree and the index. -`git rm` will not remove a file from just your working directory. -(There is no option to remove a file only from the working tree -and yet keep it in the index; use `/bin/rm` if you want to do that.) -The files being removed have to be identical to the tip of the branch, -and no updates to their contents can be staged in the index, +Remove files matching pathspec from the index, or from the working tree +and the index. `git rm` will not remove a file from just your working +directory. (There is no option to remove a file only from the working +tree and yet keep it in the index; use `/bin/rm` if you want to do +that.) The files being removed have to be identical to the tip of the +branch, and no updates to their contents can be staged in the index, though that default behavior can be overridden with the `-f` option. When `--cached` is given, the staged content has to match either the tip of the branch or the file on disk, @@ -26,15 +26,20 @@ allowing the file to be removed from just the index. OPTIONS ------- -...:: - Files to remove. Fileglobs (e.g. `*.c`) can be given to - remove all matching files. If you want Git to expand - file glob characters, you may need to shell-escape them. - A leading directory name - (e.g. `dir` to remove `dir/file1` and `dir/file2`) can be - given to remove all files in the directory, and recursively - all sub-directories, - but this requires the `-r` option to be explicitly given. +...:: + Files to remove. A leading directory name (e.g. `dir` to remove + `dir/file1` and `dir/file2`) can be given to remove all files in + the directory, and recursively all sub-directories, but this + requires the `-r` option to be explicitly given. ++ +The command removes only the paths that are known to Git. ++ +File globbing matches across directory boundaries. Thus, given two +directories `d` and `d2`, there is a difference between using +`git rm 'd*'` and `git rm 'd/*'`, as the former will also remove all +of directory `d2`. ++ +For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. -f:: --force:: @@ -69,19 +74,6 @@ OPTIONS for each file removed. This option suppresses that output. -DISCUSSION ----------- - -The list given to the command can be exact pathnames, -file glob patterns, or leading directory names. The command -removes only the paths that are known to Git. Giving the name of -a file that you have not told Git about does not remove that file. - -File globbing matches across directory boundaries. Thus, given -two directories `d` and `d2`, there is a difference between -using `git rm 'd*'` and `git rm 'd/*'`, as the former will -also remove all of directory `d2`. - REMOVING FILES THAT HAVE DISAPPEARED FROM THE FILESYSTEM -------------------------------------------------------- There is no option for `git rm` to remove from the index only From patchwork Thu Jan 16 16:09:19 2020 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: 11337363 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 CFAC3109A for ; Thu, 16 Jan 2020 16:09:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A39F4207E0 for ; Thu, 16 Jan 2020 16:09:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jNp98dZU" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726954AbgAPQJc (ORCPT ); Thu, 16 Jan 2020 11:09:32 -0500 Received: from mail-wm1-f65.google.com ([209.85.128.65]:40011 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726653AbgAPQJc (ORCPT ); Thu, 16 Jan 2020 11:09:32 -0500 Received: by mail-wm1-f65.google.com with SMTP id t14so4381784wmi.5 for ; Thu, 16 Jan 2020 08:09:31 -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=NcVSestg0cCMFI0FGLqke4lkaZeF7nP01/+19yZgfHA=; b=jNp98dZUyGgCCM4ZgJbvJuC4AcUQ9bskFS8+jPslZQQRnh3BT4trVSZa0al3ifYYkv KMQ6Hg6oqhV27RjDuCuGNDD4MnhDwef+72sMP71/s4Fe/OJEQLR1TMemT3yjzHdxtr3t FQlLsPnkUAoARRQV/1haH2d1DfxSkCphDXk6wGXsLYkKgPm1rEcrbJ84T6HT+JiYms59 AWJku5B6kvJ5fOxxGBIk/iKPYN7LDLuup1jYATvZO4OUYzGJUkhOauapzEq6vV4P8dQX vG2wNuRye4k6AYIYlheBG1UtSJcOJL4cQp1LBSHd/euy8A/W4a1Cn+I2cHHxZAG8PcJE NGhQ== 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=NcVSestg0cCMFI0FGLqke4lkaZeF7nP01/+19yZgfHA=; b=iHML82XbwHaQ/QwWIJfd7cR4t8jG/FCbjKhPx/VvpH7qryrWFLVtPoUwwTXQRZfnix oeZI8sBsFM/GqzsoFnpkv6EYrL0LyA5FNr5hoWByh4Uqc53lyQT204m6wdxm8wLFprcV Ca3okoXv07LAsMthTaJei919zpwBj9ZrwVM1i//iJ/BL20LeHM+PGm/CL1VJNysv08K0 +Fv6LoXFhZpjSHbnG1OXMSaPmJbTJ/DFFVahwxW1fMDOUwUpQkaTT9hPWCBKsP0FoGco U4I3Y1y3l4xWaYXtzMxE8wlFkcnTaQDdkXSQ1PUwTqx2Vq+Qf77vpMqrSJ7uUMgl28Bl k3iA== X-Gm-Message-State: APjAAAW9U9KKr56D9e/X34Kw8PT8zBmaTtnhNRUUFvSJ8J+1DKuQr838 hfPFV/O7zKZJcqn0lYyJ4A3vSKgJ X-Google-Smtp-Source: APXvYqzzICz/75PYfTt2eibbzslp3HGQSV+ncnworWZIlLSKYwomVk6LG5EGexr6rO+WN5R+Fsgwjw== X-Received: by 2002:a05:600c:2c0b:: with SMTP id q11mr132777wmg.2.1579190970106; Thu, 16 Jan 2020 08:09:30 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id j2sm769511wmk.23.2020.01.16.08.09.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jan 2020 08:09:27 -0800 (PST) Message-Id: <5611e3ae326bb7f61abf870e3b2851226b6af1d8.1579190965.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Alexandr Miloslavskiy via GitGitGadget" Date: Thu, 16 Jan 2020 16:09:19 +0000 Subject: [PATCH 2/8] rm: support the --pathspec-from-file option Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Paul-Sebastian Ungureanu , Alexandr Miloslavskiy , 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) It is not allowed to pass pathspec in both args and file. `if (!argc)` block was adapted to work with --pathspec-from-file. For that, I also had to parse pathspec earlier. Now it happens before `read_cache()` / `hold_locked_index()` / `setup_work_tree()`, which sounds fine to me. In case of empty pathspec, there is now a clear error message instead of showing usage. As a consequence, exit code has also changed. Judging from [1] it doesn't seem that showing usage in this case was important (according to commit message, it was to avoid segfault), and it doesn't fit into how other commands react to empty pathspec. Finally, the new error message is easier to understand. [1] Commit 7612a1ef ("git-rm: honor -n flag" 2006-06-09) Signed-off-by: Alexandr Miloslavskiy --- Documentation/git-rm.txt | 17 +++++++- builtin/rm.c | 28 ++++++++++--- t/t3601-rm-pathspec-file.sh | 79 +++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 7 deletions(-) create mode 100755 t/t3601-rm-pathspec-file.sh diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt index e02a08e5ef..ab750367fd 100644 --- a/Documentation/git-rm.txt +++ b/Documentation/git-rm.txt @@ -8,7 +8,9 @@ git-rm - Remove files from the working tree and from the index SYNOPSIS -------- [verse] -'git rm' [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] ... +'git rm' [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] + [--quiet] [--pathspec-from-file= [--pathspec-file-nul]] + [--] [...] DESCRIPTION ----------- @@ -73,6 +75,19 @@ For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. `git rm` normally outputs one line (in the form of an `rm` command) for each file removed. This option suppresses that output. +--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). + REMOVING FILES THAT HAVE DISAPPEARED FROM THE FILESYSTEM -------------------------------------------------------- diff --git a/builtin/rm.c b/builtin/rm.c index 19ce95a901..8e40795751 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -235,7 +235,8 @@ static int check_local_mod(struct object_id *head, int index_only) } static int show_only = 0, force = 0, index_only = 0, recursive = 0, quiet = 0; -static int ignore_unmatch = 0; +static int ignore_unmatch = 0, pathspec_file_nul = 0; +static char *pathspec_from_file = NULL; static struct option builtin_rm_options[] = { OPT__DRY_RUN(&show_only, N_("dry run")), @@ -245,6 +246,8 @@ static struct option builtin_rm_options[] = { OPT_BOOL('r', NULL, &recursive, N_("allow recursive removal")), OPT_BOOL( 0 , "ignore-unmatch", &ignore_unmatch, N_("exit with a zero status even if nothing matched")), + OPT_PATHSPEC_FROM_FILE(&pathspec_from_file), + OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul), OPT_END(), }; @@ -259,8 +262,24 @@ int cmd_rm(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, builtin_rm_options, builtin_rm_usage, 0); - if (!argc) - usage_with_options(builtin_rm_usage, builtin_rm_options); + + parse_pathspec(&pathspec, 0, + PATHSPEC_PREFER_CWD, + prefix, argv); + + if (pathspec_from_file) { + if (pathspec.nr) + die(_("--pathspec-from-file is incompatible with pathspec arguments")); + + parse_pathspec_file(&pathspec, 0, + PATHSPEC_PREFER_CWD, + prefix, pathspec_from_file, pathspec_file_nul); + } else if (pathspec_file_nul) { + die(_("--pathspec-file-nul requires --pathspec-from-file")); + } + + if (!pathspec.nr) + die(_("Nothing specified, nothing removed")); if (!index_only) setup_work_tree(); @@ -270,9 +289,6 @@ int cmd_rm(int argc, const char **argv, const char *prefix) if (read_cache() < 0) die(_("index file corrupt")); - parse_pathspec(&pathspec, 0, - PATHSPEC_PREFER_CWD, - prefix, argv); refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, &pathspec, NULL, NULL); seen = xcalloc(pathspec.nr, 1); diff --git a/t/t3601-rm-pathspec-file.sh b/t/t3601-rm-pathspec-file.sh new file mode 100755 index 0000000000..0f69ae8478 --- /dev/null +++ b/t/t3601-rm-pathspec-file.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +test_description='rm --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 fileA.t fileB.t fileC.t fileD.t && + git commit -m "files" && + + git tag checkpoint +' + +restore_checkpoint () { + git reset --hard checkpoint +} + +verify_expect () { + git status --porcelain --untracked-files=no -- fileA.t fileB.t fileC.t fileD.t >actual && + test_cmp expect actual +} + +test_expect_success 'simplest' ' + restore_checkpoint && + + cat >expect <<-\EOF && + D fileA.t + EOF + + echo fileA.t | git rm --pathspec-from-file=- && + verify_expect +' + +test_expect_success '--pathspec-file-nul' ' + restore_checkpoint && + + cat >expect <<-\EOF && + D fileA.t + D fileB.t + EOF + + printf "fileA.t\0fileB.t\0" | git rm --pathspec-from-file=- --pathspec-file-nul && + verify_expect +' + +test_expect_success 'only touches what was listed' ' + restore_checkpoint && + + cat >expect <<-\EOF && + D fileB.t + D fileC.t + EOF + + printf "fileB.t\nfileC.t\n" | git rm --pathspec-from-file=- && + verify_expect +' + +test_expect_success 'error conditions' ' + restore_checkpoint && + echo fileA.t >list && + + test_must_fail git rm --pathspec-from-file=list -- fileA.t 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with pathspec arguments" err && + + test_must_fail git rm --pathspec-file-nul 2>err && + test_i18ngrep -e "--pathspec-file-nul requires --pathspec-from-file" err && + + >empty_list && + test_must_fail git rm --pathspec-from-file=empty_list 2>err && + test_i18ngrep -e "Nothing specified, nothing removed" err +' + +test_done From patchwork Thu Jan 16 16:09:20 2020 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: 11337375 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 E01B2109A for ; Thu, 16 Jan 2020 16:09:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BF454207E0 for ; Thu, 16 Jan 2020 16:09:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="YS+/M6YW" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726970AbgAPQJe (ORCPT ); Thu, 16 Jan 2020 11:09:34 -0500 Received: from mail-wm1-f43.google.com ([209.85.128.43]:51574 "EHLO mail-wm1-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726908AbgAPQJe (ORCPT ); Thu, 16 Jan 2020 11:09:34 -0500 Received: by mail-wm1-f43.google.com with SMTP id d73so4350975wmd.1 for ; Thu, 16 Jan 2020 08:09:31 -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=rmSJGPnCV5djEoGHTIwck4H4KwpzvNlqsbHiJGq/mnE=; b=YS+/M6YWzfe01ocQxZpPdjuGuclrZNmqGEDIpr8Q5t9kKDBCOv/byNpT5aqus89N5E wZPzinFPmTp/8IH0DW7QLGcVRwmpWNpEIp6rcv93Bhq6Z6xX1sE4LfgvYbyObffifk9K KrwqShvJmFYqQxznP40HejMFLCtaC03PL8KcG3BGaIg5I4ylnrZt2nbpM6Arcqm5Qtr3 zRDP2vjB3n9DIIYnHeJkQa/PRkNYFC35Y3UQ3pgDxS5CCIKjrg2I/EKtJJUn8NCHYSVv teg/jatR/ep8PwV5AgaufxxZ7xzNmzZuMA8YRYZnScBlCSIX1J1s5gGlBj/mE8hnKdiR VdvQ== 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=rmSJGPnCV5djEoGHTIwck4H4KwpzvNlqsbHiJGq/mnE=; b=qJSE6kcovpQGPLJmhw1oOlxN+rcDnHfLyglDBNqjEW+5SixraKIo9c3pnjpWtXqHuA bkCfHmNK7KH1/Z0z5A7DW/HtsYV/iTbHv15By+gUpon83zMrYBFN//m8mGVOHTCWXWfQ 99pF282DxuIk2ZwhuDeYtSMD/aHidgMyY8VMpwFkNr1NjjGeb8Q8/8sJjVYO/1Z7t8mi pewMi6aVtlpo6chz5whsT4sdnid2OP+/jusjkpd9KklbOskvuZKSy6TegLCYfpRjM8vh rKoGUTjg2Mdafvv2rsL2bv64s3ihAWDdO38iCp1CgUuxzyDzYVUk/7oGqolZ16pm+N9r 3pxw== X-Gm-Message-State: APjAAAV23+3xgi5UnT056LKuDC3gbCngAqUwvBUsRoEFOmy0gxSxCH+S 5doG7rZYW0I0MtqbASudsntZTRNx X-Google-Smtp-Source: APXvYqwfFtz5wWNk8oyo1kVKVLX4AU61jxFHDmbXY7yeCLgFssIQ0BhgxjysW8C7fzbqoV46rNRl4w== X-Received: by 2002:a1c:a9c6:: with SMTP id s189mr68894wme.151.1579190971054; Thu, 16 Jan 2020 08:09:31 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id q3sm4915156wmc.47.2020.01.16.08.09.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jan 2020 08:09:30 -0800 (PST) Message-Id: <0824bba2101bb034bafb124d2b810721923233f3.1579190965.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Alexandr Miloslavskiy via GitGitGadget" Date: Thu, 16 Jan 2020 16:09:20 +0000 Subject: [PATCH 3/8] doc: stash: split options from description (1) Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Paul-Sebastian Ungureanu , Alexandr Miloslavskiy , Alexandr Miloslavskiy Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Alexandr Miloslavskiy This patch moves blocks of text as-is to make it easier to review the next patch. Signed-off-by: Alexandr Miloslavskiy --- Documentation/git-stash.txt | 68 +++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index 53e1a1205d..2dedc21997 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -58,31 +58,6 @@ non-option arguments are not allowed to prevent a misspelled subcommand from making an unwanted stash entry. The two exceptions to this are `stash -p` which acts as alias for `stash push -p` and pathspecs, which are allowed after a double hyphen `--` for disambiguation. -+ -When pathspec is given to 'git stash push', the new stash entry records the -modified states only for the files that match the pathspec. The index -entries and working tree files are then rolled back to the state in -HEAD only for these files, too, leaving files that do not match the -pathspec intact. -+ -If the `--keep-index` option is used, all changes already added to the -index are left intact. -+ -If the `--include-untracked` option is used, all untracked files are also -stashed and then cleaned up with `git clean`, leaving the working directory -in a very clean state. If the `--all` option is used instead then the -ignored files are stashed and cleaned in addition to the untracked files. -+ -With `--patch`, you can interactively select hunks from the diff -between HEAD and the working tree to be stashed. The stash entry is -constructed such that its index state is the same as the index state -of your repository, and its worktree contains only the changes you -selected interactively. The selected changes are then rolled back -from your worktree. See the ``Interactive Mode'' section of -linkgit:git-add[1] to learn how to operate the `--patch` mode. -+ -The `--patch` option implies `--keep-index`. You can use -`--no-keep-index` to override this. save [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] []:: @@ -128,14 +103,6 @@ pop [--index] [-q|--quiet] []:: Applying the state can fail with conflicts; in this case, it is not removed from the stash list. You need to resolve the conflicts by hand and call `git stash drop` manually afterwards. -+ -If the `--index` option is used, then tries to reinstate not only the working -tree's changes, but also the index's ones. However, this can fail, when you -have conflicts (which are stored in the index, where you therefore can no -longer apply the changes as they were originally). -+ -When no `` is given, `stash@{0}` is assumed, otherwise `` must -be a reference of the form `stash@{}`. apply [--index] [-q|--quiet] []:: @@ -185,6 +152,41 @@ store:: reflog. This is intended to be useful for scripts. It is probably not the command you want to use; see "push" above. +If the `--all` option is used instead then the +ignored files are stashed and cleaned in addition to the untracked files. + +If the `--include-untracked` option is used, all untracked files are also +stashed and then cleaned up with `git clean`, leaving the working directory +in a very clean state. + +If the `--index` option is used, then tries to reinstate not only the working +tree's changes, but also the index's ones. However, this can fail, when you +have conflicts (which are stored in the index, where you therefore can no +longer apply the changes as they were originally). + +If the `--keep-index` option is used, all changes already added to the +index are left intact. + +With `--patch`, you can interactively select hunks from the diff +between HEAD and the working tree to be stashed. The stash entry is +constructed such that its index state is the same as the index state +of your repository, and its worktree contains only the changes you +selected interactively. The selected changes are then rolled back +from your worktree. See the ``Interactive Mode'' section of +linkgit:git-add[1] to learn how to operate the `--patch` mode. ++ +The `--patch` option implies `--keep-index`. You can use +`--no-keep-index` to override this. + +When pathspec is given to 'git stash push', the new stash entry records the +modified states only for the files that match the pathspec. The index +entries and working tree files are then rolled back to the state in +HEAD only for these files, too, leaving files that do not match the +pathspec intact. + +When no `` is given, `stash@{0}` is assumed, otherwise `` must +be a reference of the form `stash@{}`. + DISCUSSION ---------- From patchwork Thu Jan 16 16:09:21 2020 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: 11337365 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 1B94C139A for ; Thu, 16 Jan 2020 16:09:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E291020728 for ; Thu, 16 Jan 2020 16:09:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="i/pzTXJc" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726979AbgAPQJf (ORCPT ); Thu, 16 Jan 2020 11:09:35 -0500 Received: from mail-wr1-f65.google.com ([209.85.221.65]:43993 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726924AbgAPQJe (ORCPT ); Thu, 16 Jan 2020 11:09:34 -0500 Received: by mail-wr1-f65.google.com with SMTP id d16so19731335wre.10 for ; Thu, 16 Jan 2020 08:09:32 -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=9HMLKaW23nHkIRPTOEObEQjluD03VSoDSYMePDAPG8Y=; b=i/pzTXJcmZAaqiAdkm6YEYHXKzD692/N+JalqmAz3p76BXNztSTBuQE6t2oztbbem9 EAIiIpUMawlzQ7qkCk0nUr+jgXEyrs5F5ggNCf4nd66MSJihoN44QDoH5P4HnUNoV6qO zKAdV6MoCxe6yex35lPlzGm1x+fSJg9yYWWLkWaMdlWoifBOwwwnXswzFgou5OrivdPD XnF0GN6jAE2QlkvdAJAqbysdOLBLmuF6wBQ5WUiI99gXfcFY1nKrH0LmgzPRpQJ8bXqE tfYd22IRG8v+w4RvcuRjtfyETP6sa3qS+MdtR7QVO1ZaEy5sf1bBRVcUzTNskgjJfPDY rALQ== 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=9HMLKaW23nHkIRPTOEObEQjluD03VSoDSYMePDAPG8Y=; b=uWxJ36BMAWISlUgS5vY8paG+LcxQQUm+FUrp3BLJUZ33MBoiLKaiReuyeyuZxC6eXd m+RZ/3UXfZ+ZnKRahy/CVUZVOZQvOuYX5h8C6Wb6Vsft1DPrPE5djTtpM8Cmuo/DKSAr qaOBrs0BxWpqCPpRJpOV6PIPcJr+uiGOrWjVsE68Tq2yt5k8VnS6wQgwXcsXFpiwySWS FP7RQT0tvo21Mbf1EJOjl4y+D2EBdIGTyzj1CLAsFLJCKt7VBexESwQzJb8o2kNKx6rb aePnJOEcXyQSohHwE6+NNuolJSBJj4tmaGJ0sZP+IYZrdi3JoQ1iAp5k0Hb4LKt3wCFk yMsw== X-Gm-Message-State: APjAAAW7xoKwTS+NyP9q8f942FDd/huNyubaxNmAqRuszpZX0d+am+Va 2rLm8MsFvzQgX9ukhTj+q7gQul9d X-Google-Smtp-Source: APXvYqyOydVQ071wuBUidSQPvLlmm8u37FZSFQEvJTJvLq/8qogUUdHe5XW0Ey6PdyT8FDqL8UkKTA== X-Received: by 2002:adf:ea8a:: with SMTP id s10mr4059650wrm.278.1579190971778; Thu, 16 Jan 2020 08:09:31 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 4sm4959036wmg.22.2020.01.16.08.09.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jan 2020 08:09:31 -0800 (PST) Message-Id: <708363241f4940e5b627af8519345b762deb77ab.1579190965.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Alexandr Miloslavskiy via GitGitGadget" Date: Thu, 16 Jan 2020 16:09:21 +0000 Subject: [PATCH 4/8] doc: stash: split options from description (2) Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Paul-Sebastian Ungureanu , Alexandr Miloslavskiy , Alexandr Miloslavskiy Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Alexandr Miloslavskiy Together with the previous patch, this brings docs for `git stash` to the common layout used for most other commands (see for example docs for `git add`, `git commit`, `git checkout`, `git reset`) where all options are documented in a separate list. I have decided to use alphabetical sorting in the list of options. Other docs often sort in order of appearance or order of importance, but in this case it wouldn't be easy to read the list where options from multiple sub-commands are mixed together. There is some text editing done to make old descriptions better fit into the list-style format. Signed-off-by: Alexandr Miloslavskiy --- Documentation/git-stash.txt | 72 ++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index 2dedc21997..f75b80a720 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -43,9 +43,6 @@ created stash, `stash@{1}` is the one before it, `stash@{2.hours.ago}` is also possible). Stashes may also be referenced by specifying just the stash index (e.g. the integer `n` is equivalent to `stash@{n}`). -OPTIONS -------- - push [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-m|--message ] [--] [...]:: Save your local modifications to a new 'stash entry' and roll them @@ -152,40 +149,51 @@ store:: reflog. This is intended to be useful for scripts. It is probably not the command you want to use; see "push" above. -If the `--all` option is used instead then the -ignored files are stashed and cleaned in addition to the untracked files. - -If the `--include-untracked` option is used, all untracked files are also -stashed and then cleaned up with `git clean`, leaving the working directory -in a very clean state. - -If the `--index` option is used, then tries to reinstate not only the working -tree's changes, but also the index's ones. However, this can fail, when you -have conflicts (which are stored in the index, where you therefore can no -longer apply the changes as they were originally). - -If the `--keep-index` option is used, all changes already added to the -index are left intact. - -With `--patch`, you can interactively select hunks from the diff -between HEAD and the working tree to be stashed. The stash entry is -constructed such that its index state is the same as the index state -of your repository, and its worktree contains only the changes you -selected interactively. The selected changes are then rolled back -from your worktree. See the ``Interactive Mode'' section of -linkgit:git-add[1] to learn how to operate the `--patch` mode. +OPTIONS +------- +-a:: +--all:: + All ignored and untracked files are also stashed and then cleaned + up with `git clean`. + +-u:: +--include-untracked:: + All untracked files are also stashed and then cleaned up with + `git clean`. + +--index:: + Tries to reinstate not only the working tree's changes, but also + the index's ones. However, this can fail, when you have conflicts + (which are stored in the index, where you therefore can no longer + apply the changes as they were originally). + +-k:: +--keep-index:: +--no-keep-index:: + All changes already added to the index are left intact. + +-p:: +--patch:: + Interactively select hunks from the diff between HEAD and the + working tree to be stashed. The stash entry is constructed such + that its index state is the same as the index state of your + repository, and its worktree contains only the changes you selected + interactively. The selected changes are then rolled back from your + worktree. See the ``Interactive Mode'' section of linkgit:git-add[1] + to learn how to operate the `--patch` mode. + The `--patch` option implies `--keep-index`. You can use `--no-keep-index` to override this. -When pathspec is given to 'git stash push', the new stash entry records the -modified states only for the files that match the pathspec. The index -entries and working tree files are then rolled back to the state in -HEAD only for these files, too, leaving files that do not match the -pathspec intact. +...:: + The new stash entry records the modified states only for the files + that match the pathspec. The index entries and working tree files + are then rolled back to the state in HEAD only for these files, + too, leaving files that do not match the pathspec intact. -When no `` is given, `stash@{0}` is assumed, otherwise `` must -be a reference of the form `stash@{}`. +:: + A reference of the form `stash@{}`. When no `` is + given, the latest stash is assumed (that is, `stash@{0}`). DISCUSSION ---------- From patchwork Thu Jan 16 16:09:22 2020 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: 11337367 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 9FF871820 for ; Thu, 16 Jan 2020 16:09:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7C3AB207FF for ; Thu, 16 Jan 2020 16:09:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IHYUhel6" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726988AbgAPQJf (ORCPT ); Thu, 16 Jan 2020 11:09:35 -0500 Received: from mail-wr1-f65.google.com ([209.85.221.65]:38842 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726653AbgAPQJf (ORCPT ); Thu, 16 Jan 2020 11:09:35 -0500 Received: by mail-wr1-f65.google.com with SMTP id y17so19744173wrh.5 for ; Thu, 16 Jan 2020 08:09:33 -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=Rupxb/F+zMjSWq64R5cbUJIONY34r8lX6c//KyJp2PE=; b=IHYUhel6349VtSjBabehVwkqRegJ29eltsK1BRVeSBc2GHjyprdaQJ6jjcf3HXtY4g jHz7FdCPmlxrHTyMapRjJvz+pg77tCM0A6FAL7k0uHsf2gMJWbsor99f02ey/spNH4m0 7jTvXu4FYpl41wWzTaYK+p0Ip6k/0IhzXGmtlj9bnZHRsK0B+BsWdNwtt/UYtntBV1Qw fS+NgY3ooMSxsIPYj6nN7hb74pImW9MgBq4uEPwOGHvePeeMx9i2s4P7AHypd8iNgsro Uehpvsk0N4s/BdVIe1FjuMatGIeSm8GiHQCTBTUI933RzdWL/RQGtc8uGQlux7VndPOA pgzw== 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=Rupxb/F+zMjSWq64R5cbUJIONY34r8lX6c//KyJp2PE=; b=DbR2JJ8kp4ymPPquu28oOdcg9uMa5L46NvrWzGBOJ4bBNuc+0psLAi5mJRdHOS9de/ MJuNLeL3+BJPFQutz8h4RMqQFJ84n1P4cO8KXGPx+bbE5epXh34QULfaZellg3J4UFdY MUq0im5Xo5/WRAKBrjlWHYrr3FcurwvYBWE/D/6dc+TDK4cLCg4Xy/GtxMIk/P7+EnPT F8ob9Kobguli33Kq24Fk9H7HnLbxiVbdSQuauCrbL+qmz272hSNabHPSTED7X+9kgJI/ TG7zPIUWZY1abgSPOfJhwQwTJKGX1VTfsJ2vJ7z9O4sJNlrnCDEonumrzbklptKTu+rJ 3prA== X-Gm-Message-State: APjAAAXN1XoHX80srtpVKzpV3V7CirwZipR62XxjuuxJP8CRWij1BdwT Taajj2ZyEoOfPPSZwwmzNnHMg7Cd X-Google-Smtp-Source: APXvYqzVdGIB0UlQEOAqle+4aa8YICVeosw/8HysATgENq9CtWi22lnRRN5lZ5ePwKmxwviBHn8ChA== X-Received: by 2002:a5d:66c3:: with SMTP id k3mr3903554wrw.370.1579190972797; Thu, 16 Jan 2020 08:09:32 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id x11sm892090wmg.46.2020.01.16.08.09.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jan 2020 08:09:32 -0800 (PST) Message-Id: <8a5f2dbe9eef0d6fe360a8ac1130b854e73245bf.1579190965.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Alexandr Miloslavskiy via GitGitGadget" Date: Thu, 16 Jan 2020 16:09:22 +0000 Subject: [PATCH 5/8] doc: stash: document more options Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Paul-Sebastian Ungureanu , Alexandr Miloslavskiy , Alexandr Miloslavskiy Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Alexandr Miloslavskiy Signed-off-by: Alexandr Miloslavskiy --- Documentation/git-stash.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index f75b80a720..f5fa62dc7c 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -185,6 +185,13 @@ OPTIONS The `--patch` option implies `--keep-index`. You can use `--no-keep-index` to override this. +-q:: +--quiet:: + Quiet, suppress feedback messages. + +\--:: + Separates pathspec from options for disambiguation purposes. + ...:: The new stash entry records the modified states only for the files that match the pathspec. The index entries and working tree files From patchwork Thu Jan 16 16:09:23 2020 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: 11337369 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 2A60A109A for ; Thu, 16 Jan 2020 16:09:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 089BB2077C for ; Thu, 16 Jan 2020 16:09:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Fk4WAG4C" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727003AbgAPQJh (ORCPT ); Thu, 16 Jan 2020 11:09:37 -0500 Received: from mail-wr1-f68.google.com ([209.85.221.68]:41582 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726957AbgAPQJf (ORCPT ); Thu, 16 Jan 2020 11:09:35 -0500 Received: by mail-wr1-f68.google.com with SMTP id c9so19727995wrw.8 for ; Thu, 16 Jan 2020 08:09:34 -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=Hp7X8A21RPBggR87QrLxVtnn4L5GlpLQtz3kUeB9qho=; b=Fk4WAG4CLWVAQ/XgkldmaxiceFwMmFWYT7jZaQ7BPSV1rRALS6PTMcet5rPd8c4RvS 0tbN1Vs02/OcNhruxL53g3lMPd0w11WXboN+LLvD5EYl1qUVQeWyio89673WrJTr2zRe 3v6NK9yUE0P0ITwPJWCORWgUNnqlsR5Qqzu19IdYIDxD6c+HcFBz3d+E0f1Xe0QjgsRw 2de+Q6zD3H1JHvqGqYY1R6oIbH28fZWdgOWWGya+xRxrgkPcpBe3pAo9b0wNAcuPOO5n qFbY2V2bRPrAahgT85cuBNQGjhngeYfMIVSfpzCum0h7FgTUdMxYV78Lc+iVvCtsdnak S6Pg== 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=Hp7X8A21RPBggR87QrLxVtnn4L5GlpLQtz3kUeB9qho=; b=esvSPJSvcgaiA/QPpYgtkxPZS6fKJ+b1fL/QiPUAwkkH+EJX3ECit/yM/+jVbG/V4u K6HH46Uix2MfDIol/t/hFvhRXMSDfYEeDb14kzWGVRa2MCxCcX875UrOX+JJtDpxe0an hcFYIcWlryAFU9z1lkms7nFJpHU2Zh6lBcUfJJLG63vfB4t3wMMK7sWAdVQkUV9/PRCm QWwpzARdogNnG7wzpVOIkuE4aX1qe7bP8Dci13FVdZjRxC74Nvk2eRfvqsrFXNObzJ1U G8PmQtWDdorspL7yqU1+siwKqzmNAgrE3dwt8oMrVkCVYFGkGYqDRUW+xEXYQ3TNYQCL yfsg== X-Gm-Message-State: APjAAAVeh6Hq8F3PWf/bvLRjfD5WMVxwpSXKHajc6Qw6pqfT5fL1A5Tb Vmg3/A+VgEeHadtBmS9Mchl39KMx X-Google-Smtp-Source: APXvYqzJFZKfOKAFlh2ekocSk5f+y9reYPl9/JbiP/16zKbxBMQSlnQOz13LRmQf92bdcwFTHvDtUw== X-Received: by 2002:a5d:6ca1:: with SMTP id a1mr4008559wra.36.1579190973497; Thu, 16 Jan 2020 08:09:33 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id x7sm28987934wrq.41.2020.01.16.08.09.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jan 2020 08:09:33 -0800 (PST) Message-Id: <5e17a0c470ec576d9dc4c24acecbad5ac2ddd9ed.1579190965.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Alexandr Miloslavskiy via GitGitGadget" Date: Thu, 16 Jan 2020 16:09:23 +0000 Subject: [PATCH 6/8] doc: stash: synchronize description Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Paul-Sebastian Ungureanu , Alexandr Miloslavskiy , Alexandr Miloslavskiy Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Alexandr Miloslavskiy This patch continues the effort that is already applied to `git commit`, `git reset`, `git checkout` etc. 1) Added reference to 'linkgit:gitglossary[7]'. 2) Fixed mentions of incorrectly plural "pathspecs". Signed-off-by: Alexandr Miloslavskiy --- Documentation/git-stash.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index f5fa62dc7c..576ad757d9 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -53,13 +53,13 @@ push [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q For quickly making a snapshot, you can omit "push". In this mode, non-option arguments are not allowed to prevent a misspelled subcommand from making an unwanted stash entry. The two exceptions to this -are `stash -p` which acts as alias for `stash push -p` and pathspecs, +are `stash -p` which acts as alias for `stash push -p` and pathspec elements, which are allowed after a double hyphen `--` for disambiguation. save [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] []:: This option is deprecated in favour of 'git stash push'. It - differs from "stash push" in that it cannot take pathspecs. + differs from "stash push" in that it cannot take pathspec. Instead, all non-option arguments are concatenated to form the stash message. @@ -197,6 +197,8 @@ The `--patch` option implies `--keep-index`. You can use that match the pathspec. The index entries and working tree files are then rolled back to the state in HEAD only for these files, too, leaving files that do not match the pathspec intact. ++ +For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. :: A reference of the form `stash@{}`. When no `` is From patchwork Thu Jan 16 16:09:24 2020 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: 11337371 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 1E158139A for ; Thu, 16 Jan 2020 16:09:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E78C62077C for ; Thu, 16 Jan 2020 16:09:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="e+wu5dsm" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727007AbgAPQJh (ORCPT ); Thu, 16 Jan 2020 11:09:37 -0500 Received: from mail-wr1-f65.google.com ([209.85.221.65]:35789 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726653AbgAPQJh (ORCPT ); Thu, 16 Jan 2020 11:09:37 -0500 Received: by mail-wr1-f65.google.com with SMTP id g17so19712445wro.2 for ; Thu, 16 Jan 2020 08:09:35 -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=o54LTk41F7GdjdM41hLXdu642jqyPrhLkXFEoFT0caQ=; b=e+wu5dsmBOTYRdcGyiNtMh0ey9VdjgjNF0sMT2eLPlcrxwLbH/pnx+cvYAAZnuRBDL +CSTFYoqRMsospjIm4pEIT+MLr/KBxUkljdPAhPVrh8WWjFb7BLRwAROTgya9wLcGmFa 6/rPiLes4taQdzFSU17iaveKXpp75OWF3RsrZS7BqLohQVhlNbslL6q76Jq6rnqTjeaD 14jNn3e32LRzvbYeqExtnYx8Np+lVdVGiTNJP4nb/MTqmOerkAXymvAyva5x3MgE2TkE 1/FaXKvgi94+mn9kJYs7rQu5ELhXtoPC7g8utbCqKtH2CUcRl6+ZxcwPd4seqwd3de6F GXcg== 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=o54LTk41F7GdjdM41hLXdu642jqyPrhLkXFEoFT0caQ=; b=SjWMvt6JhecDEp7Wl6jUQMNLfhM20Juh73BAIYQ1C8ThtfApCngV102PbxHfsE55VH 045DYUWr9V1eMHpLOCdS06htl2hisnnn0tN+TVZAZq+JpYu/t7d1+I0hUNK+cHITL/V5 kiNrhbuCVqgpWVWJJMvq47SDSTRW3oQ5VucTDevDPgePfIgledBCPCG9imQv9a59efWr Afo8rXRd6vYMfohMvq+I1SGBPLPUPm4/MN/Cv6nGWSmV9Gcx1No3Ji5xco2ov/BXTXSN 2gPaq8wOsa58gUCCjSBdEj5EcQwg7AdDNuNfAn/Fok+XttjwiHUv7aB0LVLYxiyXg2PA e0qA== X-Gm-Message-State: APjAAAWusNSGta0cVMDhRsQ5+jsE/6JRmP4hY3Tp1Xx+i9bXge5CpgF1 56SKzA9kPJbTDZeZh9pxGUpSFqtC X-Google-Smtp-Source: APXvYqxFFWVskDelYu/2bTVbefYLtcv4tRaamzzGrdnHwIywDUBbf2ulrvABLHFSdlrzum0BE2cVUQ== X-Received: by 2002:adf:97d6:: with SMTP id t22mr312868wrb.407.1579190974616; Thu, 16 Jan 2020 08:09:34 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id n189sm1481067wme.33.2020.01.16.08.09.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jan 2020 08:09:34 -0800 (PST) Message-Id: <7a8d36d49f85940d95f989741e68ba480abaa4eb.1579190965.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Alexandr Miloslavskiy via GitGitGadget" Date: Thu, 16 Jan 2020 16:09:24 +0000 Subject: [PATCH 7/8] stash: eliminate crude option parsing Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Paul-Sebastian Ungureanu , Alexandr Miloslavskiy , Alexandr Miloslavskiy Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Alexandr Miloslavskiy Eliminate crude option parsing and rely on real parsing instead, because 1) Crude parsing is crude, for example it's not capable of handling things like `git stash -m Message` 2) Adding options in two places is inconvenient and prone to bugs As a side result, the case of `git stash -m Message` gets fixed. Also give a good error message instead of just throwing usage at user. ---- Some review of what's been happening to this code: Before [1], `git-stash.sh` only verified that all args begin with `-` : # The default command is "push" if nothing but options are given seen_non_option= for opt do case "$opt" in --) break ;; -*) ;; *) seen_non_option=t; break ;; esac done Later, [1] introduced the duplicate code I'm now removing, also making the previous test more strict by white-listing options. ---- [1] Commit 40af1468 ("stash: convert `stash--helper.c` into `stash.c`" 2019-02-26) Signed-off-by: Alexandr Miloslavskiy --- builtin/stash.c | 59 +++++++++++++++++------------------------------- t/t3903-stash.sh | 5 ++++ 2 files changed, 26 insertions(+), 38 deletions(-) diff --git a/builtin/stash.c b/builtin/stash.c index 4ad3adf4ba..7bc4c5d696 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -1448,8 +1448,10 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q return ret; } -static int push_stash(int argc, const char **argv, const char *prefix) +static int push_stash(int argc, const char **argv, const char *prefix, + int push_assumed) { + int force_assume = 0; int keep_index = -1; int patch_mode = 0; int include_untracked = 0; @@ -1471,10 +1473,22 @@ static int push_stash(int argc, const char **argv, const char *prefix) OPT_END() }; - if (argc) + if (argc) { + force_assume = !strcmp(argv[0], "-p"); argc = parse_options(argc, argv, prefix, options, git_stash_push_usage, - 0); + PARSE_OPT_KEEP_DASHDASH); + } + + if (argc) { + if (!strcmp(argv[0], "--")) { + argc--; + argv++; + } else if (push_assumed && !force_assume) { + die("subcommand wasn't specified; 'push' can't be assumed due to unexpected token '%s'", + argv[0]); + } + } parse_pathspec(&ps, 0, PATHSPEC_PREFER_FULL | PATHSPEC_PREFIX_ORIGIN, prefix, argv); @@ -1547,7 +1561,6 @@ static int use_builtin_stash(void) int cmd_stash(int argc, const char **argv, const char *prefix) { - int i = -1; pid_t pid = getpid(); const char *index_file; struct argv_array args = ARGV_ARRAY_INIT; @@ -1580,7 +1593,7 @@ int cmd_stash(int argc, const char **argv, const char *prefix) (uintmax_t)pid); if (!argc) - return !!push_stash(0, NULL, prefix); + return !!push_stash(0, NULL, prefix, 0); else if (!strcmp(argv[0], "apply")) return !!apply_stash(argc, argv, prefix); else if (!strcmp(argv[0], "clear")) @@ -1600,45 +1613,15 @@ int cmd_stash(int argc, const char **argv, const char *prefix) else if (!strcmp(argv[0], "create")) return !!create_stash(argc, argv, prefix); else if (!strcmp(argv[0], "push")) - return !!push_stash(argc, argv, prefix); + return !!push_stash(argc, argv, prefix, 0); else if (!strcmp(argv[0], "save")) return !!save_stash(argc, argv, prefix); else if (*argv[0] != '-') usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]), git_stash_usage, options); - if (strcmp(argv[0], "-p")) { - while (++i < argc && strcmp(argv[i], "--")) { - /* - * `akpqu` is a string which contains all short options, - * except `-m` which is verified separately. - */ - if ((strlen(argv[i]) == 2) && *argv[i] == '-' && - strchr("akpqu", argv[i][1])) - continue; - - if (!strcmp(argv[i], "--all") || - !strcmp(argv[i], "--keep-index") || - !strcmp(argv[i], "--no-keep-index") || - !strcmp(argv[i], "--patch") || - !strcmp(argv[i], "--quiet") || - !strcmp(argv[i], "--include-untracked")) - continue; - - /* - * `-m` and `--message=` are verified separately because - * they need to be immediately followed by a string - * (i.e.`-m"foobar"` or `--message="foobar"`). - */ - if (starts_with(argv[i], "-m") || - starts_with(argv[i], "--message=")) - continue; - - usage_with_options(git_stash_usage, options); - } - } - + /* Assume 'stash push' */ argv_array_push(&args, "push"); argv_array_pushv(&args, argv); - return !!push_stash(args.argc, args.argv, prefix); + return !!push_stash(args.argc, args.argv, prefix, 1); } diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index ea56e85e70..3ad23e2502 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -285,6 +285,11 @@ test_expect_success 'stash --no-keep-index' ' test bar,bar2 = $(cat file),$(cat file2) ' +test_expect_success 'dont assume push with non-option args' ' + test_must_fail git stash -q drop 2>err && + test_i18ngrep -e "subcommand wasn'\''t specified; '\''push'\'' can'\''t be assumed due to unexpected token '\''drop'\''" err +' + test_expect_success 'stash --invalid-option' ' echo bar5 >file && echo bar6 >file2 && From patchwork Thu Jan 16 16:09:25 2020 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: 11337373 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 D52D6139A for ; Thu, 16 Jan 2020 16:09:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A93D62077C for ; Thu, 16 Jan 2020 16:09:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="AW6w+qvj" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727011AbgAPQJi (ORCPT ); Thu, 16 Jan 2020 11:09:38 -0500 Received: from mail-wm1-f68.google.com ([209.85.128.68]:36217 "EHLO mail-wm1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726994AbgAPQJh (ORCPT ); Thu, 16 Jan 2020 11:09:37 -0500 Received: by mail-wm1-f68.google.com with SMTP id p17so4425340wma.1 for ; Thu, 16 Jan 2020 08:09:36 -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=GifjSWWRlpFZpUFK+3j64IFt2acxdlcCjqeHrzQAx/w=; b=AW6w+qvjOSNQnMqwyIFsB35D1KNSK7luGAtVv7qUBubj8qjVSUbeSo54OLHIcBvT1A 6F7uSbugix7FJXO5tR5gm2YkSvYxAuSQq03mp0B0IGeQhOQDenibPKcpiAth0UzXuvPb g00z4hKwq4mAmG4D5BEx7/HSjCq8Lcdq5NEjt3BcJXqWVMAThC1AyQodFzGIN/ons3s+ ZHmEChtvuZ4ZzaGHx9+NWRDFBksIHgHhKoE71J7RFLjgcvIu0FRFcIW5Tr8k9DQQX/36 aaItaa4H1U+bqcbHcK1BRJo1XWZ7QnN7lUyxUG32qBWKuETT/1YZ8Mda/tsKLne2+VdI S19w== 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=GifjSWWRlpFZpUFK+3j64IFt2acxdlcCjqeHrzQAx/w=; b=mvAHnkt0EhVlVIfdVNoFZKYqpIWjCB/MKovui5yMNg3GTY63H7+8o+LcARbEMJp8to ecE105R8rGzl5Hkf2gdGPqILprUhoBi2+nut98TQKBHm/f3SqOCdXjtSPqS8oTxjkFoH ZwpvwuGcgDHw92XklpIEtrIrUOMthWb4O94UCPwA9XQzsQVGlu0YiMbEgs+b60kubk8O DjaGIKrZjIWpKNJSNszTn4s0sWKNJQ6149+yLAMERvfr/kPg1Bg4xZnqm/IDsezvNCFU IRdVnDFxBOJgQ2iAtr8JyrltQyfhhH+wDOmMfIbulfHp1ajTsQ+v/GK+wDCbDKFIP2Tg I8Wg== X-Gm-Message-State: APjAAAV/SNFDxL2TE08BNRF/9JaYoman0tbF4sUEhxXtzdyOtUKVdEwk kWr1tz27weZ/ZbRnAVV46Y5ECHqe X-Google-Smtp-Source: APXvYqxbnj6cTuhrQ6QwHo1KuMGwMq/vdIwxINbEZSyd9N+S4H9ADRWwlpnwbzdm7h7WKhAwPcw4rg== X-Received: by 2002:a1c:dc85:: with SMTP id t127mr146436wmg.16.1579190975385; Thu, 16 Jan 2020 08:09:35 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id q6sm31221123wrx.72.2020.01.16.08.09.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jan 2020 08:09:34 -0800 (PST) Message-Id: <721410233bbee49fa13773ae9c04b4c6ed076a1a.1579190965.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Alexandr Miloslavskiy via GitGitGadget" Date: Thu, 16 Jan 2020 16:09:25 +0000 Subject: [PATCH 8/8] stash push: support the --pathspec-from-file option Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Paul-Sebastian Ungureanu , Alexandr Miloslavskiy , 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 `-`. Such use case is not really expected. 2) It is not allowed to pass pathspec in both args and file. Signed-off-by: Alexandr Miloslavskiy --- Documentation/git-stash.txt | 16 +++++- builtin/stash.c | 20 +++++++ t/t3909-stash-pathspec-file.sh | 100 +++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100755 t/t3909-stash-pathspec-file.sh diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index 576ad757d9..4e6a27c4fd 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -15,6 +15,7 @@ SYNOPSIS 'git stash' branch [] 'git stash' [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all] [-m|--message ] + [--pathspec-from-file= [--pathspec-file-nul]] [--] [...]] 'git stash' clear 'git stash' create [] @@ -43,7 +44,7 @@ created stash, `stash@{1}` is the one before it, `stash@{2.hours.ago}` is also possible). Stashes may also be referenced by specifying just the stash index (e.g. the integer `n` is equivalent to `stash@{n}`). -push [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-m|--message ] [--] [...]:: +push [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-m|--message ] [--pathspec-from-file= [--pathspec-file-nul]] [--] [...]:: Save your local modifications to a new 'stash entry' and roll them back to HEAD (in the working tree and in the index). @@ -185,6 +186,19 @@ OPTIONS The `--patch` option implies `--keep-index`. You can use `--no-keep-index` to override this. +--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). + -q:: --quiet:: Quiet, suppress feedback messages. diff --git a/builtin/stash.c b/builtin/stash.c index 7bc4c5d696..74d92595a2 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -27,6 +27,7 @@ static const char * const git_stash_usage[] = { N_("git stash clear"), N_("git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n" " [-u|--include-untracked] [-a|--all] [-m|--message ]\n" + " [--pathspec-from-file= [--pathspec-file-nul]]\n" " [--] [...]]"), N_("git stash save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n" " [-u|--include-untracked] [-a|--all] []"), @@ -1456,7 +1457,9 @@ static int push_stash(int argc, const char **argv, const char *prefix, int patch_mode = 0; int include_untracked = 0; int quiet = 0; + int pathspec_file_nul = 0; const char *stash_msg = NULL; + const char *pathspec_from_file = NULL; struct pathspec ps; struct option options[] = { OPT_BOOL('k', "keep-index", &keep_index, @@ -1470,6 +1473,8 @@ static int push_stash(int argc, const char **argv, const char *prefix, N_("include ignore files"), 2), OPT_STRING('m', "message", &stash_msg, N_("message"), N_("stash message")), + OPT_PATHSPEC_FROM_FILE(&pathspec_from_file), + OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul), OPT_END() }; @@ -1492,6 +1497,21 @@ static int push_stash(int argc, const char **argv, const char *prefix, parse_pathspec(&ps, 0, PATHSPEC_PREFER_FULL | PATHSPEC_PREFIX_ORIGIN, prefix, argv); + + if (pathspec_from_file) { + if (patch_mode) + die(_("--pathspec-from-file is incompatible with --patch")); + + if (ps.nr) + die(_("--pathspec-from-file is incompatible with pathspec arguments")); + + parse_pathspec_file(&ps, 0, + PATHSPEC_PREFER_FULL | PATHSPEC_PREFIX_ORIGIN, + prefix, pathspec_from_file, pathspec_file_nul); + } else if (pathspec_file_nul) { + die(_("--pathspec-file-nul requires --pathspec-from-file")); + } + return do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode, include_untracked); } diff --git a/t/t3909-stash-pathspec-file.sh b/t/t3909-stash-pathspec-file.sh new file mode 100755 index 0000000000..55e050cfd4 --- /dev/null +++ b/t/t3909-stash-pathspec-file.sh @@ -0,0 +1,100 @@ +#!/bin/sh + +test_description='stash --pathspec-from-file' + +. ./test-lib.sh + +test_tick + +test_expect_success setup ' + >fileA.t && + >fileB.t && + >fileC.t && + >fileD.t && + git add fileA.t fileB.t fileC.t fileD.t && + git commit -m "Files" && + + git tag checkpoint +' + +restore_checkpoint () { + git reset --hard checkpoint +} + +verify_expect () { + git stash show --name-status >actual && + test_cmp expect actual +} + +test_expect_success 'simplest' ' + restore_checkpoint && + + # More files are written to make sure that git didnt ignore + # --pathspec-from-file, stashing everything + echo A >fileA.t && + echo B >fileB.t && + echo C >fileC.t && + echo D >fileD.t && + + cat >expect <<-\EOF && + M fileA.t + EOF + + echo fileA.t | git stash push --pathspec-from-file=- && + verify_expect +' + +test_expect_success '--pathspec-file-nul' ' + restore_checkpoint && + + # More files are written to make sure that git didnt ignore + # --pathspec-from-file, stashing everything + echo A >fileA.t && + echo B >fileB.t && + echo C >fileC.t && + echo D >fileD.t && + + cat >expect <<-\EOF && + M fileA.t + M fileB.t + EOF + + printf "fileA.t\0fileB.t\0" | git stash push --pathspec-from-file=- --pathspec-file-nul && + verify_expect +' + +test_expect_success 'only touches what was listed' ' + restore_checkpoint && + + # More files are written to make sure that git didnt ignore + # --pathspec-from-file, stashing everything + echo A >fileA.t && + echo B >fileB.t && + echo C >fileC.t && + echo D >fileD.t && + + cat >expect <<-\EOF && + M fileB.t + M fileC.t + EOF + + printf "fileB.t\nfileC.t\n" | git stash push --pathspec-from-file=- && + verify_expect +' + +test_expect_success 'error conditions' ' + restore_checkpoint && + echo A >fileA.t && + echo fileA.t >list && + + test_must_fail git stash push --pathspec-from-file=list --patch 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with --patch" err && + + test_must_fail git stash push --pathspec-from-file=list -- fileA.t 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with pathspec arguments" err && + + test_must_fail git stash push --pathspec-file-nul 2>err && + test_i18ngrep -e "--pathspec-file-nul requires --pathspec-from-file" err +' + +test_done