我想要执行一组需要保存然后恢复 HEAD 的操作。
以下是我想做的事情的逻辑表述:
# Save HEAD
original_head="$(cat .git/HEAD)"
# Perform other operations that muck with HEAD
# ...
# Restore HEAD
echo -n "$original_head" > .git/HEAD
cat
上述使用echo
仅仅是说明性的;它们不是 git 原生的,也不是特别可靠,因为它们会在新创建的是.git
文件而不是目录的工作树中失败。
稍微好一点的方法是使用symbolic-ref
:
# Save
original_head="$(git symbolic-ref HEAD)"
# Restore
git symbolic-ref HEAD "$original_head"
这种方法稍微好一点,但是如果 HEAD 最初是分离的,它就会失败:
# Detach HEAD
git checkout $(git rev-parse HEAD)
# Try to get HEAD value to save:
git symbolic-ref HEAD
fatal: ref HEAD is not a symbolic ref
以下是我目前正在采取的解决此问题的方法:
# Save HEAD
symbolic_head=''
detached_head=''
if git symbolic-ref HEAD >/dev/null 2>&1; then
symbolic_head="$(git symbolic-ref HEAD)"
else
detached_head="$(git rev-parse HEAD)"
fi
# Perform other operations that muck with HEAD
# ...
# Restore HEAD
if [[ -n $symbolic_head ]]; then
git symbolic-ref HEAD "$symbolic_head"
else
git update-ref HEAD "$detached_head"
fi
有没有更直接的方式来表示“获取 HEAD 的值,无论它是符号引用还是普通引用”,然后“设置 HEAD 的值,无论它是符号引用还是普通引用”?
如果你
当您已经检出一个分支时,您的恢复将不会执行任何操作,附加头上的操作会影响分支,这就是附加的工作方式。
您所要求的非常不寻常,如果这真的是您想要的,那么我认为您正在做的事情,只是逐字节保存 ref 内容并恢复它们,这是最好的,甚至可能是唯一的方法。
但是有更好的方法来实现我所想象的一切(至少到目前为止)。
编辑:啊,从评论中,还有一些我没弄清楚的:
HEAD
是为了方便起见而使用的约定“瓷器”命令,更传统的源代码控制操作命令。如果你不需要它们的作用,请使用底层核心命令,即“管道”:是低级操作
git checkout
运行¹;除此之外,checkout 的主要额外步骤是更新HEAD
指向$thatrev
,如果您将其拼写为引用的缩写形式,refs/heads/
则从附加HEAD
到该(分支提示)引用开始。这实际上是它的全部内容,该命令已经获得了许多其他选项来在此过程中执行各种其他方便的事情,但它们都只是将核心命令串联在一起以实现所需的效果。如果您的工作树很脏,您可能需要进行
git read-tree --reset -m
一些其他清理,在读取树工作之前,Git 不喜欢在没有您明确命令的情况下踩踏未提交的工作。对于其他用途,带有边带工作树
git worktree add `mktemp -d`; cd $_
,完成后删除工作树,一旦完成添加的新分支工作树以跟踪您正在做的事情,也删除它。该命令有很多可用选项,如果需要进行某种准备,请查看
--no-checkout
选项并可能硬链接任何所需文件,git ls-files $options|cpio -pdl $thescratchtree
等等。在我,我在 worktree 命令出现之前就开始使用 Git,并且仍然使用沙盒进行任何重大手术
git clone -ns . `mktemp -d`; cd $_
,并按照自己的方式使用克隆,然后将我想要的任何结果推回。对我来说,这仍然感觉最干净、最安全,尤其是对于重大手术尝试。附言:
如果您坚持使用低级的东西,
original_head=$(cat .git/HEAD)
那就比较笨拙了read original_head <.git/HEAD
,您只需echo $original_head >.git/HEAD
进行恢复即可。¹ checkout 确实运行了
git read-tree -um HEAD $thatrev
,请参阅文档,它会亮起更多关于正在更改或放弃的内容的检查。