存储后出现的那些“WIP”和“索引”提交是啥?
Posted
技术标签:
【中文标题】存储后出现的那些“WIP”和“索引”提交是啥?【英文标题】:What are those 'WIP' and 'index' commits that appear after stashing?存储后出现的那些“WIP”和“索引”提交是什么? 【发布时间】:2014-11-19 05:22:02 【问题描述】:当我在本地开发分支上运行git lg
时,最新提交如下所示:
* 7d21213 - (1 hours ago) update business rules - developer1 (HEAD, origin/develop, origin/HEAD, develop)
但是,如果我通过运行 git stash
存储本地更改,然后运行 git lg
,我会得到以下信息:
* at12334 - (13 seconds ago) WIP on develop: 7d21213 update business rules - developer1 (refs/stash)
|\
| * ef9a11b - (14 seconds ago) index on develop: 7d21213 update business rules - developer1
|/
* 7d21213 - (1 hours ago) update business rules - developer1 (HEAD, origin/develop, origin/HEAD, develop)
这是什么意思?似乎在存储后创建了两个新提交(标记为 index
和 WIP
)。是这样吗?如果是这样,这种提交背后的逻辑是什么?
注意
git lg
是在测试环境中已经定义为的别名
git log --graph --abbrev-commit --decorate --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)' --all
【问题讨论】:
【参考方案1】:“WIP”是Work-In-Progress 的首字母缩写。它的意思是建议您暂时保存工作的当前状态,即使您没有处于自然停止点。
Stashing 使用熟悉的提交/合并机制将您的工作保存在存储库中。特别是,可以通过运行gitk --reflog
在上下文中查看所有当前隐藏的项目,尽管只有最近的存储将标记为stash
。常规提交和存储之间的一个重要区别是,当存储被删除时(例如通过git stash clear
),它们在 reflog 中不再可见,因此更难恢复。
存储通常分为两部分:
-
自上次提交以来已“添加”的任何内容都会执行“索引”提交。
“WIP”提交是作为工作状态和索引提交之间的合并执行的。
如果自上次提交后您还没有执行任何add
操作,则索引提交将为空。但是,即使索引为空,它仍然会被提交。 The subsequent implicit merge can complicate things,例如,如果您想从藏匿处挑选,以避免与 git stash pop
相关的某些并发症。
Git 的存储机制很聪明,powerful,而且很有用,但它也很复杂,容易出错,而且很危险。我最近的做法是避免使用git stash
,而是使用git commit -a -m "stash"
来保存我的工作并使用git reset HEAD~1
(在签出“stash”提交之后)来恢复它。
这使得git stash
最有用的应用程序成为一种快速摆脱所有本地更改(如果您知道不再需要它们)的方法。
顺便说一句,您可以通过运行 git stash clear
从日志中删除“WIP”和“索引”提交——但如果您的有价值的工作仅保存在存储中,请不要这样做强>。
【讨论】:
存储库的一个有价值的用途是在你重新设置/合并上游更改时将正在进行的工作保持片刻——因为 git 不允许你在有未完成的更改时进行重新设置. 有时您稍后会回来并希望您可以对自己的帖子进行投票。git commit -a -m "WIP"
的“+1”作为 git stash
的更好替代品。
git stash
在 rebase 期间很有用——如果您想回溯一点以进行评估和测试以及更早的 rebase 提交。我不知道是否有另一种方法可以复制 git stash
在这种情况下所做的事情。
在签出“stash”提交之后是什么意思?
@rvcristiand:我在这里把“stash”放在引号中,因为它指的是我的 simulated stash(带有提交消息“stash”)——而不是指实际“git stash”,我正在避免。你可以检查一个特定的提交——最好的方法通常是检查一个指向它的分支。关键是git stash
是一个方便的工具,可以使用正常的提交/签出机制(可能更安全)轻松模拟。【参考方案2】:
git lg
?什么git lg
?
请注意,lg
不是本地 Git 动词。诚然,很多人使用名为lg
的别名,通常对应于
git log --all --oneline --graph --decorate
这个定义似乎就是您在这里使用的定义。但是,别名是本地的; git lg
在您的配置中的含义可能与 Bob 和 Alice 的配置中的含义不同。
因此,您应该始终在问题中包含相关别名的定义,以便我们(Stack Overflow 用户)可以与您在同一页面上,并且确切地知道您运行时会发生什么
git <alias>
(git lg
,这里)。
神秘物体是什么
这在git-stash
man page的讨论部分中有解释:
一个 stash 表示为一个提交,其树记录了 工作目录,它的第一个父级是 HEAD 的提交,当 stash 已创建。第二个父节点的树记录了 存储时的索引,它是 HEAD 的子项 犯罪。祖先图如下所示:
.----W / / -----H----I
其中
H
是HEAD
提交,I
是记录索引状态的提交,W
是记录索引状态的提交 工作树。
在你的情况下,
短 SHA 为ef9a11b
的对象对应于您的索引状态(上图中的I
),
短 SHA 为at12334
的对象对应于您的工作目录的状态(上图中的W
)。
这两个对象(W
和I
)通常不会在git log
的输出中列出,但如果您使用--all
标志,它们会列出。
【讨论】:
感谢您的回复,我对您提出的问题进行了改进。您是否有任何进一步的解释为什么需要记录索引的状态。存储后工作树的状态发生了变化,为了能够恢复它,我们需要保留它,没关系。但是索引也改变了吗?此外,可以在一周和几次提交后弹出 stash。恢复索引真的重要吗? 您需要为索引记录一个不同的对象,因为索引的状态不一定与工作树的状态相对应。例如,您可以对文件进行本地修改,暂存这些更改(将它们添加到索引中),进行更多修改,但不暂存它们;工作树和索引将不同。至于为什么要保存索引的状态(以及工作树的状态)......也许为下一次提交暂存文件是一项非常细致和乏味的任务,你不想必须从头开始。 例如,如果将两行添加到文件 A 并将更改添加到索引。之后再将两行添加到同一个文件中。我们可以说一半的更改存储在工作树中,另一半是索引。因此,为了在存储后恢复文件,索引和工作副本都将被存储。 @stackr 就是这样,是的。以上是关于存储后出现的那些“WIP”和“索引”提交是啥?的主要内容,如果未能解决你的问题,请参考以下文章