Come utilizzare correttamente Git con Xcode?


94

Sono uno sviluppatore di iPhone da un po 'di tempo e recentemente ho incluso git nel mio flusso di lavoro. Finora ho usato le impostazioni di git trovate su http://shanesbrain.net/2008/7/9/using-xcode-with-git per il mio flusso di lavoro.

Quelle impostazioni dicono a git di escludere * .pbxproj dalle unioni? C'è una vera ragione per farlo? Ad esempio, quando aggiungo un file al progetto e eseguo il push all'origine, i miei colleghi sviluppatori non avranno quel file aggiunto al loro progetto xcode quando eseguono il pull. Quindi, se uno di loro crea una versione, questo file potrebbe non essere incluso. Non dovrei semplicemente lasciare che git gestisca le unioni per il file di progetto? Perché o perché no questo file dovrebbe essere in unioni e come gestire correttamente la situazione quando i file vengono aggiunti al progetto?


9
Non lavoro con XCode, ma se i file * .pbxproj sono qualcosa di simile ai file * .csproj di Visual Studio (una specie di elenco di file) questa impostazione mi sembra piuttosto idiota. Sembra che qualcuno fosse stanco dei conflitti di unione quando due persone hanno aggiunto file al progetto e hanno pensato che la soluzione migliore fosse rovinare tutto ...
R. Martinho Fernandes

Il problema con XCode (non sono sicuro di Visual Studio) è che i file .pbxproj sono a malapena leggibili dall'uomo, quindi non ha senso risolvere i conflitti manualmente.
Tom

7
I file * .pbxproj sono in realtà abbastanza ben strutturati, hai solo lunghi tratti tra la fine del blocco e i segmenti iniziali. La grazia salvifica è che il file ha interruzioni di riga molto ben posizionate, quindi è difficile rovinarlo solo modificando le linee e automerge generalmente funziona molto bene. Significa anche che i blocchi di unione sono generalmente facili da capire: puoi vedere un lato con alcuni set di file aggiunti, l'altro con diversi set di file aggiunti.
Kendall Helmstetter Gelner

Risposte:


136

Ho lavorato a tempo pieno su applicazioni per iPhone dal lancio dell'SDK, la maggior parte del tempo trascorso lavorando in team con più sviluppatori.

La verità è che è molto più dannoso non consentire l'unione di quel file .pbxproj di quanto non sia utile. Come dici tu, quando aggiungi un file a meno che altre persone non ottengano quel file, devono anche aggiungerlo al loro progetto - in un'applicazione di qualsiasi dimensione, che fa schifo e porta via anche un enorme vantaggio del controllo del codice sorgente in quanto tu non può davvero tornare a uno stato di progetto precedente completo solo tramite git.

Il file .pbxproj è semplicemente un elenco di proprietà (simile a XML). Per esperienza, quasi l'unico conflitto di unione che hai mai ottenuto è se due persone hanno aggiunto file contemporaneamente. La soluzione nel 99% dei casi di conflitto di unione è mantenere entrambi i lati dell'unione, il che per git implica semplicemente la rimozione di qualsiasi riga >>>>, <<<< e ====. In effetti questo è così comune che ho creato un semplice script di shell per correggere un file .pbxproj in uno stato di unione da git, lo eseguo dalla directory del progetto (a livello di classi):

#!/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

Nel peggiore dei casi, se fallisce (chiedi a XCode di caricare il progetto e non si carica), elimina semplicemente il file .pbxproj, controlla il master da git e aggiungi nuovamente i tuoi file. Ma non l'ho mai visto per molti mesi di utilizzo con questo script, lavorando di nuovo a tempo pieno su applicazioni per iPhone con molti altri sviluppatori.

Un'altra opzione (indicata nei commenti di seguito) che puoi provare a utilizzare al posto dello script, è aggiungere questa riga a un file .gitattributes:

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

Quindi git prenderà sempre entrambi i lati di un'unione per i file .pbxproject, avendo lo stesso effetto dello script che ho fornito solo senza alcun lavoro aggiuntivo.

Infine, ecco il mio file .gitignore completo, che mostra cosa ho impostato per ignorare in quanto ci sono alcune cose che non vuoi - nel mio caso solo i resti di emacs e l'intera directory di build:

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

