gpt4 book ai didi

git - 更改提交的父级

转载 作者:行者123 更新时间:2023-12-04 01:47:24 25 4
gpt4 key购买 nike

我尝试将提交 move 到另一个分支之上,而忽略在目标分支中所做的所有更改。

目前的情况是:

      master

--A--B--C
\
D--E

我想将提交 E 移到 C 前面
      master

--A--B--C--E'
\
D--E

E' 与 E 相同,除了父节点现在是 C 而不是 D(这意味着 E 和 E' 的树应该相同)。

更准确地说:
"git cat-file -p E" shows e.g.
tree b98c9a9f9501ddcfcbe02a9de52964ed7dd76d5a
parent D

"git cat-file -p E'" should show
tree b98c9a9f9501ddcfcbe02a9de52964ed7dd76d5a
parent C

我尝试使用不同的参数以及cherry-pick进行rebase,但所有这些最终都尝试将在C中完成的任何更改 merge 到新的E'提交中:(

到目前为止,我发现的唯一防止大规模 merge 的解决方案是
check out C
copy over all stuff from E to C
commit and get E'

现在树是相同的,父树是不同的,但必须有一种更简单、更快的方法,因为所有要做的就是用现有的树对象创建一个简单的提交对象。

最佳答案

是的,你的图表是准确的! 😀

唉,Git 中没有明显的工具来实现你想要的结果。这里的问题是 rebase 只是自动 cherry-pick , cherry-pick 是关于将提交及其快照转换为变更集,并将这些变更与其他一些提交 merge 以进行新的提交,这不是你想要的想要:要保留原始快照。

幸运的是,有几种非常简单的方法可以做到这一点。不幸的是,他们中的一些人至少使用了一个管道命令,即一个不是为用户设计的,不是 Shiny 的瓷器,内部 Git 命令。

首先,让我们注意您自己的解决方案是正确的:

Only solution preventing massive merge I found so far is

check out C
copy over all stuff from E to C
commit and get E'


在实际的 Git 命令中,例如:
$ git checkout -b new-branch master
$ git rm -r . # in case there are files in C that aren't in E at all
$ git checkout <hash-of-E> -- . # overwrite using E
$ git commit

这实际上并没有那么糟糕,但它会导致工作树的大量更新,如果您的下一个 make 可能会很烦人。需要一个小时,或者其他什么。

更简单的方法#1

第一个更简单的方法是:
$ git checkout -b new-branch master
$ git read-tree -u <hash-of-E>
$ git commit
read-tree操作将您的索引内容替换为从提交 E 中获取的内容。 -u标志告诉 Git:当你做这个索引更新时,也更新工作树:如果一个文件从索引中完全删除,也从工作树中删除它,或者如果一个文件在索引中被替换,将它替换为工作树也是。这个标志实际上不是必需的,因为 git commit将使用索引中的内容,但为了理智,这是一个好主意。

更简单的方法#2

第二种更简单的方法是:
$ git commit-tree -p master -m "<message>" <hash-of-E>^{tree}

这会打印出新提交的哈希 ID;然后我们需要设置一些东西来指向这个新的哈希 ID:
$ git update-ref refs/heads/new-branch <hash-ID>

或者,在一行中:
$ git update-ref refs/heads/new-branch $(git commit-tree -p master -m "<message>" <hash-of-E>^{tree})

请注意 -m "<message>"可以换成 -F <file>从文件中读取消息,甚至 -F -从标准输入读取消息。然后,您可以从提交 E 中复制提交消息。使用 git log --no-walk --format=%B <hash-of-E>并将其通过管道传递给单行命令的其余部分。

请确保 new-branch确实是一个新的分支名称,如果不是,则它是您要重新设置的分支而不是当前分支,因为 git update-ref默认情况下不进行错误检查。

更简单的方法#3

你也可以做这样的工作:
$ git checkout -b new-branch <hash-of-E>   # now at E, with E in index and work-tree
$ git reset --soft master # make new-branch identify C, without
# touching index or work-tree
$ git commit -c <hash-of-E> # make new commit using E's message

最后一种方法的工作树流失最少,因此可能是三种方法中最好的。然而,方法#2 在不接触任何东西的情况下创建新的提交,所以如果你实际上不想在新分支上,方法#2 可能是最好的。

关于git - 更改提交的父级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54726994/

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