SVN - Guia Rápido

O que é o Sistema de Controle de Versão?

Version Control System (VCS) é um software que ajuda os desenvolvedores de software a trabalhar juntos e manter um histórico completo de seu trabalho.

Following are the goals of a Version Control System.

  • Permita que os desenvolvedores trabalhem simultaneamente.
  • Não substituam as alterações uns dos outros.
  • Mantenha a história de cada versão de tudo.

A VCS is divided into two categories.

  • Sistema de Controle de Versão Centralizado (CVCS), e
  • Sistema de controle de versão distribuído / descentralizado (DVCS).

Neste tutorial, vamos nos concentrar apenas no Sistema de Controle de Versão Centralizado e especialmente Subversion. O Subversion se enquadra no sistema de controle de versão centralizado, o que significa que ele usa um servidor central para armazenar todos os arquivos e permite a colaboração em equipe.

Terminologias de controle de versão

Vamos começar discutindo alguns dos termos que usaremos neste tutorial.

  • Repository:Um repositório é o coração de qualquer sistema de controle de versão. É o local central onde os desenvolvedores armazenam todo o seu trabalho. O repositório não apenas armazena arquivos, mas também o histórico. O repositório é acessado através de uma rede, atuando como um servidor e uma ferramenta de controle de versão atuando como um cliente. Os clientes podem se conectar ao repositório e, em seguida, podem armazenar / recuperar suas alterações de / para o repositório. Ao armazenar as alterações, um cliente torna essas alterações disponíveis para outras pessoas e, recuperando as alterações, um cliente recebe as alterações de outras pessoas como uma cópia de trabalho.

  • Trunk: O tronco é um diretório onde todo o desenvolvimento principal acontece e normalmente é verificado pelos desenvolvedores para trabalhar no projeto.

  • Tags: O diretório de tags é usado para armazenar instantâneos nomeados do projeto. A operação de tag permite dar nomes descritivos e memoráveis ​​a uma versão específica no repositório.

    Por exemplo, LAST_STABLE_CODE_BEFORE_EMAIL_SUPPORT é mais memorável do que

    UUID do repositório: 7ceef8cb-3799-40dd-a067-c216ec2e5247 e

    Revisão: 13

  • Branches:A operação de filial é usada para criar outra linha de desenvolvimento. É útil quando você deseja que seu processo de desenvolvimento siga em duas direções diferentes. Por exemplo, ao lançar a versão 5.0, você pode querer criar um branch para que o desenvolvimento dos recursos 6.0 possa ser mantido separado das correções de bugs do 5.0.

  • Working copy:A cópia de trabalho é um instantâneo do repositório. O repositório é compartilhado por todas as equipes, mas as pessoas não o modificam diretamente. Em vez disso, cada desenvolvedor verifica a cópia de trabalho. A cópia de trabalho é um local de trabalho privado onde os desenvolvedores podem fazer seu trabalho ficando isolados do resto da equipe.

  • Commit changes:Commit é um processo de armazenamento de alterações do local de trabalho privado para o servidor central. Após a confirmação, as alterações são disponibilizadas para toda a equipe. Outros desenvolvedores podem recuperar essas mudanças atualizando sua cópia de trabalho. Commit é uma operação atômica. Todo o commit é bem-sucedido ou é revertido. Os usuários nunca veem o commit pela metade.

Instalação SVN

Subversion é uma ferramenta popular de controle de versão de código aberto. É de código aberto e está disponível gratuitamente na Internet. Ele vem por padrão com a maioria das distribuições GNU / Linux, então pode já estar instalado em seu sistema. Para verificar se está instalado ou não, use o seguinte comando.

[jerry@CentOS ~]$ svn --version

Se o cliente Subversion não estiver instalado, o comando relatará o erro, caso contrário, exibirá a versão do software instalado.

[jerry@CentOS ~]$ svn --version
-bash: svn: command not found

Se você estiver usando GNU / Linux baseado em RPM, use yumcomando para instalação. Após a instalação bem-sucedida, execute osvn --version comando.

[jerry@CentOS ~]$ su - Password: [root@CentOS ~]# yum install subversion [jerry@CentOS ~]$ svn --version
svn, version 1.6.11 (r934486)
compiled Jun 23 2012, 00:44:03

E se você estiver usando GNU / Linux baseado em Debian, use apt comando para instalação.

[jerry@Ubuntu]$ sudo apt-get update [sudo] password for jerry: [jerry@Ubuntu]$ sudo apt-get install subversion

[jerry@Ubuntu]$ svn --version
svn, version 1.7.5 (r1336830)
compiled Jun 21 2013, 22:11:49

Configuração do Apache

Vimos como instalar o cliente Subversion no GNU / Linux. Vamos ver como criar um novo repositório e permitir o acesso aos usuários.

No servidor, temos que instalar Apache httpd módulo e svnadmin ferramenta.

[jerry@CentOS ~]$ su -
Password: 
[root@CentOS ~]# yum install mod_dav_svn subversion

o mod_dav_svn pacote permite o acesso a um repositório usando HTTP, via servidor Apache httpd e subversion pacote instala a ferramenta svnadmin.

O subversion lê sua configuração de /etc/httpd/conf.d/subversion.confArquivo. Depois de adicionar a configuração,subversion.conf arquivo tem a seguinte aparência:

LoadModule dav_svn_module     modules/mod_dav_svn.so
LoadModule authz_svn_module   modules/mod_authz_svn.so

<Location /svn>
   DAV svn
   SVNParentPath /var/www/svn
   AuthType Basic
   AuthName "Authorization Realm"
   AuthUserFile /etc/svn-users
   Require valid-user
</Location>

Vamos criar usuários do Subversion e conceder-lhes acesso ao repositório. O comando htpasswd é usado para criar e atualizar os arquivos de texto simples que são usados ​​para armazenar nomes de usuários e senhas para autenticação básica de usuários HTTP. A opção '-c' cria um arquivo de senha ; se o arquivo de senha já existir, ele será sobrescrito. É por isso que use a opção '-c' apenas na primeira vez. A opção '-m' ativa a criptografia MD5 para senhas.