# old skool
.svn

# osx noise
.DS_Store
profile

3
Usi un file .gitattributes per il tuo progetto xcode? E grazie per la tua intuizione. Penso che in futuro sarà molto più facile provare a unire i file pbxproj.
Rickharrison

1
Finora non lo siamo stati, anche se alcuni aspetti sembrano interessanti, ma le persone con cui ho lavorato non erano utenti avanzati di git, quindi la promozione di funzionalità avanzate non è forte.
Kendall Helmstetter Gelner

1
"Il file .pbxproj è semplicemente JSON (simile a XML)." In realtà, è un elenco di proprietà formattato OpenStep. Stesse idee di base di JSON, ma la sintassi differisce in alcuni punti.
Peter Hosey

1
Un'altra cosa da provare: impostare merge = union: stackoverflow.com/questions/2729109/…
Kendall Helmstetter Gelner

1
Sono d'accordo con @KendallHelmstetterGelner invece di eseguire lo script, che elimina quelle linee speciali, si potrebbe aggiornare il .gitattribute con l' unioninterruttore: *.pbxproj text/plain -crlf -diff -merge union.
Besi


8

Francamente, le risposte esistenti sono fuorvianti.

Se non elimini o rinomini mai i file merge=union, è una buona idea usare la strategia, che combina direttamente le differenze in diversi commit.

Tuttavia, nel mondo reale, a volte è necessario eliminare o rinominare i file. Unire le differenze senza alcuna modifica creerebbe molti problemi in queste situazioni e questi problemi di solito portano al problema "Integrità dell'area di lavoro - Impossibile caricare il progetto", che ti impedisce nemmeno di eseguire il progetto.

La migliore soluzione che ho ottenuto finora:

1) Progettare bene il progetto e aggiungere tutti i file necessari all'inizio, quindi raramente sarà necessario modificare il file project.pbxproj .

2) Rendi minuscole le tue caratteristiche. Non fare troppe cose in un ramo.

3) Per qualsiasi motivo, se è necessario modificare la struttura del file e ottenere conflitti project.pbxproj, utilizzare il proprio editor di testo preferito per risolverli manualmente. Mentre riduci i tuoi compiti, i conflitti potrebbero essere facili da risolvere.


3

La risposta breve è che anche se non includi quella riga .gitattributes, potresti non essere in grado di unire facilmente due versioni modificate di un .pbxproj. È meglio che git lo consideri come binario.

Vedi qui per i dettagli: Git e pbxproj

Aggiornamento: anche se il libro git è ancora d'accordo con questa risposta, non lo faccio più. Controllo della versione .pbxprojcome qualsiasi altro file sorgente non binario.


sembra che tu possa impostare un filtro di commit per inviare il file simplejsono qualcosa di più ordinato nel suo percorso verso l'indice. Tuttavia, non sarebbe ancora garantito che funzioni.
intuito il

1
Non è un file formattato JSON. Sembra simile ma ha molte differenze nei dettagli.
eonil

Dice che è JSON nel libro di git, ma sembra che sia sbagliato. git-scm.com/book/ch7-2.html
huggie

1
OK. .pbxprojè in realtà un file NeXT / Cocoa PList vecchio stile, che è più vecchio e definito molto prima di JSON, e ora deprecato da Apple. (ma lo usano ancora in alcuni punti) La menzione del file nel libro è completamente sbagliata. Ho rimosso il voto perché lo hai menzionato esplicitamente.
eonil

2

Ho creato uno script Python in grado di gestire i conflitti di unione nei file del progetto XCode.

Se vuoi provarlo, puoi verificarlo qui: https://github.com/simonwagner/mergepbx

Dovrai installarlo come driver di unione, quindi viene chiamato automaticamente quando hai un conflitto di unione nel tuo file di progetto (il README.md ti dirà come farlo).

Dovrebbe funzionare molto meglio rispetto all'utilizzo di merge=unionasmergepbx comprende la semantica del file di progetto e quindi risolverà correttamente il conflitto.

Tuttavia il progetto è ancora alpha, non aspettarti che comprenda ogni file di progetto disponibile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.