Как объединить текущую ветку в другую?

182

У меня есть две ветви, master и dev. Я всегда работаю над dev и проверяю код только в основной ветке, как только он одобрен для производственного использования. Когда я делаю это, я должен сделать следующее:

git checkout master
git merge dev
git checkout dev

Это ужасно многословно, и, поскольку я делаю это часто, я бы хотел минимизировать это. Есть ли какая-нибудь команда git, которую я могу использовать для слияния из моей текущей ветки dev в другую master ветки без предварительной проверки master ветки? Что-то вроде:

git merge dev to master

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

Крис
источник
1
Вы пытались использовать git push для этого?
Джей Салливан
11
Что с предложениями толчка? Это для обновления пультов , а не слияния в собственном хранилище.
Каскабель
4
Джефроми прав, толчок здесь не полезен. Я говорю о другой локальной ветке, а не удаленной.
Крис
2
Еще хуже , когда у вас есть неподтвержденные локальные изменения: git stash, git checkout master, git merge dev, git checkout dev, git stash pop.
Му разум
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
zerome
источник
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 репо вы можете просто сделать это: git push . dev:master

Более обобщенное решение, которое будет работать в любом месте дерева:

git push $(git rev-parse --show-toplevel) dev:master
Кевин Лида
источник
3
git push . dev:masterсильно упростила мою жизнь! Лучший ответ на сегодняшний день, спасибо
Джереми Белоло
Вы собираетесь отправить объединенный мастер в удаленный репозиторий, такой как github? спасите шаг, делаяgit push origin dev:master
Алекс Р
1
Можно ли повторить merge --no-ffповедение с этим?
exhuma
1
Я получаю недопустимое удаленное имя "." в винде. Мне все еще нужно сделать git remote add self file:///myRepo?
kiewic
1
Но это на самом деле не делает слияние ... Это будет работать, если dev опережает master, но что, если это не так?
Томас Левеск
44

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

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

так что вы можете вызвать его из любого хранилища как

git merge-to master dev
Cascabel
источник
3
Что произойдет, если слияние не является автоматическим, но требует разрешения слияния? (В этом случае я предполагаю, что работа над мастером не ведется, поэтому этого не произойдет, но все же) ...
Стейн Г. Стриндхауг
@ Штайн: Так как я использовал &&, нет ;, он не сможет слиться, и не попытаться переключиться обратно. Надеемся, что пользователь достаточно умен, чтобы увидеть сообщение «Слияние не удалось» и разобраться с ним.
Каскабель
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"
Саймон Эспкамп
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ветку, объединит ее с CURRENT и затем переключится обратно.

Например, если вы находитесь на masterветке, он объединит мастера с dev, и вы все равно будете на мастере.

Это определенно идет к моим точечным файлам :)

[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 выше. этот псевдоним объединяет текущую ветку с указанной веткой. Он использует метод remotes и использует команды 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
TField
источник
4

Чтобы объединить текущую ветку с другой веткой без проверки другой ветки:

Ускоренное слияние

Это действительно легко. По определению, ускоренное слияние просто означает, что указатель ветви перемещается вперед в дереве фиксации. Так что все, что вам нужно сделать, это просто симулировать это:

git branch -f master dev

Предостережения: Предполагается, что это masterуказывает на коммит, который также находится в devветке или некоторой другой ветке. Если этого не произойдет, вы рискуете потерять работу! В отличие от того, git mergeчто создаст коммит слияния (или выдает жалобу), когда быстрая перемотка вперед невозможна, этот метод молча заставляет указатель ветви указывать на другой коммит.

Это также предполагает, что вы являетесь единственным, кто работает над репо, и / или вы знаете, что делаете.

Подсказка: Если вы сделали a 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чтобы просто внести изменения в разработку. Некоторым может быть все равно, но для других это может быть важно.

ADTC
источник
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
  • функция включает в себя нулевую команду, : 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"
ARTM
источник