为什么'git stash apply'应用我的变化?

n17*_*911 17 git

我做了一个改变然后我git stash和我git stash apply

我的问题是

  1. 为什么在我之后git stash apply,我的变化变得"上演"了?即如果我这样做git diff,我什么都看不到,如果我这样做,我只会看到我的不同之处git diff --cached

  2. 反正有没有"取消"我的git stash apply命令上演的变化?

  3. 是否有任何git命令基本上让我'备份我的更改,将其重置为HEAD并将我的备份复制回'?我想git stash,然后git stash apply是那个命令,但有些人如何"上演"我的所有变化?有没有相应的东西让我git stash apply没有上演我的变化部分?

Gre*_*ill 13

如果您发现您的更改意外上演,请执行以下操作:

git reset HEAD
Run Code Online (Sandbox Code Playgroud)

如果在应用隐藏的更改时存在冲突,我通常只会看到这个.在执行之前,您需要检查是否是这种情况git reset.

git stash命令是最适合您的用例的命令.我一直用它来达到这个目的.


Von*_*onC 9

为什么git stash会应用我的更改?

任何会影响工作树的东西(比如agit checkout -- afile)都会首先影响你的索引.

索引是将工作树中的东西移动到对象存储库以及将对象从对象存储库移动到工作树的中间人.

索引还用于git stash apply记录合并冲突,因为索引具有stage-n条目.见git merge:

对于冲突路径,索引文件最多可记录三个版本:

  • 阶段1存储来自共同祖先的版本,
  • HEAD的第2阶段,和
  • 来自MERGE_HEAD的第3阶段(您可以检查各阶段git ls-files -u).

在演变的历史git stash --apply中,需要注意两个有趣的事件:2011年4月(Git 1.7.5.1,提交e0e2a9c),stash删除了对应用的脏工作树检查.

在我们应用存储之前,我们确保工作树中没有不在索引中的更改.此检查可以追溯到原始版本git-stash.sh,并且可能是为了防止工作树中的更改在合并期间意外丢失.

但是,此检查有两个问题:

  1. 它过于严格.如果我的存储只更改文件" foo",但" bar"在工作树中是脏的,它将阻止我们应用存储.

  2. 这是多余的.在我们实际调用merge-recursive之前,我们根本不会触及工作树.
    但它有自己的(更准确的)检查以避免丢失工作树数据,并将通过更好的消息中止合并,告诉我们哪些路径是问题.

所以我们可以完全放弃支票.

使用索引来管理由git stash apply2015年4月检测到的另一个bug导致的合并,Git 2.4.2,提交ed178ef:

stash:需要一个干净的索引来申请

如果您在索引中已暂存内容并运行" stash apply",我们可能会遇到冲突并将新条目放入索引中.
在那时恢复到原始状态很困难,因为像" git reset --keep" 这样的工具会吹走任何上演的东西.
我们可以通过在有阶段性更改时拒绝申请来使此更安全.