Я работаю над проектом, который имеет 2 ветви, A и B. Обычно я работаю в ветви A и объединяю вещи из ветви B. Для объединения я обычно делаю:
git merge origin/branchB
Тем не менее, я также хотел бы сохранить локальную копию ветви B, так как я могу иногда проверять ветку, не сливаясь сначала с моей веткой A. Для этого я бы сделал:
git checkout branchB
git pull
git checkout branchA
Есть ли способ сделать вышеупомянутое в одной команде, и без необходимости переключать ветку назад и вперед? Должен ли я использовать git update-ref
для этого? Как?
git
git-merge
git-pull
git-checkout
Чарльз
источник
источник
--no-ff
опцию, которая в любом случае вызывает фиксацию слияния. Если вас это заинтересует, мой ответ показывает, как вы могли бы это сделать - не такой надежный, как мой опубликованный здесь ответ, но сильные стороны этих двух вопросов, безусловно, можно объединить.Ответы:
Краткий ответ
Пока вы выполняете ускоренное слияние, вы можете просто использовать
Примеры:
Хотя ответ Амбер также будет работать в случаях ускоренной перемотки вперед, использование
git fetch
этого способа немного безопаснее, чем просто принудительное перемещение ссылки ветвления, посколькуgit fetch
автоматически предотвратит случайные не быстрые перемотки вперед, если вы не используете+
в refspec.Длинный ответ
Вы не можете объединить ветвь B с ветвью A без предварительной проверки A, если это приведет к слиянию без ускоренной перемотки вперед. Это потому, что рабочая копия необходима для разрешения любых потенциальных конфликтов.
Однако в случае слияния с ускоренной пересылкой это возможно , поскольку по определению такие слияния никогда не приводят к конфликтам. Чтобы сделать это без предварительной проверки ветки, вы можете использовать
git fetch
с refspec.Вот пример обновления
master
(запрещающий изменения без ускоренной перемотки вперед), если у вас есть другая ветвь,feature
проверенная:Этот вариант использования настолько распространен, что вы, вероятно, захотите создать для него псевдоним в файле конфигурации git, например:
Этот псевдоним делает следующее:
git checkout HEAD
: это переводит вашу рабочую копию в отдельное состояние. Это полезно, если вы хотите обновить,master
пока вы его не извлекли. Я думаю, что это было необходимо сделать, потому что в противном случае ссылка на ветвь дляmaster
не будет двигаться, но я не помню, действительно ли это не в моей голове.git fetch upstream master:master
: это переместит ваш местный жительmaster
в то же место, что иupstream/master
.git checkout -
проверяет вашу ранее извлеченную ветку (это то, что-
делает в этом случае).Синтаксис
git fetch
для (не) ускоренного слиянияЕсли вы хотите, чтобы
fetch
команда потерпела неудачу, если обновление происходит без ускоренной перемотки, вы просто используете refspec в формеЕсли вы хотите разрешить обновления без ускоренной пересылки, добавьте a
+
в начало refspec:Обратите внимание, что вы можете передать свой локальный репозиторий как «удаленный» параметр, используя
.
:Документация
Из
git fetch
документации, которая объясняет этот синтаксис (выделено мной):Смотрите также
Git оформить заказ и слить, не касаясь рабочего дерева
Слияние без изменения рабочего каталога
источник
git checkout --quiet HEAD
поgit checkout --quiet --detach
состоянию на Git 1.7.5.git fetch . origin/foo:foo
обновить мой локальный foo до моего локального происхождения / foogit checkout -
трюк! Так же просто, какcd -
.Нет, нет. Извлечение целевой ветви необходимо для разрешения конфликтов, среди прочего (если Git не может автоматически объединить их).
Однако, если слияние происходит быстро, вам не нужно проверять целевую ветвь, потому что вам на самом деле ничего не нужно объединять - все, что вам нужно сделать, это обновить ветку, чтобы она указала на новый руководитель исх. Вы можете сделать это с
git branch -f
:Обновлю,
branch-b
чтобы указать на главуbranch-a
.-f
Вариант означает--force
, что означает , что вы должны быть осторожны при ее использовании.источник
git reset
работает только в проверенной ветке.git fetch upstream branch-b:branch-b
(взято из этого ответа ).git fetch <remote> B:A
, где B и A - это совершенно разные ветви, но B можно быстро переместить вперед в A. Вы также можете передать свой локальный репозиторий как «удаленный», используя.
в качестве удаленного псевдонима:git fetch . B:A
,branch -f
того, как вы указываете , может быть опасно. Так что не используйте это! Используйтеfetch origin branchB:branchB
, что не удастся безопасно, если слияние не вперед.Как сказала Эмбер, слияния с ускоренной перемоткой - единственный случай, когда вы могли это сделать. Любое другое слияние, по-видимому, должно пройти через все трехстороннее слияние, применение исправлений, разрешение конфликтных ситуаций - и это означает, что вокруг должны быть файлы.
У меня есть сценарий, который я использую именно для этого: выполнение слияний в ускоренном режиме без соприкосновения с рабочим деревом (если только вы не объединяетесь в HEAD). Это немного долго, потому что это, по крайней мере, немного надежно - он проверяет, чтобы слияние было бы быстрым, затем выполняет его, не проверяя ветвь, но производя те же результаты, как если бы вы имели - вы видите
diff --stat
Сводка изменений, и запись в reflog точно такая же, как слияние с ускоренной перемоткой, а не «сброс», который вы получаете, если используетеbranch -f
. Если вы называете этоgit-merge-ff
и поместите его в директории бен, вы можете назвать его как мерзавец команды:git merge-ff
.PS Если кто-нибудь видит какие-либо проблемы с этим сценарием, пожалуйста, прокомментируйте! Это была работа «пиши и забудь», но я был бы рад ее улучшить.
источник
# or git branch -f localbranch remote/remotebranch
напоминает мне об источнике и опциях. Оставил свой комментарий по другой ссылке +1."$branch@{u}"
качестве коммитта для слияния, чтобы получить ветку восходящего потока (из kernel.org/pub/software/scm/git/docs/gitrevisions.html )Вы можете сделать это, только если слияние ускорено. Если это не так, то git нужно проверить файлы, чтобы он мог объединить их!
Чтобы сделать это только для ускоренной перемотки вперед :
где
<commit>
выбранный коммит, который вы хотите перемотать вперед. Это в основном похоже на использованиеgit branch -f
для перемещения ветки, за исключением того, что она также записывает это в журнал изменений, как будто вы на самом деле сделали слияние.Пожалуйста, пожалуйста, пожалуйста , не делайте этого для чего-то, что не является перемоткой вперед, или вы просто сбросите свою ветку на другой коммит. (Для проверки посмотрите,
git merge-base <branch> <commit>
дает ли ветвь SHA1.)источник
git merge-base --is-ancestor <A> <B>
. «Б» - это то, что нужно объединить в «А». В качестве примера можно привести A = master и B = развернуть, убедившись, что разработка быстро переходит в master. Примечание: он существует с 0, если он не ff-способен, существует с 1, если он есть.В вашем случае вы можете использовать
который делает то, что вы хотите (при условии быстрого слияния). Если ветвь не может быть обновлена, потому что она требует слияния без ускоренной перемотки вперед, тогда это безопасно завершается с сообщением.
Эта форма извлечения также имеет несколько полезных опций:
Обратите внимание, что это
<remote>
может быть локальный репозиторий и<sourceBranch>
ветвь отслеживания. Таким образом, вы можете обновить локальную ветку, даже если она не извлечена, без доступа к сети .В настоящее время мой доступ к вышестоящему серверу осуществляется через медленный VPN, поэтому я периодически подключаюсь,
git fetch
обновляю все пульты, а затем отключаюсь. Тогда, если, скажем, удаленный мастер изменился, я могу сделатьчтобы безопасно привести моего местного мастера в актуальное состояние, даже если у меня в настоящее время есть другая ветвь, проверенная. Доступ в сеть не требуется.
источник
Другой, по общему признанию, довольно грубый способ - просто заново создать ветку:
Это отбрасывает локальную устаревшую ветвь и воссоздает одну с тем же именем, поэтому используйте с осторожностью ...
источник
Вы можете клонировать репо и выполнить слияние в новом репо. На той же файловой системе, это будет жесткая ссылка, а не скопировать большую часть данных. Закончите, потянув результаты в исходный репо.
источник
Введите git-forward-merge :
https://github.com/schuyler1d/git-forward-merge
Работает только для автоматических слияний, если есть конфликты, вам нужно использовать обычное слияние.
источник
Во многих случаях (например, слияние) вы можете просто использовать удаленную ветвь без необходимости обновлять локальную ветвь отслеживания. Добавление сообщения в reflog звучит как излишнее и остановит его быстрее. Чтобы облегчить восстановление, добавьте следующее в ваш git config
Затем введите
чтобы увидеть недавнюю историю для вашей отрасли
источник
[core]
нет[user]
? (и он по умолчаниюЯ написал функцию оболочки для аналогичного варианта использования, с которым я сталкиваюсь ежедневно в проектах. По сути, это ярлык для поддержания локальных веток в актуальном состоянии с помощью общей ветки, такой как разработка до открытия PR и т. Д.
glmh
(«git pull and merge here») автоматическиcheckout branchB
,pull
последний, повторноcheckout branchA
иmerge branchB
.Не учитывает необходимость хранить локальную копию branchA, но его можно легко изменить, добавив шаг перед проверкой branchB. Что-то вроде...
Для простых быстрых слияний, это пропускает к приглашению сообщения фиксации.
Для слияний без ускоренной пересылки это переводит вашу ветвь в состояние разрешения конфликта (вам, вероятно, нужно вмешаться).
Чтобы настроить, добавить в
.bashrc
или.zshrc
, и т. Д .:Применение:
источник
Другой способ эффективно сделать это:
Поскольку это нижний регистр
-d
, он удалит его только в том случае, если данные еще будут где-то существовать. Это похоже на ответ @ kkoehne, за исключением того, что оно не вызывает. Из-за этого-t
он снова настроит пульт.У меня была немного другая потребность, чем в OP, который заключался в создании новой ветви функций
develop
(илиmaster
) после объединения запроса на удаление. Это может быть выполнено в одну строку без силы, но это не обновляет локальнуюdevelop
ветвь. Это просто вопрос проверки новой ветки и ее основаниеorigin/develop
:источник
просто вытащить мастера, не проверяя мастер, который я использую
git fetch origin master:master
источник
Абсолютно возможно выполнить любое слияние, даже без слияния без перемотки вперед
git checkout
.worktree
Ответ на @grego хороший намек. Чтобы расширить это:Теперь вы объединили локальную рабочую ветку с локальной,
master
не переключая оформление заказа.источник
Если вы хотите сохранить то же дерево, что и одна ветвь, которую хотите объединить (т. Е. Не настоящее «слияние»), вы можете сделать это следующим образом.
источник
Вы можете попытаться
git worktree
открыть две ветви рядом друг с другом, это звучит так, как будто это то, что вы хотите, но сильно отличается от некоторых других ответов, которые я видел здесь.Таким образом, вы можете иметь две отдельные ветви отслеживания в одном и том же git-репо, так что вам нужно всего лишь один раз получить обновления, чтобы получать обновления в обоих рабочих деревьях (вместо того, чтобы выполнять git clone дважды и git pull для каждого)
Worktree создаст новый рабочий каталог для вашего кода, в котором вы можете одновременно проверять другую ветку вместо того, чтобы поменять местами ветки.
Если вы хотите удалить его, вы можете очистить с помощью
источник