Git copy commit without checkout or rebase?

hvvq6cgz  于 2023-09-29  发布在  Git
关注(0)|答案(2)|浏览(86)

我目前在提交123456和分支foo上。我想添加一个新的提交到分支bar,其内容与123456的内容完全相同(没有重新定基,只是从同一个快照创建的,所以差异将是任何它将是)。
我可以这样做:

$ git checkout bar
$ git reset foo
$ git commit -am '...'
$ git checkout foo

我有两个问题:

  • 有没有一种方法可以做到这一点,而不需要离开foo或需要改变我的工作树?
  • 有没有一种干净的方法可以从123456复制提交消息?(我当然可以手动完成,但通过原生git命令自动完成会更好)
jq6vz3qz

jq6vz3qz1#

这很容易做到

git checkout bar
git restore --worktree --staged --source=foo -- .
git commit -m "Here we make it just like 1234546 (or foo back when I created this commit)"

你可以使用git commit -C 123456来使用那个提交的信息来进行新的提交 *,但是 * 这会产生误导,因为你创建的是一个单独的提交 *,而且 * 你忽略了foo..bar中的所有历史记录。在一次提交中这样做有意义吗?好吧,也许它适合你的用例 *,但 * 我不认为它对每个人都有效。
当然,这可以在不改变你的工作树的情况下完成。通过使用超级秒工作树。所以,检查git help worktree
现在我想了想,还有另一种方法可以做到这一点,而不必从你的工作树中移动一个位,也不需要第二个工作树,但它是黑客:

# we are on foo, right?
git branch temp $( git commit-tree -p bar -m "Here we make it just like 1234546 (or foo back when I created this commit)" 123456^{tree}" )
# commit-tree is a command not intended for the faint-of-heart. It
# will create a new commit just like 123456 in contents and that has bar
# as its parent.... and the outer command will set the branch temp
# on it.
# It's a hackish thing so no -C available to copy the info from
# 123456.
# if you like it, then move bar to that position
git branch -f bar temp
# and now you can delete temp
git branch -D temp
zvms9eto

zvms9eto2#

是的,你在寻找核心命令,那些通常的便利性是建立在上面的。核心的make-a-commit命令是git commit-tree,它需要parents、tree和message。核心的set-a-ref命令是git update-ref,您希望bar指向一个新提交,该提交的父级是当前的tip,所以

git update-ref refs/heads/bar $(
        git show -s --pretty=format:%B @ \
        | git commit-tree -p bar @: 
)

相关问题