Як об'єднати поточну гілку в іншу гілку


182

У мене є дві гілки, майстер і дев. Я завжди працюю над dev і лише перевіряю код у головній гілці після того, як його затверджено для використання у виробництві. Коли я це роблю, я повинен робити наступне:

git checkout master
git merge dev
git checkout dev

Це жахливо багатослівно, і оскільки я це часто роблю, я хотів би його мінімізувати. Чи є якась одна команда git, яку я можу використати для злиття від свого поточного розробника гілки до іншого ведучого гілки, не спочатку потрібно перевірити головну гілку? Щось, можливо, як:

git merge dev to master

було б дивним. Я переглянув документацію git і нічого не побачив.


1
Ви спробували використовувати для цього git push?
Джей Салліван

11
Що з пропозиціями поштовху? Це для оновлення віддалених , а не для об'єднання у власне сховище.
Каскабель

4
Jefromi має рацію, натиснути тут не корисно. Я говорю про ще одну місцеву гілку, а не про віддалену гілку.
Кріс

2
Ще гірше , коли у вас є непідтверджені локальні зміни: git stash, git checkout master, git merge dev, git checkout dev, git stash pop.
Mu Mind

2
Приємне запитання. Я цього хотів і тому, що хотів увійти в неіснуючу гілку. Я хотів уникнути перемикання гілок, тому що у мене є процес, який починає збірку, якщо якісь файли в робочому дереві змінюються.
Келвін

Відповіді:


94

1. Додайте віддалений псевдонім для вашого локального сховища, наприклад:

git remote add self file:///path/to/your/repository

(Або на вікнах git remote add self C:\path\to\your\repository)

2. Натисніть на пульт дистанційного керування, наприклад:

git push self dev:master

2
Підмодулі! Це не тільки вирішує проблему заданого питання, але також вирішує проблему перемикання гілок, коли є лише підмодуль. Чудова порада!
eddiemoya

2
+1 Це творчо і зовсім не торкається робочого дерева. Просто уточнення: /path/to/your/repositoryце шлях до вашого робочого дерева, тобто не включайте .gitкаталог. Крім того, це не повинно говорити: пульт дистанційного оновлення доведеться оновити, якщо перемістити репо.
Келвін

Мені не пощастило змусити це працювати в Windows ... git remote add self file:///c/projectsпросто повертається із записками про використання
Маслоу

2
@ JosephK.Strauss Ви можете спочатку об'єднати головний майстер у поточну гілку ( dev), а потім натиснути комісію злиття, використовуючи git push self dev:master.
Леонід Швечиков

4
Чому віддалений псевдонім? .працював нормально для мене git push . head:master.
geon

60

Поточна відповідь від @zerome - це дуже добре, але трохи непотрібно.

В основі вашого git repo ви можете просто зробити це: git push . dev:master

Більш узагальненим рішенням, яке працювало б у будь-якому місці дерева, було б:

git push $(git rev-parse --show-toplevel) dev:master

3
git push . dev:masterбагато спростило мені життя! Найкраща відповідь на сьогоднішній день, дякую
Джеремі Белоло

ти збираєшся підштовхнути об'єднаний майстер до віддаленого сховища на зразок github? збережіть крок, зробившиgit push origin dev:master
Алекс R

1
Чи можна повторити merge --no-ffповедінку при цьому?
ексгума

1
Я отримую неправильне віддалене ім’я ". в Windows. Чи потрібно ще робити git remote add self file:///myRepo?
kiewic

1
Але це насправді не робить злиття ... Це спрацює, якщо dev випереджає господаря, але що робити, якщо його немає?
Томас Левеск

44

Вашим найкращим варіантом буде просто використовувати псевдонім, розміщений у вашому глобальному gitconfig ( ~/.gitconfig):

[alias]
    merge-to = "!f() { git checkout $1 && git merge $2 && git checkout -; }; f"

так що ви можете викликати його з будь-якого сховища як

git merge-to master dev

3
Що буде, якщо злиття не буде автоматичним, але вимагає вирішення злиття? (У цьому випадку я припускаю, що робота над майстром не робиться, тому це не сталося б, але все-таки) ...
Штейн Г. Стріндгауг

@Stein: Оскільки я використовував &&, ні ;, це не вдасться об'єднати і не спробувати переключитися назад. Сподіваємося, користувач досить розумний, щоб побачити повідомлення про "злиття не вдалося" та вирішити його.
Каскабель

6
Я віддаю перевагу цій merge-to = "!f() { export tmp_branch=гітці | grep '*' | тр -d «*» ; git checkout $1 && echo git merge $tmp_branch && echo git checkout $tmp_branch; unset $tmp_branch; }; f", то давайте мені не доведеться набирати в галузі я перебуваю в даний момент, так що якщо я хочу , щоб об'єднати devв masterі я на devданий момент я просто введітьgit merge-to master
Steve

2
Краща версія з правильними підставками та без відлуння:merge-to = "!f() { export tmp_branch=`git branch | grep '* ' | tr -d '* '`; git checkout $1 && git merge $tmp_branch && git checkout $tmp_branch; unset $tmp_branch; }; f"
Simon Epskamp

