Conceitos e exemplos em versionamento de código

28
Conceitos e Exemplos em Versionamento de Código 30-40 minutos Atualizado em 20 Ago 2014 [email protected] Exemplos com Subversion

description

Uma pequena apresentação dedicada a expôr desenvolvedores a conceitos e termos relacionados ao controle de versão de código em projetos de software; essa é uma prática essencial no desenvolvimento de software com a qual todos os desenvolvedores se depararão no decorrer de suas carreiras.

Transcript of Conceitos e exemplos em versionamento de código

Page 1: Conceitos e exemplos em versionamento de código

Conceitos e Exemplos em Versionamento de Código

30-40 minutosAtualizado em 20 Ago 2014 [email protected]

Exemplos com Subversion

Page 2: Conceitos e exemplos em versionamento de código

IntroduçãoUm sistema de controle de versão de código-fonte (VCS) é um programa que guarda todas as modificações que levaram cada linha de arquivo do seu projeto desde o seu estado inicial (provavelmente em branco) até o estado atual, passando por todas as mudanças intermediárias.

Um VCS pode lhe ser útil se você, por exemplo:● deseja guardar a história do seu projeto e se proteger contra eventuais

perdas, mudanças que causaram erros ou

● pertence a uma equipe de desenvolvimento com 2 ou mais desenvolvedores

Page 3: Conceitos e exemplos em versionamento de código

Cenários Comuns● Um desenvolvedor deseja mudar uma funcionalidade existente mas deseja

que a antiga fique disponível enquanto a nova versão está sendo escrita;

● Um desenvolvedor percebe que sua aplicação, que estava funcionando, agora contém um erro, mas ele não consegue identificar qual mudança introduziu este erro.

● Dois desenvolvedores estão trabalhando cada um em uma tarefa, mas ambas envolvem mudar um mesmo arquivo de código; ambas as tarefas têm alta prioridade então um não pode esperar até que o outro acabe para então começar a trabalhar. As duas tarefas têm que ser feitas ao mesmo tempo.

Page 4: Conceitos e exemplos em versionamento de código

Principais ferramentas● CVS

● Subversion (SVN)

● Team Foundation Server (TFS)

● Git

● Mercurial

● Perforce

Page 5: Conceitos e exemplos em versionamento de código

RepositórioO repositório (também chamado de repo) é o lugar onde o seu projeto, bem como todo o histórico de modificações do mesmo, fica guardado.

Em geral ele é localizado em outra máquina e é identificado por uma url.

Seu repositório reflete a história do seu projeto, até a versão mais recente do seu projeto (também chamada de HEAD).

Quando alguém executa uma operação do tipo commit, o repositório é atualizado com as modificações introduzidas por aquele commit.

Page 6: Conceitos e exemplos em versionamento de código

Repositório (cont.)Exemplo: criar um repositório local na sua máquina

● svnadmin create /home/usuario/meu-repo

Note que este repositório só poderá ser acessado de dentro da sua máquina através do protocolo file://, por exemplo:*

● svn list file:///home/usuario/meu-repo

* A partir de outras máquinas, este repositório ser acessado de outras formas; por exemplo, os protocolos svn+ssh// e http://.

comando para listar arquivos de um repositório

Page 7: Conceitos e exemplos em versionamento de código

CheckoutUma operação do tipo checkout faz uma cópia do código de um repositório para o seu diretório atual.

Exemplos:● svn checkout http://example.com:9834/trunk minha_copia

Este comando faz uma cópia do código cujo repositório está em http://svn.example.com:9834/trunk para o diretório atual, sob o nome minha_copia/.

● svn checkout svn+ssh://usuario@servidor/var/svnrepos/meu-repoEste comando usa o protocolo ssh para se conectar ao servidor e faz uma cópia do código em sua máquina (para dentro de um diretório chamado meu-repo/ pois não foi definido um nome alternativo como no exemplo anterior)

Page 8: Conceitos e exemplos em versionamento de código

Working copy(também chamado de working directory)

A sua working copy é a sua cópia do projeto.

Quando você faz uma operação de checkout ou clone, o diretório para onde os arquivos do projeto foram copiados é a sua working copy.

Nada do que você faz na sua working copy é publicado (para o seu repositório até que você faça um commit), portanto modificações, criação de arquivos e remoção de arquivos na sua cópia local não afetam o seu repositório.

Page 9: Conceitos e exemplos em versionamento de código

AddUm arquivo ou diretório criado na sua working copy não é versionado (tracked) por default. Para que um VCS (nesse caso, o SVN) comece a versionar (isto é, guardar o histórico de modificações) de um arquivo, é necessário que se execute o comando add:

