Manuals

Resolvendo Conflitos

De vez quando irás obter um conflito quando actualizares/fundires os teus ficheiros a partir do repositório, ou quando trocares a tua cópia de trabalho para um URL diferente. Existem dois tipos de conflitos:

conflitos de ficheiro

Um conflito de ficheiro ocorre quando dois (ou mais) programadores alteraram o mesmo punhado de linhas do ficheiro.

conflitos de árvore

Um conflito de árvore ocorre quando um programador move/renomeia/apaga um ficheiro ou pasta, que outro programador também moveu/renomeou/apagou ou apenas modificou.

Conflitos de Ficheiro

A file conflict occurs when two or more developers have changed the same few lines of a file. As Subversion knows nothing of your project, it leaves resolving the conflicts to the developers. The conflicting area in a text file is marked like this:

<<<<<<< filename
your changes
=======
code merged from repository
>>>>>>> revision
      

Also, for every conflicted file Subversion places three additional files in your directory:

filename.ext.mine

This is the file that was theEste é o teu ficheiro como existia na cópia de trabalho antes de a teres actualizado - Isto é, sem marcadores de conflito. Este ficheiro tem as tuas últimas alterações a mais nada.

filename.ext.rOLDREV

Este é o ficheiro que foi a revisão BASE antes de actualizares a cópia de trabalho. Isto é, é o ficheiro que tu SVN exportaste antes de efectuares as tuas últimas alterações.

filename.ext.rNEWREV

Este é o ficheiro que o teu cliente Subversion acabou de receber do servidor, quando actualizaste a tua cópia de trabalho. Este ficheiro corresponde à revisão HEAD do repositório.

Podes lançar uma ferramenta externa de integração/ editor de conflitos com TortoiseSVNEditar Conflitos ou poderás utilizar um qualquer editor de texto para resolver o conflito manualmente. Deverás decidir como é que irá ficar o código, efectua as alterações necessárias e guarda o ficheiro. Usando uma ferramenta de integração como o TortoiseMerge ou uma das outras ferramentas populares, é na generalidade a opção mais fácil já que apresentam na generalidade os ficheiros envolvidos numa painel de 3 vistas e não têm de se preocupar com os marcadores de conflitos. Se usares um editor de ficheiro terás então de pesquisar por linhas começadas pela string <<<<<<<.

Posteriormente executa o comando TortoiseSVNResolvido e submete as tuas modificações para o repositório. Toma nota que o comando Resolvido, na realidade, não resolve o conflito. Apenas remove os ficheiros filename.ext.mine and filename.ext.r*, para te permitir submeter as tuas alterações.

Se tens conflitos com os teus ficheiros binários, o Subversion não tenta fundir os ficheiros. O ficheiro local permanece intocável (exactamente como o alteraste) e obtens os ficheiros filename.ext.r*. Se queres descartar as tuas alterações e manter a versão do repositório, usa o comando Reverter. Se queres manter a tua versão e reescrever a versão do repositório, usa o comando Resolvido e submete a tua versão.

Podes usar o comando Resolvido para ficheiros múltiplos, se clicares na pasta pai e seleccionares TortoiseSVNResolvido... Isto irá mostrar a caixa de diálogo listando todos os ficheiros em conflito nessa pasta, e podes seleccionar quais é queres marcar como resolvidos.

Conflitos de Propriedade

Um conflito de propriedade ocorre quando dois (ou mais) programadores alteraram a mesma propriedade. Tal como no caso dos ficheiros, deve-se exclusivamente aos programadores a resolução do conflito.

Se uma das alterações tiver de se sobrepor a outra, então escolhe a opção para Resolver usando a propriedade local ou Resolver usando a propriedade remota. Se as alterações tem de ser integradas selecciona então Edita manualmente a propiedade, decide o valor que a propriedade deve ter e marca como resolvido.

Conflitos de Árvore

Um conflito de árvore ocorre quando, um programador moveu/renomeou/apagou um ficheiro ou pasta que outro programador também moveu/renomeou/apagou ou apenas modificou. Existem muitas e variadas situações que podem gerar um conflito de árvore, e todas elas requerem diferentes passos para a sua resolução.

Quando no Subversion, um ficheiro é apagado localmente esse ficheiro também é apagado no sistema de ficheiros local e, mesmo que este seja parte de um conflito de árvore não poderá mostrar um ícone de conflito sobreposto, e tu não poderás clicar nele com o botão direito do rato para resolver o conflito. Usa então a caixa de diálogo Verificar alterações para aceder à opção Editar conflito.

