mu *_*u 無 7 git git-stash git-index
在开发过程中,我经常将文件的工作版本(但不提交它们)添加到我的git repo中.我继续处理这些文件,直到它们达到可执行阶段,当我可以提交它们时.所以回购看起来如下
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: testfile1
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: testfile1
# modified: testfile2
Run Code Online (Sandbox Code Playgroud)
当我做一个git stash,然后做一个git stash pop,我得到
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: testfile1
# modified: testfile2
Run Code Online (Sandbox Code Playgroud)
问题
目前,我手动做
git stash --keep-index
git stash
git stash pop
git add <stashed_files>
git stash pop
Run Code Online (Sandbox Code Playgroud)
这个问题是
编辑 - 我更喜欢命令行解决方案,因为我在测试服务器上以类似的方式工作.
我看到这已经回答了,但是让我再补充一点,并发出一个警告:里面有一个小问题git stash.
当你运行git stash或git stash save(默认是save这些是相同的东西)没有使用时-p,stash脚本 - 它存在于git-core目录中,其位置根据git安装而变化,它可能在/usr/libexec/git-core或/usr/local/libexec/git-core例如 - 创建一个带有两个的提交(或有时三)家长提交.按顺序,这些提交是:
-uor -a,未跟踪甚至忽略文件(它还用于git clean从工作目录中删除它们)HEAD提交之间的增量(这是buglet的来源;见下文).然后它设置refs/stash为指向最后一个提交,即工作目录提交.这个提交有它的父母:
stash^(第一个父)stash^2(第二个父)stash^3(第三个父级),如果它存在.事实上,这个藏匿包含了藏匿时所有内容,但当你使用git stash pop --index或git stash apply --index恢复"预藏匿状态" 时,小虫最好显示出来.(我要使用git stash apply专门下文,但pop只是apply其次drop.)
现在,如果您刚刚运行git stash apply,正如您所指出的那样,它会为您提供大量changes not staged for commit文件,即使您在运行之前已经仔细地进行了一些操作git stash save.这是因为将这些更改合并到一起要容易得多,无论工作目录状态如何,包括您是否已检出不同的分支或其他任何内容,包括在运行之前是否暂存某些文件git stash apply.(实际上,git stash apply使用git的合并代码来引入工作目录更改.)
git stash apply --index但是,如果您运行,stash脚本首先会尝试将索引与原始索引完全相同save.(如果还没有暂存,则会恢复原始状态.)假设它可以执行此操作,然后尝试类似地设置工作目录(再次使用合并机制).如果它无法正确设置索引,则它对索引没有任何作用,并建议您在没有的情况下重试--index.
这是buglet的用武之地.假设你从一个文件开始,比如basefile没有任何变化.你做了一个改变,并分阶段:
$ cat basefile
base
$ git status --short
$ echo add to basefile >> basefile; git add basefile
Run Code Online (Sandbox Code Playgroud)
但是你决定要让工作目录副本从HEAD修订版中没有变化:
$ ed basefile
21
2d
w
5
q
$ git status --short
MM basefile
Run Code Online (Sandbox Code Playgroud)
这里棘手的一点是basefile在索引中修改,然后在work-dir中再次修改,但第二个更改将其恢复到HEAD提交中的内容.运行时git stash save,存储脚本会意外地将索引版本记录为工作进行中的版本.
如果您现在执行git stash apply --index并运行git status --short:
$ git stash save
Saved working directory and index state WIP on master: 94824e1 initial
HEAD is now at 94824e1 initial
stash created
$ git stash apply --index
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: basefile
#
$ git status --short
M basefile
Run Code Online (Sandbox Code Playgroud)
这里git已将索引版本恢复到索引中,然后将工作目录版本设置为索引版本中的相同内容:
$ cat basefile
base
add to basefile
Run Code Online (Sandbox Code Playgroud)
存储脚本的修复是一个单词更改,但到目前为止似乎没有人喜欢它.也许问题是,如果你没有 应用存储--index,这有效地将索引更改(额外的行add to basefile)与任何内容组合在一起,以便工作目录版本具有额外的行.但是,当索引和工作目录版本不同时,这与它的行为方式不一致:
$ git stash drop
Dropped refs/stash@{0} (61c83c866bc522c58df62320b77e647ffd28aa95)
$ echo base > basefile
$ git status --short
$ echo add to basefile >> basefile
$ git add basefile
$ ed basefile
21
2c
different change
w
22
q
$ git status --short
MM basefile
$ git stash save
Saved working directory and index state WIP on master: 94824e1 initial
HEAD is now at 94824e1 initial
$ git stash apply
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: basefile
#
no changes added to commit (use "git add" and/or "git commit -a")
$ cat basefile
base
different change
Run Code Online (Sandbox Code Playgroud)
在这里,通过"拼凑"索引和工作树的变化,但不应用--index,我们只恢复工作树的变化.
(幸运的是,因为我们正在使用apply而不是pop我们现在可以改变主意:
$ git reset --hard HEAD
HEAD is now at 94824e1 initial
$ git stash apply -q --index
$ git status --short
MM basefile
Run Code Online (Sandbox Code Playgroud)
如果我们查看index和work-dir版本,我们现在可以看到两个版本basefile.)
(对存储脚本的单字修复是在行读取中更改HEAD为$i_tree:
git diff --name-only -z HEAD -- >"$TMP-stagenames" &&
Run Code Online (Sandbox Code Playgroud)
我把它发布到了git邮件列表并得到了...蟋蟀.:-))