(dentro de sua working copy)

● svn add arquivo1.txt

Note que um comando do tipo commit só envia para o repositório mudanças em arquivos versionados (isto é, arquivos em que se executou svn add). Arquivos não versionados são ignorados pelo VCS.

Page 10: Conceitos e exemplos em versionamento de código

CommitA operação de commit atualiza o repositório com modificações feitas nos arquivos versionados em uma cópia local.

● mensagem de commit

● revision N

Exemplos● svn commit a.txt b.txt -m "nova versão"

Este comando atualiza o repositório de origem (de onde você fez checkout) com as mudanças feitas nos arquivos a.txt e b.txt.

uma pequena mensagem explicando o commit e a sua

razão

o estado do repositório após o N-ésimo commit

Page 11: Conceitos e exemplos em versionamento de código

UpdateUma operação de update faz a sua working copy refletir o estado atual do repositório.

Se, por exemplo, modificações foram feitas por outro desenvolvedor no seu repositório de origem desde a última vez que você fez uma operação de checkout, uma operação de update irá modificar a sua working copy de modo a ficar igual ao estado atual do repositório.

Exemplos:● svn update arquivo1.txt

● svn update -r40

sua working copy agora está no estado como estava após o 40º commit

Page 12: Conceitos e exemplos em versionamento de código

RevertUma operação do tipo revert descarta as modificações em um arquivo na sua working copy (ou seja, modificações que ainda não sofreram commit), fazendo-o ficar idêntica ao último commit do repositório.

Exemplos:● svn revert arquivo1.txt

● svn revert --depth=infinity .A opção --depth=infinity faz a operação de revert ser feita em diretórios-filhos do diretório atual, recursivamente.

Page 13: Conceitos e exemplos em versionamento de código

BranchUm branch é um artifício suportado por vários VCSs. Ele representa uma outra linha de desenvolvimento.

Casos de uso:● Você deseja começar a implementar uma funcionalidade nova

(grande e que necessitará de vários commits) mas quer que sua versão principal continue estável enquanto a funcionalidade nova não fica pronta.

● Você deseja fazer experimentos com funcionalidades novas mas não deseja que a versão principal seja afetada.

Page 14: Conceitos e exemplos em versionamento de código

BranchExemplo de criação um branch:

● svn copy http://example.com/trunk \ http://example.com/branches/my-branch \ -m "criando um novo branch"

Cria um branch do repositório, acessível pela url http://example.com/branches/my-branch. Pode-se fazer checkout deste como se fosse um repositório normal.

Page 15: Conceitos e exemplos em versionamento de código

Merge● Comando que gera uma versão final de um arquivo a partir de duas versões do

mesmo arquivo.

● Na maioria das vezes, não é necessária intervenção manual do usuário, pois os VCSs conseguem fazer merges automáticos para a maioria dos casos.

● Quando um merge automático não consegue ser feito, é gerado um conflito que deve ser resolvido manualmente.

por exemplo, em dois branches ou em duas revisions diferentes

Page 16: Conceitos e exemplos em versionamento de código

Merge (cont.)Exemplos:● svn merge http://example.com/branches/branch-a

Se você executar este comando de dentro de uma working copy (e assumindo que o branch branch-a foi criado a partir do mesmo repositório), este comando fará um merge do branch branch-a com a sua working copy atual.

Page 17: Conceitos e exemplos em versionamento de código

ConflitosConflitos acontecem quando o seu VCS não consegue, de forma automática, fundir em um arquivo novo mudanças oriundas de duas versões diferentes.

Conflitos podem surgir após operações de update ou merge.

Exemplo: conflito após uma operação de update no SVN:$ svn updateUpdating '.':Conflict discovered in 'foo.c'.Select: (p) postpone, (df) diff-full, (e) edit, (mc) mine-conflict, (tc) theirs-conflict, (s) show all options:

Page 18: Conceitos e exemplos em versionamento de código

ConflitosExemplo de um arquivo com marcadores de conflito (SVN): arquivo1.txt

there are<<<<<<< .minenine=======eight>>>>>>> .r999

planets in the solar system

parte comum às duas versões

versão do branch atual (“minha” versão)

versão do outro branch ou revision (versão “deles”)

Page 19: Conceitos e exemplos em versionamento de código

Resolvendo conflitosUm método simples de resolver conflitos é simplesmente editar (manualmente) o arquivo com marcadores de conflito e avisar ao SVN que o conflito foi resolvido:

● editar o arquivo arquivo1.txt

● svn resolve --accept working arquivo1.txt