Configuração do usuário

Deixe-nos criar usuário tom.

[root@CentOS ~]# htpasswd -cm /etc/svn-users tom
New password: 
Re-type new password: 
Adding password for user tom

Deixe-nos criar usuário jerry

[root@CentOS ~]# htpasswd -m /etc/svn-users jerry
New password: 
Re-type new password: 
Adding password for user jerry
[root@CentOS ~]#

Crie o diretório pai do Subversion para armazenar todo o trabalho (consulte /etc/httpd/conf.d/subversion.conf ).

[root@CentOS ~]# mkdir /var/www/svn
[root@CentOS ~]# cd /var/www/svn/

Configuração do Repositório

Crie um repositório de projeto denominado project_repo . O comando svnadmin criará um novo repositório e alguns outros diretórios dentro dele para armazenar os metadados.

[root@CentOS svn]# svnadmin create project_repo

[root@CentOS svn]# ls -l project_repo
total 24
drwxr-xr-x. 2 root root 4096 Aug  4 22:30 conf
drwxr-sr-x. 6 root root 4096 Aug  4 22:30 db
-r--r--r--. 1 root root    2 Aug  4 22:30 format
drwxr-xr-x. 2 root root 4096 Aug  4 22:30 hooks
drwxr-xr-x. 2 root root 4096 Aug  4 22:30 locks
-rw-r--r--. 1 root root  229 Aug  4 22:30 README.txt

Vamos mudar a propriedade do usuário e do grupo do repositório.

[root@CentOS svn]# chown -R apache.apache project_repo/

Verifique se o SELinux está habilitado ou não usando a ferramenta de status SELinux.

[root@CentOS svn]# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        targeted

Para nosso servidor, o SELinux está habilitado, então temos que mudar o contexto de segurança do SELinux.

[root@CentOS svn]# chcon -R -t httpd_sys_content_t /var/www/svn/project_repo/

Para permitir confirmações por HTTP, execute o seguinte comando.

[root@CentOS svn]# chcon -R -t httpd_sys_rw_content_t /var/www/svn/project_repo/

Reinicie o servidor Apache e terminaremos a configuração do servidor Apache.

[root@CentOS svn]# service httpd restart
Stopping httpd:                                            [FAILED]
Starting httpd: httpd: apr_sockaddr_info_get() failed for CentOS
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
                                                           [  OK  ]
[root@CentOS svn]# service httpd status
httpd (pid  1372) is running...
[root@CentOS svn]#

Configuramos o servidor Apache com sucesso, agora vamos configurar o repositório. Para fornecer acesso ao repositório apenas para usuários autênticos e para usar o arquivo de autorização padrão; acrescente as seguintes linhas ao arquivo project_repo / conf / svnserve.conf .

anon-access = none
authz-db = authz

Convencionalmente, todo projeto Subversion tem trunk, tags, e branches diretórios diretamente sob o diretório raiz do projeto.

O tronco é um diretório onde acontece todo o desenvolvimento principal e normalmente é verificado pelos desenvolvedores para trabalhar no projeto.

O diretório de tags é usado para armazenar instantâneos nomeados do projeto. Ao criar uma versão de produção, a equipe marcará o código que vai para a versão.

O diretório branches é usado quando você deseja seguir diferentes linhas de desenvolvimento.

Vamos criar a estrutura de diretório trunk, tags e branches no repositório do projeto.

[root@CentOS svn]# mkdir /tmp/svn-template
[root@CentOS svn]# mkdir /tmp/svn-template/trunk
[root@CentOS svn]# mkdir /tmp/svn-template/branches
[root@CentOS svn]# mkdir /tmp/svn-template/tags

Agora importe os diretórios de /tmp/svn-template para o repositório.

[root@CentOS svn]# svn import -m 'Create trunk, branches, tags directory structure' /tmp/svn-template/ 
Adding         /tmp/svn-template/trunk
Adding         /tmp/svn-template/branches
Adding         /tmp/svn-template/tags
Committed revision 1.
[root@CentOS svn]#

Isso está feito! Criamos com sucesso o repositório e permitimos o acesso aTom e Jerry. A partir de agora, eles podem realizar todas as operações com suporte para o repositório.

O ciclo de vida de um Sistema de Controle de Versão é discutido neste capítulo. Em capítulos posteriores, veremos o comando Subversion para cada operação.

Criar Repositório:

O repositório é um local central onde os desenvolvedores armazenam todo o seu trabalho. O repositório não apenas armazena arquivos, mas também o histórico de mudanças. O que significa que ele mantém um histórico das alterações feitas nos arquivos.

A operação 'criar' é usada para criar um novo repositório. Na maioria das vezes, essa operação é feita apenas uma vez. Quando você cria um novo repositório, seu VCS espera que você diga algo para identificá-lo, como onde deseja que ele seja criado ou qual nome deve ser dado ao repositório.

Verificação de saída

A operação 'Checkout' é usada para criar uma cópia de trabalho do repositório. A cópia de trabalho é um local de trabalho privado onde os desenvolvedores fazem suas alterações e, posteriormente, enviam essas alterações para o repositório.

Atualizar

Como o nome sugere, a operação 'update' é usada para atualizar a cópia de trabalho. Esta operação sincroniza a cópia de trabalho com o repositório. Como o repositório é compartilhado por todas as equipes, outros desenvolvedores podem enviar suas alterações e sua cópia de trabalho se torna mais velha.

Vamos supor que Tom e Jerry sejam os dois desenvolvedores trabalhando em um projeto. Ambos verificam a versão mais recente do repositório e começam a trabalhar. Neste ponto, suas cópias de trabalho estão completamente sincronizadas com o repositório. Jerry conclui seu trabalho de forma muito eficiente e envia suas alterações para o repositório.

