gpt4 book ai didi

git - 如何修改 git stash 中的消息?

转载 作者:太空狗 更新时间:2023-10-29 14:03:27 25 4
gpt4 key购买 nike

假设我太快将一个存储放入 git,并且没有提供信息性存储消息。我想修改存储中的消息,但无法从 git 文档中找到执行此操作的方法。我可以让 repo 进入干净状态,然后 pop 存储并重新应用 w/git stash 保存“我的保存消息”,但想知道是否有人有解决方案来修改消息。

最佳答案

这在技术上是不可能的,但通过诡计很容易实现预期的目标。 Git 只是没有任何内置机制来完成 这个诡计,即使 git commit--amend 选项可以做到这一点. (也没有干净的方法来劫持 git commit --amend 。)

最后,你必须按照你的建议去做。如果需要,您可以将其 stash 在脚本中,但对于一次性情况而言,这比手动完成更多工作。

技术细节,如果你想构建一个脚本

在 Git 命令行命令和选项等的掩护下,Git 存储条目实际上 是一个提交。更准确地说,它至少是两次提交,有时是三次。 The git stash documentation在标有“讨论”的部分中(相当轻率和粗心地)描述了这一点,使 git stash 提交特别的是它们在 no 分支上——好吧,那个,那个集群中的w (work-tree) 提交,也就是refs/stash 引用所在的提交,具有 merge 提交的形式,因此它可以列出多个父提交 ID。我更喜欢将它们绘制为:

...--F--G   <-- branch
|\
i-w <-- (the stash)

或:

...--F--G   <-- branch
|\
i-w <-- (the stash)
/
u

这与 Git 文档绘图有点不同,但展示了我如何称呼 stash bag(带有可选的 u commit holding untracked files) 悬卡在您进行 stash 时的当前提交中。 (如果您还没有将 HEAD 移到别处,那么该提交仍然是当前提交。)这里的大写字母代表实际的提交哈希,又大又丑并且无法记住。

与所有提交一样,特殊存储提交是只读的——它们永远无法更改,只能忘记它们的哈希 ID(git stash drop 就是这样做的)。

请注意,git commit --amend 实际上进行了一个 提交,将当前 (HEAD) 提交推到一边,不碍事。也就是说,如果我们开始:

...--F--G   <-- branch (HEAD)

并运行 git commit --amend,Git 进行了一个 提交——我们称之为 G2——它的父级是 F 而不是使用 G 作为 G2 的父级的正常想法,然后将 G2 的 ID 写入分支,给出我们:

       G
/
...--F--G2 <-- branch (HEAD)

只要旧的提交 G 没有我们可以找到它的名称,Git 就永远不会向我们显示它,并最终将其完全删除,看起来好像我们以某种方式更改了提交 GG2.

要使现有的存储条目具有不同的提交注释,我们必须做同样的事情:我们将现有的 w 提交复制到一个 提交,具有不同的提交消息,但保留 wcontent 及其所有父散列。如果我们调用替换 w2,我们得到:

...--F--G_  <-- branch
|\`-.
i-w2 \
\ \
-----w <-- (the stash)

如果我们然后重新指向 refs/stash 以指向 w2 而不是 w,并假装 w 不再存在,我们得到了我们想要的:

...--F--G   <-- branch
|\
i-w2 <-- (the stash)

事实上,我们可以将其编写为脚本,从这些代码片段开始:

# get the parents of refs/stash as $1 and $2; $3 exists if there is a u commit
set -- $(git rev-parse refs/stash^@)
# convert these to "-p $1 -p $2 -p $3"
case $# in
2) parents="-p $1 -p $2";;
3) parents="-p $1 -p $2 -p $3";;
*) fatal "refs/stash does not appear to be a valid stash";;
esac
# find the stashed w commit's tree
tree=$(git rev-parse refs/stash^{tree}) || exit
# optional: for editing purposes, gather the current message
existing_message=$(git log --no-walk --pretty=format:%B refs/stash)

# obtain an updated message in some fashion
[snip]

然后:

# create a new w commit, suitable for "git stash store"
new_w_commit=$(git commit-tree $parents "$new_message" $tree)

最终:

git stash drop --quiet
git stash store --quiet -m "$new_message" $new_w_commit

它使用 git stash 脚本本身将 stash@{0} 替换为新的存储。 (在中断的情况下,颠倒这两个操作的顺序可能更明智。弄清楚如何使用 stash@{n} 引用来完成此操作留作练习。这些都不是甚至远程测试。)

关于git - 如何修改 git stash 中的消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50378129/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com