如何一次重新设置许多分支的基础(使用相同的基础提交) ?

在我的项目中有一个主分支,我用它来从其他人那里获取更改。由此,我通常有几个主题分支,我目前的工作。

我的问题是: 有没有一种方法可以让我将新的变化拉入到我的主人中,然后立即将我的所有主题分支重新定位到这个变化上?

情况是这样的:

        D--E topic1
/
A--B--C master
\
F--G topic2

我想用一个简单的命令来完成这个任务(H 来自上游) :

D'--E' topic1
/
A--B--C--H master
\
F'--G' topic2

现在,我知道我可以通过将 topic1和 topic2重新基于 master 来完成这个任务,我甚至可以编写一个脚本来自动完成这个任务。但是,如果我有其他几个分支,创建新的分支,并经常删除其他分支,而且我总是收到上游的更改,那该怎么办?

这个操作(几个 rebase) ,如果是手工完成的,既累人又容易出错。

有更简单的办法吗?

21427 次浏览

我相当肯定,没有一种方法可以自动地做到这一点。请记住,“ git rebase master”还可以让您回到需要您解决合并冲突的 shell,所以如果您想编写一个脚本来自动化所有这些,您需要考虑到这一点。

但是,您可以相当容易地跟踪哪些分支需要更新。嗯,对于任何分行来说“ git rev-list 分行”。.如果分支不是最新的 wrt (即只是在 master 上提交) ,“ master”将生成输出。因此,您需要遍历除 master 之外的所有本地头部,以生成一个报告(nb“ git show-Branch”大致可以这样做) :

git for-each-ref 'refs/heads/*' | \
while read rev type ref; do
branch=$(expr "$ref" : 'refs/heads/\(.*\)' )
revs=$(git rev-list $rev..master)
if [ -n "$revs" ]; then
echo $branch needs update
git diff --summary --shortstat -M -C -C $rev master
fi
done

所以,如果你觉得自己很勇敢,你可以用“ git checkout $Branch & & git rebase master”来替换“ git diff”(或者如果你已经设置好了,可以用“ git pull —— rebase”来替换)。我认为你必须检查是否存在一个。“ git/rebase-application”目录或检查索引中的未合并文件(“ git ls-files-u”) ,以测试是否需要等待进行合并。

当然,如果没有冲突,那么就很容易... ... 在不容易的情况下,产生一些同样有效的东西,这就是问题所在:

如果你的一个分支是基于其他东西的,这并不一定能解决问题... ... 这就是为什么我提到使用“ git pull —— rebase”来代替,因为这会根据分支配置重新定义基础,而不是盲目地从 master。虽然检测不是基于分支配置... ... 也许只检查每个分支并执行“ git pull”,让分支配置处理所有事情,包括是重新基础还是合并,是最简单的方法?

你可以像这样编写一个 shell 一行程序:

for branch in topic1 topic2 topic3;do git rebase master $branch;done

由于您希望重新设置基础的主题分支可能会随着时间的推移而改变,因此这是一个快速和 dir ^ H ^ H ^ 灵活的解决方案: -)

我已经把它转换成了一个健壮的脚本,维护在 我的 Git 扩展库中:

$ git-urebaselocalbr --help
Rebase all / the last committed N local branches (except for the current branch
and master) to the updated upstream head.
Usage: git-urebaselocalbr [--continue|--skip|--abort] [--branches "<branch1> ..."] [N] [-i|--interactive] [options]
git branch | sed 's/\*/ /g' | xargs -n1 git rebase master

如果您想将 所有本地分支重新设置为 master,您可以尝试这样做:

git branch | cut -c 3- | for branch in $(cat); do git rebase master $branch; done