● svn commit -m "conflito resolvido!"

não esquecer de dar commit!

dizer ao SVN que a versão final é a versão é a que está

na working copy

Page 20: Conceitos e exemplos em versionamento de código

Resolvendo conflitos (cont.)Você também pode mandar o SVN aceitar uma das versões em detrimento da outra:Exemplos:

● svn resolve --accept mine-conflict arquivo1.txtAssumindo que o arquivo arquivo1.txt está em conflito, este comando adota a “minha” versão do conteúdo para todos os conflitos.

● svn resolve --accept theirs-conflict arquivo2.txtA versão do branch remoto (“deles”) é escolhida e a minha versão, bem como os marcadores de conflito, são retirados do arquivo.

N.B.: Outras opções como theirs-full, mine-conflict e theirs-conflict também estão disponíveis.

Page 21: Conceitos e exemplos em versionamento de código

Melhores práticas● Dê commit frequentemente

○ quanto mais commits, mais lugares para onde você pode fazer revert○ mais fácil fazer merge se as duas versões de um arquivo não estão muito

diferentes entre si.○ você se força a dividir o desenvolvimento em unidades pequenas e

autocontidas de tarefas.○ Ajuda a contar a ‘história’ do projeto através dos commits.

● Dê commit de todos os arquivos relacionados a uma mudança de forma única, incluindo todos eles; em outras palavras, seu commit deve ter unidade lógica.

Page 22: Conceitos e exemplos em versionamento de código

Melhores práticas (cont.)● Todos os commits devem deixar o software funcionando.

○ Ou seja: todos os testes devem estar passando.○ Ou seja: nunca dê commit antes de testar.

● Não dê commit em arquivos gerados○ Arquivos executáveis (no caso de linguagens compiladas) ou arquivos de

output gerados por ferramentas não devem ser versionados.

● Não dê commit em arquivos de preferências○ Arquivos como .vimrc (vim), .nbproject/ (netbeans) ou .idea/

(IntelliJ) são pessoais e não deve ser versionados.

Page 23: Conceitos e exemplos em versionamento de código

Melhores práticas (cont.)● Use mensagens de commit descritivas e explicativas

○ Lembre-se que você não se lembrará do que fez hoje daqui a alguns meses.

○ As mensagens de commit servem como documentação do projeto.

● Não dê commit em coisas feitas pela metade○ Divida coisas grandes em unidades lógicas menores e dê commit em

cada uma delas separadamente.○ Senão, espere até o fim da tarefa para dar commit.

Page 24: Conceitos e exemplos em versionamento de código

XTRA: Comandos úteis para o dia-a-dia (SVN)

● svn delete arquivo1.txtRemove um arquivo da sua working copy e do repositório (quando você der commit, o arquivo vai ser removido do repositório)

● svn delete --keep-local arquivo1.txtRemove um arquivo do repositório mas o deixa na sua working copy (ele fica no estado untracked).

● svn mv arquivo1.txt ../arquivo2.txtMover (e/ou renomear) um arquivo, deixando claro para o SVN que se trata do mesmo arquivo.

Page 25: Conceitos e exemplos em versionamento de código

XTRA: Repositórios centralizados e descentralizados● Em um VCS centralizado, só há uma cópia do repositório. Cada usuário só tem

acesso à sua cópia dos arquivos (no seu working directory); quando você executa um commit, o repositório central é atualizado.

● Em um VCS descentralizado (DVCS), não há um único repositório; cada usuário guarda uma cópia do repositório inteiro; o comando commit envia suas modificações para a sua cópia do repositório.

● Para interagir com repositórios remotos são usados alguns comandos novos, como fetch, pull e push.

Page 26: Conceitos e exemplos em versionamento de código

XTRA: push e pullComo VCSs descentralizados podem ter várias cópias do mesmo repositório em existência, há dois comandos extras que definem operações entre um repositório local e um outro repositório remoto:

● comando push○ Envia o seu repositório (com todos os seus commits) para um

repositório remoto, atualizando o mesmo (pode ser rejeitado).

● comando pull○ Tenta atualizar o seu repositório local, incorporando modificações

vindas de um repositório remoto (pode haver conflitos).

Page 27: Conceitos e exemplos em versionamento de código

XTRA: Migrações - versionamento de bancos de dados● Dois projetos rodando a mesma versão do código mas com bancos de

dados com estruturas diferentes (tabelas e atributos) vão exibir comportamento diferente.

● Hoje em dia (2014) este já é um problema bem resolvido pela maioria dos frameworks em existência.

● Migrações consistem em fazer cada mudança na estrutura do seu banco de dados através de arquivos.