O TortoiseSVN pode ajudar a encontrar o sítio correcto para fundir as alterações mas, poderá ser necessário trabalho adicional para resolver os conflitos. Lembra-te que após a actualização a revisão BASE de trabalho irá conter sempre a revisão de cada item como estava no repositório, na altura da actualização. Se reverteres uma alteração após a actualização esta voltará ao estado do repositório e não, à versão que estava quando começaste a efectuar as tuas alterações locais.

Apagar localmente, editar após actualizar

  1. O programador A modifica Foo.c e submete-o para o repositório.

  2. O programador B simultaneamente move na sua cópia de trabalho Foo.c para Bar.c, ou simplesmente apagou Foo.c, ou a sua pasta pai.

Uma actualização na cópia de trabalho do programador B resulta num conflito de árvore:

  • Foo.c foi apagado da cópia de trabalho, mas foi marcado como um conflito de árvore.

  • Se o conflito resultou de, uma mudança de nome em vez de um apagar então, o Bar.c é marcado como adicionado mas não contém as modificações do programador A.

O programador B tem de escolher se vai manter as alterações do Programador A. No caso de uma mudança no nome do ficheiro, ele pode fundir as alterações com o Foo.c no ficheiro renomeado Bar.c. Para simples apagamentos de ficheiros e pastas, ele pode escolher manter o item com as alterações do Programador A e descartar o item apagado. Ou, ao colocar o conflito como resolvido, sem efectuar mais nenhuma acção, descarta efectivamente as alterações do Programador A.

The conflict edit dialog offers to merge changes if it can find the original file of the renamed Bar.c. If there are multiple files that are possible move sources, then a button for each of these files is shown which allow you to chose the correct file.

Edição local, apagar após actualizar

  1. O Programador A move Foo.c para Bar.c e submete-o para o repositório.

  2. O Programador B modifica na sua cópia de trabalho Foo.c.

Ou em caso de mover uma pasta...

  1. O Programador A move a pasta pai FooFolder para BarFolder e submete-o para o repositório.

  2. O Programador B modifica na sua cópia de trabalho Foo.c.

Uma actualização da cópia de trabalho pelo programador B, resulta num conflito de árvore. Para um conflito de ficheiro simples:

  • Bar.c é adicionado à cópia de trabalho como um ficheiro normal.

  • Foo.c é marcado como adicionado (com história) e adquire um conflito de árvore.

Para um conflito de pasta:

  • BarFolder é adicionado à cópia de trabalho como uma pasta normal.

  • FooFolder é marcado como adicionado (com história) e adquire um conflito de árvore.

    Foo.c é marcado como modificado.

O programador B agora tem de decidir se quer manter a reorganização do programador A e fundir as suas alterações no ficheiro correspondente na nova estrutura, ou simplesmente reverter as alterações de A e manter o ficheiro local.

To merge her local changes with the reshuffle, Developer B must first find out to what filename the conflicted file Foo.c was renamed/moved in the repository. This can be done by using the log dialog. Then use the button which shows the correct source file to resolve the conflict.

If Developer B decides that A's changes were wrong then she must choose the Mark as resolved button in the conflict editor dialog. This marks the conflicted file/folder as resolved, but Developer A's changes need to be removed by hand. Again the log dialog helps to track down what was moved.

Apagar localmente, apagar após actualizar

  1. O Programador A move Foo.c para Bar.c e submete-o para o repositório.

  2. O Programador B move Foo.c para Bix.c.

Uma actualização na cópia de trabalho do programador B resulta num conflito de árvore:

  • Bix.c é marcado como adicionado com história.

  • Bar.c é adicionado à cópia de trabalho com o estado 'normal'.

  • Foo.c é marcado como apagado e adquire um conflito de árvore.

Para resolver este conflito, o Programador B tem de descobrir para que nome o ficheiro em conflito Foo.c renomeado/movido no repositório. Isso pode ser feito recorrendo à caixa de diálogo de registo.

Então o programador B tem de decidir qual o novo nome de ficheiro do ficheiro Foo.c deve manter - o criado pelo programador A ou o nome criado pelo próprio.

Depois de o programador B ter resolvido o conflito manualmente, o conflito de árvore tem de ser marcado como resolvido, com o botão na caixa de diálogo editor de conflito.

