Jak prawidłowo używać Gita z Xcode?

94

Od jakiegoś czasu jestem programistą iPhone'a, a ostatnio włączałem git do mojego przepływu pracy. Do tej pory korzystałem z ustawień git znalezionych na http://shanesbrain.net/2008/7/9/using-xcode-with-git w moim przepływie pracy.

Te ustawienia mówią gitowi, aby wykluczył * .pbxproj z połączeń? Czy istnieje prawdziwy powód, aby to zrobić? Na przykład, kiedy dodam plik do projektu i wypchnę do źródła, moi programiści nie będą mieli tego pliku dodanego do ich projektu xcode podczas ściągania. Następnie, jeśli jeden z nich tworzy wydanie, ten plik może nie zostać uwzględniony. Czy nie powinienem po prostu pozwolić gitowi obsługiwać scalania dla pliku projektu? Dlaczego lub dlaczego nie ten plik powinien być w scaleniach i jak poprawnie obsłużyć sytuację, gdy pliki są dodawane do projektu?

rickharrison
źródło
9
Nie pracuję z XCode, ale jeśli pliki * .pbxproj są czymś w rodzaju plików * .csproj programu Visual Studio (coś w rodzaju listy plików), to ustawienie wydaje mi się raczej idiotyczne. Wygląda na to, że ktoś był zmęczony konfliktami scalania, gdy dwie osoby dodały pliki do projektu i pomyślały, że najlepszym rozwiązaniem jest schrzanić wszystko ...
R. Martinho Fernandes
Problem z XCode (nie jestem pewien co do programu Visual Studio) polega na tym, że pliki pbxproj są ledwo czytelne dla człowieka, więc nie ma sensu rozwiązywać konfliktów ręcznie.
Tom
7
Pliki * .pbxproj są w rzeczywistości dość dobrze zbudowane, po prostu masz długie odcinki między końcem bloku a segmentem początkowym. Oszczędność polega na tym, że plik ma bardzo dobrze rozmieszczone podziały wierszy, więc trudno go zepsuć, modyfikując tylko wiersze, a automerge ogólnie działa bardzo dobrze. Oznacza to również, że bloki łączenia są ogólnie łatwe do zrozumienia - możesz zobaczyć jedną stronę z kilkoma dodanymi zestawami plików, a drugą z różnymi zestawami plików.
Kendall Helmstetter Gelner

Odpowiedzi:

136

Pracowałem nad aplikacjami na iPhone'a w pełnym wymiarze czasu od momentu uruchomienia SDK, większość tego czasu spędziłem w zespołach z wieloma programistami.

Prawda jest taka, że ​​znacznie bardziej szkodliwe jest uniemożliwienie scalenia tego pliku .pbxproj niż jest to pomocne. Jak mówisz, kiedy dodajesz plik, chyba że inne osoby go otrzymają, muszą również dodać go do swojego projektu - w aplikacji o dowolnym rozmiarze, to jest do bani, a także odbiera ogromną korzyść z kontroli kodu źródłowego, ponieważ ty nie może tak naprawdę powrócić do kompletnego wcześniejszego stanu projektu tylko przez git.

Plik .pbxproj to po prostu lista właściwości (podobna do XML). Z doświadczenia wynika, że ​​prawie JEDYNYM konfliktem scalania, jaki kiedykolwiek otrzymałeś, jest sytuacja, gdy dwie osoby dodały pliki w tym samym czasie. Rozwiązaniem w 99% przypadków konfliktu scalania jest zachowanie obu stron scalania, co w przypadku gita przynajmniej polega na usunięciu wszelkich linii >>>>, <<<< i ====. W rzeczywistości jest to tak powszechne, że utworzyłem prosty skrypt powłoki, aby naprawić plik .pbxproj w stanie scalania z git, uruchamiam to z katalogu projektu (na poziomie klas):

#!/bin/sh

    projectfile=`find -d . -name 'project.pbxproj'`
    projectdir=`echo *.xcodeproj`
    projectfile="${projectdir}/project.pbxproj"
    tempfile="${projectdir}/project.pbxproj.out"
    savefile="${projectdir}/project.pbxproj.mergesave"

    cat $projectfile | grep -v "<<<<<<< HEAD" | grep -v "=======" | grep -v "^>>>>>>> " > $tempfile
    cp $projectfile $savefile
    mv $tempfile $projectfile

W najgorszym przypadku, jeśli to się nie powiedzie (prosisz XCode o załadowanie projektu i nie można go załadować), po prostu usuwasz plik .pbxproj, wyewidencjonowujesz master z git i ponownie dodaj swoje pliki. Ale nigdy nie zdarzyło mi się to przez wiele miesięcy używania tego skryptu, ponownie pracując w pełnym wymiarze godzin nad aplikacjami na iPhone'a z kilkoma innymi programistami.

Inną opcją (wskazaną w komentarzach poniżej), którą możesz spróbować zamiast skryptu, jest dodanie tej linii do pliku .gitattributes:

*.pbxproj text -crlf -diff -merge=union

Wtedy git zawsze będzie łączył obie strony dla plików .pbxproject, uzyskując taki sam efekt jak skrypt, który dostarczyłem, tylko bez dodatkowej pracy.

Na koniec, oto mój kompletny plik .gitignore, pokazujący, co mam ustawione do ignorowania, ponieważ jest kilka rzeczy, których nie chcesz - w moim przypadku tak naprawdę tylko pozostałości emacsa i cały katalog kompilacji:

