【问题标题】:How to recover stashed uncommitted changes如何恢复隐藏的未提交更改
【发布时间】:2013-09-30 22:22:34
【问题描述】:

我的开发分支中有一些未提交的更改,我使用git stash 隐藏了它们,但在这些隐藏的更改中有些更改非常重要。有没有办法恢复这些更改?

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

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

【问题讨论】:

  • 你试过使用'stash pop'吗?
  • 没有。实际上我是 git 的新手。由于我不完全了解所有命令,因此我没有尝试其他任何命令!我不想失去这些变化。
  • 如果您不想丢失隐藏的更改,请尝试使用“git stash apply”。这会将隐藏的更改应用到您当前的分支,同时仍保留存储。如果一切正常,应用存储后,您可以使用 'git stash drop' 删除存储
  • @robert 感谢您提供的简单答案,而不是接受的(对于新手而言)极其复杂的答案。

标签: git git-stash


【解决方案1】:
git stash pop

一切都会恢复原状

按照 cmets 的建议,您可以使用 git stash branch newbranch 将 stash 应用到新分支,这与运行相同:

git checkout -b newbranch
git stash pop

【讨论】:

  • 感谢您的帮助。我可以将这些更改放入新分支吗?现在我在开发分支上
  • git stash branch newbranch,将使用隐藏的更改创建一个新分支。
  • @robert: git stash branch newbranch 确实会这样做;但请注意,它会创建新分支,其父级设置为在完成stash 时提交的HEAD。换句话说,它是为了当你在经过长时间的 hack 会议或其他任何事情后回来时,盯着那些乱七八糟的东西,然后决定“我应该把它放在一个分支上,而不是藏起来”:-)
  • 有时您只需要 TLDR 答案:)
  • @sachinruk 有时?总是,人们不会来 StackOverflow 获取文档,这不是目的,因此,我不是批评写得好的答案,也不是捍卫 1 班轮。
【解决方案2】:

简单问题的简单答案是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——但你也可以写 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 来测试“将要提交的内容”。这个超出了这个答案的范围;请参阅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 a 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 合并”时,并且正如合并文档所警告的那样:

运行带有非平凡未提交更改的 git merge 是 气馁:虽然可能,但它可能会让你处于艰难的状态 在发生冲突时退出。

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


最坏的情况呢?

假设你正在做很多高级 Git 的东西,并且你已经做了一个存储,并且想要 git stash apply --index,但是不再可能使用 --index 应用保存的存储,因为分支也已经分歧了距离你保存它的时间已经很久了。

这就是git stash branch 的用途。

如果你:

  1. 检查确切的提交您在执行原始stash 时所做的操作,然后
  2. 创建一个新分支,最后
  3. git stash apply --index

重新创建更改的尝试肯定奏效。这就是git stash branch <em>newbranch</em> 所做的。 (然后它会在成功应用后丢弃存储。)


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

--index 的作用解释起来很简单,但内部有点复杂:

  • 当您有更改时,您必须在commit-ing 之前git add(或“暂存”)它们。
  • 因此,当您运行 git stash 时,您可能编辑了 foozorg 两个文件,但只修改了其中一个。
  • 因此,当您要求取回存储时,如果它 git adds added 的事情并且 git add 未添加的事情可能会很好。也就是说,如果您是 add-ed foo 而不是 zorg 在您执行 stash 之前,那么拥有完全相同的设置可能会很好。上演过的,应该再上演一次;已修改但未暂存的内容应再次修改但未暂存。

apply--index 标志试图以这种方式进行设置。如果您的工作树是干净的,这通常可以正常工作。但是,如果您的工作树已经有 add-ed 的东西,您可以看到这里可能存在一些问题。如果您忽略 --indexapply 操作不会尝试保留整个暂存/未暂存设置。相反,它只是调用 Git 的合并机制,使用 "stash bag" 中的工作树提交。如果您不关心保留暂存/未暂存,则省略 --index 可以让 git stash apply 更轻松地完成任务。

【讨论】:

  • 我不明白你的评论。你的意思是:你跑了git stash pop?或者您的意思是:您编辑了一些文件,但还没有再次运行git stash?或者你的意思完全是别的?
  • 是的。请注意,在我的(长)编辑中,我建议在apply-ing 存储之前提交您现在拥有的内容。您不必必须执行此操作,但它使您查看起来更简单。您可以稍后使用rebase -i 将多个提交压缩在一起,或者挑选特定的更改或其他任何内容。
  • 是的:git stash apply --index(记住两个破折号)。如果你忽略--index,没什么大不了的; --index 的唯一要点是保持分阶段/非分阶段设置。 (您可能一开始可能没有任何特殊设置。)然后git status 等,并根据需要添加/提交等。当(且仅当)您完成所有存储时,使用git stash drop 来丢弃它。
  • 只要您保留(不要droppop)存储,您在提交时始终拥有安全的原始存储代码,因为存储一个承诺!如果您想准确地取回它,但在分支上,请使用git stash branch(请参阅上面的那部分,或Shunya's answer 中的Pro Git book)。然后你可以git checkout那个分支,或者git cherry-pick那个分支的提交,等等。
  • @ChuckWolber:Git 的命名约定还有很多不足之处(我们可以为“远程”、“跟踪”和“分支”这几个词赋予多少不同的含义?!)。值得注意的是,您可以将存储应用于与原始存储无关的内容。
【解决方案3】:

为了简单起见,您有两个选项可以重新应用您的存储:

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

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

【讨论】:

  • 谢谢,伙计,非常有帮助。
【解决方案4】:

检查您的存储内容:-

git 存储列表

从存储列表中应用特定的存储编号:-

git stash apply stash@{2}

或仅应用第一个存储:-

git stash pop

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

【讨论】:

    【解决方案5】:

    在 mac 上这对我有用:

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

    git stash list
    

    git stash apply(只是你想要的存储列表中的数字)

    像这样:

    git stash apply 1
    

    【讨论】:

      【解决方案6】:

      您可以使用“git stash”存储未提交的更改,然后使用“git checkout -b”签出到新分支,然后应用隐藏的提交“git stash apply”

      【讨论】:

        猜你喜欢
        • 2011-03-15
        • 2020-05-15
        • 1970-01-01
        • 2023-03-04
        • 2016-08-15
        • 2012-08-15
        • 2016-03-15
        • 2011-08-14
        • 2018-07-01
        相关资源
        最近更新 更多