当我在本地开发分支上运行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
答案 0 :(得分:9)
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的讨论部分对此进行了解释:
存储表示为提交,其树记录了状态 工作目录,它的第一个父项是HEAD时的提交 藏匿创建了。第二个父树的树记录了状态 制作藏匿时的索引,并将其作为HEAD的子节点 承诺。祖先图如下所示:
.----W / / -----H----I
其中
H
是HEAD
提交,I
是一个记录索引状态的提交,W
是一个记录状态的提交 工作树。
在你的情况下,
ef9a11b
的对象对应于索引的状态(上图中的I
),at12334
的对象对应于工作目录的状态(上图中的W
)。这两个对象(W
和I
)通常不会在git log
的输出中列出,但是如果您使用--all
标志,则会这样做。< / p>
答案 1 :(得分:9)
&#34; WIP&#34;是Work-In-Progress的首字母缩写。这意味着即使您不在自然停留点,也会暂时保存您当前的工作状态。
Stashing使用熟悉的提交/合并机制将您的工作保存在存储库中。特别是,可以通过运行gitk --reflog
来查看上下文中所有当前存储的项目,尽管只有最新的存储将标有stash
。常规提交和存储之间的一个重要区别是,当删除被删除时(例如通过git stash clear
),它们在reflog中不再可见,因此更难以恢复。
藏匿通常分两部分进行:
如果您自上次提交后仍未执行任何add
操作,则索引提交将为空。但是,即使索引为空,它仍然会被提交。 The subsequent implicit merge can complicate things例如,如果你想从藏匿处挑选,以避免与git stash pop
相关的某些复杂情况。
Git的存储机制很聪明,powerful并且很有用,但它也很复杂,容易出错并且很危险。我最近的做法是避免使用git stash
支持使用git commit -a -m "stash"
来保存我的工作和git reset HEAD~1
(在查看&#34; stash&#之后)获得类似的结果34;承诺)恢复它。
这使得git stash
最有用的应用程序只是一个快速的方法来消除所有本地更改,如果你知道你不再需要它们。
顺便说一句,你可以删除&#34; WIP&#34;和&#34;索引&#34;通过运行git stash clear
从您的日志提交 - 但如果您只将有价值的工作保存在存储,则不要这样做。