Есть ли чистый способ обработки двух оригинальных git-репозиториев, которые начинались с одного и того же контента?
Скажем, у меня есть два репозитория, которые были созданы из одного исходного содержимого. Например, если я использовал git для управления файлами конфигурации apache в /etc/apache2 и я запустил git init
на машине-а и машине-б отдельно.
С тех пор я внес некоторые изменения в конфигурацию машины-b, которые я хотел бы применить к конфигурации на машине-a, не переписывая необычные вещи, такие как имена хостов и т. Д.
Если я сделаю это:
machine-a% remote add machine-b ssh://...
machine-a% git fetch machine-b
Я получаю все коммиты на машине-b, а GitX показывает совершенно отключенный набор коммитов, как я и ожидал.
Однако, если я пытаюсь объединить любое из изменений машины-b, я получаю конфликты на всех измененных строках.
Для моих целей это достаточно хорошо, но мне интересно, есть ли более чистое решение?
3 ответа
Возможно, вы захотите посмотреть на мерзавцы. Некоторая информация доступна здесь: http://git-scm.com/docs/git-filter-branch
По сути, вы хотите подделать родословную.
Вы сделали первоначальный коммит на обеих машинах - давайте назовем их "baseA" и "baseB". Затем вы создали второй коммит поверх этого с обеих сторон - 'secondA' и 'secondB'. Что вы хотите сделать, так это сказать git, что "secondB" не имеет "baseB" в качестве предка, а вместо этого "baseA" в качестве родителя.
Вы можете сделать это с помощью прививки. Например, поместите это в ваш файл.git/info/grafts:
secondB baseA
(но затем используя настоящие SHA). Теперь, если вы посмотрите в GitX, вы увидите, что истории связаны. Чтобы сделать изменение постоянным, вам нужно запустить git filter-branch.
Обновление из комментариев
Я не уверен, что вы сделали "правильно", хотя это сработает. Если вы сделаете то, что сделали, вы получите как историю:
BaseA --- SecondA -- .. - .. - Merge
\ BaseB --- SecondB ... - .. /
Который будет работать (и слияние будет успешным без проблем). Однако, что немного приятнее, так это:
BaseA --- SecondA -- .. - .. - Merge
\ SecondB ... - .. /
который в основном отбрасывает "BaseA" как коммит и устанавливает "BaseA" в качестве родителя для SecondB. Это должно быть возможно с использованием правила взяточничества, которое я вам сказал.
Чтобы продемонстрировать это, я создал небольшой репозиторий, который вы можете скачать здесь.
Если вы посмотрите на историю в GitX ("gitx master second_master"), вы увидите, что истории отключены. Если вы переместите файл.git/info/_grafts в.git/info/grafts, вы получите вторую красивую историю.
Я также добавил файл.git / info / false_grafts. Если вы используете это, вы получите историю, которую вы создали.
Если вы посмотрите на SHA в файле трансплантатов, то увидите, что файл _grafts в основном имеет следующее:
SecondB BaseA
и файл неправильный_графов имеет это:
BaseB BaseA
Это интересное использование Git; Я мог бы использовать его для работы с несколькими веб-сайтами, которые основаны на одной и той же кодовой базе вики, но имеют очень разные конфигурации.
Настройте репозиторий Git с исходным содержимым и создайте отдельные ветки для каждого компьютера, на котором хранится его текущая конфигурация. Клонируйте другой компьютер и установите каждый компьютер как удаленный для другого.
Теперь вы можете вносить изменения на одной машине и помещать их в свою ветку на другой машине, когда вы их фиксируете.
Если вы фиксируете общие элементы отдельно от не общих элементов, вы можете
$ git checkout [localmachine bracnch]
$ git cherry-pick [SHA1 of common commit1]
$ git cherry-pick [SHA1 of common commit2]
И, если вы не знаете, что вы хотите использовать повторно до фиксации на одной машине, вы можете использовать git add --patch
вытащить отдельные дифференциалы из одной ветви и поставить их в соответствие другой ветке.
Для более чем двух машин / сайтов вы можете объединить общие изменения на MASTER
и объединить изменения в MASTER
на каждую из ветвей.
Как Git может определить, что такое "изменение конфигурации" и что такое "необычная вещь"? Есть ли только определенные файлы, которыми вы хотите поделиться между ними, например, файлы типа MIME?
Как насчет разделения общих частей на отдельные файлы и использования директивы Include Apache и добавления любых файлов, которые вы хотите игнорировать, в.gitignore?