Agora a cópia de trabalho de Tom está desatualizada. A operação de atualização puxará as últimas alterações de Jerry do repositório e atualizará a cópia de trabalho de Tom .

Realizar mudanças

Após o checkout, pode-se fazer várias operações para realizar alterações. Editar é a operação mais comum. Pode-se editar o arquivo existente para adicionar / remover conteúdo do arquivo.

Pode-se adicionar arquivos / diretórios. Mas imediatamente esses arquivos / diretórios não se tornam parte do repositório, em vez disso, são adicionados à lista de alterações pendentes e se tornam parte do repositório após a operação de confirmação.

Da mesma forma, pode-se excluir arquivos / diretórios. A operação de exclusão exclui imediatamente o arquivo da cópia de trabalho, mas a exclusão real do arquivo é adicionada à lista de alterações pendentes e as alterações são feitas no repositório após a operação de confirmação.

A operação 'Renomear' altera o nome do arquivo / diretório. A operação 'Mover' é usada para mover arquivos / diretórios de um lugar para outro em uma árvore de repositório.

Rever alterações

Quando você faz o check-out da cópia de trabalho ou atualiza a cópia de trabalho, então sua cópia de trabalho é completamente sincronizada com o repositório. Mas conforme você faz alterações em sua cópia de trabalho, ela se torna mais nova que o repositório. E é uma boa prática revisar suas alterações antes da operação de 'confirmação'.

A operação de 'Status' lista as modificações que foram feitas na cópia de trabalho. Como mencionamos antes, sempre que você faz alterações na cópia de trabalho, todas essas alterações se tornam parte da lista de alterações pendentes. E a operação de 'status' é usada para ver a lista de alterações pendentes.

A operação de 'Status' fornece apenas uma lista de alterações, mas não os detalhes sobre elas. Pode-se usar a operação diff para ver os detalhes das modificações que foram feitas na cópia de trabalho.

Corrigir erros

Suponhamos que alguém tenha feito alterações em sua cópia de trabalho, mas agora, ele deseja descartar essas alterações. Nesta situação, a operação 'reverter' ajudará.

A operação Reverter reverte as modificações que foram feitas na cópia de trabalho. É possível reverter um ou mais arquivos / diretórios. Também é possível reverter toda a cópia de trabalho. Neste caso, a operação 'reverter' destruirá a lista de alterações pendentes e trará a cópia de trabalho de volta ao seu estado original.

Resolver conflitos:

Podem ocorrer conflitos no momento da fusão. A operação de 'fusão' lida automaticamente com tudo o que pode ser feito com segurança. Todo o resto é considerado conflito. Por exemplo, o arquivo "hello.c" foi modificado no ramo e excluído em outro ramo. Tal situação exige que uma pessoa tome a decisão. A operação 'resolver' é usada para ajudar o usuário a descobrir as coisas e informar o VCS sobre as formas de lidar com os conflitos.

Confirmar alterações

A operação 'Commit' é usada para aplicar mudanças da cópia de trabalho ao repositório. Esta operação modifica o repositório e outros desenvolvedores podem ver essas mudanças atualizando sua cópia de trabalho.

Antes de confirmar, é necessário adicionar arquivos / diretórios à lista de alterações pendentes. Este é o lugar onde as mudanças esperam para serem confirmadas. Com o commit, geralmente fornecemos uma mensagem de log para explicar por que alguém fez alterações. Esta mensagem de log torna-se parte da história do repositório. A confirmação é uma operação atômica, o que significa que a confirmação inteira foi bem-sucedida ou foi revertida. Os usuários nunca veem o commit incompleto.

O Subversion fornece o comando checkout para retirar uma cópia de trabalho de um repositório. O comando abaixo criará um novo diretório no diretório de trabalho atual com o nome project_repo . Não se preocupe com a URL do repositório, pois na maioria das vezes, ela já é fornecida pelo administrador do subversion com acesso apropriado.

[tom@CentOS ~]$ svn checkout http://svn.server.com/svn/project_repo --username=tom

O comando acima produzirá o seguinte resultado.

A    project_repo/trunk
A    project_repo/branches
A    project_repo/tags
Checked out revision 1.

Após cada operação de verificação bem-sucedida, o número de revisão será impresso. Se você quiser ver mais informações sobre o repositório, execute o comando info .

[tom@CentOS trunk]$ pwd
/home/tom/project_repo/trunk

[tom@CentOS trunk]$ svn info

O comando acima produzirá o seguinte resultado.

Path: .
URL: http://svn.server.com/svn/project_repo/trunk
Repository Root: http://svn.server.com/svn/project_repo
Repository UUID: 7ceef8cb-3799-40dd-a067-c216ec2e5247
Revision: 1
Node Kind: directory
Schedule: normal
Last Changed Author: jerry
Last Changed Rev: 0
Last Changed Date: 2013-08-24 18:15:52 +0530 (Sat, 24 Aug 2013)

[tom@CentOS trunk]$

Jerry verifica a versão mais recente do repositório e começa a trabalhar em um projeto. Ele cria o arquivo array.c dentro do diretório do tronco.

[jerry@CentOS ~]$ cd project_repo/trunk/ [jerry@CentOS trunk]$ cat array.c

O comando acima produzirá o seguinte resultado.

#include <stdio.h>
#define MAX 16

int main(void) {
   int i, n, arr[MAX];
   printf("Enter the total number of elements: ");
   scanf("%d", &n);

   printf("Enter the elements\n");

   for (i = 0; i < n; ++i) scanf("%d", &arr[i]);
   printf("Array has following elements\n");
   for (i = 0; i < n; ++i) printf("|%d| ", arr[i]);
   
   printf("\n");
   return 0;
}

Ele quer testar seu código antes de fazer o commit.

[jerry@CentOS trunk]$ make array cc array.c -o array [jerry@CentOS trunk]$ ./array 
Enter the total number of elements: 5
Enter the elements
1
2
3
4
5
Array has following elements
|1| |2| |3| |4| |5|

