是否有相当于hg rebase -s source -d newparent
的git?
也就是说,'修剪'source
处的分支并在newparent
处'移植'。或source
重新newparent
(在适当的情况下合并)。
或者如何从中获取:
A - B - C
\
D - E
\
F
对此:
A - B - C
\
D'- E'
\
F'
在这种情况下,source
为D
,newparent
为B
。执行hg rebase -s D -d B
会产生所需的结果。有没有git等价物?
我已经尝试了git rebase --onto B D
但除了移动分支标签外,它显然没有做任何事情。
编辑澄清:目标不是在树中重新提交与上述完全相同的提交。以上就是一个例子。我的目标是让我在任何其他提交之上重新提交一个提交,只要没有像尝试重新提交合并提交或类似的那样奇怪的情况。我创建了几个重新创建上面树的脚本,一个用于hg
:
#!/bin/sh
set -e
rm -rf .hg
hg init
cat > .hg/hgrc <<'EOF'
[ui]
username = Rebase tester <no@email>
[extensions]
rebase =
EOF
echo A > file.txt
hg add file.txt
hg commit -m A_msg
hg bookmark A_bm
hg bookmark dummy # to stop A from tracking us
echo B > file.txt
hg commit -m B_msg
hg bookmark B_bm
hg bookmark graftpoint
hg bookmark -f dummy
echo C > file.txt
hg commit -m C_msg
hg bookmark C_bm
hg checkout A_bm
hg bookmark -f dummy
echo D > file.txt
hg commit -m D_msg
hg bookmark D_bm
hg bookmark prunepoint
hg bookmark -f dummy
echo E > file.txt
hg commit -m E_msg
hg bookmark E_bm
hg checkout D_bm
hg bookmark -f dummy
echo F > file.txt
hg commit -m F_msg
hg bookmark F_bm
hg bookmark -d dummy
hg log -G -T '{desc} {bookmarks} {rev}:{node|short}'
hg rebase -s D_bm -d B_bm -t internal:other
hg log -G -T '{desc} {bookmarks} {rev}:{node|short}'
和一个git:
#!/bin/sh
set -e
rm -rf .git
git init
git config user.name 'Rebase tester'
git config user.email 'no@email'
echo A > file.txt
git add file.txt
git commit -m A_msg
git branch A_br
echo B > file.txt
git commit -a -m B_msg
git branch B_br
git branch graftpoint
echo C > file.txt
git commit -a -m C_msg
git branch C_br
git checkout A_br
git checkout -b D_br
echo D > file.txt
git commit -a -m D_msg
git branch prunepoint
git checkout -b E_br
echo E > file.txt
git commit -a -m E_msg
git checkout D_br
git checkout -b F_br
echo F > file.txt
git commit -a -m F_msg
git log --graph --all --format=format:'%s %d %h%n'
#insert command(s) here
git log --graph --all --format=format:'%s %d %h%n'
第一个脚本输出的树是:
@ F_msg F_bm 5:5ffe9c283d51
|
| o E_msg E_bm 4:9f83c609d7b2
|/
o D_msg D_bm prunepoint 3:c3561e22f394
|
| o C_msg C_bm 2:e7dd832a739b
| |
| o B_msg B_bm graftpoint 1:c3d6803dba3e
|/
o A_msg A_bm 0:f52f4706cef0
和
@ F_msg F_bm 5:efe4fde4dcdf
|
| o E_msg E_bm 4:b2402cb25f70
|/
o D_msg D_bm prunepoint 3:5849595efdde
|
| o C_msg C_bm 2:e7dd832a739b
|/
o B_msg B_bm graftpoint 1:c3d6803dba3e
|
o A_msg A_bm 0:f52f4706cef0
完全符合预期。第二个脚本的输出是
* C_msg (master, C_br) de97063
|
* B_msg (B_br) 6053c6b
|
| * E_msg (E_br) 13d4fac
| |
| | * F_msg (HEAD, F_br) b9ce3c4
| |/
| |
| * D_msg (D_br) ed2ba19
|/
|
* A_msg (A_br) 2cf9476
(两次)。第二个应该是这样的:
* C_msg (master, C_br) de97063
|
| * E_msg (E_br) 1398dc5
| |
| | * F_msg (HEAD, F_br) 8ee34ad
| |/
| |
| * D_msg (D_br) ed873f7
|/
|
* B_msg (B_br) 6053c6b
|
* A_msg (A_br) 2cf9476
我的问题是hg rebase -s source -d destination
适用于任何情况,但我还没有办法对git
做同样的事情。我发现了几个第三方程序,但它们似乎没有解决这个用例。一个是git reparent,另一个是git-reparent-branch。我还发现了一个solution using grafts and filter-branch,但我不清楚这会正确处理冲突。
答案 0 :(得分:0)
根据torek的回答,在撰写本文时,没有自动化的方法。因此,下一个最好的方法可能是手动重现树。我说&#34;树&#34;因为我不知道如果涉及合并提交将会发生什么。
因此,假设提交修剪形成一个独立的子树,以下应该有效:
gitk --all
)。git rebase --onto HEAD HEAD tip1
。在示例中就是这样做的:
git checkout graftpoint
set +e
git rebase --onto HEAD HEAD E_br
# Known conflict
echo D > file.txt
git add file.txt
git rebase --continue
set -e
# Repeat for the branching point at E_br~1
git checkout E_br~1
git branch -f prunepoint # fix this reference while we're here
git branch -f D_br # fix this reference while we're here
git rebase --onto HEAD HEAD F_br
这会生成所需的图表:
* C_msg (master, C_br) 612ba5c
|
| * E_msg (E_br) 1b4fb2e
| |
| | * F_msg (HEAD, F_br) 78d5a1f
| |/
| |
| * D_msg (prunepoint, D_br) c4975c0
|/
|
* B_msg (graftpoint, B_br) cc630ea
|
* A_msg (A_br) 01084ac
(A_br
,B_br
和C_br
的哈希值当然与操作前的树中的哈希值相同,这与问题中的不同,因为树是重新生成的-created)。
答案 1 :(得分:0)
为什么会这么复杂?
git rebase --onto B A D
git rebase --onto D D@{1} E # or ... "--onto D{,@{1}} E" in bash
git rebase --onto D D@{1} F # or ... "--onto D{,@{1}} F" in bash
应该做的工作(以模数解决任何合并冲突)。
我经常这样做,因为我编写了一个自动执行此操作的脚本。遗憾的是,Git并没有为用户提供这样的工具,而是让他们自己编写,但是Git中的概念没有任何内在的错误可以防止这种情况发生。 Git中的概念与Mercurial中的概念完全不同。