小编典典

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

all

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

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

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


阅读 102

收藏
2022-03-01

共1个答案

小编典典

简单问题的简单答案是git stash apply

只需检查您想要更改的分支,然后git stash apply. 然后使用git diff来查看结果。

在你完成所有更改之后——他apply看起来不错,你确定你不再需要存储了—— 然后git stash drop它来摆脱它。

我总是建议使用git stash apply而不是git stash pop.
不同之处在于,apply留下存储以便于重试apply或查看等。如果pop能够提取存储,它也会立即提取drop它,如果您随后意识到您想在其他地方提取它(在不同的分支中),或者
with --index,或者类似的,这并不容易。如果你apply 可以选择什么时候去drop

无论如何,这一切都很次要,对于 Git 的新手来说,应该差不多。(你可以跳过所有其他的!)


如果您正在做更高级或更复杂的事情怎么办?

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

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

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

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

现在您想保留甚至移动 这些 更改, 应用您的存储。

实际上,您可以git stash save再次git stash进行“堆栈”更改。如果你这样做,你有两个藏匿处,一个只是叫做stash“ut
you can also write stash@{0}”,一个是拼写stash@{1}。使用git stash list(随时)查看所有内容。最新的总是编号最低的。当 you 时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 -p(超高级)git addgit rm运行git stash save. 您在隐藏的索引/暂存区域中有一个版本,在工作树中有另一个(不同的)版本。你想保留这一切。所以现在你使用git stash apply --index, 有时会失败:

    Conflicts in index.  Try without --index.
    
  2. 您正在使用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

现在你处于一个“干净”的起点。或者它可能更像这样:

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 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 的东西,并且你已经做了一个 stash,并且想要git stash apply --index,但是它不再可能应用保存的
stash,--index因为自从你保存它以来分支已经分歧太多了。

这是git stash branch为了什么。

如果你:

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

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


最后说几句--index(这到底是什么?)

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

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

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

2022-03-01