Ele compilou e testou seu código e tudo está funcionando conforme o esperado, agora é hora de confirmar as alterações.

[jerry@CentOS trunk]$ svn status
?       array.c
?       array

O Subversion está mostrando '?' na frente dos nomes dos arquivos porque não sabe o que fazer com eles.

Antes de confirmar, Jerry precisa adicionar este arquivo à lista de alterações pendentes.

[jerry@CentOS trunk]$ svn add array.c 
A         array.c

Vamos verificar isso com a operação 'status'. Programas do SubversionAantes de array.c , significa que o arquivo foi adicionado com sucesso à lista de alterações pendentes.

[jerry@CentOS trunk]$ svn status
?       array
A       array.c

Para armazenar o arquivo array.c no repositório, use o comando commit com a opção -m seguida pela mensagem de confirmação. Se você omitir a opção -m, o Subversion abrirá o editor de texto onde você pode digitar uma mensagem de várias linhas.

[jerry@CentOS trunk]$ svn commit -m "Initial commit"
Adding         trunk/array.c
Transmitting file data .
Committed revision 2.

Agora o arquivo array.c é adicionado com sucesso ao repositório, e o número da revisão é incrementado em um.

Jerry já adicionou o arquivo array.c ao repositório. Tom também verifica o código mais recente e começa a trabalhar.

[tom@CentOS ~]$ svn co http://svn.server.com/svn/project_repo --username=tom

O comando acima produzirá o seguinte resultado.

A    project_repo/trunk
A    project_repo/trunk/array.c
A    project_repo/branches
A    project_repo/tags
Checked out revision 2.

Mas, ele descobriu que alguém já adicionou o código. Ele está curioso para saber quem fez isso e verifica a mensagem de log para ver mais detalhes usando o seguinte comando:

[tom@CentOS trunk]$ svn log

O comando acima produzirá o seguinte resultado.

------------------------------------------------------------------------
r2 | jerry | 2013-08-17 20:40:43 +0530 (Sat, 17 Aug 2013) | 1 line

Initial commit
------------------------------------------------------------------------
r1 | jerry | 2013-08-04 23:43:08 +0530 (Sun, 04 Aug 2013) | 1 line

Create trunk, branches, tags directory structure
------------------------------------------------------------------------

Quando Tom observa o código de Jerry , ele imediatamente percebe um bug nele. Jerry não estava verificando o estouro do array, o que poderia causar sérios problemas. Então Tom decide consertar esse problema. Após a modificação, array.c ficará assim.

#include <stdio.h>

#define MAX 16

int main(void)
{
   int i, n, arr[MAX];

   printf("Enter the total number of elements: ");
   scanf("%d", &n);

   /* handle array overflow condition */
   if (n > MAX) {
      fprintf(stderr, "Number of elements must be less than %d\n", MAX);
      return 1;
   }

   printf("Enter the elements\n");

   for (i = 0; i < n; ++i)
      scanf("%d", &arr[i]);

   printf("Array has following elements\n");
   for (i = 0; i < n; ++i)
      printf("|%d| ", arr[i]);
      printf("\n");

   return 0;
}

Tom deseja usar a operação de status para ver a lista de alterações pendentes.

[tom@CentOS trunk]$ svn status
M       array.c

arquivo array.c é modificado, é por isso que o Subversion mostraMletra antes do nome do arquivo. Em seguida, Tom compila e testa seu código e está funcionando bem. Antes de confirmar as alterações, ele deseja verificar novamente, revisando as alterações que fez.

[tom@CentOS trunk]$ svn diff
Index: array.c
===================================================================
--- array.c   (revision 2)
+++ array.c   (working copy)
@@ -9,6 +9,11 @@
    printf("Enter the total number of elements: ");
    scanf("%d", &n);
 
+   if (n > MAX) {
+      fprintf(stderr, "Number of elements must be less than %d\n", MAX);
+      return 1;
+   }
+
    printf("Enter the elements\n");
 
    for (i = 0; i < n; ++i)

Tom adicionou algumas linhas no arquivo array.c , é por isso que o Subversion mostra + assinar antes de novas linhas. Agora ele está pronto para enviar suas alterações.

[tom@CentOS trunk]$ svn commit -m "Fix array overflow problem"

O comando acima produzirá o seguinte resultado.

Sending        trunk/array.c
Transmitting file data .
Committed revision 3.

As alterações de Tom foram confirmadas com sucesso no repositório.

Jerry havia confirmado a primeira versão do código. Mas ele acha que deve escrever duas funções para aceitar a entrada e exibir o conteúdo do array. Após a modificação, array.c tem a seguinte aparência.

#include <stdio.h>
#define MAX 16

void accept_input(int *arr, int n) {
   int i;
   for (i = 0; i < n; ++i) 
   scanf("%d", &arr[i]);
}

void display(int *arr, int n) {
   int i;
   for (i = 0; i < n; ++i) 
   printf("|%d| ", arr[i]);
   
   printf("\n");
}

int main(void) {
   int i, n, arr[MAX];

   printf("Enter the total number of elements: ");
   scanf("%d", &n);

   printf("Enter the elements\n");
   accept_input(arr, n);

   printf("Array has following elements\n");
   display(arr, n);

   return 0;
}

Jerry compila e testa seu código e está pronto para confirmar as alterações. Antes disso, ele deseja revisar as alterações usando o seguinte comando.

[jerry@CentOS trunk]$ svn diff

O comando acima produzirá o seguinte resultado.

Index: array.c
===================================================================
--- array.c   (revision 2)
+++ array.c   (working copy)
@@ -2,6 +2,24 @@
 
 #define MAX 16
 
