git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: contact@your-diary.io
To: git@vger.kernel.org
Subject: Bug report for git stash push.
Date: Sun, 13 Mar 2022 21:20:46 +0900	[thread overview]
Message-ID: <aa8c4afddad08838584a5f9ec5c8e7ab@your-diary.io> (raw)

Dear, Git team

Hi.
I, ynn, am contacting you to report a counter-intuitive behavior of `git 
stash push -- <file(s)>`.
I believe this is a (at least documentation) bug.

Prior to this email, I've discussed this problem on Stack Overflow:
https://stackoverflow.com/questions/71411369/git-stash-push-file-doesnt-only-save-the-specified-file

---------------------------------------------------

# tl;dr

`git stash push -- <file(s)>` is expected to save only the specified 
`<file(s)>` and let the other files intact.
However, it doesn't.

---------------------------------------------------

# Expected Behavior

According to `man git-stash`, `git stash push` is explained as below.

```
push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] 
[-u|--include-untracked] [-a|--all]
[-q|--quiet] [-m|--message <message>] [--pathspec-from-file=<file> 
[--pathspec-file-nul]] [--]
[<pathspec>...]
     Save your local modifications to a new stash entry and roll them 
back to HEAD (in the working
     tree and in the index). The <message> part is optional and gives the 
description along with
     the stashed state.
```

where `<pathspec>` is defined as

```
<pathspec>...

     This option is only valid for push command.

     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.
```

This definition of `<pathspec>` says two things:

(A) The new stash entry records the modified states only for the files 
that match the pathspec.

(B) 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.

Let's confirm these two in the next section.

---------------------------------------------------

# Actual Behavior

## Preparations

```
$ git init test1
$ cd test1
$ echo aaa > a.txt
$ echo bbb > b.txt
$ git add .
$ git commit -m 'H'
$ cd ..
$ cp -r test1 test2
```

## Pattern1

When files are not staged, both (A) and (B) are satisfied.

```
$ cd test1

$ echo aaa >> a.txt

$ echo bbb >> b.txt

$ git status
On branch master
Changes not staged for commit:
   (use "git add <file>..." to update what will be committed)
   (use "git restore <file>..." to discard changes in working directory)
     modified:   a.txt
     modified:   b.txt

no changes added to commit (use "git add" and/or "git commit -a")

$ git stash push -- a.txt
Saved working directory and index state WIP on master: 9806f0c H

$ git status # (B) is satisfied
On branch master
Changes not staged for commit:
   (use "git add <file>..." to update what will be committed)
   (use "git restore <file>..." to discard changes in working directory)
     modified:   b.txt

no changes added to commit (use "git add" and/or "git commit -a")

$ git stash show # (A) is satisfied
  a.txt | 1 +
  1 file changed, 1 insertion(+)

$ cd ..
```

## Pattern2

When files are staged, only (B) is satisfied.

```
$ cd test2

$ echo aaa >> a.txt

$ echo bbb >> b.txt

$ git add . # stages them

$ git status
On branch master
Changes to be committed:
   (use "git restore --staged <file>..." to unstage)
     modified:   a.txt
     modified:   b.txt

$ git stash push -- a.txt
Saved working directory and index state WIP on master: 9806f0c H

$ git status # (B) is satisfied
On branch master
Changes to be committed:
   (use "git restore --staged <file>..." to unstage)
     modified:   b.txt

$ git stash show # (A) is NOT satisfied.
  a.txt | 1 +
  b.txt | 1 +
  2 files changed, 2 insertions(+)
```

Let's cite the explanation (A) again.

(A) The new stash entry records the modified states only for the files 
that match the pathspec.

However, in the example above, the modified states of `a.txt` AND 
`b.txt` are saved in the newly created stash entry.

---------------------------------------------------

# Conclusion

- Though I don't tell if the behavior is what the author of `git stash` 
intended to be, it seems counter-intuitive. Whilst I specify the 
pathspec `-- a.txt`, not only `a.txt` but also `b.txt` are saved.

- The behavior seems to contradict with the documentation, meaning at 
least the documentation should be fixed.

Thank you.

---------------------------------------------------

# Environments

Information from `git bugreport`:

```
[System Info]
git version:
git version 2.35.1
cpu: x86_64
no commit associated with this build
sizeof-long: 8
sizeof-size_t: 8
shell-path: /bin/sh
uname: Linux 5.16.11-arch1-1 #1 SMP PREEMPT Thu, 24 Feb 2022 02:18:20 
+0000 x86_64
compiler info: gnuc: 11.1
libc info: glibc: 2.35
$SHELL (typically, interactive shell): <unset>

[Enabled Hooks]
```

---------------------------------------------------

                 reply	other threads:[~2022-03-13 12:30 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aa8c4afddad08838584a5f9ec5c8e7ab@your-diary.io \
    --to=contact@your-diary.io \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).