2012-11-05 3 views
122

Раскадровка - скорее королевская боль из перспективы рабочего процесса git, когда на них сотрудничают несколько человек. Например, XML в файле .storyboard имеет свои начальные <document> теги toolsVersion и systemVersion, измененные по любой конфигурации, с которой работает последний манипулятор. Синхронизация всех версий Xcode точно помогает с toolsVersion, но systemVersion изменяется независимо от того, что, в зависимости от конкретной версии Mac и/или OS X, запускается разработчиком.Xcode изменяет немодифицированную раскадровку и XIB-файлы

Это идиотский, но в основном безвредный. Однако нас беспокоит то, что в другое время некоторые другие изменения автоматически делаются на раскадровку, просто открывая их после git pull. То есть Алиса вносит изменения в раскадровку, совершает и толкает их в репозиторий. Затем Боб вытаскивает изменения Алисы и открывает раскадровку, чтобы внести дальнейшие изменения. В тот момент, когда он открывает раскадровку, значок файла немедленно изменяется на состояние с измененным, но несохраненным, а git status показывает, что произошло любое количество странных изменений. Все это без того, чтобы Боб ничего не изменил или не сохранил сам файл.

Наиболее распространенным автоматическим изменением, которое мы видим, является исчезновение или повторное появление всего тега hierachy <classes> в конце файла раскадровки. Мы не выяснили, что вызывает это. У нас может быть несколько локализованных версий раскадровки в разных каталогах .lproj, и при их открытии внутри Interface Builder иерархия классов может быть спонтанно удалена из некоторых и добавлена ​​в другие или оставлена ​​одна в некоторых. Это вызывает много шума в git diff, но на самом деле это не нарушает никаких функций. Мы часто будем избирательно добавлять фактические изменения, внесенные нами в индекс git, фиксировать их, а затем просто отбрасывать спонтанные, бессмысленные изменения <classes>. Это должно держать мелкие и приятные, как и должно быть. В конце концов, однако, это просто становится слишком много, чтобы беспокоиться, так как Xcode продолжает повторять изменения, а кто-то просто ragecommits их вместе с некоторыми другими вещами ... это нормально, пока чей-то Xcode не захочет изменить их для no очевидная причина. (Наша история фиксации имеет много ругательств над этим.)

Есть ли у кого-нибудь подобное подобное поведение? Является ли это ошибкой Xcode или проблемой конфигурации на одном или нескольких наших Mac-разработчиков? Мы видели подобное поведение при работе с XIB-файлами, но раскадровки выглядят более восприимчивыми к этому.

+0

Действительно, проекты Xcode и Git не очень хорошо сочетаются друг с другом. Я не думаю, что вы можете избежать этого беспорядка иначе, чем отбросить ненужные изменения - это почти всегда изменения файлов проекта для меня и других файлов xml. Я уверен, что я не изменился. Будем рады, если есть какое-то «решение».Мне нравится Perforce для удобной функции блокировки, не позволяющей Xcode слишком сильно меняться, возможно, это может быть сделано вручную для файлов, которые вы не собираетесь изменять, а только для просмотра. –

+3

Не стоит использовать раскадровки с git или что-то еще. Они не предназначены для дружеских отношений. Мы сдались и пошли с .xib, который не так уж хорош, но, по крайней мере, он зернистый. – ahwulf

+0

Мы обнаружили, что раскадровки довольно аккуратны для довольно многих вещей на самом деле, хотя часто необходимо смешивать их с XIB. Если эта ошибка когда-либо будет исправлена, мы будем очень рады работать с ними в подавляющем большинстве случаев. –

ответ

73

Это не ошибка, это следствие того, как Xcode обрабатывает файлы раскадровки. Я пишу программу разложения и слияния для файлов раскадровки (GitHub link), и я часами анализировал логику файлов раскадровки и то, как Xcode обрабатывает ее. Это то, что я обнаружил:

  • Почему странные изменения происходят в раскадровку файлов? Xcode использует NSXML API для анализа файлов раскадровки в некоторой логической древовидной структуре на основе NSSet. Когда Xcode необходимо записать изменения, он создает NSXMLDocument на основе логической древовидной структуры, очищает файл раскадровки и вызывает XMLDataWithOptions:, чтобы снова заполнить файл. Поскольку наборы не сохраняют порядок своих элементов, даже малейшая модификация может изменить весь XML-файл раскадровки.

  • Почему метка класса исчезает или появляется случайно? Раздел <class> - это не что иное, как внутренний кеш Xcode. Xcode использует его для кэширования информации о классах. Кэш часто меняется. Элементы добавляются, когда файлы класса .h/.m открываются и удаляются, когда Xcode подозревает, что они устарели (по крайней мере, старые Xcodes ведут себя так). Когда вы сохраняете раскадровку, текущая версия кэша сбрасывается, поэтому раздел <class> часто изменяется или даже исчезает.

