как вытащить на несколько веток одновременно с Git?

13

В репо у меня есть несколько веток, среди которых «master» и «development», которые настроены для отслеживания удаленных веток «origin / master» и «origin / development».

Можно ли указать, что я хочу, чтобы мастер и разработка были объединены (переадресованы) одновременно?

Когда я делаю 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. Я бы предпочел встроенное решение, если оно существует :)

Superole
источник
Я пытался, git pull origin refs/heads/develop:refs/remotes/origin/develop refs/heads/master:refs/remotes/origin/masterно это привело к тому, что удаленный мастер был объединен с разработчиком ..
Superole
1
Почему это может быть ошибочным или неэффективным? Git предназначен для такой настройки. Кстати, чтобы избежать необходимости проверять каждую ветвь, вы можете разделить свою pullстроку на fetchследующую, а затем mergeна каждую ветку.
Jjlin
@jjlin хорошо, если я могу сделать это, не проверяя каждую ветку, которая может помочь по эффективности. Это подвержено ошибкам, потому что матрица вещей, которые могут пойти не так, и влияние, которое она может оказать на остальную часть сценария, несколько сложны. Я не говорю, что сделать его безопасным невозможно, но это будет компромисс. Поэтому я бы предпочел встроенное решение, если оно существует :)
Superole

Ответы:

11

Вы можете установить псевдоним, который используется 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виды использования refspecs с fetchдля быстрой перемотки вперед masterи developфилиалов в местных репо. Синтаксис в основном говорит Git: «Здесь есть refspec формы <source>:<destination>, возьмите <destination>и перенесите его в ту же точку, что и <source>». Таким образом, источники в псевдониме являются ответвлениями origin, в то время как адресаты являются версиями этих веток для локального репо.

  3. Наконец, git checkout --quiet -проверяет ветку, в которой вы были в последний раз, независимо от того, был ли сбой в предыдущих командах. Так что, если вы были включены, masterкогда вы бежали git sync, и все прошло успешно, вы выйдете из отдельного состояния головы и проверите новое обновление master.

Смотрите также мой ответ на git: обновить локальную ветку без проверки? ,

40XUserNotFound
источник
Я не совсем понимаю магию обособленно, почему указатель на мастер не может быть перемещен, когда проявление развернуто? ... в любом случае я попробовал это, и, похоже, это работает, за исключением того, что теперь я получаю "Ваша ветвь опережает 'origin / development' на 1 коммит".
Супероль
... который решается в следующий раз, когда я потяну
Superole
@Superole, какая ветвь впереди, origin/developкогда вы используете псевдоним? Это не имело бы смысла, если бы это было ваше местное developотделение. Кроме того, указатель для master может быть перемещен, если он developизвлечен, смысл в том, что если он masterизвлечен, то вы не можете выполнить ускоренную перемотку вперед, masterпоскольку это повлияет на вашу рабочую копию, поэтому вы отсоединяете рабочую копию. из него сначала с помощью git checkout head. Я видел другой ответ, который описывал его как «стоящий на скале», вы должны сойти со скалы, прежде чем сможете его сдвинуть.
40XUserNotFound
это было действительно мое местное развитие. И причина должна быть в том, что этот выбор не обновляет ветви отслеживания. Как я понимаю; тяга извлекается в происхождение / развитие, а затем объединяется с развитием.
Superole
Очень важно, что этот ответ вызывает fatal: bad config line xx in file xxx. который вызван точкой с запятой. Вы должны заключить всю команду в двойные кавычки, чтобы избежать этой проблемы.
Уильям Люн
1

Установите Git-Up . Это дает вам команду, git-upкоторая будет тянуть все локальные ветви в вашем хранилище.

BillyTom
источник
милая! Я проверю это наверняка.
Супероль
2
хех: P Заявления о поддержке Windows предсказуемо отсутствуют. и до сих пор не сформулировано строгое доказательство того, что оно определенно не будет портить ваши настройки git, удалять данные или отправлять бессмысленные сообщения в Hacker News от вашего имени. , в сочетании с необходимостью Руби, отогнал меня. Мне нравится концепция, хотя.
Superole
Рад, что метод есть вообще ... отчасти отстой, хотя каждый метод требует какого -то стороннего инструмента. Такие, как эта и те, с какой-то командой оболочки "recipe" или псевдонимом, использующим конкретную (платформенно-зависимую) оболочку.
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 в качестве 1-го аргумента, и в противном случае он имеет неопределенное поведение. Это также не оптимально для вариантов использования с более чем двумя ветвями, но это даст мне то, что мне сейчас нужно.

git pull
git ffwd master
Superole
источник