Как объединить конфликты (файл project.pbxproj) в Xcode использовать SVN?

В нашей команде два члена. Мы используем SCM XCode (используйте SVN) для управления нашими файлами исходного кода.
Мы все добавляем файлы в наш проект XCode. Он посвятил себя серверу SVN. Когда я обновляю, XCode обнаруживает, что есть конфликты в project.pbxproj файл. Затем я выбираю выйти Xcode и вручную объединить конфликты. Тогда я начинаю редактировать мой project.pbxprojСлей наши изменения. На самом деле я не знаю, как XCode управляет файлами, я просто добавляю текст, который мой project.pbxproj файла не было. Когда я закончу, мой проект не может открыться. Я думаю, потому что project.pbxproj файл не может быть отредактирован вручную.

Итак, я хочу знать, когда вы обнаружите эту проблему, файл project.pbxproj конфликтует, как ее решить?

Спасибо!

10 ответов

Решение

К сожалению, вы ничего не можете сделать, кроме как внести изменения вручную за один раз, а затем зарегистрировать новый "объединенный" проект.

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

Обычно редактирование очень легко, хотя. Просто зайдите в файл project.pbxproj с помощью текстового редактора и найдите раздел конфликта слияния - обычно это помечается чем-то вроде:

>>>>>>>
Stuff 1
======
Stuff 2
<<<<<<<<

В 99% случаев конфликта слияния проекта Xcode вы просто хотите принять обе стороны слияния (потому что два человека добавили разные файлы) - так что вы просто удалили бы маркеры слияния, в приведенном выше случае, что в конечном итоге будет выглядеть так:

Stuff 1
Stuff 2

Как я уже сказал, это прекрасно работает в большинстве случаев. Если XCode не будет читать файл проекта, когда вы закончите, просто возьмите самую последнюю версию без слияния и вручную добавьте ваши файлы снова.

Это решение только для git, но вы можете добавить .gitattributes файл в свой проект, затем в этом файле добавьте следующую строку:

*.pbxproj merge=union

Это скажет git сохранить обе стороны слияния, что будет тем, что вы хотите, большую часть времени.

Чтобы вручную разрешить конфликты слияния, проверьте UUID каждого конфликтующего элемента.

Пример:

<<<<<<< HEAD
    6B01C4B72008E70000A19171 /* ExistingFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B01C4B62008E70000A19171 /* ExistingFile.swift */; };
    3F01C4B72008E70000889299 /* NewFileA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F01C4B72008E70000889299 /* NewFileA.swift */; };
=======
    6B01C4B72008E70000A19171 /* ExistingFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B01C4B62008E70000A19171 /* ExistingFile.swift */; };
    4DF01C4B72008E70000882ED /* NewFileB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF01C4B72008E70000882ED /* NewFileB.swift */; };
>>>>>>> branch_to_merge

Проверьте каждый UUID:

  • Если это происходит в обеих версиях, удалите его в одной версии: ExistingFile.swift
  • Если это не происходит в ветви сравнения, сохраните это: NewFileA.swift а также NewFileB.swift
  • Если на него нет ссылки где-либо еще в файле, т.е. вы можете найти только одно вхождение в целом project.pbxproj файл, я бы предположил, что это артефакт и безопасно его удалить.

Результат будет:

    6B01C4B72008E70000A19171 /* ExistingFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B01C4B62008E70000A19171 /* ExistingFile.swift */; };
    3F01C4B72008E70000889299 /* NewFileA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F01C4B72008E70000889299 /* NewFileA.swift */; };
    4DF01C4B72008E70000882ED /* NewFileB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF01C4B72008E70000882ED /* NewFileB.swift */; };

Примечание: я не рекомендую добавлять *.pbxproj merge=union к .gitattribues файл, который в основном игнорирует конфликты слияния, потому что конфликтующее слияние должно всегда проверяться вручную, если для этого не существует сложного сценария.

На данный момент лучший инструмент визуального слияния, который я использовал для файлов pbx, - это инструмент слияния Visual Studio Code. Я открываю файл pbx в приложении "Код" и исправляю конфликты, затем снова открываю XCode.

Я искал простое решение этой проблемы, когда наткнулся на этот другой вопрос / ответ:

/questions/4766004/sliyanie-fajlov-proekta-xcode/4766020#4766020

Я был просто поражен тем, насколько простым является это решение, я пытался слиться в разрозненную ветвь функций, которая была за почти 200 ревизиями за стволом, XCode и Mercurial не были счастливы от этого. Я попытался вручную объединить файл pbxproj (в котором было более 100 конфликтов) 8 раз, прежде чем пытаться найти решение.

В основном решение таково (при условии, что вы используете Mercurial, потому что это круто):

  1. Попытайтесь слить в Mercurial:

    hg update FEATURE_BRANCH
    hg merge default
    *mercurial gives you a ton of crap about the pbxproj file having merge conflicts*
    
  2. Открыть Xcode

  3. На верхней панели инструментов выберите Xcode->Open Developer Tool->FileMerge
  4. Слева откройте конфликтующий файл 'project.pbxproj' (файл с разметкой конфликта слияния)
  5. На правой стороне откройте свой "project.pbxproj.orig"
  6. Выберите File->Save Merge и сохраните поверх файла 'project.pbxproj'
  7. Затем вернемся в командную строку:

    hg resolve -m ProjectName.xcodeproj/project.pbxproj
    *merge any other broken files*
    hg commit -m "manually merged with trunk"
    
  8. Ешь торт, потому что ты готов

Иногда один или несколько файлов могут быть воссозданы (например, ManagedObjects) в разных ветвях, поэтому при объединении может быть два объявления для одного файла в одном блоке. В этом случае вам следует удалить одно из объявлений.

Как указано выше, наиболее распространенным способом разрешения конфликтов является

  1. принять "все"
  2. повторно импортировать файлы в проект

Я написал bash-скрипт, который заботится о (1) выше.

Обратите внимание, что это решит только самый распространенный случай конфликтов слияния!

#!/bin/bash
#
#
#
if [ $# -eq 0 ]
 then
    echo "File must be provided as argument, darnit!"
    exit 1
fi

if [ $# -eq 2 ]
 then
    echo "only ONE File must be provided as argument, darnit!"
    exit 1
fi


echo "Will remove lines from file:" $1
grep -v "<<<<<" $1  | grep -v ">>>>>>" | grep -v "====" > out.tmp;mv out.tmp $1
echo "Done removing lines from file:" $1

Я случайно столкнулся с этой сложной проблемой.

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

  1. Git Checkout Master.
  2. Копировать содержимое в project.pbxproj
  3. Git оформить заказ в свою ветвь функции и вставить его.(Переопределить текущий контент в project.pbxproj)
  4. Бежать

    react-native link
    

Вы можете открыть его на VSCODE и исправить там конфликтующее слияние. поищите цветные аннотации в среде IDE или найдите <<< >>> в текстовом поиске.

Я основал инструмент "xUnique" https://github.com/truebit/xUnique, он работает!

Я знаю, что 90 процентов конфликтов ясны, и вы можете принять оба изменения в конфликтах, поэтому вам не нужно беспокоиться, вы разрешите его, если проявите терпение, как я обнаружил, что используйте такие инструменты, как xUnique, которые вам очень помогут

Лучше всего просто принять вашу версию или его версию полностью, не пытаясь объединить их. Кроме того, подумайте, является ли рассматриваемый файл чем-то, что вообще должно быть в хранилище; может быть более уместно позволить каждому человеку иметь свою собственную версию этого.

Ознакомьтесь с документацией по разрешению конфликтов.

Другие вопросы по тегам