git stash apply 仅恢复未暂存的文件
git stash apply recovered only unstaged files
我在分支 A 上更改了大约 24 个文件。None 其中已提交。其中一些有变化的文件,比如 18 个是未暂存的。等6个文件上演。由于其他一些工作,我不得不结账到其他分行 B。
我在分支 A 上存储了这些更改,检出到分支 B,完成我的工作,然后又检回分支 A。
我现在做了 git stash apply。我只能看到未暂存的更改已恢复,但没有迹象表明已更改和已暂存的文件更改。
任何人都可以帮助我如何恢复这些暂存但未提交的更改?
你可以:
- 放弃您当前的更改(例如:
git checkout .
),
- 运行
git stash apply --index
当您创建存储(使用 git stash
)时,git 会存储您的存储库的两个快照:您当前的索引(当前暂存文件的状态)和您当前的工作树(磁盘上文件的状态)。
当您 运行 git stash apply
时,它只恢复您的工作树的状态;当您 运行 git stash apply --index
时,它会恢复索引(就像您隐藏更改时一样)和工作树。
在您在问题中描述的情况中:您从分支 A
隐藏起来,然后又回到了 运行 宁 git stash apply
之前的状态。因此,您可以 100% 保证在应用您的存储时不会发生冲突。
--index
选项的小改动如下:如果在 运行 宁 git stash apply --index
时发生冲突,因为 git 使用索引来存储(并让你解决)冲突,你不会真正知道冲突是来自“索引”部分还是“工作树”部分。再次强调:这不适用于您在问题中描述的情况。
您需要使用 git stash apply --index
。原因如下。
I have some 24 files changed on branch A. None of these are committed. Some of these files with changes, say 18 are unstaged. And other 6 files are staged.
值得指出的是:staged 只是意味着 在 Git 的索引 .
中更新
让我们进一步分解一下。 Git 提交有两个部分:
任何给定 Git 提交的一部分是元数据:关于 提交的信息,例如提交人、时间等.这非常有用,但现在对您来说并不重要。
该提交的另一部分是 每个文件 的已保存快照,与您(或任何人)制作时的形式一样提交。
整个提交是只读的:任何现有提交的任何部分都不能更改。此外,存储的文件 inside 提交是一种特殊的、压缩的和去重复的 Git-only 格式,只有 Git 可以 阅读。因此,不仅这些文件无法更改,您计算机上的大多数程序也无法以任何方式使用它们。这意味着在您可以 使用 提交之前,您必须 Git 提取归档文件 .
这次提取(主要)是git checkout
或git switch
的内容:你告诉Git:删除我之前提取的所有文件,我是不再对 那些 文件感兴趣。转到另一个提交并提取它的文件。现在你有了可以查看和使用的文件,甚至变化。这些可用的、可工作的文件位于 Git 所谓的 working tree 或 work-tree 中(另请参阅 git worktree
, 自 Git 2.5).
起可用
显然,如果所有文件都有一些源存档,则每个文件必须有 两个 副本:提交中的一个(仅由 Git 并且无人可写——Git 存储它的方式,它甚至可能不是一个文件),加上你的工作树中的那个(在正常的日常形式中:一个实际的 file).但是这里有一个技巧。每个文件都有一个 third“副本”。这个额外的副本——或引号中的“副本”——采用去重格式,但是,与提交中的副本不同,可以替换.我们也应该将其称为 second 副本:第一个副本在提交中,这是每个文件的 second 副本。因为它已经删除了重复数据,所以它最初只是重新使用提交的副本。因此,工作树中的普通文件是 third 副本——它始终是 copy,因为它不在 Git-仅去重格式。
第二个副本,采用 Git 的内部格式,但可以替换,存在于 Git 所称的不同的 index 中,或者暂存区,或者——现在很少见——缓存。 (名称的最后一种形式主要显示为标志,例如 git rm --cached
或 git diff --cached
)。当您在工作树文件上使用 git add
时,Git:
- 将工作树文件副本压缩为Git的内部格式;
- 检查是否重复;和
- 将正确的更新副本(新文件,或重新使用旧副本)放入 Git 的索引中。
当您 运行 git commit
、Git 实际上 制作 来自 索引中的任何内容的提交快照当时。 这就是为什么你必须经常git add
文件。你告诉Git:替换索引副本。这得到更新后的工作树复制到 Git 的索引中,准备提交。所以说 6 个文件是“暂存”的真正意思是:在下一次提交中的(比如说)400 个文件中——现在在 Git 的索引中——394 个与提交中的文件相同当前 提交,6 个与当前提交不同。
说 24 个文件“未暂存”意味着:在 Git 的索引中的(比方说)400 个文件中,376 个(400 减去 24)与我的工作树中的正常格式文件相匹配, 而 24 个则没有。
请注意,由于每个文件 有 三个副本,因此可以同时进行 阶段性更改 (文件的索引副本 file.ext
与已提交的副本不同) 和 未暂存的更改 (file.ext
的工作树副本与未来的副本不同-提交的索引副本)。那是因为 staged change 只是意味着 HEAD
-vs-index 的不同:next 提交的这个文件的副本被更新了。 Unstaged change 只是意味着索引与工作树的区别:你 可以 git add
这个文件,它会替换索引与工作树副本一起复制(Git-ified 进入下一个)提交。
git stash
所做的是:
- 保存整个索引文件集,就像在提交中一样:事实上,它确实从中进行提交,任何提交的工作方式,除了新提交不在任何分支上;然后
- 对于 Git 索引中存在的每个文件,
git add
工作树文件,并从 进行提交, 结果也是如此,除了(再次)新提交不在任何分支上;然后
- 运行
git reset --hard
.
此序列有时会因您提供给 git stash
的选项而改变,但这是主要序列:Git 在 [=71] 上进行 两次提交 =]no branch,保存索引和工作树状态,然后使用git reset --hard
使索引和工作树匹配当前(HEAD
)提交。
以后,当你去恢复索引and/or工作树git stash apply
,你必须选择:
我只想应用工作树提交,完全忽略索引提交: 这是 git stash apply
。或者:
我想同时应用工作树提交 和 索引提交: 这是 git stash apply --index
.
所以Git总是保存两者,但是在apply
时候你必须选择是否使用保存索引,或不。默认为“不”。
我在分支 A 上更改了大约 24 个文件。None 其中已提交。其中一些有变化的文件,比如 18 个是未暂存的。等6个文件上演。由于其他一些工作,我不得不结账到其他分行 B。 我在分支 A 上存储了这些更改,检出到分支 B,完成我的工作,然后又检回分支 A。 我现在做了 git stash apply。我只能看到未暂存的更改已恢复,但没有迹象表明已更改和已暂存的文件更改。
任何人都可以帮助我如何恢复这些暂存但未提交的更改?
你可以:
- 放弃您当前的更改(例如:
git checkout .
), - 运行
git stash apply --index
当您创建存储(使用 git stash
)时,git 会存储您的存储库的两个快照:您当前的索引(当前暂存文件的状态)和您当前的工作树(磁盘上文件的状态)。
当您 运行 git stash apply
时,它只恢复您的工作树的状态;当您 运行 git stash apply --index
时,它会恢复索引(就像您隐藏更改时一样)和工作树。
在您在问题中描述的情况中:您从分支 A
隐藏起来,然后又回到了 运行 宁 git stash apply
之前的状态。因此,您可以 100% 保证在应用您的存储时不会发生冲突。
--index
选项的小改动如下:如果在 运行 宁 git stash apply --index
时发生冲突,因为 git 使用索引来存储(并让你解决)冲突,你不会真正知道冲突是来自“索引”部分还是“工作树”部分。再次强调:这不适用于您在问题中描述的情况。
git stash apply --index
。原因如下。
I have some 24 files changed on branch A. None of these are committed. Some of these files with changes, say 18 are unstaged. And other 6 files are staged.
值得指出的是:staged 只是意味着 在 Git 的索引 .
中更新让我们进一步分解一下。 Git 提交有两个部分:
任何给定 Git 提交的一部分是元数据:关于 提交的信息,例如提交人、时间等.这非常有用,但现在对您来说并不重要。
该提交的另一部分是 每个文件 的已保存快照,与您(或任何人)制作时的形式一样提交。
整个提交是只读的:任何现有提交的任何部分都不能更改。此外,存储的文件 inside 提交是一种特殊的、压缩的和去重复的 Git-only 格式,只有 Git 可以 阅读。因此,不仅这些文件无法更改,您计算机上的大多数程序也无法以任何方式使用它们。这意味着在您可以 使用 提交之前,您必须 Git 提取归档文件 .
这次提取(主要)是git checkout
或git switch
的内容:你告诉Git:删除我之前提取的所有文件,我是不再对 那些 文件感兴趣。转到另一个提交并提取它的文件。现在你有了可以查看和使用的文件,甚至变化。这些可用的、可工作的文件位于 Git 所谓的 working tree 或 work-tree 中(另请参阅 git worktree
, 自 Git 2.5).
显然,如果所有文件都有一些源存档,则每个文件必须有 两个 副本:提交中的一个(仅由 Git 并且无人可写——Git 存储它的方式,它甚至可能不是一个文件),加上你的工作树中的那个(在正常的日常形式中:一个实际的 file).但是这里有一个技巧。每个文件都有一个 third“副本”。这个额外的副本——或引号中的“副本”——采用去重格式,但是,与提交中的副本不同,可以替换.我们也应该将其称为 second 副本:第一个副本在提交中,这是每个文件的 second 副本。因为它已经删除了重复数据,所以它最初只是重新使用提交的副本。因此,工作树中的普通文件是 third 副本——它始终是 copy,因为它不在 Git-仅去重格式。
第二个副本,采用 Git 的内部格式,但可以替换,存在于 Git 所称的不同的 index 中,或者暂存区,或者——现在很少见——缓存。 (名称的最后一种形式主要显示为标志,例如 git rm --cached
或 git diff --cached
)。当您在工作树文件上使用 git add
时,Git:
- 将工作树文件副本压缩为Git的内部格式;
- 检查是否重复;和
- 将正确的更新副本(新文件,或重新使用旧副本)放入 Git 的索引中。
当您 运行 git commit
、Git 实际上 制作 来自 索引中的任何内容的提交快照当时。 这就是为什么你必须经常git add
文件。你告诉Git:替换索引副本。这得到更新后的工作树复制到 Git 的索引中,准备提交。所以说 6 个文件是“暂存”的真正意思是:在下一次提交中的(比如说)400 个文件中——现在在 Git 的索引中——394 个与提交中的文件相同当前 提交,6 个与当前提交不同。
说 24 个文件“未暂存”意味着:在 Git 的索引中的(比方说)400 个文件中,376 个(400 减去 24)与我的工作树中的正常格式文件相匹配, 而 24 个则没有。
请注意,由于每个文件 有 三个副本,因此可以同时进行 阶段性更改 (文件的索引副本 file.ext
与已提交的副本不同) 和 未暂存的更改 (file.ext
的工作树副本与未来的副本不同-提交的索引副本)。那是因为 staged change 只是意味着 HEAD
-vs-index 的不同:next 提交的这个文件的副本被更新了。 Unstaged change 只是意味着索引与工作树的区别:你 可以 git add
这个文件,它会替换索引与工作树副本一起复制(Git-ified 进入下一个)提交。
git stash
所做的是:
- 保存整个索引文件集,就像在提交中一样:事实上,它确实从中进行提交,任何提交的工作方式,除了新提交不在任何分支上;然后
- 对于 Git 索引中存在的每个文件,
git add
工作树文件,并从 进行提交, 结果也是如此,除了(再次)新提交不在任何分支上;然后 - 运行
git reset --hard
.
此序列有时会因您提供给 git stash
的选项而改变,但这是主要序列:Git 在 [=71] 上进行 两次提交 =]no branch,保存索引和工作树状态,然后使用git reset --hard
使索引和工作树匹配当前(HEAD
)提交。
以后,当你去恢复索引and/or工作树git stash apply
,你必须选择:
我只想应用工作树提交,完全忽略索引提交: 这是
git stash apply
。或者:我想同时应用工作树提交 和 索引提交: 这是
git stash apply --index
.
所以Git总是保存两者,但是在apply
时候你必须选择是否使用保存索引,或不。默认为“不”。