+void accept_input(int *arr, int n)
+{
+   int i;
+
+   for (i = 0; i & n; ++i)
+      scanf("%d", &arr[i]);
+}
+
+void display(int *arr, int n)
+{
+   int i;
+
+   for (i = 0; i < n; ++i)
+      printf("|%d| ", arr[i]);
+   
+   printf("\n");
+}
+
 int main(void)
 {
    int i, n, arr[MAX];
@@ -10,15 +28,10 @@
    scanf("%d", &n);
 
    printf("Enter the elements\n");
+   accept_input(arr, n);
 
-   for (i = 0; i < n; ++i)
-      scanf("%d", &arr[i]);
-
    printf("Array has following elements\n");
-   for (i = 0; i < n; ++i)
-      printf("|%d| ", arr[i]);
-   
-   printf("\n");
+   display(arr, n);
 
    return 0;
 }

Para as novas linhas adicionadas, o Subversion mostra + sinal antes da linha e para a linha removida mostra -placa. Agora, Jerry tenta confirmar as alterações usando o seguinte comando:

[jerry@CentOS trunk]$ svn commit -m "Add function to accept input and to display array contents"

O comando acima produzirá o seguinte resultado.

Sending        trunk/array.c
svn: Commit failed (details follow):
svn: File or directory 'array.c' is out of date; try updating
svn: resource out of date; try updating

O Subversion não está permitindo submeter as alterações de Jerry , porque Tom já modificou o repositório e a cópia de trabalho de Jerry está desatualizada. Para evitar sobrescrever as mudanças uns dos outros, o Subversion falha nesta operação. Jerry deve atualizar a cópia de trabalho antes de enviar suas alterações. Então ele usa o comando de atualização conforme mostrado abaixo.

[jerry@CentOS trunk]$ svn update
G    array.c
Updated to revision 3.

Subversion está mostrando a carta G antes do nome do arquivo, o que significa que o arquivo foi mesclado.

[jerry@CentOS trunk]$ svn diff

O comando acima produzirá o seguinte resultado.

Index: array.c
===================================================================
--- array.c   (revision 3)
+++ array.c   (working copy)
@@ -2,6 +2,24 @@
 
 #define MAX 16
 
+void accept_input(int *arr, int n)
+{
+   int i;
+
+   for (i = 0; i < n; ++i)
+      scanf("%d", &arr[i]);
+}
+
+void display(int *arr, int n)
+{
+   int i;
+
+   for (i = 0; i < n; ++i)
+      printf("|%d| ", arr[i]);
+   
+   printf("\n");
+}

+
 int main(void)
 {
    int i, n, arr[MAX];
@@ -15,15 +33,10 @@
    }
 
    printf("Enter the elements\n");
+   accept_input(arr, n);
 
-   for (i = 0; i < n; ++i)
-      scanf("%d", &arr[i]);
-
    printf("Array has following elements\n");
-   for (i = 0; i < n; ++i)
-      printf("|%d| ", arr[i]);
-   
-   printf("\n");
+   display(arr, n);
 
    return 0;
 }

O Subversion está mostrando apenas as mudanças de Jerry , mas o arquivo array.c foi mesclado. Se você observar cuidadosamente, o Subversion agora está mostrando a revisão número 3. Na saída anterior, ele estava mostrando a revisão número 2. Apenas revise quem fez as alterações no arquivo e com que propósito.

jerry@CentOS trunk]$ svn log
------------------------------------------------------------------------
r3 | tom   | 2013-08-18 20:21:50 +0530 (Sun, 18 Aug 2013)   | 1 line

Fix array overflow problem
------------------------------------------------------------------------
r2 | jerry | 2013-08-17 20:40:43 +0530 (Sat, 17 Aug 2013) | 1 line

Initial commit
------------------------------------------------------------------------
r1 | jerry | 2013-08-04 23:43:08 +0530 (Sun, 04 Aug 2013) | 1 line

Create trunk, branches, tags directory structure
------------------------------------------------------------------------

Agora a cópia de trabalho de Jerry está sincronizada com o repositório e ele pode enviar com segurança suas alterações.

[jerry@CentOS trunk]$ svn commit -m "Add function to accept input and to display array contents"
Sending        trunk/array.c
Transmitting file data .
Committed revision 4.

Suponha que Jerry modifique acidentalmente o arquivo array.c e esteja recebendo erros de compilação. Agora ele quer jogar fora as mudanças. Nesta situação, a operação 'reverter' ajudará. A operação de reversão desfará todas as alterações locais em um arquivo ou diretório e resolverá quaisquer estados de conflito.

[jerry@CentOS trunk]$ svn status

O comando acima produzirá o seguinte resultado.

M       array.c

Vamos tentar fazer array da seguinte maneira:

[jerry@CentOS trunk]$ make array

O comando acima produzirá o seguinte resultado.

cc     array.c   -o array
array.c: In function ‘main’:
array.c:26: error: ‘n’ undeclared (first use in this function)
array.c:26: error: (Each undeclared identifier is reported only once
array.c:26: error: for each function it appears in.)
array.c:34: error: ‘arr’ undeclared (first use in this function)
make: *** [array] Error 1

Jerry executa a operação de 'reversão' no arquivo array.c .

[jerry@CentOS trunk]$ svn revert array.c 
Reverted 'array.c'

[jerry@CentOS trunk]$ svn status [jerry@CentOS trunk]$

Agora compile o código.

[jerry@CentOS trunk]$ make array
cc     array.c   -o array

Após a operação de reversão, sua cópia de trabalho volta ao estado original. A operação de reversão pode reverter um único arquivo, bem como um diretório completo. Para reverter um diretório, use a opção -R conforme mostrado abaixo.

[jerry@CentOS project_repo]$ pwd
/home/jerry/project_repo

[jerry@CentOS project_repo]$ svn revert -R trunk

