如何恢复隐藏的未提交更改

我的开发分支中有一些未提交的更改,我使用git stash将它们隐藏起来,但是在这些隐藏的更改中有一些非常重要的更改。有什么方法可以恢复这些更改吗?

此外,从那以后,我在隐藏的代码文件之上进行了一些更改。

如果可能的话,我是否有机会检索对新分支的隐藏更改?

972424 次浏览
git stash pop

会让一切回到原位

正如注释中建议的那样,您可以使用git stash branch newbranch将存储应用于新分支,这与运行相同:

git checkout -b newbranchgit stash pop

简单问题的简单答案是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新手来说,它应该是一样的。(你可以跳过其余的部分!)


如果你正在做更高级或更复杂的事情呢?

可以说,至少有三四种不同的“使用git stash的方法”。以上是“方法1”,即“简单方法”:

  1. 您从一个干净的分支开始,正在进行一些更改,然后意识到您在错误的分支中进行了更改。您只想将现在的更改“移动”到另一个分支。

这是上面描述的简单情况。运行git stash save(或普通git stash,同样的事情)。检查另一个分支并使用git stash apply。这让Git使用Git相当强大的合并机制合并你之前的更改。仔细检查结果(与git diff)看看你是否喜欢它们,如果你喜欢,使用git stash drop来删除存储。你完成了!

  1. 你开始了一些更改并隐藏了它们。然后你切换到另一个分支并开始了更多的更改,忘记了你有隐藏的。

现在你想保持,甚至移动,这些更改,也应用你的藏匿。

事实上,你可以再次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对我来说比stash@{12}更重要。(git stash命令需要一个可选的保存消息,这些可以帮助,但不知何故,我所有的存储最终都被命名为WIP on branch。)

  1. (高级)在运行git stash save之前,你已经使用了git stash save -p,或者仔细地使用了git add ed和/或git rm ed特定的代码位。你在隐藏的索引/暂存区域有一个版本,在工作树中有另一个(不同的)版本。你想保留这一切。所以现在你使用git stash apply --index,这有时会失败:

    Conflicts in index.  Try without --index.
  2. 您正在使用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 branchgit checkout -b temp     # create new temp branch to save stuffgit add ...              # add (and/or remove) stuff as neededgit 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 a new branch for "apply"git stash apply          # apply stashed changes; see below about --index

要记住的主要事情是,“stash”是一个提交,它只是一个稍微“有趣/奇怪”的提交,而不是“在分支上”。apply操作查看提交更改了什么,并试图在你现在的任何地方重复它。藏匿仍将在那里(apply将它保留在周围),所以你可以更多地查看它,或者决定这是一个错误的地方来apply它,然后以不同的方式再次尝试,或者其他什么。


任何时候你有一个存储,你可以使用git stash show -p来查看存储的简化版本。(这个简化版本只看“最终工作树”的更改,没有保存的索引更改,--index单独恢复。)命令git stash apply,没有--index,只是尝试现在在你的工作树中进行相同的更改。

即使您已经有了一些更改,这也是正确的。apply命令很乐意将存储应用于修改工作树(或者至少尝试应用它)。例如,您可以这样做:

git stash apply stash      # apply top of stash stackgit stash apply stash@{1}  # and mix in next stash stack entry too

你可以在这里选择“应用”顺序,选择特定的存储以特定的顺序应用。但是,请注意,每次你基本上都在做“git合并”,并且正如合并留档警告的那样:

运行具有非平凡未提交更改的git合并气馁:虽然可能,但它可能会让你处于一种艰难的状态在冲突的情况下退出。

如果你从一棵干净的树开始并且正在执行几个git apply操作,很容易退出:使用git reset --hard回到干净状态,并更改您的apply操作。(这就是为什么我建议首先从干净的工作树开始,对于这些复杂的情况。)


那么最糟糕的情况呢?

假设你正在做大量的高级Git东西,并且你已经做了一个藏匿,并且想要git stash apply --index,但是不再可能将保存的藏匿应用于--index,因为分支自你保存它以来已经分歧太多了。

这就是git stash branch的作用。

如果您:

  1. 看看你做最初的stash时在做的确切提交,然后
  2. 创建一个新的分支,最后
  3. git stash apply --index

重新创建更改的尝试肯定会奏效。这就是git stash branch newbranch所做的。(然后它会删除存储,因为它已成功应用。)


关于--index的最后几句话(它到底是什么?)

--index的作用很容易解释,但内部有点复杂:

  • 当你有变化时,你必须在commit-ing之前git add(或“阶段”)它们。
  • 因此,当您运行git stash时,您可能编辑了文件foozorg,但只暂存了其中一个。
  • 因此,当你要求取回存储时,如果它git addadded的事情并没有git add非添加的事情可能会很好。也就是说,如果你是add edfoo但不是zorg在你做stash之前回来,拥有完全相同的设置可能会很好。上演的,应该再次上演;修改但未上演的,应该再次修改但不上演。

--indexapply的标志尝试以这种方式设置。如果你的工作树是干净的,这通常只是有效的。但是,如果你的工作树已经有了add-ed的东西,你可以看到这里可能存在一些问题。如果你省略了--indexapply操作不会尝试保留整个分阶段/非分阶段设置。相反,它只是调用Git的合并机制,使用"藏匿袋"中的工作树提交。如果你不关心保留分阶段/非分阶段,省略--index会让git stash apply更容易做它的事情。

为了使这个简单,你有两个选项来重新应用你的藏匿:

  1. git stash pop-恢复到保存状态,但它会从临时存储中删除存储。
  2. git stash apply-恢复到保存状态并保留存储列表以供以后重用。

您可以在本文中阅读有关git藏匿的更多详细信息。

要检查您的藏匿内容:-

git存储列表

从藏匿列表中应用特定藏匿编号:-

git stash应用stash@{2}

或者只申请第一个藏匿:-

git stash pop

备注: git stash pop将从您的藏匿列表中删除藏匿,而git stash应用不会。所以相应地使用它们。

在Mac上,这对我很有效:

git stash list(查看你所有的stash)

git stash list

git stash应用(只是您想要从存储列表中获得的数字)

像这样:

git stash apply 1

您可以使用以下方法隐藏未提交的更改:

git stash

然后使用以下命令签出到新分支:

git checkout -b

然后应用隐藏的提交:

git stash apply

您可以在git bash中使用单个命令

git stash pop

正如许多人所说,做git stash apply stash@{1}将获得当前分支的更改,我不知道为什么这对我不起作用。

对我来说,做git stash apply stashNumber总是有效的。

例如-如果我想检索藏匿号1,那么这是如何做到的-git stash apply 1

PS:您可以使用pop代替apply…唯一的区别是apply不会删除存储,但执行pop会删除您弹出的存储号。