简单问题的简单答案是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 会进行“堆栈”更改。如果你这样做,你有两个 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。)
-
(超高级)在运行git stash save 之前,您已经使用了git stash save -p,或仔细git add-ed 和/或git rm-ed 代码的特定位。您在隐藏的索引/暂存区域中有一个版本,在工作树中有另一个(不同的)版本。你想保留这一切。所以现在你使用git stash apply --index,有时会失败:
Conflicts in index. Try without --index.
-
您使用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 的用途。
如果你:
- 检查确切的提交您在执行原始
stash 时所做的操作,然后
- 创建一个新分支,最后
git stash apply --index
重新创建更改的尝试肯定会奏效。这就是git stash branch <em>newbranch</em> 所做的。 (然后它会在成功应用后丢弃存储。)
关于--index 的最后一句话(到底是什么?)
--index 的作用解释起来很简单,但内部有点复杂:
- 当您有更改时,您必须在
commit-ing 之前git add(或“暂存”)它们。
- 因此,当您运行
git stash 时,您可能编辑了 foo 和 zorg 两个文件,但只修改了其中一个。
- 因此,当您要求取回存储时,如果它
git adds added 的事情并且不 git add 未添加的事情可能会很好。也就是说,如果您是 add-ed foo 而不是 zorg 在您执行 stash 之前,那么拥有完全相同的设置可能会很好。上演过的,应该再上演一次;已修改但未暂存的内容应再次修改但未暂存。
apply 的 --index 标志试图以这种方式进行设置。如果您的工作树是干净的,这通常可以正常工作。但是,如果您的工作树已经有 add-ed 的东西,您可以看到这里可能存在一些问题。如果您忽略 --index,apply 操作不会尝试保留整个暂存/未暂存设置。相反,它只是调用 Git 的合并机制,使用 "stash bag" 中的工作树提交。如果您不关心保留暂存/未暂存,则省略 --index 可以让 git stash apply 更轻松地完成任务。