Até agora, vimos como reverter as alterações, que foram feitas na cópia de trabalho. Mas e se você quiser reverter uma revisão confirmada! A ferramenta do Sistema de Controle de Versão não permite excluir o histórico do repositório. Podemos apenas anexar a história. Isso acontecerá mesmo se você excluir arquivos do repositório. Para desfazer uma revisão antiga, temos que reverter todas as mudanças feitas na revisão antiga e então submeter uma nova revisão. Isso é chamado de mesclagem reversa.

Vamos supor que Jerry adicione um código para a operação de pesquisa linear. Após a verificação, ele confirma suas alterações.

[jerry@CentOS trunk]$ svn diff
Index: array.c
===================================================================
--- array.c   (revision 21)
+++ array.c   (working copy)
@@ -2,6 +2,16 @@
 
 #define MAX 16
 
+int linear_search(int *arr, int n, int key)
+{
+   int i;
+
+   for (i = 0; i < n; ++i)
+      if (arr[i] == key)
+         return i;
+   return -1;
+}
+
 void bubble_sort(int *arr, int n)
 {
    int i, j, temp, flag = 1;

[jerry@CentOS trunk]$ svn status ? array M array.c [jerry@CentOS trunk]$ svn commit -m "Added code for linear search"
Sending        trunk/array.c
Transmitting file data .
Committed revision 22.

Jerry está curioso para saber o que Tom está fazendo. Portanto, ele verifica as mensagens de log do Subversion.

[jerry@CentOS trunk]$ svn log

O comando acima produzirá o seguinte resultado.

------------------------------------------------------------------------
r5 | tom   | 2013-08-24 17:15:28 +0530 (Sat, 24 Aug 2013) | 1 line

Add binary search operation
------------------------------------------------------------------------
r4 | jerry | 2013-08-18 20:43:25 +0530 (Sun, 18 Aug 2013) | 1 line

Add function to accept input and to display array contents

Depois de ver as mensagens de log, Jerry percebe que cometeu um erro grave. Porque Tom já implementou a operação de pesquisa binária, que é melhor do que a pesquisa linear; seu código é redundante e agora Jerry tem que reverter suas alterações para a revisão anterior. Portanto, primeiro encontre a revisão atual do repositório. Atualmente, o repositório está na revisão 22 e temos que revertê-lo para a revisão anterior, ou seja, revisão 21.

[jerry@CentOS trunk]$ svn up 
At revision 22.

[jerry@CentOS trunk]$ svn merge -r 22:21 array.c --- Reverse-merging r22 into 'array.c': U array.c [jerry@CentOS trunk]$ svn commit -m "Reverted to revision 21"
Sending        trunk/array.c
Transmitting file data .
Committed revision 23.

Tom decide adicionar um arquivo README ao projeto. Então ele cria o arquivo README e adiciona a lista TODO a ele. Depois de adicionar isso, o repositório de arquivos está na revisão 6.

[tom@CentOS trunk]$ cat README /* TODO: Add contents in README file */ [tom@CentOS trunk]$ svn status
?       README

[tom@CentOS trunk]$ svn add README A README [tom@CentOS trunk]$ svn commit -m "Added README file. Will update it's content in future."
Adding         trunk/README
Transmitting file data .
Committed revision 6.

Jerry verifica o código mais recente, que está na revisão 6. E imediatamente começa a trabalhar. Depois de algumas horas, Tom atualiza o arquivo README e confirma suas alterações. O README modificado terá esta aparência.

[tom@CentOS trunk]$ cat README * Supported operations: 1) Accept input 2) Display array elements [tom@CentOS trunk]$ svn status
M       README

[tom@CentOS trunk]$ svn commit -m "Added supported operation in README"
Sending        trunk/README
Transmitting file data .
Committed revision 7.

Agora, o repositório está na revisão 7 e a cópia de trabalho de Jerry está desatualizada. Jerry também atualiza o arquivo README e tenta confirmar suas alterações.

O arquivo README de Jerry se parece com isso.

[jerry@CentOS trunk]$ cat README 
* File list

1) array.c	Implementation of array operation.
2) README	Instructions for user.

[jerry@CentOS trunk]$ svn status M README [jerry@CentOS trunk]$ svn commit -m "Updated README"
Sending        trunk/README
svn: Commit failed (details follow):
svn: File or directory 'README' is out of date; try updating
svn: resource out of date; try updating

Etapa 1: Ver os conflitos

O Subversion detectou que o arquivo README foi alterado desde a última atualização. Então, Jerry tem que atualizar sua cópia de trabalho.

[jerry@CentOS trunk]$ svn up
Conflict discovered in 'README'.
Select: (p) postpone, (df) diff-full, (e) edit,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options:

O Subversion está reclamando que há um conflito com o arquivo README, e o Subversion não sabe como resolver isso. Portanto, Jerry escolhe a opção df para revisar o conflito.

[jerry@CentOS trunk]$ svn up
Conflict discovered in 'README'.
Select: (p) postpone, (df) diff-full, (e) edit,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options: df
--- .svn/text-base/README.svn-base	Sat Aug 24 18:07:13 2013
+++ .svn/tmp/README.tmp	Sat Aug 24 18:13:03 2013
@@ -1 +1,11 @@
-/* TODO: Add contents in README file */
+<<<<<<< .mine
+* File list
+
+1) array.c	Implementation of array operation.
+2) README	Instructions for user.
+=======
+* Supported operations:
+
+1) Accept input
+2) Display array elements
+>>>>>>> .r7
Select: (p) postpone, (df) diff-full, (e) edit, (r) resolved,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options:

Etapa 2: adiar conflitos

Em seguida, Jerry escolhe as opções de adiar (p) , para que ele possa resolver o conflito.

Select: (p) postpone, (df) diff-full, (e) edit, (r) resolved,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options: p
C    README
Updated to revision 7.
Summary of conflicts:
  Text conflicts: 1

Depois de abrir o README no editor de texto, ele percebeu que o Subversion incluiu o código de Tom e seu código com marcadores de conflito.

[jerry@CentOS trunk]$ cat README
<<<<<<< .min
* File list

