ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

你试过使用'stash pop'吗?
不,实际上我是 git 新手。由于我不完全了解所有命令,因此我没有尝试其他任何命令!我不想失去那些变化。
如果您不想丢失隐藏的更改,请尝试使用“git stash apply”。这会将隐藏的更改应用到您当前的分支,同时仍保留存储。如果一切正常,应用存储后,您可以使用“git stash drop”删除存储

t
torek

简单问题的简单答案是 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”,“简单方式”:

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

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

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

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

实际上,您可以再次git stash save,因为 git stash 会进行“堆栈”更改。如果你这样做,你有两个 stashes,一个叫 stash——但你也可以写 stash@{0}——一个拼写为 stash@git stash save。使用 git stash list(随时)查看所有内容。最新的总是编号最低的。当您 git stash drop 时,它会丢弃最新的,而之前为 stash@git stash save 的将移至堆栈顶部。如果你有,甚至更多,那个是 stash@{2} 变成 stash@git stash save,依此类推。

您也可以先apply,然后再drop 一个特定的存储:git stash apply stash@drop,依此类推。删除特定的存储只会重新编号编号较高的存储。同样,没有数字的也是stash@{0}

如果你堆积了很多存储,它会变得相当混乱(我想要的存储是 stash@{7} 还是 stash@{4}?等等,我刚刚推了另一个,现在它们是 8 和 5?)。我个人更喜欢将这些更改转移到新分支,因为分支有名称,而且 cleanup-attempt-in-December 对我来说比 stash@{12} 更重要。 (git stash 命令需要一个可选的保存消息,这些可以提供帮助,但不知何故,我所有的存储最终都命名为 WIP on branch。)

(超高级)在运行 git stash save -p 之前,您已经使用了 git stash save -p,或者仔细 git add-ed 和/或 git rm-ed 代码的特定位。您在隐藏的索引/暂存区域中有一个版本,在工作树中有另一个(不同的)版本。你想保留这一切。所以现在你使用 git stash apply --index,有时会失败:索引冲突。尝试不使用--index。您正在使用 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 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 merge”时,并且正如合并文档所警告的那样:

不鼓励使用非平凡的未提交更改运行 git merge:虽然可能,但它可能会使您处于在发生冲突时难以退出的状态。

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

那么最坏的情况呢?

假设您正在做很多高级 Git 东西,并且您已经创建了一个存储,并且想要 git stash apply --index,但是不再可能使用 --index 应用保存的存储,因为自从你保存它的时间。

这就是 git stash branch 的用途。

如果你:

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

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

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

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

当您有更改时,您必须在提交之前 git add (或“暂存”)它们。

因此,当您运行 git stash 时,您可能已经编辑了文件 foo 和 zorg,但只暂存了其中一个。

因此,当您要求取回存储时,如果它 git 添加添加的东西而不是 git 添加未添加的东西可能会很好。也就是说,如果您在进行 stash 之前添加了 foo 而不是 zorg,那么拥有完全相同的设置可能会很好。上演过的,应该再上演一次;已修改但未上演的内容应再次修改但未上演。

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


我不明白你的评论。你的意思是:你跑了git stash pop?或者您的意思是:您编辑了一些文件,但还没有再次运行 git stash?或者你的意思完全不同?
是的。请注意,在我的(长)编辑中,我建议在 apply 隐藏之前提交您现在拥有的内容。您不必必须执行此操作,但它使您查看起来更简单。您可以稍后使用 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 的命名约定有很多不足之处(我们可以为“远程”、“跟踪”和“分支”这几个词赋予多少不同的含义?!)。值得注意的是,您可以将存储应用于与原始存储无关的内容。
N
Nagendra Rao
git stash pop

会让一切恢复原状

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

git checkout -b newbranch
git stash pop

谢谢您的帮助。我可以将这些更改放入新分支吗?现在我在开发分支
git stash branch newbranch,将使用隐藏的更改创建一个新分支。
@robert:git stash branch newbranch 确实会这样做;但请注意,它会创建新分支,其父级设置为 stash 完成时的 HEAD 提交。换句话说,这是为了当你在长时间的黑客会议或其他什么之后回来时,盯着那些乱七八糟的东西,然后决定“我应该把它放在一个分支上,而不是藏起来”:-)
我已经编辑了我的问题。如果可能的话,我想把这些更改放到一个新的分支上。
@sachinruk 有时?总是,人们不会来 StackOverflow 获取文档,这不是目的,因此,我不是批评写得很好的答案,也不是捍卫 1 班轮。
S
Shivansh Rajolia - HeLleR

检查您的存储内容:-

git 存储列表

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

git stash apply stash@{2}

或仅应用第一个存储:-

git stash 弹出

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


N
Nesha Zoric

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

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

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


Z
Zack117

在 Mac 上,这对我有用:

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

git stash list

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

像这样:

git stash apply 1

S
SherylHohman

您可以使用以下方法存储未提交的更改:

git stash

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

git checkout -b

然后应用隐藏的提交:

git stash apply