У меня нет обратного кода Xcode; Я сделал эти наблюдения, экспериментируя с файлами Xcode и раскадровки. Тем не менее, я почти на 100% уверен, что он работает таким образом.

Выводы:

  • раздел кэша не имеет значения; вы можете спокойно игнорировать любые изменения в нем.
  • Вопреки тому, что вы можете найти на всех форумах, объединение файлов раскадровки - не сложная задача. Например, предположим, что вы изменили контроллер представления в документе раскадровки. Откройте файл раскадровки и найдите что-то вроде этого <viewController id=”ory-XY-OBM” sceneMemberID=”MyController1”>. Вы можете спокойно зафиксировать только изменения в этом разделе и игнорировать все остальное. Если вы изменили segues или ограничения, также совершите все, что имеет “ory-XY-OBM” внутри. Просто!
+7

Любое обновление в инструменте diff/merge xcode? Похоже, это будет очень полезно для этого сообщества. – Tony

+1

Вы можете получить приложение с моей веб-страницы (см. Профиль). Приложение на 100% бесплатно. –

+0

Я бы также рекомендовал разделить раскадровки как можно больше. –

17

Это ошибка в XCode 4.5+, я надеюсь, что она будет исправлена, и да, это PITA.

Вот полная ошибка в компании Apple

How to avoid Xcode gratuitous edits to storyboard files?

+0

У меня также было это в 4.4 – jere

+1

То же самое в 4.6. Может быть, это не ошибка. – Thromordyn

+0

4.6.3 все еще имеет его. Не могу сказать, что раскадровка/xibs когда-либо работали хорошо, но – houbysoft

11

Этот вопрос может быть несколько смягчена чрезвычайно разумным использованием git add -p на любом из Xcode, порожденных файлы, включая раскадровку XIBs, модель Core Data и файлы проект , все из которых страдают от аналогичных переходных изменений, которые не влияют на фактический интерфейс/модель/проект.

Наиболее распространенные изменения мусора, которые я видел на раскадровках, это номера версии системы (как вы упоминаете), а также постоянное добавление и удаление раздела <classes>, упущение которого я никогда не видел, вызывает проблемы. Для XIB это добавление и удаление <reference key="NSWindow"/>, что даже не класс в Cocoa Touch. Просто вау.

Подумайте об этом как о море: есть как приличный, так и высокий уровень. Пусть он помытся над тобой.

Ahh. Вот и все.

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

Единственное преимущество, которое я видел с помощью раскадровки над XIB с технической точки зрения, заключается в том, что Apple еще не кастрировала FileMerge, чтобы отказаться от слияния конфликтующих раскадровки. (FileMerge имел обыкновение объединять XIB, но новые версии нарушали это. Thxxxx guys !!!)

Пожалуйста, напишите много ошибок обо всех этих проблемах: http://bugreporter.apple.com/! И не забудьте создать записи на OpenRadar.

5

Набросок на другой ответ здесь, потому что эта ситуация значительно улучшилась. XML для XIB-файла, который представляет StoryBoard, значительно упрощен.

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

В любом случае, сегодня я заметил, что на раскадровке произошли изменения, а встроенный diff показал, что это единственный атрибут в теге документа (systemVersion). Так что неважно.

Я прочитал статьи, в которых люди говорят, что SBs были объявлены вне закона в своих командах из-за проблем с объединением. Полное безумие. Они настолько удивительны, особенно сейчас, когда у них есть интеллектуальная автоматическая автозагрузка, вы действительно упускаете их, если не используете их.

3

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

  1. Не совершайте ничего, пока явным образом не проинструктирован.

  2. Открыть Xcode и создать новую раскадровку (Command + N> iOS> Пользовательский интерфейс> Раскадровка). Предположим, вы называете это по умолчанию Storyboard.storyboard.

  3. Откройте раскадровку, нарушенную Xcode. Я предполагаю, что это Base.lproj/Main.storyboard.

  4. Выберите и скопируйте все на раскадровке (Command + A then Command + C).

  5. Открыть Storyboard.storyboard.

  6. Скопируйте и вставьте все в Storyboard.storyboard.

  7. Закрыть Xcode.

  8. Открыть терминал и сменить каталоги в вашем хранилище.

  9. Заменить Main.storyboard на Storyboard.storyboard (mv Storyboard.storyboard Base.lproj/Main.storyboard).

  10. git add Base.lproj/Main.storyboard; git commit -m "Fix Xcode's insanity."

  11. игнорировании изменения в project.pbxproj через git checkout -- project.pbxproj. Если вы напишите файл git diff, вы увидите, что он только что добавил информацию о нашей временной раскадровке (которая больше не существует).

  12. Откройте Xcode и посмотрите, что предупреждения исчезли.

  13. Дышите.

Смежные вопросы