1) array.c	Implementation of array operation.
2) README	Instructions for user.
=======
* Supported operations:

1) Accept input
2) Display array elements
>>>>>>> .r7

Jerry quer as alterações de Tom assim como as dele, então ele apenas remove as linhas que contêm os marcadores de conflito.

Portanto, o README modificado terá esta aparência.

[jerry@CentOS trunk]$ cat README
* File list

1) array.c	Implementation of array operation.
2) README	Instructions for user.

* Supported operations:

1) Accept input
2) Display array elements

Jerry resolveu o conflito e ele tenta se comprometer novamente.

[jerry@CentOS trunk]$ svn commit -m "Updated README" svn: Commit failed (details follow): svn: Aborting commit: '/home/jerry/project_repo/trunk/README' remains in conflict [jerry@CentOS trunk]$ svn status
?       README.r6
?       README.r7
?       README.mine
C       README

Etapa 3: resolver conflitos

No commit acima, a carta Cindica que há um conflito no arquivo LEIA-ME. Jerry resolveu o conflito, mas não disse ao Subversion que havia resolvido o conflito. Ele usa o comando resolve para informar o Subversion sobre a resolução do conflito.

[jerry@CentOS trunk]$ svn resolve --accept=working README Resolved conflicted state of 'README' [jerry@CentOS trunk]$ svn status
M       README

[jerry@CentOS trunk]$ svn commit -m "Updated README"
Sending        trunk/README
Transmitting file data .
Committed revision 8.

O Sistema de Controle de Versão suporta a operação de tag usando o conceito de que se pode dar um nome significativo a uma versão específica do código. Tag permite dar nomes descritivos e memoráveis ​​para uma versão específica do código. Por exemploBASIC_ARRAY_OPERATIONS é mais memorável do que revision 4.

Vejamos a operação da tag com um exemplo. Tom decide criar uma tag para que ele possa acessar o código mais facilmente.

[tom@CentOS project_repo]$ svn copy --revision=4 trunk/ tags/basic_array_operations

O comando acima produzirá o seguinte resultado.

A    tags/basic_array_operations/array.c
Updated to revision 4.
A         tags/basic_array_operations

Após a conclusão bem-sucedida, o novo diretório será criado dentro do diretório de tags .

[tom@CentOS project_repo]$ ls -l tags/
total 4
drwxrwxr-x. 3 tom tom 4096 Aug 24 18:18 basic_array_operations

Tom quer verificar antes de confirmar. A operação de status está mostrando que a operação de tag foi bem-sucedida, então ele pode confirmar suas alterações com segurança.

[tom@CentOS project_repo]$ svn status
A  +    tags/basic_array_operations

[tom@CentOS project_repo]$ svn commit -m "Created tag for basic array operations"
Adding         tags/basic_array_operations

Committed revision 5.

A operação de filial cria outra linha de desenvolvimento. É útil quando alguém deseja que o processo de desenvolvimento siga em duas direções diferentes. Suponhamos que você tenha lançado um produto da versão 1.0, talvez queira criar um novo branch para que o desenvolvimento da 2.0 possa ser mantido separado das correções de bugs 1.0.

Nesta seção, veremos como criar, percorrer e mesclar branch. Jerry não está feliz por causa do conflito, então ele decide criar uma nova agência privada.

[jerry@CentOS project_repo]$ ls
branches  tags  trunk

[jerry@CentOS project_repo]$ svn copy trunk branches/jerry_branch A branches/jerry_branch [jerry@CentOS project_repo]$ svn status
A  +    branches/jerry_branch

[jerry@CentOS project_repo]$ svn commit -m "Jerry's private branch" Adding branches/jerry_branch Adding branches/jerry_branch/README Committed revision 9. [jerry@CentOS project_repo]$

Agora Jerry está trabalhando em seu ramo privado. Ele adiciona uma operação de classificação para a matriz. O código modificado de Jerry se parece com isso.

[jerry@CentOS project_repo]$ cd branches/jerry_branch/ [jerry@CentOS jerry_branch]$ cat array.c

O comando acima produzirá o seguinte resultado.

#include <stdio.h>
#define MAX 16

void bubble_sort(int *arr, int n)
{
   int i, j, temp, flag = 1;
   for (i = 1; i < n && flag == 1; ++i) {
      flag = 0;
      for (j = 0; j < n - i; ++j) {
         if (arr[j] > arr[j + 1]) {
            flag = 1;
            temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
         }
      }
   }
}

void accept_input(int *arr, int n)
{
   int i;

   for (i = 0; i < n; ++i) 
   scanf("%d", &arr[i]);
}

void display(int *arr, int n)
{
   int i;

   for (i = 0; i < n; ++i)
   printf("|%d| ", arr[i]);

   printf("\n");
}

int main(void)
{
   int i, n, key, ret, arr[MAX];

   printf("Enter the total number of elements: ");
   scanf("%d", &n);

   /* Error handling for array overflow */
   if (n >MAX) {
      fprintf(stderr, "Number of elements must be less than %d\n", MAX);
      return 1;
   }

   printf("Enter the elements\n");
   accept_input(arr, n);

   printf("Array has following elements\n");
   display(arr, n);

   printf("Sorted data is\n");
   bubble_sort(arr, n);
   display(arr, n);

   return 0;
}

Jerry compila e testa seu código e está pronto para confirmar suas alterações.

[jerry@CentOS jerry_branch]$ make array cc array.c -o array [jerry@CentOS jerry_branch]$ ./array

O comando acima produzirá o seguinte resultado.

Enter the total number of elements: 5
Enter the elements
10
-4
2
7 
9
Array has following elements
|10| |-4| |2| |7| |9| 
Sorted data is
|-4| |2| |7| |9| |10| 

[jerry@CentOS jerry_branch]$ svn status ? array M array.c [jerry@CentOS jerry_branch]$ svn commit -m "Added sort operation"
Sending        jerry_branch/array.c
Transmitting file data .
Committed revision 10.

