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

时间:2013-09-25 10:56:21

标签: git git-stash

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

此外,我已经对存储的代码文件进行了一些更改。

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

6 个答案:

答案 0 :(得分:905)

简单问题的简单答案是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会制作一个"堆栈"变化如果您这样做,则会有两个存储区,一个名为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 - ed和/或git rm - 您的代码的特定位{1}}。您在stashed索引/暂存区域中有一个版本,在工作树中有另一个(不同的)版本。你想保留所有这些。所以现在使用git stash save,有时会失败:

    git stash apply --index
  4. 您正在使用Conflicts in index. Try without --index. 来测试"将要提交的内容"。这个超出了这个答案的范围;请改为this other StackOverflow answer

  5. 对于复杂的情况,我建议从" clean"工作目录首先,通过提交您现在的任何更改(如果您愿意,可以在新分支上)。就这样"某处"你正在应用它们,没有别的东西,你只是尝试隐藏的变化:

    git stash save --keep-index

    现在你正在"清洁"初始点。或者它可能更像是这样:

    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
    

    要记住的主要事情是" stash" 一个提交,它只是一个有点/有趣/怪异的"在分支机构上承诺不是""。 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

    您可以选择" apply"在这里订购,挑选特定的藏匿处以特定顺序应用。但是,请注意,每次您基本上执行" git merge"时,并且合并文档会发出警告:

      

    使用非平凡的未提交更改运行git merge          气馁:虽然可能,但可能让你陷入困境          在冲突的情况下退出。

    如果您从一个干净的目录开始并且只是进行了几次git stash apply stash # apply top of stash stack git stash apply stash@{1} # and mix in next stash stack entry too 操作,那么很容易退出:使用git apply返回清理状态,并更改您的git reset --hard操作。 (这就是为什么我建议首先在干净的工作目录中开始,对于这些复杂的情况。)


    最糟糕的情况怎么样?

    让我们说你做了很多高级Git Stuff,而且你已经成为了一个藏匿者,并希望apply,但它已经不可能了将保存的存储应用于git stash apply --index,因为自保存以来分支已经过多分歧。

    这是--index的用途。

    如果你:

    1. 查看您在执行原始git stash branch时所使用的确切提交,然后
    2. 创建一个新分支,最后
    3. stash
    4. 重新创建更改的尝试肯定工作。这就是git stash apply --index的作用。 (然后它会在成功应用之后丢弃存储。)


      关于git stash branch newbranch的最后一句话(它究竟是什么?)

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

      • 如果您有更改,则必须在--index之前git add(或#34; stage")。
      • 因此,当您运行commit时,可能已经编辑了git stashfoo这两个文件,但只上了其中一个。
      • 所以当你要求收回藏品时,如果它zorg git add件事情并且 add非添加的东西。也就是说,如果您在执行git add之前add编辑foo而不是zorg,那么拥有完全相同的设置可能会更好。什么上演,应该再次上演;修改但未上演的内容应再次修改但不上演。

      stash的{​​{1}}标志试图以这种方式进行设置。如果你的工作树很干净,这通常是有效的。但是,如果您的工作树已经有了--index内容,那么您可以看到这里可能存在一些问题。如果省略apply,则add操作不会尝试保留整个暂存/未暂存的设置。相反,它只是使用"stash bag"中的工作树提交来调用git的合并机制。如果您不关心保留暂停/未暂停,请忽略--index使apply更容易做到这一点。

答案 1 :(得分:45)

git stash pop

将一切都恢复原状

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

git checkout -b newbranch
git stash pop

答案 2 :(得分:12)

为简单起见,您有两种选择来重新应用您的藏匿处:

  1. git stash pop - 恢复到已保存的状态,但会从临时存储中删除存储。
  2. git stash apply - 恢复到已保存状态并保留隐藏列表,以便以后重复使用。
  3. 您可以在本文中详细了解git stashes

答案 3 :(得分:1)

要检查您的隐藏内容:-

  

git存储列表

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

  

git stash apply stash @ {2}

或仅应用第一个存储区:-

  

git stash pop

答案 4 :(得分:0)

在Mac上,这对我有用:

git存储列表(查看所有存储)

git stash list

git stash适用(只是您希望从存储列表中获取的数字)

像这样:

git stash apply 1

答案 5 :(得分:0)

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