2016-12-07 1 views
0

Кажется, что на эту тему тысячи вариантов, и многие из них были заданы, но я не могу найти подходящее решение для меня.git: checkout vs merge vs ?? для разрешения конфликтов в пользу наших выборочно

У меня есть две линии развития: одна на «хозяине», сделанная мной (нашей), и одна на ветке «их_new_stuff». Оба изменили значительное количество файлов, касаясь многих файлов в одном месте и создавая конфликты.

Теперь мне нужно объединить свою работу в нашу работу и разобраться с конфликтами следующим образом: на 99% этих конфликтов я могу просто принять «наш». Однако мне также нужны все изменения, которые они сделали, которые не конфликтуют, и в нескольких ключевых конфликтах мне нужно принять их или объединить вручную. Знание того, какие файлы требуют ручного слияния или «их» в слиянии, требует ручного контроля.

Я попытался следующие:

Попробуйте 1:

git merge their_new_stuff 
# for each file with conflicts: 
    # if requires manual merge: 
     # do manual merge 
    # else: 
     git checkout --ours all/files/not/merged/by/hand.cc 

Сначала я думал, что это было то, что я хотел, но это не работает, потому что фотографии с «нашим» является полный файл checkout и не только проверяет/разрешает конфликтующие части. Поэтому я теряю несогласные изменения, которые я хочу.

Попробуйте 2:

git merge -s recursive -Xours their_new_stuff 

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

Попробуйте 3: Тогда я думал, что я мог бы быть в состоянии сделать что-то вроде:

git merge their_new_stuff 
# for each file with conflict: 
    # if file needs manual merge: 
     cp file file2 
git merge --abort 
git merge -s recursive -Xours their_new_stuff 
# for each file with manual merge: 
    cp file2 file 
    # merge by hand 

Я думаю, что это должно работать, но он чувствует себя очень klugy. Есть ли «правильный» способ сделать это? В идеале я хотел бы сделать что-то вроде:

git merge their_new_stuff 
# for each file with conflict 
    # if needs manual merge 
     # do manual merge 
    # else 
     # is there any command that does something like?: 
     git remerge -s recursive -Xours file 

Фактически я хочу выполнить слияние, получив маркеры конфликтов. Осмотрите для ручного слияния, и если ручное слияние не требуется, повторите слияние только с этим файлом с помощью «-Xours». Это возможно?

+0

Git имеет 'ГИТ-слияние-File', который можно использовать на основе каждого файла. Обратите внимание, что для использования * для * вы должны извлечь (как правило, из трех этапов индекса) базу (этап 1), локальные ('--ours') и другие (' --theirs') файлы в обычные файлы файловой системы. Обратите внимание, что 'merge-file' * does * принимает' --ours' и '--theirs', которые имеют значение стиля' -X'. – torek

+0

@torek Спасибо, не знал об этом. Это интересно - я думаю, я мог бы «слить», чтобы увидеть конфликты, затем прервать, а затем использовать '' merge-file -ours'' в файлах «keep ours» и '' merge-file'' без '' --ours'', чтобы получить маркеры конфликтов в файлах с «ручным слиянием». Если что-то лучше не появится в ближайшее время, не стесняйтесь ответить на этот вопрос, и я соглашусь. –

+0

Вам даже не нужно (и, возможно, не хочу) прервать слияние: вы хотите извлечь три индексные версии файла во временные разделы, и они останутся * в * индексе только тогда, когда файл остается неразрешенным. (См. Также: 'git ls-files --stage',' git ls-files --unmerged'.) – torek

ответ

1

Git является respository на основе системы управления версиями, а это означает, что изменения в состоянии в ветке Git обычно применяются к всем файлов в этой отрасли. Это принципиально отличается от других инструментов VCS, таких как SVN, где отдельные файлы можно манипулировать и совершать. В Git нет понятия в виде единого слияния файлов. Если вы объедините две ветви, то все файлы должны быть сверены во время слияния.

Оба изменили значительное количество файлов, касаясь многих файлов в одном и том же месте и создавая конфликты.

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

Что касается вашей текущей проблемы, я бы просто посоветовал вам объединиться вручную. Если вы уверены, что вы хотите версию либо родительский файл, а затем использовать один из следующих способов:

git checkout --theirs <path/to/file.ext> 
git checkout --ours <path/to/file.ext> 
+0

Спасибо за ответ. Да, я понимаю, что слияние - это концепция, основанная на репо, но мое впечатление (я долговременный пользователь Mercurial, но новый для git) заключался в том, что git имел большую поддержку слияния на уровне hunk. Наверное, это то, что мне нужно узнать? В то время как ваша идеальная ситуация была бы приятной, в этом проекте это не так с 10 разработчиками. 99% конфликтов - это действительно измененный интерфейс конструктора, и два человека фактически изменили его примерно так же. –

+0

@EthanCoon В моем опыте, если вы недостаточно умны, чтобы разрешить конфликт с уродливым слиянием, тогда Git обычно тоже не является. Да, вы могли бы попытаться создать скрипты для автоматизации этого, но я максимально параноик при разрешении конфликтов слияния и всегда делаю это вручную. Может, кто-то другой даст вам другой ответ. –

+0

Я достаточно умен, чтобы сделать это, я просто ленив! С первого взгляда я вижу, что я хочу «наш», но только для этого интерфейса. Так как checkout IS file-wise, а не hunk-wise, это не работает. Если файл имеет только конфликты смены интерфейса, то разрешение всех конфликтов в пользу наших будет работать, но я, похоже, не достаточно умен, чтобы сказать git, чтобы сделать это. –