Como usar o Git corretamente com o Xcode?

94

Sou desenvolvedor de iphone há algum tempo e recentemente incluí o git em meu fluxo de trabalho. Eu usei as configurações do git encontradas em http://shanesbrain.net/2008/7/9/using-xcode-with-git para meu fluxo de trabalho até agora.

Essas configurações dizem ao git para excluir * .pbxproj dos merges? Existe uma razão real para fazer isso? Por exemplo, quando adiciono um arquivo ao projeto e empurro para a origem, meus colegas desenvolvedores não terão esse arquivo adicionado ao projeto xcode quando fizerem pull. Então, se um deles criar uma versão, esse arquivo pode não ser incluído. Não deveria simplesmente deixar o git lidar com as mesclagens do arquivo de projeto? Por que ou por que não esse arquivo deve ser mesclado e como lidar adequadamente com a situação quando os arquivos são adicionados ao projeto?

Rickharrison
fonte
9
Eu não trabalho com o XCode, mas se os arquivos * .pbxproj forem parecidos com os arquivos * .csproj do Visual Studio (uma espécie de lista de arquivos), essa configuração parece bastante idiota para mim. Parece que alguém estava cansado de conflitos de mesclagem quando duas pessoas adicionaram arquivos ao projeto e acharam que a melhor solução era bagunçar tudo ...
R. Martinho Fernandes
O problema com o XCode (não tenho certeza sobre o Visual Studio) é que os arquivos .pbxproj dificilmente podem ser lidos por humanos, então não faz sentido resolver conflitos manualmente.
Tom,
7
Os arquivos * .pbxproj são na verdade muito bem estruturados, você só tem longos trechos entre o final do bloco e os segmentos de início. A vantagem é que o arquivo tem quebras de linha muito bem colocadas, então é difícil bagunçar apenas modificando as linhas e o automerge geralmente funciona muito bem. Isso também significa que os blocos de mesclagem são geralmente fáceis de entender - você pode ver um lado com alguns conjuntos de arquivos adicionados, o outro com diferentes conjuntos de arquivos adicionados.
Kendall Helmstetter Gelner

Respostas:

136

Trabalhei em aplicativos para iPhone em tempo integral desde o lançamento do SDK, a maior parte desse tempo trabalhando em equipes com vários desenvolvedores.

A verdade é que é muito mais prejudicial impedir a mesclagem desse arquivo .pbxproj do que útil. Como você disse, quando você adiciona um arquivo, a menos que outras pessoas o obtenham, elas também têm que adicioná-lo ao projeto - em um aplicativo de qualquer tamanho, isso é uma merda e também tira um grande benefício do controle do código-fonte, pois você não pode realmente reverter para um estado de projeto anterior completo apenas por meio do git.

O arquivo .pbxproj é simplesmente uma lista de propriedades (semelhante ao XML). Por experiência, o ÚNICO conflito de mesclagem que você teve é ​​se duas pessoas adicionaram arquivos ao mesmo tempo. A solução em 99% dos casos de conflito de mesclagem é manter ambos os lados da mesclagem, o que para o git pelo menos envolve simplesmente a remoção de quaisquer linhas >>>>, <<<< e ====. Na verdade, isso é tão comum que criei um script de shell simples para corrigir um arquivo .pbxproj em um estado de mesclagem do git. Eu o executo de dentro do diretório do projeto (no nível Classes):

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

No pior caso, se ele falhar (você pede ao XCode para carregar o projeto e ele falha ao carregar), você simplesmente exclui o arquivo .pbxproj, verifica o master no git e adiciona novamente seus arquivos. Mas isso nunca aconteceu em muitos meses de uso com este script, novamente trabalhando em tempo integral em aplicativos para iPhone com vários outros desenvolvedores.

Outra opção (apontada nos comentários abaixo) que você pode tentar usar no lugar do script, é adicionar esta linha a um arquivo .gitattributes:

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

Então o git sempre pegará os dois lados de uma fusão para os arquivos .pbxproject, tendo o mesmo efeito que o script que forneci, mas sem nenhum trabalho extra.

Por último, aqui está o meu arquivo .gitignore completo, mostrando o que eu tenho configurado para ignorar, pois há algumas coisas que você não quer - no meu caso, apenas restos do emacs e todo o diretório de construção:

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

# old skool
.svn

