Git 隐藏两个分支

Git stash two branches

是这样的情况:

  1. 我对 b运行ch A
  2. 进行了更改
  3. git stash 上 b运行ch A
  4. git checkout B
  5. 对 b运行ch B
  6. 进行了更改
  7. git stash 上 b运行ch B
  8. git checkout A
  9. git stash pop 上 b运行ch A

在上面列表的第 7 步之后,我在隐藏之前对 b运行ch A 所做的更改没有返回,但我在 b运行ch B 上所做的更改弹出b运行ch A。我在 b运行ch A 上使用了 cmd z,文件恢复到之前的状态,其中包含我所做的更改。似乎 b运行ch A 的 HEAD 移动到了 b运行ch B 的 HEAD。当我 git checkout Bgit stash pop 在那个 b运行ch: b运行ch B 对 b运行ch A 进行了所有更改,但没有对 b运行ch B 进行更改。我再次使用 cmd z恢复到我需要的 b运行ch 状态。

这在一段时间内给我带来了很多问题,直到我被允许在项目上再次提交代码(有一段时间没有人可以提交,因为在提交时自动推送到服务器,而经理没有想要服务器中的新代码,直到他们 运行 一些测试)。我怎样才能只弹出对 b运行ches 本身所做的更改而不弹出对其他 b运行ches 所做的更改?

git stash 所做的是提交。1

当然,git commit 所做的就是提交。那么为什么我们有 git stash 呢?

这些命令之间的一个显着区别是 git stash 所做的提交 不在任何 b运行ches 上。这允许你在一个 b运行ch 上 stash,然后移动到另一个 b运行ch 并在那里应用存储。换句话说,它可以让您移动正在进行的工作。

您可以经常(但并非总是)移动进行中的工作。参见 Git - checkout another branch when there are uncommitted changes on the current branch。但是,当你不能时,你可以使用git stash来解决这个问题。

另一方面,如果您想 "stash on a branch",就像您的情况一样,您最好只进行常规提交,而不是特殊的隐藏提交。这样的commit比较容易处理,也没有a bug that git stash has。你不太可能遇到这个错误,但是 "regular commits are simpler and easier to deal with"(在 b运行ches 上提交,相对于隐藏)是避免 git stash.

的一个很好的理由

如果您更喜欢使用 git stash,请注意每个新的藏品 "pushes" 之前的藏品在 "stash stack" 中更高。旧存储变成 stash@{1}stash@{1} 变成 stash@{2},依此类推。当你 drop(丢弃)或 pop(尝试应用,然后丢弃)一个藏匿处时,它上面堆叠的那些会向下移动 - 所以如果你 git stash drop stash@{3} 当你有 stash@{4}stash@{5},现在您将剩下 stash@{3}stash@{4}

您可以这样命名任何藏品,包括最近的藏品:stash@{0}stash 的含义相同。 (Git 实际上使用 stashreflog 实现了所有这些。)


1事实上,它至少两次次提交,有时是三次。两次提交存储索引和工作树状态;第三次提交(如果存在)来自 -u-a 并存储未暂存的 (-u) 或所有 (-a) 文件。工作树提交是一个非常奇怪的合并提交,索引提交作为其第二个父项,第三个提交(如果存在)作为其第三个父项。工作树提交的第一个父级和索引提交的唯一父级是您 运行 git stash.

时的当前提交

如果你绘制提交图片段——任何时候你在 Git 中做任何复杂的事情都是一个好主意——索引和工作树提交对有点悬在原始提交之外, refs/stash 引用指向该对,而不是 b运行ch 名称。它看起来几乎像一个小手提包,或者挂在树上的食物储藏室 b运行ch 以使其远离熊,或类似的东西,所以我喜欢将其称为 "stash bag"。

Torek(像往常一样)提供了一个很好的答案,但我相信这里的简洁答案只是为了注意存储包含堆栈形式的数据(后进先出)。因此,当您推送 A 的工作然后推送 B 的工作时,它会先弹出 B,然后弹出 A。因此,当您返回 A 然后进行第一个弹出时,您得到了保存的 B 工作。

弹出一个存储会重新应用最后一个存储,无论您从哪个分支存储!因此,您发布的问题是在分支 B 上创建的最后一个存储被重新应用到分支 A 上。下次,您必须指定要弹出的存储。

给定问题的解决方案:

  1. 再次隐藏当前状态
  2. 弹出最后一个
  3. 之前的存储

就这些了。

如果您键入 git stash list,将根据您给定的情况显示类似的内容

stash@{0}: WIP on branch-b
stash@{1}: WIP on branch-a

键入 git stash pop 将始终获得 stash@{0} 节点。

因此,如果您在 branch a 并且您想要在该分支中应用您的进度。根据列表,您应该键入:

git stash pop stash@{1}