Enquanto isso, no porta-malas, Tom decide implementar a operação de busca. Tom adiciona código para operação de pesquisa e seu código se parece com isto.

[tom@CentOS trunk]$ svn diff

O comando acima produzirá o seguinte resultado.

Index: array.c
===================================================================
--- array.c   (revision 10)
+++ array.c   (working copy)
@@ -2,6 +2,27 @@
 
 #define MAX 16
 
+int bin_search(int *arr, int n, int key)
+{
+   int low, high, mid;
+
+   low   = 0;
+   high   = n - 1;
+   mid   = low + (high - low) / 2;
+
+   while (low <= high) {
+      if (arr[mid] == key)
+         return mid;
+      if (arr[mid] > key)
+         high = mid - 1;
+      else
+         low = mid + 1;
+      mid = low + (high - low) / 2;
+   }
+
+   return -1;
+}
+
 void accept_input(int *arr, int n)
 {
    int i;
@@ -22,7 +43,7 @@
 
 int main(void)
 {
-   int i, n, arr[MAX];
+   int i, n, ret, key, arr[MAX];
 
    printf("Enter the total number of elements: ");
    scanf("%d", &n);
@@ -39,5 +60,16 @@
    printf("Array has following elements\n");
    display(arr, n);
 
+   printf("Enter the element to be searched: ");
+   scanf("%d", &key);
+
+   ret = bin_search(arr, n, key);
+   if (ret < 0) {
+      fprintf(stderr, "%d element not present in array\n", key);
+      return 1;
+   }
+
+   printf("%d element found at location %d\n", key, ret + 1);
+
    return 0;
 }

Depois de revisar, ele confirma suas alterações.

[tom@CentOS trunk]$ svn status
?       array
M       array.c

[tom@CentOS trunk]$ svn commit -m "Added search operation"
Sending        trunk/array.c
Transmitting file data .
Committed revision 11.

Mas Tom está curioso para saber o que Jerry tem feito em seu ramo privado.

[tom@CentOS trunk]$ cd ../branches/
[tom@CentOS branches]$ svn up A jerry_branch A jerry_branch/array.c A jerry_branch/README [tom@CentOS branches]$ svn log
------------------------------------------------------------------------
r9 | jerry | 2013-08-27 21:56:51 +0530 (Tue, 27 Aug 2013) | 1 line

Added sort operation
------------------------------------------------------------------------

Ao ver a mensagem de log do Subversion, Tom descobriu que Jerry implementou a operação de 'classificação'. Tom implementou a operação de pesquisa usando o algoritmo de pesquisa binária, ele sempre espera os dados em ordem classificada. Mas e se o usuário fornecer dados em uma ordem não classificada? Nessa situação, a operação de pesquisa binária falhará. Então ele decide usar o código de Jerry para classificar os dados antes da operação de pesquisa. Portanto, ele pede ao Subversion para mesclar o código do branch de Jerry no tronco.

[tom@CentOS trunk]$ pwd /home/tom/project_repo/trunk [tom@CentOS trunk]$ svn merge ../branches/jerry_branch/
--- Merging r9 through r11 into '.':
U    array.c

Após a fusão, array.c ficará assim.

[tom@CentOS trunk]$ cat array.c

O comando acima produzirá o seguinte resultado.

#include <stdio.h>
#define MAX 16

void bubble_sort(int *arr, int n)
{
   int i, j, temp, flag = 1;

   for (i = 1; i < n && flag == 1; ++i) {
      flag = 0;
      for (j = 0; j < n - i; ++j) {
         if (arr[j] > arr[j + 1]) {
            flag      	= 1;
            temp      	= arr[j];
            arr[j]      = arr[j + 1];
            arr[j + 1]	= temp;
         }
      }
   }
}

int bin_search(int *arr, int n, int key)
{
   int low, high, mid;

   low   = 0;
   high  = n - 1;
   mid   = low + (high - low) / 2;

   while (low <= high) {
      if (arr[mid] == key)
         return mid;
      if (arr[mid] > key)
         high = mid - 1;
      else
         low = mid + 1;
      mid = low + (high - low) / 2;
   }
   return -1;
}

void accept_input(int *arr, int n)
{
   int i;

   for (i = 0; i < n; ++i)
      scanf("%d", &arr[i]);
}

void display(int *arr, int n)
{
   int i;
   for (i = 0; i < n; ++i)
      printf("|%d| ", arr[i]);
   printf("\n");
}

int main(void)
{
   int i, n, ret, key, arr[MAX];

   printf("Enter the total number of elements: ");
   scanf("%d", &n);

   /* Error handling for array overflow */
   if (n > MAX) {
      fprintf(stderr, "Number of elements must be less than %d\n", MAX);
      return 1;
   }

   printf("Enter the elements\n");
   accept_input(arr, n);

   printf("Array has following elements\n");
   display(arr, n);

   printf("Sorted data is\n");
   bubble_sort(arr, n);
   display(arr, n);

   printf("Enter the element to be searched: ");
   scanf("%d", &key);

   ret = bin_search(arr, n, key);
   if (ret < 0) {
      fprintf(stderr, "%d element not present in array\n", key);
      return 1;
   }

   printf("%d element found at location %d\n", key, ret + 1);

   return 0;
}

Após a compilação e teste, Tom submete suas alterações ao repositório.

[tom@CentOS trunk]$ make array
cc     array.c   -o array

[tom@CentOS trunk]$ ./array Enter the total number of elements: 5 Enter the elements 10 -2 8 15 3 Array has following elements |10| |-2| |8| |15| |3| Sorted data is |-2| |3| |8| |10| |15| Enter the element to be searched: -2 -2 element found at location 1 [tom@CentOS trunk]$ svn commit -m "Merge changes from Jerry's code"
Sending        trunk
Sending        trunk/array.c
Transmitting file data .
Committed revision 12.

[tom@CentOS trunk]$