# osx noise
.DS_Store
profile
Kendall Helmstetter Gelner
fonte
3
Você usa um arquivo .gitattributes para o seu projeto xcode? E obrigado por sua visão. Acho que será muito mais fácil tentar mesclar os arquivos pbxproj no futuro.
rickharrison
1
Até agora não temos, embora alguns aspectos pareçam interessantes - mas as pessoas com quem trabalhei não foram usuários git avançados, portanto, a promoção de recursos avançados não é forte.
Kendall Helmstetter Gelner
1
“O arquivo .pbxproj é simplesmente JSON (semelhante a XML).” Na verdade, é uma lista de propriedades formatada em OpenStep. As mesmas ideias básicas do JSON, mas a sintaxe difere em alguns lugares.
Peter Hosey
1
Outra coisa a tentar - definir merge = union: stackoverflow.com/questions/2729109/…
Kendall Helmstetter Gelner
1
Concordo com @KendallHelmstetterGelner em vez de correr o seu roteiro, que remove as linhas especiais, você pode atualizar seu .gitattribute com o unioninterruptor: *.pbxproj text/plain -crlf -diff -merge union.
Besi
9

Isso funciona para mim no Xcode 4.6 e Git 1.7.5.

Adicione e confirme o arquivo .gitattributes com este:

*.pbxproj binary merge=union

Eu testei isso com outro membro da equipe e funciona muito bem.

Retirado de: http://robots.thoughtbot.com/post/33796217972/xcode-and-git-bridging-the-gap

Oneyenjug
fonte
Merge = union é bom, mas a ferramenta mergepbx deve ser a resposta aceita.
Alper
8

Francamente, as respostas existentes são enganosas.

Se você nunca deleta ou renomeia arquivos, então usar a merge=unionestratégia, que apenas combina as diferenças em diferentes commits diretamente, é uma boa idéia.

No entanto, no mundo real, às vezes precisamos excluir ou renomear arquivos. Mesclar as diferenças sem nenhuma modificação criaria muitos problemas nessas situações, e esses problemas geralmente levam ao problema "Integridade do espaço de trabalho - não foi possível carregar o projeto", que o impede de executar o projeto.

A melhor solução que consegui até agora:

1) Projete bem o projeto e adicione todos os arquivos necessários no início, para que raramente precise alterar o project.pbxproj.

2) Faça seus recursos minúsculos. Não faça muitas coisas em um galho.

3) Por qualquer motivo, se você precisar modificar a estrutura do arquivo e gerar conflitos project.pbxproj, use seu editor de texto favorito para resolvê-los manualmente. À medida que você torna suas tarefas minúsculas, os conflitos podem ser fáceis de resolver.

Brian
fonte
3

A resposta curta é que, mesmo que você não inclua essa linha .gitattributes, pode não ser capaz de mesclar facilmente duas versões modificadas de um .pbxproj. É melhor para o git tratá-lo como um binário.

Veja aqui os detalhes: Git e pbxproj

Atualização: Mesmo que o livro git ainda concorde com esta resposta, eu não concordo mais. Eu controlei minha versão .pbxprojcomo qualquer outro arquivo fonte não binário.

Tom
fonte
Parece que você pode configurar um filtro de confirmação para enviar o arquivo simplejsonou algum organizador desse tipo em seu caminho para o índice. Ainda não seria garantido que funcionasse.
intuído de
1
Não é um arquivo formatado em JSON. Parece semelhante, mas tem muitas diferenças nos detalhes.
eonil
Diz que é JSON no livro do git, mas parece que está errado. git-scm.com/book/ch7-2.html
huggie
1
ESTÁ BEM. .pbxprojO arquivo é, na verdade, um arquivo NeXT / Cocoa PList de estilo antigo, que é mais antigo e definido muito antes do JSON, e agora obsoleto pela Apple. (mas eles ainda estão usando em alguns lugares) A ​​menção sobre o arquivo no livro é completamente errada. Removi o voto negativo porque você mencionou explicitamente.
eonil
2

Eu criei um script Python que pode lidar com conflitos de mesclagem em arquivos de projeto XCode.

Se quiser experimentar, você pode conferir aqui: https://github.com/simonwagner/mergepbx

Você terá que instalá-lo como um driver de mesclagem, para que seja chamado automaticamente quando houver um conflito de mesclagem no arquivo de projeto (o README.md lhe dirá como fazer isso).

Deve funcionar muito melhor do que usar, merge=unionpois mergepbxentende a semântica do arquivo do seu projeto e, portanto, resolverá o conflito corretamente.

No entanto, o projeto ainda é alfa, não espere que ele compreenda todos os arquivos de projeto que existem.

Simon
fonte