我在开发分支中进行了一些未提交的更改,并使用git stash
进行了隐藏,但是其中一些更改在这些已隐藏的更改中非常重要。有什么办法找回这些更改吗?
另外,自此以后,我对隐藏的代码文件进行了一些更改。
如果有可能,我是否有可能将隐藏的更改检索到新分支?
git stash apply
只需签出要进行更改的分支,然后git stash apply
。然后使用git diff
查看结果。
完成所有更改后( apply
看起来不错,并且确定不再需要存储),然后使用git stash drop
摆脱它。
我总是建议使用git stash apply
而不是git stash pop
。区别在于apply
留下存储区,以便于重试apply
或查看等操作。如果pop
能够提取存储区,它也会立即drop
其删除,并且如果您突然意识到自己想要要将其提取到其他位置(在不同的分支中),或者使用--index
或类似的方法,并不是那么容易。如果您apply
,则可以选择何时drop
。
但是,无论哪种方式,它都相当次要,对于 git 的新手来说,它应该大致相同。 (并且您可以跳过所有其他步骤!)
至少有 3 或 4 种不同的 “使用 git stash 的方式”。上面是针对 “方法 1” 的 “简单方法”:
您从一个干净的分支开始,正在进行一些更改,然后意识到您在错误的分支中进行了更改。您只想进行现在的更改,然后将其 “移动” 到另一个分支。
如上所述,这是简单的情况。运行git stash save
(或普通的git stash
,同样的东西)。签出另一个分支,并使用git stash apply
。使用 git 强大的合并机制,可以使 git 合并到您的早期更改中。仔细检查结果(使用git diff
)以查看是否喜欢它们,如果愿意,请使用git stash drop
放下隐藏物。你完成了!
您开始了一些更改并将其隐藏。然后,您切换到另一个分支并开始更多更改,而忘记了已藏匿的分支。
现在,您要保留甚至移动这些更改,并也应用存储。
实际上,您可以git stash save
,因为git stash
会使更改 “堆叠”。如果这样做,则有两个stash
,一个仅称为存储 - 但您也可以编写stash@{0}
- 和一个拼写的stash@{1}
。使用git stash list
(随时)查看它们。最新的始终是编号最小的。当您git stash drop
,它会丢弃最新的,然后将stash@{1}
移到堆栈的顶部。如果您拥有更多,则stash@{2}
会变成stash@{1}
,依此类推。
您也可以apply
然后drop
特定的存储: git stash apply stash@{2}
,依此类推。删除特定的存储区,仅对编号较高的存储区重新编号。同样,没有数字的那个也是stash@{0}
。
如果您堆积了很多存储卡,它可能会变得很凌乱(是我想要stash@{7}
还是stash@{4}
?是,我只是推了另一个存储卡,现在它们是 8 和 5?)。 。我个人更喜欢将这些更改转移到新分支,因为分支具有名称,并且cleanup-attempt-in-December
Decempt 对我而言比stash@{12}
得多。 ( git stash
命令采用了可选的保存消息,它们可以提供帮助,但是以某种方式,我所有的存储都只是WIP on branch
。)
(高级)您已经使用git stash save -p
,或者git stash save
git add
-ed 和 / 或git rm
-ed 代码的特定位。在隐藏的索引 / 暂存区中有一个版本,在工作树中有另一个(不同的)版本。您要保留所有这些。因此,现在您使用git stash apply --index
,有时会失败,并显示以下信息:
Conflicts in index. Try without --index.
您正在使用git stash save --keep-index
来测试 “将提交的内容”。这个问题超出了答案的范围。请参阅此其他 StackOverflow 答案。
对于复杂的情况,建议您首先提交一个 “干净的” 工作目录,方法是提交您现在所做的任何更改(如果需要,可以在新分支上)。这样,您正在应用它们的 “某处” 就没有其他任何东西了,而您只是在尝试隐藏的更改:
git status # see if there's anything you need to commit
# uh oh, there is - let's put it on a new temp branch
git checkout -b temp # create new temp branch to save stuff
git add ... # add (and/or remove) stuff as needed
git commit # save first set of changes
现在您处于 “干净” 的起点。也许它更像是这样:
git status # see if there's anything you need to commit
# status says "nothing to commit"
git checkout -b temp # optional: create new branch for "apply"
git stash apply # apply stashed changes; see below about --index
要记住的主要事情是,“存储”是一个提交,只是一个稍微 “有趣 / 怪异” 的提交,而不是 “在分支上”。 apply
操作将查看提交更改的内容,并尝试在您现在的任何位置重复执行。存放处仍会存在( apply
可以保留它),因此您可以对其进行更多查看,或者确定这是错误的位置,以其他方式apply
它,或者进行其他操作。
任何时候您都有存储库,都可以使用git stash show -p
查看存储库中内容的简化版本。 (此简化版本仅查看 “最终工作树” 的更改,而不--index
单独恢复的已保存索引更改git stash apply
命令,不带--index
,仅尝试在工作中进行相同的更改,现在的目录。
即使您已经进行了一些更改,也是如此。 apply
命令很乐意将存储区应用到修改后的工作目录(或至少尝试应用它)。例如,您可以执行以下操作:
git stash apply stash # apply top of stash stack
git stash apply stash@{1} # and mix in next stash stack entry too
您可以在此处选择 “应用” 顺序,挑选出特定的存储区以特定的顺序进行应用。但是请注意,每次您基本上都在进行 “git merge”,并且如合并文档所警告:
不建议运行 git merge 并进行重要的,未提交的更改:虽然可能,但可能会导致您陷入冲突中难以退缩的状态。
如果您从一个 clean 目录开始并且仅执行几个git apply
操作,则很容易git reset --hard
返回到 clean 状态,并更改您的apply
操作。 (因此,对于这些复杂的情况,我建议首先从一个干净的工作目录开始。)
假设您正在做很多高级 Git Stuff,并且已经做了一个存储,并且想要git stash apply --index
,但是不再可以用--index
来应用保存的存储,因为分支已经分开自您保存时间以来过多。
这就是git stash branch
的用途。
如果你:
stash
时的确切提交,然后git stash apply --index
重新创建更改的尝试肯定会奏效。这就是git stash branch <em>newbranch</em>
所做的。 (然后,由于成功应用了存储,它会删除该存储。)
--index
最后几句话(到底是什么?) --index
作用很容易解释,但内部有点复杂:
commit
git add
(或 “登台”)它们。git stash
,您可能已经编辑了文件foo
和zorg
,但仅上演了其中一个。git add
s add
ed 东西而没有git add
未添加的东西,则可能会很好。也就是说,如果在执行stash
add
ed foo
而不zorg
,则最好具有完全相同的设置。上演过的,应该再次上演;已修改但未上演的内容应再次修改但不可上演。 apply
的--index
标志会尝试以这种方式进行设置。如果您的工作树是干净的,通常就可以了。但是,如果您的工作树已经add
东西,那么您可以在这里看到可能有一些问题。如果省略--index
,则apply
操作不会尝试保留整个暂存 / 未暂存的设置。相反,它只是使用 “存储袋” 中的工作树提交来调用 git 的合并机制。如果您不关心保留暂存 / 未暂存,则省略--index
可以使git stash apply
更容易执行此操作。
git stash pop
将一切恢复原状
如注释中所建议,您可以使用git stash branch newbranch
将隐藏应用到新分支,这与运行相同:
git checkout -b newbranch
git stash pop
为简单起见,您有两种选择可以重新应用存储:
git stash pop
恢复到保存状态,但会从临时存储中删除该存储。git stash apply
恢复到保存状态,并保留存储列表,以备日后重用。您可以在本文中详细了解有关git stash 的信息。