如何在'git stash-p中忽略添加的帅哥`

如何在'git stash-p中忽略添加的帅哥`,git,git-stash,Git,Git Stash,想象一下这个场景: # edit two files git add -p // add hunks from one file 现在,当您运行git stash-p时,它会再次询问您是否要隐藏刚刚通过git add-p选择的大块肉。有没有办法将git配置为默认情况下忽略这些已经添加的大块头?大多数时候,我不想隐藏我已经添加的东西。 当(因为调用 Git Stase没有任何参数就相当于 Git StasePux,考虑添加保持索引< /代码>选项.< /P> 这意味着已经添加到索引中的所有更改都

想象一下这个场景:

# edit two files
git add -p // add hunks from one file
现在,当您运行
git stash-p
时,它会再次询问您是否要隐藏刚刚通过
git add-p
选择的大块肉。有没有办法将git配置为默认情况下忽略这些已经添加的大块头?大多数时候,我不想隐藏我已经添加的东西。

当(因为调用<代码> Git Stase<代码>没有任何参数就相当于<代码> Git StasePux<代码>,考虑添加<代码>保持索引< /代码>选项.< /P> 这意味着已经添加到索引中的所有更改都保持不变

所以
-p
patch
)选项不应该查询那些(已经缓存的)大块头

注意:
--patch
选项意味着
--keep index
,因此(用于测试)请确保您使用的是可用的最新Git版本(2.17),然后尝试
Git stash push-p

如果问题仍然存在,那么,如评论所述,首先执行提交将允许
隐藏-p
使用干净的索引进行操作。

git reset--soft@
将恢复提交的索引。

手册页中有一个类似的示例:

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.
曼吉特藏匿处:

"Testing partial commits
You can use git stash save --keep-index when you want 
to make two or more commits out of the changes in the 
work tree, and you want to test each change before 
committing:

# ... hack hack hack ...
$ git add --patch foo            # add just first part to the index
$ git stash save --keep-index    # save all other changes to the stash"*
我可以确认:

如果您使用
git stash-p
(这意味着
--保留索引
),仍然会询问是否应该隐藏索引中已经存在的更改(如您所述)

因此,手册页似乎令人困惑,其他地方也提到了这一点:

总之:

"Testing partial commits
You can use git stash save --keep-index when you want 
to make two or more commits out of the changes in the 
work tree, and you want to test each change before 
committing:

# ... hack hack hack ...
$ git add --patch foo            # add just first part to the index
$ git stash save --keep-index    # save all other changes to the stash"*
--keep index
(或
-p
,这意味着
--keep index
)只会保持索引不变。已经进行的更改仍然会插入到隐藏中。好了,没有办法做到你所说的

或者更准确地说(再次从手册页):

备选方案:

"Testing partial commits
You can use git stash save --keep-index when you want 
to make two or more commits out of the changes in the 
work tree, and you want to test each change before 
committing:

# ... hack hack hack ...
$ git add --patch foo            # add just first part to the index
$ git stash save --keep-index    # save all other changes to the stash"*
至少有3种方法可以实现您的目标(或多或少):

  • 不要将
    -p
    与git隐藏一起使用。把所有东西都藏起来(用
    --保留索引
    和可能的
    --全部
    ,以确保安全地把所有东西都藏起来)
  • 在隐藏之前提交阶段性更改。这样,您就不会有头和工作树之间的差异,因为这些更改您想从隐藏中忽略。但是,如果你还不确定你是否想做这件事呢?您可以随时在以后进行更改,并使用
    --amend
    更改现有提交
  • 取消保存更改(从索引中删除),然后隐藏
好的,从评论来看,我们想要的是隐藏所有尚未添加的更改(无论是在
git add-p
过程中排除的更改,还是尚未添加的更改)

这样做的原因是在提交阶段状态之前,对阶段状态应用一些测试/可能的调整

这是一个直接的
git stash-k
,像往常一样隐藏所有内容,但保留索引状态和相应的工作树,即从工作树中清除我不打算提交的所有内容

因此:

存储库现在有四个有趣的快照:原始内容(也称为隐藏库)、快照索引、快照工作树和当前索引(、提交和工作树),它们是
stash^2
处的索引快照,并应用了清理。请注意,这里提交的所有三个新快照都将存储库作为父快照

现在您希望恢复对工作树的更改,但很明显,从基础到隐藏索引和工作树的更改与当前索引和工作树中的更改不匹配(以及新提交,它们都匹配),因此,当git弹出存储库时,它会发现冲突:从存储库到存储索引的更改与从存储库到当前索引的更改不匹配

如果Git直接提供了您想要的内容,即“隐藏除索引中的更改以外的所有工作树更改”,您可以使用它,这样隐藏弹出窗口就不会有任何问题,一个直接的
Git隐藏弹出窗口就可以做到这一点。幸运的是,如果说Git擅长任何事情,那就是合并、组合、拆分和全面的差异挖掘

git cherry-pick -nm2 stash
# cherry-pick updated the index, too. maybe git reset here to unstage that stuff.
git stash drop
隐藏弹出是从隐藏基础到隐藏状态的更改与从隐藏基础(通常与当前基础非常相似)到当前状态的更改的合并。您希望将隐藏的工作树更改返回到您的工作树中,但只有那些您尚未添加的更改,因为您添加的所有更改仍在这里,它们现在只是略有不同

因此,cherry pick是
-n
,no commit,
-m2
,用于更改的主线是它的第二个父项,即您在存储时所做但未添加的所有差异

举个例子可能会有所帮助

 cd `mktemp -d`
 git init
 printf >file %s\\n 1 2 3 4 5
 git add .;git commit -m1
 printf >file %s\\n 1 2a 3 4 5
 git add .
 printf >file %s\\n 1 2a 3 4a 5
现在您已经有效地
git add-p
'd了2a更改,而4a更改只在您的工作树中

 $ git stash -k
 $ cat file
 1
 2a
 3
 4
 5
 $ sed -i '2s,^,_,' file   # indent the 2a line
 $ git commit -am2
现在,初始提交,
:/1
12345
,您当前的提交、索引和工作树都是
1\u2a3445
,您的隐藏索引是
12345
,而您的隐藏工作树是
12345

您希望返回的更改是隐藏索引和隐藏工作树之间的差异,这是隐藏提交与其第二个父级之间的差异。因此,樱桃采摘


cherry pick的其他拼写方法包括

git cherry-pick -nm1 -Xours stash
它应用所有隐藏的工作树更改,但在发生冲突时使用本地版本(基本上是查找并丢弃冲突的差异,而不是像
-m2
那样避免它们),并且


让这一切变得更简单的方法是编写territory脚本,最简单的方法是将其设置为git别名

git config --global alias.poptree '!git cherry-pick -nm2 stash; git reset; git stash pop'
现在您有了一个
git-poptree
命令来做您想做的事情


编辑:作为进一步的补充,假设你在reme之前已经做了更多的工作
( index=`git write-tree` &&
  git cherry-pick -nm2 stash &&
  git read-tree $index &&
  git stash drop
)