# xcode noise
build/*
*.pbxuser
*.mode1v3
*~

# old skool
.svn

# osx noise
.DS_Store
profile
Kendall Helmstetter Gelner
źródło
3
Czy używasz w ogóle pliku .gitattributes w swoim projekcie xcode? Dziękuję za wgląd. Myślę, że w przyszłości znacznie łatwiej będzie spróbować scalić pliki pbxproj.
rickharrison
1
Do tej pory nie byliśmy, chociaż niektóre aspekty tego wyglądają interesująco - ale ludzie, z którymi pracowałem, nie byli zaawansowanymi użytkownikami git, więc propagowanie zaawansowanych funkcji nie jest mocne.
Kendall Helmstetter Gelner
1
„Plik .pbxproj to po prostu JSON (podobny do XML)”. Właściwie jest to lista właściwości w formacie OpenStep. Te same podstawowe pomysły co JSON, ale składnia różni się w kilku miejscach.
Peter Hosey
1
Kolejna rzecz do wypróbowania - ustaw merge = union: stackoverflow.com/questions/2729109/…
Kendall Helmstetter Gelner
1
Zgadzam się z @KendallHelmstetterGelner zamiast uruchomiony skrypt, który usuwa te specjalne linie, można zaktualizować .gitattribute z unionprzełącznikiem: *.pbxproj text/plain -crlf -diff -merge union.
Besi,
9

Działa to dla mnie w Xcode 4.6 i Git 1.7.5.

Dodaj i zatwierdź plik .gitattributes za pomocą tego:

*.pbxproj binary merge=union

Przetestowałem to z innym członkiem zespołu i działa świetnie.

Zaczerpnięte z: http://robots.thoughtbot.com/post/33796217972/xcode-and-git-bridging-the-gap

oneyenjug
źródło
Merge = union jest dobre, ale narzędzie connectepbx powinno być akceptowaną odpowiedzią.
Alper
8

Szczerze mówiąc, istniejące odpowiedzi są mylące.

Jeśli nigdy nie usuniesz plików ani nie zmienisz ich nazw, merge=uniondobrym pomysłem jest użycie strategii, która po prostu łączy bezpośrednio różnice w różnych zatwierdzeniach.

Jednak w prawdziwym świecie czasami musimy usuwać pliki lub zmieniać ich nazwy. Scalanie różnic bez żadnych modyfikacji spowodowałoby wiele problemów w takich sytuacjach, a te problemy zwykle prowadzą do problemu „Integralność obszaru roboczego - nie można załadować projektu”, co sprawia, że ​​nawet nie można uruchomić projektu.

Najlepsze rozwiązanie, jakie do tej pory otrzymałem:

1) Dobrze zaprojektuj projekt i dodaj wszystkie potrzebne pliki na początku, więc rzadko będziesz musiał zmieniać project.pbxproj.

2) Spraw, aby Twoje funkcje były małe. Nie rób zbyt wielu rzeczy w oddziale.

3) Z jakiegokolwiek powodu, jeśli chcesz zmodyfikować strukturę plików i dostać konflikty project.pbxproj, użyj swojego ulubionego edytora tekstu, aby rozwiązać je ręcznie. Gdy zmniejszysz swoje zadania, konflikty mogą być łatwe do rozwiązania.

Brian
źródło
3

Krótka odpowiedź jest taka, że ​​nawet jeśli nie uwzględnisz tej linii .gitattributes, możesz nie być w stanie łatwo połączyć dwóch zmodyfikowanych wersji pliku .pbxproj. Lepiej, żeby git traktował to jako plik binarny.

Zobacz tutaj, aby uzyskać szczegółowe informacje: Git i pbxproj

Aktualizacja: Mimo że książka git nadal zgadza się z tą odpowiedzią, już tego nie robię. Kontroluję wersję .pbxprojtak samo jak każdy inny niebinarny plik źródłowy.

Tomek
źródło
Wygląda na to, że możesz ustawić filtr zatwierdzania, aby wysłać plik przez simplejsonlub jakąś taką kolejkę w drodze do indeksu. Jednak nadal nie można zagwarantować, że zadziała.
intuicja
1
To nie jest plik w formacie JSON. Wygląda podobnie, ale ma wiele różnic w szczegółach.
eonil
Mówi, że jego JSON w księdze git, ale wygląda na to, że jest zły. git-scm.com/book/ch7-2.html
huggie
1
OK. .pbxprojplik jest w rzeczywistości plikiem NeXT / Cocoa PList w starym stylu, który jest starszy i zdefiniowany dużo wcześniej niż JSON, a teraz jest przestarzały przez Apple. (ale w niektórych miejscach nadal go używają) Wzmianka o pliku w książce jest całkowicie błędna. Usunąłem głos negatywny, ponieważ wyraźnie o tym wspomniałeś.
eonil
2

Stworzyłem skrypt w Pythonie, który radzi sobie z konfliktami scalania w plikach XCode Project.

Jeśli chcesz to wypróbować, możesz to sprawdzić tutaj: https://github.com/simonwagner/mergepbx

Będziesz musiał zainstalować go jako sterownik scalający, więc zostanie wywołany automatycznie, gdy wystąpi konflikt scalania w pliku projektu (plik README.md powie ci, jak to zrobić).

Powinno działać znacznie lepiej niż używanie, merge=unionponieważ mergepbxrozumie semantykę pliku projektu, a zatem poprawnie rozwiąże konflikt.

Jednak projekt jest nadal w wersji alfa, nie oczekuj, że zrozumie każdy plik projektu, który jest dostępny.

Szymon
źródło