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

问题描述 投票:548回答:4

我在开发分支中有一些未提交的更改,我使用git stash将它们藏起来,但是有一些变化在那些被隐藏的变化中非常重要。有没有办法找回这些变化?

此外,我已经在存储的代码文件之上做了一些更改。

如果可能的话,我是否有可能检索到新分支的藏匿更改?

git git-stash
4个回答
946
投票

这个简单问题的简单答案是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丢弃藏匿物。你完成了!
  2. 你开始做一些改变并把它们藏起来了。然后你切换到另一个分支并开始更多的更改,忘记你已经存储了。 现在,您希望保留甚至移动这些更改,并应用您的存储。 事实上你可以再次git stash save,因为git stash做出了“堆叠”的变化。如果你这样做,你有两个stashes,一个叫做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。)
  3. (超级高级)在运行git stash save -p之前,你已经使用了git add,或者仔细地使用了git rm-ed和/或git stash save-ed代码。您在stashed索引/暂存区域中有一个版本,在工作树中有另一个(不同的)版本。你想保留所有这些。所以现在你使用git stash apply --index,有时会失败: Conflicts in index. Try without --index.
  4. 您正在使用git stash save --keep-index来测试“将要提交的内容”。这个超出了这个答案的范围;相反,请参阅this other StackOverflow answer

对于复杂的情况,我建议首先在“干净”的工作目录中启动,提交您现在所做的任何更改(如果您愿意,可以在新的分支上)。这样你正在应用它们的“某个地方”就没有别的了,你只会尝试隐藏的变化:

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:尽管可能,但是在发生冲突的情况下,它可能会使您处于难以退出的状态。

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


最糟糕的情况怎么样?

假设您正在做很多高级Git Stuff,而且你已经成为藏品,并且想要使用git stash apply --index,但是不再可能将保存的藏匿点应用于--index,因为自从您保存的时间以来分支已经分歧太多了它。

这就是git stash branch的用途。

如果你:

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

尝试重新创建更改肯定会起作用。这就是git stash branch newbranch所做的。 (然后它会成功应用后丢弃存储。)


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

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

  • 当你有变化时,你必须在git adding之前使用commit(或“stage”)它们。
  • 因此,当你运行git stash时,你可能已经编辑了两个文件foozorg,但只是进行了其中一个。
  • 因此,当你要求收回藏匿物时,如果git adds是added的东西而不是git add非添加的东西可能会很好。也就是说,如果你在做add之前fooed zorg而不是stash,那么拥有完全相同的设置可能会很好。什么上演,应该再次上演;修改但未上演的内容应再次修改但不上演。

--indexapply旗帜试图以这种方式设置。如果你的工作树很干净,这通常是有效的。但是,如果您的工作树已经有了added,那么您可以看到这里可能存在一些问题。如果省略--indexapply操作不会尝试保留整个分阶段/未分阶段的设置。相反,它只是使用"stash bag"中的工作树提交来调用git的合并机制。如果你不关心保持上演/不上课,省略--indexgit stash apply更容易做到这一点。


46
投票
git stash pop

将使一切恢复原状

如评论中所建议,您可以使用git stash branch newbranch将存储应用于新分支,这与运行相同:

git checkout -b newbranch
git stash pop

15
投票

为简单起见,您有两种方法可以重新应用您的存储:

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

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


2
投票

检查您的藏匿内容: -

git stash list

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

git stash apply stash @ {2}

或仅申请第一个藏匿处: -

git stash pop

© www.soinside.com 2019 - 2024. All rights reserved.