git 存储推送<file>不仅保存指定的文件

  • 本文关键字:保存 文件 file 存储 git git
  • 更新时间 :
  • 英文 :


man git-stash中,git stash push的解释如下:

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.

其中<pathspec>

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

所以git stash push -- <file>应该只将<file>保存为一个隐藏条目,对吧?

然而,就我所测试的而言,git stash push -- <file>保存了所有内容(即不限于<file>(:

$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified:   LICENSE.md
modified:   README.md
modified:   src/attach.ts
$ git stash push -- README.md
Saved working directory and index state WIP on master: ccd0b050 fix(highlight): use coc#compat#buf_line_count
$ git status #This is as expected.
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified:   LICENSE.md
modified:   src/attach.ts
$ git stash show #Why? This is not what I expect.
LICENSE.md    | 2 +-
README.md     | 2 +-
src/attach.ts | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
$ git reset --hard
HEAD is now at ccd0b050 fix(highlight): use coc#compat#buf_line_count
$ git status #This is as expected.
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
$ git stash pop #Strangely, not only `README.md` is restored.
On branch master
Your branch is up to date with 'origin/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:   LICENSE.md
modified:   README.md
modified:   src/attach.ts
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (0ee651d4a9206e2e8ce384ca6623175fa3edcdcd)

这怎么解释呢?

环境:git 2.35.1的macOS(通过brew安装(,git 2.35.1的Arch Linux

TL;DR:我认为git-stash是从存储完整的索引开始的,所以如果在运行git stash push -- <paths...>之前,您的文件被暂存以进行提交,那么完整的索引就会存储在存储中。


从以下设置开始:

$ git init
$ echo aaa > a.txt && echo bbb > b.txt
$ git add a.txt b.txt
$ git commit -m "first commit"
$ echo aaa >> a.txt  # add a line to a.txt
$ echo bbb >> b.txt  # add a line to b.txt
# repo state after the above setup :
$ git status -s
M a.txt
M b.txt
$ git stash show
No stash entries found.

如果文件在隐藏之前不是暂存的,则只隐藏一个文件可以正常工作:

$ git stash push -- a.txt
Saved working directory and index state WIP on master: c652c35 first commit
# index and stash content are as is expected :
$ git status -s
M b.txt
$ git stash show
a.txt | 1 +
1 file changed, 1 insertion(+)
$ git log --oneline --graph --name-status --cc stash
*   07770c0 (refs/stash) WIP on master: c652c35 first commit
|  
| | 
MM      a.txt
| * 58d58bf index on master: c652c35 first commit
|/  
* c652c35 (HEAD -> master) first commit
...

如果文件是在隐藏之前暂存的(我认为这就是你描述的情况?(,那么git stash似乎是从编写完整的索引开始的:

$ git add a.txt b.txt 
$ git stash push -- a.txt
Saved working directory and index state WIP on master: c652c35 first commit
$ git status -s
M  b.txt
$ git stash show
a.txt | 1 +
b.txt | 1 +
2 files changed, 2 insertions(+)
$ git log --oneline --graph --name-only --cc stash
*   1a10665 (refs/stash) WIP on master: c652c35 first commit
|  
| | 
| * c26f4a2 index on master: c652c35 first commit
|/  
|   M   a.txt   # the complete index is stashed
|   M   b.txt
* c652c35 (HEAD -> master) first commit
...

最新更新