Desaparecido localmente, editar após fusão

  1. O Programador A trabalhando no trunk modifica então Foo.c e submete-o para o repositório.

  2. O Programador B trabalhando no ramo move Foo.c para Bar.c e submete-o para o repositório.

A fusão das alterações no trunk do programador A para o ramo, da cópia de trabalho, do programador B resulta num conflito de árvore:

  • Bar.c já está na cópia de trabalho com o estado 'normal'.

  • Foo.c é marcado como desparecido, com um conflito de árvore.

Para resolver este conflito, o Programador B tem de marcar o ficheiro como resolvido na caixa de diálogo do editor de conflito, que irá remove-lo da lista de conflitos. Ele então tem de decidir se copia o ficheiro desaparecido Foo.c do repositório para a cópia de trabalho, se funde as alterações do Programador A no ficheiro Foo.c no renomeado Bar.c ou se ignora as alterações ao marcar o conflito como resolvido e não fazendo mais nada.

Tem em atenção que se copias o ficheiro desaparecido do repositório e depois marcas como resolvido, a tua copia será removida novamente. Tens de resolver primeiro o conflito.

Edição local, apagar após fusão

  1. O Programador A trabalhando no trunk move o Foo.c para Bar.c e submete-o para o repositório.

  2. O Programador B trabalhando no ramo modifica o Foo.c e submete-o para o repositório.

  1. O Programador A trabalhando no trunk move a pasta pai FooFolder para BarFolder e submete-o para o repositório.

  2. O Programador B trabalhando num ramo modifica Foo.c na sua cópia de trabalho

A fusão das alterações no trunk do programador A para o ramo, da cópia de trabalho, do programador B resulta num conflito de árvore:

  • Bar.c é marcado como adicionado.

  • Foo.c é marcado como modificado com um conflito de árvore.

O programador B agora tem de decidir se quer manter a reorganização do programador A e fundir as suas alterações no ficheiro correspondente na nova estrutura, ou simplesmente reverter as alterações de A e manter o ficheiro local.

To merge her local changes with the reshuffle, Developer B must first find out to what filename the conflicted file Foo.c was renamed/moved in the repository. This can be done by using the log dialog for the merge source. The conflict editor only shows the log for the working copy as it does not know which path was used in the merge, so you will have to find that yourself. The changes must then be merged by hand as there is currently no way to automate or even simplify this process. Once the changes have been ported across, the conflicted path is redundant and can be deleted.

If Developer B decides that A's changes were wrong then she must choose the Mark as resolved button in the conflict editor dialog. This marks the conflicted file/folder as resolved, but Developer A's changes need to be removed by hand. Again the log dialog for the merge source helps to track down what was moved.

Apagamento local, apagar após fusão

  1. O Programador A trabalhando no trunk move o Foo.c para Bar.c e submete-o para o repositório.

  2. O Programador B trabalhando num ramo move o Foo.c para Bix.c e submete-o para o repositório.

A fusão das alterações no trunk do programador A para o ramo, da cópia de trabalho, do programador B resulta num conflito de árvore:

  • Bix.c é marcado com o estado normal (não modificado).

  • Bar.c é marcado como adicionado com história.

  • Foo.c é marcado como desaparecido e adquire um conflito de árvore.

To resolve this conflict, Developer B has to find out to what filename the conflicted file Foo.c was renamed/moved in the repository. This can be done by using the log dialog for the merge source.

Então o programador B tem de decidir qual o novo nome de ficheiro do ficheiro Foo.c deve manter - o criado pelo programador A ou o nome criado pelo próprio.

Depois de o programador B ter resolvido o conflito manualmente, o conflito de árvore tem de ser marcado como resolvido, com o botão na caixa de diálogo editor de conflito.

Outros conflitos de árvore

Existem outros casos que estão etiquetados como conflitos de árvore, simplesmente porque o conflito envolve uma pasta ao invés de um ficheiro. Por exemplo, se adicionastes uma pasta com o mesmo nome para o trunk e para um ramo, e tentares integrar, irás então obter um conflito de árvore. Se quiseres manter a pasta do destino da integração, marca o conflito como resolvido. Se quiseres usar a pasta da origem da integração, então precisas de SVN remover primeiro a do destino de integração, e correr de novo a integração. Se precisares de algo mais complicado, então tens de resolver o conflito manualmente.

TortoiseSVN homepage