2016-09-26 4 views
8

Я хочу сохранить все мои файлы в git хранилище с отдельной веткой для каждой машины. У меня есть проблема, которую я не могу решить, что блокирует меня от , используя для этого git. Я хотел бы знать, как другие люди решили это.Избегайте конфликтов слияния при слиянии мастера с отдельной веткой для каждого хоста

Я собираюсь иметь одну master ветвь, которая содержит только определения и определения, которые, как предполагается, являются общими для всех ветвей шаблона, например:

export EMAIL="@[email protected]" 
export SURFRAW_google_results=1000 

Я заменит @[email protected] с моим правильным e-mail на машинных отделениях и зафиксировать его, но SURFRAW_google_results останется неизменным. Для например, на work ветке я буду иметь это:

export EMAIL="[email protected]" 
export SURFRAW_google_results=1000 

Теперь я решил изменить SURFRAW_google_results=1000 10. Это должен использоваться по всему миру, так что я первый я изменить его на master:

export EMAIL="@[email protected]" 
export SURFRAW_google_results=10 

и затем я перебазироваться work на master:

$ git checkout work 
$ git rebase master 

А теперь я получаю конфликт, потому что линия, которая находится выше линии I изменился отличается:

<<<<<<< a60114eea1c98d2354a07bd4fd0cdd63cba62e93 
export EMAIL="@[email protected]" 
export SURFRAW_google_results=10 
======= 
export EMAIL="[email protected]" 
export SURFRAW_google_results=1000 
>>>>>>> m 

В случае bash я мог быстро уйти с в том числе машины конкретной части путем поиске механизма, но как насчет , которые не поддерживают включение/выключение других конфигураций, таких как .fluxbox/keys или .screenrc?

+0

Если я правильно понимаю вашу проблему, вы не хотите разрешать конфликт, но хотите предотвратить его в будущем, когда тот же файл изменится, и вы захотите снова переустановить его? – Ma3x

+0

Да, я ищу способ предотвратить такие конфликты. Я прочитал много статей о людях, которые хранят отдельные части конфигураций в отдельных ветвях, но никто не описывал, как бороться с конфликтами. – user1042840

+1

Я не думаю, что вы можете предотвратить конфликты в своем сценарии, однако вы можете записать желаемое разрешение (возможно, другое для каждой ветви машины), чтобы в будущем вам больше не нужно было разрешать эти конфликты. Мне никогда не приходилось использовать это самостоятельно, но посмотрите, может ли это решить вашу проблему: https://git-scm.herokuapp.com/blog/2010/03/08/rerere.html. – Ma3x

ответ

8

Вместо изменения параллельных данных непосредственно между ветвями (что приводит к конфликту as illustrated in this answer), вы можете с учетом content filter driver, используя .gitattributes declaration.

smudge (изображение из «Customizing Git - Git Attributes», от «Pro Git book»)

Идеи заключается в том, чтобы управлять этими точечными файлами в версии, но с шаблоном заполнителей вместо фактических значений (которое зависит от филиал).
Сгенерированные фактические dotfiles остаются игнорируемыми (по .gitignore).
Это означает, что ваше фактическое рабочее дерево не становится «грязным».

Файлы с фактическими значениями может быть также версируются, но с разными названиями (так что никаких конфликтов при слиянии/перебазирования)

Сценарий размазать выберите нужный файл значение в зависимости от имени ветви, и генерировать правильный dotfile на основе шаблона dotfile применяется скрипт smudge во время git checkout.

Чтобы иметь размытие, действующее по-разному на каждую ветку, я бы рекомендовал вызвать скрипт, который начинается с поиска имени текущей ветви.
См. Пример в моем более раннем ответе «Best practice - Git + Build automation - Keeping configs separate».

#!/bin/sh 
branch=$(git rev-parse --symbolic --abbrev-ref HEAD) 

OP упоминает, что для сценария размазать применять на проверку, удаление необходим индекс. Это верно, так как I explained here:

индекс среднего человек для перемещения вещей с рабочим дерева к объекту-магазину и для перемещения вещей из объекта-магазина к работе дереву.

Удаляя индекс, вы принудительно git восстанавливаете его, что означает применение любого фильтра фильтра содержимого, если он присутствует.

См. "git: re-checkout files after creating smudge filter".

+0

Я попробовал 'smudge' /' clean' фильтры - они были бы здорово, потому что они: 1. не делайте рабочее дерево грязным 2. предотвратите конфликты слияния 3. может быть запускать автоматически. Но проблема в том, что они не запускаются, когда файл * тот же * на обоих ветвях. Например, если у меня есть шаблон '.bashrc', заполненный' @ EMAIL @' на моей главной ветке, и я переключаюсь на 'work', который имеет шаблон _same_' .bashrc' и дополнительно имеет '.conf' файл, содержащий реальные определения всех заполнителей, такие как как 'EMAIL', а затем фильтр' smudge' не запускается. Я не нашел способ заставить его. – user1042840

+0

@ user1042840 Я всегда мог заставить фильтр smudge запускаться снова с глобальной 'git checkout'. См. Пример https://github.com/VonC/compileEverything/blob/3fb31b840b6d03e28125ffccb69122c07cd63837/gitolite/install_or_update_gitolite.sh#L16-L21 (март 2013 г.), когда я хотел активировать свой фильтр «shebang» (https: // github .com/VonC/compileEverything/blob/3fb31b840b6d03e28125ffccb69122c07cd63837/gitolite/attributes: https://github.com/VonC/compileEverything/blob/3fb31b840b6d03e28125ffccb69122c07cd63837/gitolite/shebang_replace): обычно достаточно 'git checkout HEAD - .'. – VonC

+0

К сожалению, ни один из методов, которые я пробовал, работает с 'git 2.9.0' и с 'git', скомпилированным из текущего' HEAD', если файлы, указанные в '.gitattributes', не меняются - фильтры не запускаются. Это действительно работает для вас? – user1042840