Git 提交但保留当前索引和工作树?

Git commit but keep current index and working tree?

我经常遇到以下情况:我正处于一个复杂的操作过程中,我想尝试两种或多种从这里开始的方法。所以我可能会添加并提交,现在我可以从这一点开始,在一个或多个分支上尝试我的各种策略。

但这就是问题所在:我不想忘记到目前为止我在这个分支上对 HEAD 所做的更改。为什么?好吧,在我编码的 IDE 中,代码编辑器边缘的“更改栏”非常有用,它们标记了所有暂存和未暂存的更改。我不想失去那些改变酒吧。实际上,他们响应的是工作树和 HEAD.

之间的 diff

所以你看,我想保存我所有的工作,以便在以后需要时稳定地指向 return,但我不希望这影响 HEAD、索引和工作树。实际上,我想做一个“只是一个副本”的提交,而不改变宇宙的任何其他内容。

这是一张图表。我有这个:

A -- B -- C -- (mybranch) [and I've edited files X, Y, and Z with respect to C]

我想要这个:

             D? something that preserves the state of files X, Y, and Z
            /
A -- B -- C  -- (mybranch) [and X, Y, and Z are still _modified_ with respect to C]

基本上我想做的是将事物的状态复制到一个提交中,而不是有效地检查那个提交。有执行此操作的命令吗?

目前我发现的是这样的:

git switch -c temp
git commit -m 'hold my place just in case'
git switch -
git restore --source temp --worktree --staged -- .

但老实说我不喜欢它;不知何故,这感觉有风险。我认为,我更喜欢某种形式的 git stash push,它不会改变索引和工作树的状态。

git commit 保留当前索引和工作树,它唯一做的另一件事是更新 HEAD 以指向新提交。

git stash -k 从您当前的索引和工作树中进行了几次新提交,但是您不需要 interim-work-tree 快照,通过执行普通提交和 re-hanging HEAD 标签,

git commit
git tag snap
git reset --soft @^

或者直接做,

git tag snap $(git commit-tree -p @ -m snap `git write-tree`)

然后您可以cherry-pick随时丢弃快照。

您也可以直接执行管道命令git write-tree and git commit-tree

git branch rememberme $(git commit-tree $(git write-tree) -p HEAD)

可以很容易地包装在别名中,使分支名称成为用户输入或使用 push 来创建中间步骤的历史记录。

git stash 实际上有子命令允许“隐藏而不清除更改”:

git stash create       # creates the same commits as 'git stash push",
                       # but don't store them
git stash store <sha>  # adds commit <sha> in the stash list

您可以创建一个别名:

git config --global alias.snap '! git stash store $(git stash create)'

查看git help stash了解更多详情(例如:您可以添加git stash store -m "..."来添加自定义消息...)


相对于 git commit-tree $(git write-tree) 的好处是:git stash create 也将未暂存的内容保存在已修改的文件上。


还要注意 git stash store 基本上 git update-ref refs/stash 有一些标准化的选项,并且存储列表只是 refs/stash.

的 reflog

如果你想用另一个名字存储这些快照,你可以使用:

git update-ref -m "spapshot while working on '$commitmsg'" --create-reflog \
        refs/snap $(git stash create)

并检查 git reflog snap 以获得您的“快照”列表。

答案很有趣也很鼓舞人心,但最后我选择了来自 https://github.com/GitAlias/gitalias 的以下别名:

snapshot = !git stash push --include-untracked --message \"snapshot: $(date)\" && git stash apply \"stash@{0}\" --index

这会创建一个存储,然后立即恢复索引和工作树。你无法从表面上看出发生了什么,但现在有一个可行的 well-marked 提交,如果需要可以轻松检索。