如何使用git一次拉入多个分支?


11

在一个仓库中,我有多个分支,其中包括“ master”和“ develop”,它们被设置为跟踪远程分支“ origin / master”和“ origin / develop”。

是否可以指定我同时希望将主控和开发都合并(快进)?

当我这样做git pull,现在我得到这样的:

remote: Counting objects: 92, done.
remote: Compressing objects: 100% (56/56), done.
remote: Total 70 (delta 29), reused 28 (delta 8)
Unpacking objects: 100% (70/70), done.
From scm.my-site.com:my-repo
   5386563..902fb45  develop    -> origin/develop
   d637d67..ba81fb2  master     -> origin/master
Updating 5386563..902fb45
Fast-forward

提取所有远程分支,但只有我当前所在的分支与其相应的远程分支合并。

所以我必须做git checkout master...

Switched to branch 'master'
Your branch is behind 'origin/master' by 106 commits, and can be fast-forwarded.

...然后git pull再次,然后切换回开发,以获得所需的结果。

我知道我可以使别名/脚本执行这些步骤。但我想避免这种情况,因为它容易出错并且效率不高
编辑:好的,让我改一下。我的目标不是不鼓励或不喜欢git的脚本/别名自定义。我只希望内置的解决方案,如果存在的话:)


我试过git pull origin refs/heads/develop:refs/remotes/origin/develop refs/heads/master:refs/remotes/origin/master,但导致远程主要合并到开发..
Superole

1
为什么会容易出错或效率低下?Git旨在像这样进行定制。顺便说一句,为避免不必签出每个分支,您可能需要将a拆分pull为a,fetch然后将a merge拆分为每个分支。
jjlin 2013年

@jjlin很好,如果我能做到而无需签出可能有助于提高效率的每个分支。这很容易出错,因为可能出错的事物的矩阵及其对脚本其余部分的影响有些复杂。我并不是说要保证安全是不可行的,但这将是一个权衡。所以我更喜欢内置的解决方案,如果存在的话:)
Superole 2013年

Answers:


9

您可以设置一个git fetch与refspecs一起使用的别名,从而仅用一个命令即可快速合并分支。将此设置为用户.gitconfig文件中的别名:

[alias]
    sync = "!sh -c 'git checkout --quiet --detach HEAD && \
                    git fetch origin master:master develop:develop ; \
                    git checkout --quiet -'"

用法:git sync

这是它起作用的原因:

  1. git checkout --quiet HEAD直接检查您当前的提交,使您进入独立状态。这样,如果您使用master或,则将develop工作副本与那些分支指针分离,从而允许它们被移动(当工作副本被检出时,Git不允许您移动分支引用)。

  2. git fetch origin master:master develop:develop使用refspec与fetch一起快进本地仓库中的masterand develop分支。语法基本上告诉Git“这是形式的refspec,将其<source>:<destination><destination>快并前进到与”相同的点<source>。因此,别名中的源是from的分支origin,而目标是这些分支的本地仓库版本。

  3. 最后,git checkout --quiet -不管先前的命令是否失败,都要签出最后一个分支。因此,如果您在master运行时处于开机状态git sync,并且一切都成功了,那么您将保持独立状态,并检出新近更新的master

另请参阅我对git的回答:更新本地分支而不将其检出?


我在这里不太了解魔术,为什么在检出开发工具时不能移动主指针?...无论如何,我尝试了这一点,但它似乎起作用了,除了现在,我得到“您的分支比1提交早于'origin / develop'。”
Superole

...下次我拉
车时

@Superole 使用别名时哪个分支位于前面origin/develop?如果它是您的本地develop分支机构,那没有任何意义。另外,如果已签出的指针master 可以移动develop,则要点是,如果master已签出,则指针不能快速前进,master因为这会影响您的工作副本,所以这就是为什么要分离工作副本的原因。首先使用git checkout head。我看到另一个描述它为“站在岩石上”的答案,您必须离开岩石才能移动它。
40XUserNotFound 2013年

确实是我当地的发展。并且原因一定是该提取不会更新跟踪分支。据我了解;拉动将提取到起源/开发中,然后将其合并到开发中。
Superole

这个答案引起的非常重要fatal: bad config line xx in file xxx。这是由分号引起的。您必须将整个命令用双引号引起来,以避免出现此问题。
梁威廉(William Leung)

1

安装git-up。它为您提供了git-up将提取存储库中所有本地分支的命令。


甜!我一定会检查出来的。
Superole

2
heh:P 可预测的是,该文件没有Windows支持。并且尚未制定严格的证明,它绝对不会干扰您的git设置,删除数据或代表您将毫无生气的文件发布到Hacker News。,加上对Ruby的需求,使我无法接受。我喜欢这个概念。
Superole

很高兴有一个方法在所有 ...有点儿苏茨基,但是,每一个方法需要一些第三方工具。诸如此类以及带有一些shell命令“ recipe”的别名或使用特定(特定于平台的)shell的别名。
0xC0000022L

0

看来git没有内置选项可以拉入多个分支。至少不是在1.8.0版中。尽管@Cupcake的答案很接近。

但是@jjlin的评论让我意识到至少我不需要拉两次。

因此,稍微更有效的顺序是:

git pull
git checkout master
git merge origin/master
git checkout -

不可避免地,我最终创建了一个别名,但决定不使用它,而是专注于快速转发另一个分支。

[alias]
ffwd = "!_() { git checkout $1 && git merge --ff-only origin/$1 && git checkout -; }; _"

当然,在不进行任何测试的情况下,该别名假定我提供了一个有效的ff'able分支作为第一个参数,否则具有未定义的行为。对于具有两个以上分支的用例来说,它也不是最佳选择,但是它将为我带来我现在需要的东西。

git pull
git ffwd master
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.