Git 更改父提交版本
Git change parent commit rev
我的一位同事检查了提交 correct_parent
,根据 correct_parent
做了一些更改,然后以某种方式错误地使用另一个错误的父提交 rev wrong_parent
而不是 [=13] =](我不确定他是怎么做到的)。我们称他的提交为 bad_commit
.
一大堆新的提交基于bad_commit
,包括新的合并提交,所以它不是简单的线性结构,而是更像菱形。他们终于又重新合并到一个分支中。我们称之为 bad_branch
.
我想用正确的父提交 correct_parent
以及所有后续提交重新创建 bad_commit
。
我不太确定该怎么做。可能以某种方式 git rebase
和 --strategy ours
左右。请注意,这不仅仅是一个变基,因为 wrong_parent
和 bad_commit
之间的差异并不完整,所以我不想将其作为补丁应用。
一张图片:
wrong_parent -> bad_commit (based on correct_parent) -> ...... -> bad_branch HEAD
我要:
correct_parent -> bad_commit (merge strategy: take bad_commit) -> .... -> fixed_branch
从 correct_parent
创建一个新分支,
并根据 wrong_parent
:
挑选发生在另一个分支上的提交
git checkout -b fix correct_parent
git cherry-pick wrong_parent..other_branch
感谢@poke的建议!
似乎是 git rebase
的工作。
- 创建分支指向正确的父节点
git checkout -b ok_branch <correct_parent>
- 做一个 rebase 保存合并(参考 http://git-scm.com/docs/git-rebase)
-p
--preserve-merges
Recreate merge commits instead of flattening the history by replaying commits a merge commit introduces. Merge conflict resolutions or manual amendments to merge commits are not preserved.
This uses the --interactive machinery internally, but combining it with the --interactive option explicitly is generally not a good idea unless you know what you are doing (see BUGS below).
git checkout -b replaced_branch <bad_branch>
git rebase --preserve-merges ok_branch
- 删除临时分支
git branch -D ok_branch
进行这些更改后,您将拥有
- correct parent [ok_branch] - bad commit - .... - HEAD [replaced_branch]
更新
您可能会发现 usesul 标志 --onto
(参考 https://git-scm.com/book/en/v2/Git-Branching-Rebasing#More-Interesting-Rebases)
这可以通过嫁接文件修复,使用 git filter-branch
.
永久保存
设置错误的回购:
git init
echo a > file && git add file && git commit -m "good parent"
echo b > file && git add file && git commit -m "bad parent"
echo c > file && git add file && git commit -m "child" file
这在 git log --oneline
中显示为
f6e3133 child
4dc60b6 bad parent
7b5da8a good parent
现在假设"good parent"是"child"的parent:
echo `git rev-parse @ @~2` > .git/info/grafts
并再次检查 git log --oneline
:
f6e3133 child
7b5da8a good parent
现在让它永久化:
git filter-branch
第三次检查git log --oneline
:
87b8fc8 child
7b5da8a good parent
你看到 child 有一个新的散列。那是因为提交是 re-written 和正确的 parent。 parent 没有得到新的散列,因为它没有改变。 "child" 的任何 children 也会被重写。
最后,清理一下:
rm .git/info/grafts
我的一位同事检查了提交 correct_parent
,根据 correct_parent
做了一些更改,然后以某种方式错误地使用另一个错误的父提交 rev wrong_parent
而不是 [=13] =](我不确定他是怎么做到的)。我们称他的提交为 bad_commit
.
一大堆新的提交基于bad_commit
,包括新的合并提交,所以它不是简单的线性结构,而是更像菱形。他们终于又重新合并到一个分支中。我们称之为 bad_branch
.
我想用正确的父提交 correct_parent
以及所有后续提交重新创建 bad_commit
。
我不太确定该怎么做。可能以某种方式 git rebase
和 --strategy ours
左右。请注意,这不仅仅是一个变基,因为 wrong_parent
和 bad_commit
之间的差异并不完整,所以我不想将其作为补丁应用。
一张图片:
wrong_parent -> bad_commit (based on correct_parent) -> ...... -> bad_branch HEAD
我要:
correct_parent -> bad_commit (merge strategy: take bad_commit) -> .... -> fixed_branch
从 correct_parent
创建一个新分支,
并根据 wrong_parent
:
git checkout -b fix correct_parent
git cherry-pick wrong_parent..other_branch
感谢@poke的建议!
似乎是 git rebase
的工作。
- 创建分支指向正确的父节点
git checkout -b ok_branch <correct_parent>
- 做一个 rebase 保存合并(参考 http://git-scm.com/docs/git-rebase)
-p --preserve-merges
Recreate merge commits instead of flattening the history by replaying commits a merge commit introduces. Merge conflict resolutions or manual amendments to merge commits are not preserved.
This uses the --interactive machinery internally, but combining it with the --interactive option explicitly is generally not a good idea unless you know what you are doing (see BUGS below).
git checkout -b replaced_branch <bad_branch>
git rebase --preserve-merges ok_branch
- 删除临时分支
git branch -D ok_branch
进行这些更改后,您将拥有
- correct parent [ok_branch] - bad commit - .... - HEAD [replaced_branch]
更新
您可能会发现 usesul 标志 --onto
(参考 https://git-scm.com/book/en/v2/Git-Branching-Rebasing#More-Interesting-Rebases)
这可以通过嫁接文件修复,使用 git filter-branch
.
设置错误的回购:
git init
echo a > file && git add file && git commit -m "good parent"
echo b > file && git add file && git commit -m "bad parent"
echo c > file && git add file && git commit -m "child" file
这在 git log --oneline
中显示为
f6e3133 child 4dc60b6 bad parent 7b5da8a good parent
现在假设"good parent"是"child"的parent:
echo `git rev-parse @ @~2` > .git/info/grafts
并再次检查 git log --oneline
:
f6e3133 child 7b5da8a good parent
现在让它永久化:
git filter-branch
第三次检查git log --oneline
:
87b8fc8 child 7b5da8a good parent
你看到 child 有一个新的散列。那是因为提交是 re-written 和正确的 parent。 parent 没有得到新的散列,因为它没有改变。 "child" 的任何 children 也会被重写。
最后,清理一下:
rm .git/info/grafts