2
команда unset неправильна. виправлено: merge-to = "! f () {export tmp_branch = git branch | grep '* ' | tr -d '* '; git checkout $ 1 && git merge --no-ff $ tmp_branch && git checkout $ tmp_branch; unset tmp_branch;}; f"
sassman

38

Невелика модифікація псевдоніму Jefromi, яка не потребує введення поточної гілки.

Таким чином , ви використовувати його як: git merge-to dev.

Це переключиться на devгілку, об'єднає її з ТОКУВАННЯ, а потім переключиться назад.

Наприклад, якщо припустити, що ви знаходитесь на masterгілці, вона злиє господаря в дев, і ви все одно будете господарем.

Це безумовно стосується моїх dotfiles :)

[alias]
  merge-to = "!gitmergeto() { export tmp_branch=`git branch | grep '* ' | tr -d '* '` && git checkout $1 && git merge $tmp_branch && git checkout $tmp_branch; unset tmp_branch; }; gitmergeto"

6

Це старе, але ...

Поєднання рішень від @ kevin-lyda та @ dmytrii-nagirniak вище. цей псевдонім об'єднує поточну гілку у вказану гілку. Він використовує метод дистанційного використання та використовує команди git, щоб отримати контекст.

[alias]
    merge-to = "!gitmergeto() { git push \"`git rev-parse --show-toplevel`\" `git rev-parse --abbrev-ref HEAD`:$1; } && gitmergeto"

Для використання, як:

git merge-to other-branch-name

4

Щоб об'єднати поточну гілку в іншу гілку, не перевіряючи іншу гілку:

Швидке злиття вперед

Це дійсно просто. За визначенням, швидке злиття вперед просто означає, що вказівник гілки переміщується вперед у дереві комітів. Тому все, що вам потрібно зробити, це просто імітувати це:

git branch -f master dev

Застереження: Це передбачає, що masterвказує на зобов'язання, яке також є у devфілії чи в іншій галузі. Якщо цього не відбувається, ви ризикуєте втратити роботу! На відміну від того, git mergeщо створить злиття (або скарга), коли перемотка вперед неможлива, цей метод мовчки змушує вказівник гілки вказати на інший фіксатор.

Це також передбачає, що ти єдиний, хто працює над репо, та / або знаєш, що робиш.

Порада. Якщо ви зробили git fetchта у вас є нові зобов’язання origin/master, ви можете перемістити masterвідділення, не перевіряючи, використовуючи:

git branch -f master origin/master

Об'єднати через об'єднання

Це не завжди можливо. Щоб створити комісію злиття, вам потрібно зробити операцію злиття. А щоб зробити операцію злиття, ви повинні мати коміти в іншій гілці, які не є в поточній гілці.

Якщо у вас є коммітов в masterгалузі , які знаходяться НЕ в devгалузі, ви можете:

Відмова від відповідальності: Це просто підтвердження концепції, просто щоб показати, що іноді можливо зробити злиття з іншою гілкою без перевірки. Якщо ви хочете використовувати його щодня, ви, ймовірно, хочете зробити псевдонім для нього за допомогою перенаправлення оболонки або зробити сценарій оболонки для нього. Потім знову можна також зробити сценарій оболонки для більш короткого процесу, показаного в питанні.

git checkout -b temp
git merge --no-ff -e master
git branch -f master temp
git checkout dev
git branch -D temp

Пояснення:

  1. Ознайомтеся з тимчасовою гілкою, яка вказує на те саме, що і поточне відділення.
  2. Об’єднайтеся masterу тимчасову гілку та запустіть редактор повідомлень про фіксацію. Якщо ви хочете, щоб об’єкт злиття виглядав так, як ви об'єднали devгілку master, відредагуйте її з цього:

    Merge branch 'master' into temp
    

    до цього:

    Merge branch 'dev'
    

    Порада: Ви можете використовувати -m "Merge branch 'dev'"замість того, -eщоб бути швидшим.

  3. Оновіть masterвказівник гілки, щоб вказати на об'єднання.
  4. Огляньте devвідділення.
  5. Примусово видалити тимчасову гілку.

Це все ще стосується вашого робочого дерева, але мінімально. Це не відколює дерево аж до стану оригіналу, masterщоб ще раз внести зміни в розвиток. Деяких це може не хвилювати, але для інших це може бути важливо.


1

Багато разів ви приїжджаєте з гілки, ви хотіли б об'єднати поточну гілку. У такому випадку ви можете зробити:

git co - && git merge @{-1}

наприклад:

git checkout somebranch      // (while on master)

// add some commits

git co - && git merge @{-1}  // will merge somebranch into master

1

Моє рішення схоже на інші відповіді, з такими відмінностями:

  • функція розбита на кілька рядків для читабельності
  • функція викликає, set -exтак що кожна команда друкується, і якщо команда не працює, функція виходить негайно
  • псевдонім передає свої аргументи, крім першої (цільової гілки) до git merge
  • функція включає в себе команду null, : git mergeяка гарантує, що завершення вкладки працює з деякими налаштуваннями оболонки (наприклад, gitfastз oh-my-zsh)
[alias]
  merge-to = "!f() { : git merge ; \
      set -ex ; \
      local this=$(git rev-parse --abbrev-ref HEAD) ; \
      local target=$1 ; \
      shift ; \
      git checkout $target ; \
      git merge $this \"$@\" ; \
      git checkout $this ; \
    } ; f"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.