Можно ли запускать несколько вызовов ‘git merge’ одновременно?

#git

#git

Вопрос:

Я пытаюсь написать инструмент, основанный на git, но выполняющий некоторые довольно необычные вещи, и мне нужно знать: безопасно ли запускать несколько экземпляров git merge --ff-only [remote-branch] одновременно, чтобы получить новейший коммит, доступный для любого из них? Все удаленные устройства будут находиться в одной строке коммитов. Я бы хотел, чтобы мой инструмент просто создавал их все и позволял git разбираться, но мне нужно знать, вызовет ли это проблемы. Кто-нибудь достаточно знает о внутренностях git, чтобы сказать так или иначе?

Комментарии:

1. Не могли бы вы немного подробнее рассказать о варианте использования? Могут ли разные удаленные устройства иметь конфликтующие изменения? Не могли бы вы получить базовое выполнение git fetch и использовать git log для канонического выбора последнего?

2. Я использую git для распределения некоторых данных по нескольким машинам. Конфликтов возникнуть не может, поскольку существует только один конечный источник новых коммитов. «Слияние» в данном случае действительно неправильное название, потому что все, что я хочу сделать, это посмотреть, является ли ветка удаленного отслеживания более новой, и обновить главную ветку и рабочую копию, если это так. Большинство слияний будут без операций, но иногда обновление будет распространяться, и в редких случаях может быть два или три удаленных устройства, каждое из которых имеет одинаковую обновленную фиксацию в более или менее одинаковое время.

3. Затем a git fetch со всех удаленных устройств, затем a git merge --rebase до самого удаленного head, который вы только что выбрали, делает то, что вы хотите.

4. Намного ли быстрее проверять, какой head из N пультов является наиболее актуальным, чем просто запускать все слияния одно за другим?

5. Слияние в стиле Octopus с принудительной пересылкой, вероятно, потребовало бы меньше кода для того же результата. Выполнение слияний одно за другим тоже сработало бы, но это не может быть одновременным 🙂

Ответ №1:

Если вы выполняете слияния только для —ff, почему бы вам просто не проверить ссылки с помощью git branch --contains или каким-либо другим способом, чтобы увидеть, доступен ли старый коммит, а затем выполнить сброс или update-ref?

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

Комментарии:

1. Спасибо, это действительно звучит действительно полезно!

Ответ №2:

Git использует блокировки для предотвращения одновременного доступа, в худшем случае ваша попытка слияния завершится неудачей с чем-то вроде lock file exists ошибки.

Кстати, слияние разрешает многократное слияние, существует стратегия слияния octopus.

Комментарии:

1. Слияние Octopus — это круто, однако в OP упоминается --ff-only , что никогда не произойдет в случае с octopus, верно?

2. @Romain Да, наверное… Но если бы все ветви имели одинаковые коммиты (т. Е. просто что-то вроде резервных копий друг друга), это могло бы сработать, однако я сам не пробовал и сомневаюсь…

3. Слияние octopus действительно создает MERGE_HEAD, который содержит все ссылки на каждый объединяемый коммит.

Ответ №3:

В этой ситуации, почему бы вам просто не объединить каждую удаленную ветвь по очереди, вместо того, чтобы создавать их одновременно?

  #!/bin/sh
 set -e
 for rtb in origin/master github/master gitorious/master
 do
     git merge --ff-only $rtb
 done
  

Если HEAD уже содержит одну из ветвей удаленного отслеживания, слияние все равно возвращается успешно, говоря Already up-to-date.

Комментарии:

1. Я делаю это, но оказывается, что ‘git merge’ может случайным образом занимать более минуты, если ввод-вывод работает плохо, поэтому я хотел, чтобы поток, ответственный за это, мог сделать что-то еще. Я могу просто поместить все слияния в отдельный поток, сериализовать и покончить с этим.

2. Правильно. При обходе графика фиксации должно быть задействовано очень мало операций ввода-вывода, чтобы определить, необходимо ли слияние. В большинстве случаев я подозреваю, что большая часть операций ввода-вывода заключается в фактической проверке нового коммита после обнаружения необходимости ускоренного слияния, и в этом случае ваш лучший выигрыш заключается в поиске самого последнего коммита и просто слиянии этого.