[英]How to reformat multiple branches at once in Git?
假设我在 Git 中有一个看起来像master -> A -> B
的分支结构。 也就是说, A
包含在master
之上的提交,而B
包含在A
之上的提交。
我想重新格式化A
,而不会在B
中导致需要手动解决的大量冲突。 如果我没记错的话,我可以使用git filter-branch来做到这一点,除非我不希望master
中的任何内容发生变化。 (即我不想使项目中的所有公共 Git 提交 ID 无效。)
有没有办法只在A
和B
上使用git filter-branch
(或者就我的目的而言,除了master
之外的所有分支)?
编辑:特别是,做git filter-branch... AB
就足够了吗? 这是否会避免接触master
并保持A
和B
彼此一致(即,将A
和B
之间的共同提交重写为相同的提交 ID,并且不允许它们重复,或类似的东西)。
您在这里有正确的总体思路(关于如何使用过滤器分支),但语法错误。 要让git filter-branch
复制(和过滤)可从名称A
和B
访问的提交,但不能复制+过滤可从master
访问的提交,请使用以下语法:
git filter-branch <options> -- ^master A B
我们在这里所做的,使用git rev-list
arguments ^master AB
告诉 Git: master
所有可从A
或B
访问的提交,排除所有可访问的提交。 因此,如果提交链 go:
...--o--o--o <-- master
\
o--o--o <-- A
\
o--o <-- B
例如,这会选择中间行和底行提交。 它甚至可以使用^master B
或master..B
,如phd 的回答,但这有两个更好的原因。 首先,它仍然会 select 所有中间行提交:
...--o--o--o <-- master
\
o--o--o <-- A
\
o--o <-- B
(尽管这可能不是您的结构)。 其次,在复制(和过滤)指定的提交之后,您最终会得到:
o--o <-- [filtered copy of commit to which B points]
/
o--o--o [filtered copy of commit to which A points]
/
...--o--o--o <-- master
\
o--o--o <-- A
\
o--o <-- B
filter-branch 命令将移动文档中称为正引用的所有内容。 正引用是前面没有否定的引用:在这种情况下, A
和B
,但不是master
,因为master
写成^master
,因此是负引用。
因此,这不会触及master
(无论如何都不会——它的提交没有被复制),但会将名称A
和B
拉过来,以便它们指向复制的提交。
请注意,如果您不希望对两个(在此示例中)仅B
提交中的快照进行更改,则由您编写一个聪明的过滤器来执行此操作。 (或者使用不改变树的过滤器,但是通过“重新格式化”我假设你想在每个A
提交的快照上使用--tree-filter
和类似clang-format
的东西。这可能更明智go 提前并对各种B
提交进行相同的格式更改。)
git滤波器-支... AB
不,这会将分支 A 和 B 处理回根提交。 我会这样 go :
A_behind_B=`git rev-list --count A..B`
git filter-branch ... master..B # or ^master B
git checkout A
git reset --hard B~$A_behind_B
计算 A 落后于 B 的提交数量。对从master
到 B 的提交运行filter-branch
。将 A 重置为新 B 后面的提交。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.