História dos sistemas de controle de versão



Neste artigo, comparamos do ponto de vista técnico os sistemas de controle de versão mais famosos (no futuro, planejamos expandir a lista):

  1. Primeira geração
  2. Segunda geração
  3. Terceira geração

Os sistemas de controle de versão (VCS) de primeira geração rastrearam alterações em arquivos individuais, e a edição foi suportada apenas localmente e por um usuário por vez. Os sistemas foram construídos no pressuposto de que todos os usuários efetuariam login em suas contas no mesmo nó Unix comum.

O VCS de segunda geração introduziu suporte de rede, o que levou a repositórios centralizados com versões "oficiais" de projetos. Esse foi um progresso significativo, pois vários usuários puderam trabalhar com o código ao mesmo tempo, comprometendo-se com o mesmo repositório central. No entanto, confirma o acesso necessário à rede.

A terceira geração consiste em VCS distribuído, onde todas as cópias do repositório são consideradas iguais, não há repositório central. Isso abre caminho para confirmações, ramificações e mesclagens criadas localmente sem acesso à rede e movidas para outros repositórios, conforme necessário.

Linha do tempo da versão do VCS


Por contexto, aqui está um gráfico mostrando as datas em que essas ferramentas apareceram:



SCCS (Source Code Control System): primeira geração


O SCCS é considerado um dos primeiros sistemas de controle de versão bem-sucedidos. Foi desenvolvido em 1972 por Mark Rochkind, da Bell Labs. O sistema é escrito em C e projetado para rastrear versões de arquivos de origem. Além disso, facilitou bastante a busca de fontes de erros no programa. A arquitetura básica e a sintaxe do SCCS possibilitam entender as raízes das modernas ferramentas VCS.

Arquitetura


Como a maioria dos sistemas modernos, o SCCS possui um conjunto de comandos para trabalhar com versões de arquivos:

  1. Arquivos de check-in para rastreamento de histórico no SCCS.
  2. Faça o check-out de versões específicas de arquivos para revisão ou compilação.
  3. Extraia versões específicas para edição.
  4. Introdução de novas versões de arquivos junto com comentários explicando as alterações.
  5. Descarte as alterações feitas no arquivo extraído.
  6. Principais mudanças de ramificação e mesclagem.
  7. Log de alterações de arquivo.

Ao adicionar um arquivo de rastreamento ao SCCS, um tipo especial de arquivo é criado, chamado s- ou . É referido como o arquivo de origem, apenas com o prefixo s. e é armazenado no subdiretório SCCS . Portanto, para o arquivo test.txt , um arquivo de histórico test.txt será criado no diretório ./SCCS/ . No momento da criação, o arquivo de histórico contém o conteúdo inicial do arquivo de origem, além de alguns metadados que ajudam a rastrear versões. As somas de verificação são armazenadas aqui para garantir que o conteúdo não tenha sido modificado. O conteúdo do arquivo de histórico não é compactado ou codificado (como no VCS da próxima geração).

Como o conteúdo do arquivo de origem agora está armazenado no arquivo de histórico, ele pode ser extraído no diretório de trabalho para visualização, compilação ou edição. Você pode fazer alterações no arquivo de histórico, como adicionar linhas, alterar e excluir, o que aumenta o número da versão.

Adições de arquivo subsequentes armazenam apenas ou alterações, e não todo o seu conteúdo. Isso reduz o tamanho do arquivo de histórico. Cada delta é armazenado dentro de um arquivo de histórico em uma estrutura chamada - . Como mencionado anteriormente, o conteúdo real de um arquivo é mais ou menos copiado literalmente, com seqüências de escape especiais para marcar o início e o final das seções de conteúdo adicionado e excluído. Como os arquivos de histórico do SCCS não usam compactação, eles geralmente são maiores que o arquivo real no qual as alterações são rastreadas. O SCCS usa um método chamado , que garante um tempo de recuperação constante, independentemente da idade da versão recuperada, ou seja, as versões mais antigas são recuperadas na mesma velocidade das novas.

É importante observar que todos os arquivos são rastreados e gravados separadamente. Não é possível verificar alterações em vários arquivos como um único bloco atômico, como confirmações no Git. Cada arquivo rastreado possui seu próprio arquivo de histórico, no qual seu histórico de alterações é armazenado. No caso geral, isso significa que os números de versão de vários arquivos em um projeto geralmente não coincidem. No entanto, essas versões podem ser combinadas editando simultaneamente todos os arquivos do projeto (sem nem mesmo fazer alterações reais) e adicionando todos os arquivos ao mesmo tempo. Isso aumentará simultaneamente o número da versão de todos os arquivos, mantendo-os consistentes, mas observe que isso não é o mesmo que incluir vários arquivos em uma única confirmação, como no Git. No SCCS, um histórico individual é adicionado a cada arquivo, diferente de uma confirmação grande que inclui todas as alterações de uma só vez.

Quando um arquivo é extraído para edição no SCCS, um bloqueio é colocado nele, para que ninguém mais possa editá-lo. Isso evita a substituição de alterações por outros usuários, mas também limita o desenvolvimento, porque a qualquer momento, apenas um usuário pode trabalhar com esse arquivo.

O SCCS suporta ramificações que armazenam sequências de alterações em um arquivo específico. Você pode mesclar uma ramificação com a versão original ou com outra ramificação.

Equipas principais


A seguir, é apresentada uma lista dos comandos mais comuns do SCCS.

  • sccs create <filename.ext> : adicione um novo arquivo ao SCCS e crie um novo arquivo de histórico para ele (por padrão, no diretório ./SCCS/ ).
  • sccs get <filename.ext> : extrai o arquivo do arquivo de histórico correspondente e o coloca no diretório de trabalho no modo somente leitura.
  • sccs edit <filename.ext> : extrai o arquivo do arquivo de histórico correspondente para edição. Bloqueie o arquivo de histórico para que outros usuários não possam modificá-lo.
  • sccs delta <filename.ext> : adiciona alterações ao arquivo especificado. O sistema solicitará um comentário, salve as alterações no arquivo de histórico e libere o bloqueio.
  • sccs prt <filename.ext> : exibe o log de alterações para o arquivo monitorado.
  • sccs diffs <filename.ext> : mostra as diferenças entre a cópia de trabalho atual do arquivo e o estado do arquivo quando foi extraído.

Para obter mais informações sobre os componentes internos do SCCS, consulte o Guia de Eric Allman e o Guia de Utilitários de Programação da Oracle .

Exemplo de arquivo de histórico do SCCS


 ^Ah20562 ^As 00001/00001/00002 ^Ad D 1.3 19/11/26 14:37:08 jack 3 2 ^Ac Here is a comment. ^Ae ^As 00002/00000/00001 ^Ad D 1.2 19/11/26 14:36:00 jack 2 1 ^Ac No. ^Ae ^As 00001/00000/00000 ^Ad D 1.1 19/11/26 14:35:27 jack 1 0 ^Ac date and time created 19/11/26 14:35:27 by jack ^Ae ^Au ^AU ^Af e 0 ^At ^AT ^AI 1 Hi there ^AE 1 ^AI 2 ^AD 3 This is a test of SCCS ^AE 2 ^AE 3 ^AI 3 A test of SCCS ^AE 3 

RCS (Revision Control System): primeira geração


RCS foi escrito em 1982 por Walter Tihey em C como uma alternativa ao sistema SCCS, que na época não era de código aberto.

Arquitetura


O RCS tem muito em comum com seu antecessor, incluindo:

  • Controle de versão separadamente para cada arquivo.
  • Alterações em vários arquivos não podem ser agrupadas em uma única confirmação.
  • Os arquivos rastreados não podem ser editados por vários usuários ao mesmo tempo.
  • Sem suporte de rede.
  • As versões de cada arquivo rastreado são armazenadas no arquivo de histórico correspondente.
  • Ramificando e mesclando versões apenas para arquivos individuais.

Quando um arquivo é adicionado pela primeira vez ao RCS, um arquivo de histórico correspondente é criado para ele no armazenamento local no diretório local ./RCS/ . Uma extensão ,v , é incluída neste arquivo, ou seja, um arquivo chamado test.txt será rastreado por um arquivo chamado test.txt,v .

O RCS usa um esquema de delta reverso para armazenar alterações. Quando você adiciona um arquivo, um instantâneo completo de seu conteúdo é salvo no arquivo de histórico. Quando o arquivo é modificado e retornado novamente, um delta é calculado com base no conteúdo existente do arquivo de histórico. A imagem antiga é descartada e a nova é salva junto com o delta para retornar ao estado antigo. Isso é chamado de , porque, para recuperar uma versão mais antiga, o RCS pega a versão mais recente e aplica deltas sequencialmente até atingir a versão desejada. Este método permite recuperar as versões atuais muito rapidamente, uma vez que um instantâneo completo da revisão atual está sempre disponível. No entanto, quanto mais antiga a versão, mais demorada a verificação, porque você precisa verificar mais e mais deltas.

No SCCS, é diferente: leva o mesmo tempo para recuperar qualquer versão. Além disso, a soma de verificação não é armazenada nos arquivos de histórico do RCS, portanto, a integridade do arquivo não pode ser garantida.

Equipas principais


Abaixo está uma lista dos comandos RCS mais comuns:

  • <filename.ext> : adicione um novo arquivo ao RCS e crie um novo arquivo de histórico para ele (por padrão, no diretório ./RCS/ ).
  • co <filename.ext> : extrai o arquivo do arquivo de histórico correspondente e o coloca no diretório de trabalho no modo somente leitura.
  • co -l <filename.ext> : extrai o arquivo do arquivo de histórico correspondente para edição. Bloqueie o arquivo de histórico para que outros usuários não possam modificá-lo.
  • ci <filename.ext> : adicione alterações no arquivo e crie uma nova revisão no arquivo de histórico correspondente.
  • merge <file-to-merge-into.ext> <parent.ext> <file-to-merge-from.ext> : mescla alterações de dois filhos modificados do mesmo arquivo pai.
  • rcsdiff <filename.ext> : exibe as diferenças entre a cópia de trabalho atual do arquivo e o estado do arquivo quando foi extraído.
  • rcsclean : exclua arquivos de trabalho que não estão bloqueados.

Para obter mais informações sobre componentes internos do RCS, consulte o GNU RCS Manual .

Arquivo de histórico RCS de exemplo


 head 1.2; access; symbols; locks; strict; comment @# @; 1.2 date 2019.11.25.05.51.55; author jstopak; state Exp; branches; next 1.1; 1.1 date 2019.11.25.05.49.02; author jstopak; state Exp; branches; next ; desc @This is a test. @ 1.2 log @Edited the file. @ text @hi there, you are my bud. You are so cool! The end. @ 1.1 log @Initial revision @ text @d1 5 a5 1 hi there @ 

CVS (Concurrent Versions System): segunda geração


O CVS foi criado por Dick Grun em 1986 para adicionar suporte de rede ao controle de versão. Também está escrito em C e marca o nascimento da segunda geração de ferramentas VCS, graças às quais equipes de desenvolvimento geograficamente dispersas têm a oportunidade de trabalhar juntos em projetos.

Arquitetura


O CVS é ​​uma interface para RCS, possui um novo conjunto de comandos para interagir com arquivos em um projeto, mas sob o capô o mesmo formato de arquivo de histórico RCS e comandos RCS são usados. Pela primeira vez, o CVS permitiu que vários desenvolvedores trabalhassem com os mesmos arquivos simultaneamente. Isso é implementado usando um modelo de repositório centralizado. A primeira etapa é configurar um repositório centralizado usando o CVS no servidor remoto. Os projetos podem ser importados para o repositório. Quando um projeto é importado para o CVS, cada arquivo é convertido em um arquivo de histórico ,v e armazenado em um diretório directory: . O repositório geralmente está localizado em um servidor remoto, cujo acesso é feito por uma rede local ou pela Internet.

O desenvolvedor recebe uma cópia do módulo, que é copiada para o diretório de trabalho em seu computador local. Nesse processo, nenhum arquivo é bloqueado; portanto, não há limite para o número de desenvolvedores que podem trabalhar simultaneamente com o módulo. Os desenvolvedores podem modificar seus arquivos e confirmar as alterações conforme necessário (confirmação). Se um desenvolvedor confirmar uma alteração, outros desenvolvedores deverão atualizar suas cópias de trabalho usando o processo de mesclagem automatizado (geralmente) antes de confirmar suas alterações. Às vezes, você precisa resolver manualmente os conflitos de mesclagem antes de confirmar. O CVS também fornece a capacidade de criar e mesclar ramificações.

Equipas principais


  • export CVSROOT=<path/to/repository> : defina o diretório raiz do repositório CVS, para que você não precise especificá-lo em todos os comandos.
  • cvs import -m 'Import module' <module-name> <vendor-tag> <release-tag> : importa diretórios com arquivos no módulo CVS. Antes de iniciar esse processo, vá para o diretório raiz do projeto.
  • cvs checkout <module-name> : copia o módulo para o diretório de trabalho.
  • cvs commit <filename.ext> : confirma o arquivo modificado de volta ao módulo no repositório central.
  • cvs add <filename.txt> : adiciona um novo arquivo para rastrear as alterações.
  • cvs update : atualize a cópia de trabalho mesclando alterações confirmadas existentes no repositório central, mas não na cópia de trabalho.
  • cvs status : mostra informações gerais sobre a cópia de trabalho extraída do módulo.
  • cvs tag <tag-name> <files> : adicione uma tag a um arquivo ou conjunto de arquivos.
  • cvs tag -b <new-branch-name> : cria uma nova ramificação no repositório (você precisa extraí-la antes do trabalho local).
  • cvs checkout -r <branch-name> : extrai uma ramificação existente para o diretório de trabalho.
  • cvs update -j <branch-to-merge> : Mescla uma ramificação existente com uma cópia de trabalho local.

Para obter mais informações sobre os componentes internos do CVS, consulte o GNU CVS Handbook e o artigo de Dick Grohn .

Exemplo de arquivo de histórico do CVS


 head 1.1; branch 1.1.1; access ; symbols start:1.1.1.1 jack:1.1.1; locks ; strict; comment @# @; 1.1 date 2019.11.26.18.45.07; author jstopak; state Exp; branches 1.1.1.1; next ; commitid zsEBhVyPc4lonoMB; 1.1.1.1 date 2019.11.26.18.45.07; author jstopak; state Exp; branches ; next ; commitid zsEBhVyPc4lonoMB; desc @@ 1.1 log @Initial revision @ text @hi there @ 1.1.1.1 log @Imported sources @ text @@ 

SVN (Subversion): Segunda Geração


O Subversion foi criado em 2000 pela Collabnet Inc. e atualmente é suportado pela Apache Software Foundation. O sistema é escrito em C e projetado como uma solução centralizada mais confiável que o CVS.

Arquitetura


Como o CVS, o Subversion usa um modelo de repositório centralizado. Usuários remotos requerem uma conexão de rede para confirmar com o repositório central.

O Subversion introduziu a funcionalidade de confirmações atômicas com a garantia de que a confirmação seja completamente bem-sucedida ou completamente cancelada no caso de um problema. No CVS, no caso de um mau funcionamento no meio de uma confirmação (por exemplo, devido a uma falha na rede), o repositório pode permanecer em um estado danificado e inconsistente. Além disso, uma confirmação ou versão no Subversion pode incluir vários arquivos e diretórios. Isso é importante porque permite rastrear conjuntos de alterações relacionadas juntos como um bloco agrupado, e não separadamente para cada arquivo, como nos sistemas do passado.

O Subversion atualmente usa o sistema de arquivos FSFS (Sistema de Arquivos no topo do Sistema de Arquivos). Aqui, um banco de dados é criado com a estrutura de arquivos e diretórios que correspondem ao sistema de arquivos host. Uma característica exclusiva do FSFS é que ele foi projetado para rastrear não apenas arquivos e diretórios, mas também suas versões. Este é um sistema de arquivos sensível ao tempo. Diretórios também são objetos completos no Subversion. Você pode confirmar diretórios vazios no sistema, enquanto o restante (até o Git) não os nota.

Quando você cria um repositório do Subversion, um banco de dados (quase) vazio de arquivos e pastas é criado em sua composição. O diretório db/revs é criado, que armazena todas as informações de rastreamento de versão para os arquivos adicionados (confirmados). Cada confirmação (que pode incluir alterações em vários arquivos) é armazenada em um novo arquivo no diretório revs e recebe um nome com um identificador numérico seqüencial começando com 1. O primeiro commit salva o conteúdo completo do arquivo. As confirmações futuras do mesmo arquivo salvarão apenas as alterações, também chamadas de ou deltas, para economizar espaço. Além disso, os deltas são compactados usando os algoritmos de compressão lz4 ou zlib para reduzir o tamanho.

Esse sistema só funciona até um certo ponto. Embora os deltas economizem espaço, mas se houver muitos deles, é necessário muito tempo para a operação, pois todos os deltas devem ser processados ​​para recriar o estado atual do arquivo. Por esse motivo, por padrão, o Subversion salva até 1023 deltas por arquivo e, em seguida, faz uma nova cópia completa do arquivo. Isso fornece um bom equilíbrio de armazenamento e velocidade.

O SVN não usa o sistema usual de ramificação e marcação. O modelo normal de repositório do Subversion contém três pastas na raiz:

  • trunk/
  • branches/
  • tags/

O trunk/ diretório é usado para a versão de produção do projeto. As branches/ diretório - para armazenar subpastas correspondentes a ramificações individuais. O diretório tags/ é para armazenar tags que representam versões específicas (geralmente significativas) de um projeto.

Equipas principais


  • svn create <path-to-repository> : cria um novo shell de repositório vazio no diretório especificado.
  • svn import <path-to-project> <svn-url> : importa o diretório do arquivo no repositório especificado do Subversion.
  • svn checkout <svn-path> <path-to-checkout> : copia o repositório para o diretório de trabalho.
  • svn commit -m 'Commit message' : submete um conjunto de arquivos e pastas modificados junto com a mensagem.
  • svn add <filename.txt> : adiciona um novo arquivo para rastrear as alterações.
  • svn update : atualize a cópia de trabalho mesclando alterações confirmadas existentes no repositório central, mas não na cópia de trabalho.
  • svn status : exibe uma lista de arquivos monitorados que foram alterados no diretório ativo (se houver).
  • svn info : informações gerais sobre a cópia extraída.
  • svn copy <branch-to-copy> <new-branch-path-and-name> : cria uma nova ramificação copiando uma existente.
  • svn switch <existing-branch> : alterna o diretório ativo para um ramo existente. Isso permitirá que você tire arquivos de lá.
  • svn merge <existing-branch> : mescla a ramificação especificada com a atual copiada para o diretório de trabalho. Observe que você precisará confirmar posteriormente.
  • svn log : mostra o histórico de confirmações e as mensagens correspondentes para o ramo ativo.

Para mais informações sobre os componentes internos do SVN, consulte Versão do Subversion .

Arquivo de histórico de SVN de amostra


 DELTA SVN^B^@^@ ^B ^A<89> hi there ENDREP id: 2-1.0.r1/4 type: file count: 0 text: 1 3 21 9 12f6bb1941df66b8f138a446d4e8670c 279d9035886d4c0427549863c4c2101e4a63e041 0-0/_4 cpath: /trunk/hi.txt copyroot: 0 / DELTA SVN^B^@^@$^B%^A¤$K 6 hi.txt V 15 file 2-1.0.r1/4 END ENDREP id: 0-1.0.r1/6 type: dir count: 0 text: 1 5 48 36 d84cb1c29105ee7739f3e834178e6345 - - cpath: /trunk copyroot: 0 / DELTA SVN^B^@^@'^B#^A¢'K 5 trunk V 14 dir 0-1.0.r1/6 END ENDREP id: 0.0.r1/2 type: dir pred: 0.0.r0/2 count: 1 text: 1 7 46 34 1d30e888ec9e633100992b752c2ff4c2 - - cpath: / copyroot: 0 / _0.0.t0-0 add-dir false false false /trunk _2.0.t0-0 add-file true false false /trunk/hi.txt L2P-INDEX ^A<80>@^A^A^A^M^H^@ä^H÷^Aé^FDÎ^Bzè^AP2L-INDEX ^A<91>^E<80><80>@^A?^@'2^@<8d>»Ý<90>^C§^A^X^@õ ½½^N= ^@ü<8d>Ôã^Ft^V^@<92><9a><89>Ã^E; ^@<8a>åw|I^@<88><83>Î<93>^L`^M^@ù<92>À^Eïú?^[^@^@657 6aad60ec758d121d5181ea4b81a9f5f4 688 75f59082c8b5ab687ae87708432ca406I 

Git: terceira geração


O sistema Git foi desenvolvido em 2005 por Linus Torvalds (criador do Linux). Ele é escrito principalmente em C, em combinação com alguns scripts de linha de comando. Difere do VCS em funções, flexibilidade e velocidade. Torvalds originalmente escreveu o sistema para a base de código do Linux, mas com o tempo seu escopo se expandiu e hoje é o sistema de controle de versão mais popular do mundo.

Arquitetura


Git é um sistema distribuído. Não há repositório central: todas as cópias são criadas da mesma forma, o que é muito diferente do VCS de segunda geração, onde o trabalho se baseia na adição e extração de arquivos do repositório central. Isso significa que os desenvolvedores podem trocar alterações entre si imediatamente antes de mesclar suas alterações em uma ramificação oficial.

Além disso, os desenvolvedores podem fazer suas alterações na cópia local do repositório sem o conhecimento de outros repositórios. Isso permite confirmações sem estar conectado a uma rede ou à Internet. Os desenvolvedores podem trabalhar localmente offline, até estarem prontos para compartilhar seu trabalho com outras pessoas. Nesse ponto, as alterações são enviadas para outros repositórios para verificação, teste ou implantação.

Quando um arquivo é adicionado para rastreamento no Git, ele é compactado usando o algoritmo de compactação zlib . O resultado é hash usando a função hash SHA-1. Isso fornece um hash exclusivo que corresponde especificamente ao conteúdo deste arquivo. O Git o armazena no , localizado em uma pasta oculta .git/objects . O nome do arquivo é o hash gerado e o arquivo contém conteúdo compactado. Esses arquivos são chamados de e são criados sempre que um novo arquivo (ou uma versão modificada de um arquivo existente) é adicionado ao repositório.

O Git implementa um índice intermediário, que atua como uma área intermediária para as mudanças que estão sendo preparadas para confirmação. À medida que novas alterações são preparadas, seu conteúdo compactado é referenciado em um arquivo de índice especial, que assume a forma de um objeto de .Uma árvore é um objeto Git que associa os blobs aos seus nomes de arquivos reais, permissões de arquivos e links para outras árvores e, portanto, representa o estado de um conjunto específico de arquivos e diretórios. Quando todas as alterações relevantes são preparadas para confirmação, a árvore de índice pode ser confirmada no repositório que cria o objeto no banco de dados de objetos Git. A confirmação refere-se à árvore de cabeçalho de uma versão específica, bem como ao autor da confirmação, endereço de email, data e mensagem da confirmação. Cada confirmação também armazena um link para suas confirmações pai e, com o tempo, é criado um histórico do desenvolvimento do projeto.

Como já mencionado, todos os objetos Git - blobs, árvores e confirmações - são compactados, hash e armazenados no banco de dados de objetos com base em seus hashes. Eles são chamados (objetos soltos). Aqui não são usadas diferenças para economizar espaço, o que torna o Git muito rápido, pois o conteúdo completo de cada versão do arquivo está disponível como um objeto livre. No entanto, algumas operações, como enviar confirmações para um repositório remoto, armazenar um número muito grande de objetos ou executar manualmente o comando de coleta de lixo Git, fazem com que os objetos sejam reembalados . No processo de embalagem, são calculadas diferenças inversas, que são compactadas para eliminar a redundância e reduzir o tamanho. Como resultado, arquivos .packcom o conteúdo do objeto são criados e, para cada um deles, um arquivo .idx(ou índice) é criado com um link para os objetos compactados e sua localização no arquivo em lotes.

Quando as ramificações são movidas ou recuperadas de repositórios remotos, esses arquivos em lote são transferidos pela rede. Ao esticar ou extrair ramificações, os arquivos do pacote são descompactados para criar objetos livres no repositório de objetos.

Equipas principais


  • git init: inicializa o diretório atual como um repositório Git (uma pasta oculta .gite seu conteúdo são criados).
  • git clone <git-url> : Faça o download de uma cópia do repositório Git no URL especificado.
  • git add <filename.ext> : adicione um arquivo não rastreado ou modificado à área de preparação (cria os registros correspondentes no banco de dados de objetos).
  • git commit -m 'Commit message' : confirme um conjunto de arquivos e pastas modificados junto com uma mensagem de confirmação.
  • git status : mostra o status do diretório de trabalho, ramificação atual, arquivos não rastreados, arquivos modificados etc.
  • git branch <new-branch> : crie uma nova ramificação com base na ramificação extraída atual.
  • git checkout <branch> : extrai a ramificação especificada para o diretório de trabalho.
  • git merge <branch> : mescla a ramificação especificada com a atual, extraída no diretório de trabalho.
  • git pull : Atualize a cópia de trabalho combinando as alterações confirmadas que existem no repositório remoto, mas não na cópia de trabalho.
  • git push : empacote objetos livres para confirmações locais da ramificação ativa em arquivos de pacote e transfira para um repositório remoto.
  • git log : mostra o histórico de confirmações e as mensagens correspondentes para a ramificação ativa.
  • git stash : salve todas as alterações não confirmadas do diretório ativo no cache para recuperação posterior.

Se você quiser saber como o código Git funciona, consulte o Guia para iniciantes do Git . Para obter mais informações sobre componentes internos, consulte o capítulo correspondente no livro Pro Git .

Exemplo de blob, tree e commit git


Blob com um hash 37d4e6c5c48ba0d245164c4e10d5f41140cab980:

 hi there 

Objeto de árvore com um hash b769f35b07fbe0076dcfc36fd80c121d747ccc04:

 100644 blob 37d4e6c5c48ba0d245164c4e10d5f41140cab980hi.txt 

Confirmação de hash dc512627287a61f6111705151f4e53f204fbda9b:

 tree b769f35b07fbe0076dcfc36fd80c121d747ccc04 author Jacob Stopak 1574915303 -0800 committer Jacob Stopak 1574915303 -0800 Initial commit 

Mercurial: terceira geração


Mercurial foi criado em 2005 por Matt McCall e escrito em Python. Ele também foi projetado para hospedar a base de código do Linux, mas o Git foi finalmente escolhido para esta tarefa. Este é o segundo sistema de controle de versão mais popular, embora seja usado com muito menos frequência.

Arquitetura


O Mercurial também é um sistema distribuído que permite que qualquer número de desenvolvedores trabalhe com sua cópia do projeto independentemente de outros. O Mercurial usa muitas das mesmas tecnologias que o Git, incluindo compactação e hash SHA-1, mas de maneira diferente.

Quando um novo arquivo é confirmado para rastreamento no Mercurial, um arquivo correspondente é criado para ele revlogem um diretório oculto .hg/store/data/. Você pode considerar o arquivo revlog(log de alterações) como uma versão atualizada em VCS mais antigos, como CVS, RCS e SCCS. Ao contrário do Git, que cria um novo blob para cada versão de cada arquivo preparado, o Mercurial simplesmente cria uma nova entrada de revlog para esse arquivo. Para economizar espaço, cada novo registro contém apenas o delta da versão anterior. Quando o número limite de deltas é atingido, o instantâneo completo do arquivo é salvo novamente. Isso reduz o tempo de pesquisa ao processar um grande número de deltas para restaurar uma versão específica de um arquivo.

Cada revlog é nomeado de acordo com o arquivo que está rastreando, mas com a extensão .iou .d. Os arquivos .dcontêm um delta compactado. Os arquivos .isão usados ​​como índices para rastrear rapidamente diferentes versões nos arquivos.d. Para arquivos pequenos com poucas alterações, índices e conteúdo são armazenados em arquivos .i. As entradas de revlog são compactadas para desempenho e hash para identificação. Esses valores de hash são nomeados nodeid.

Em cada confirmação, o Mercurial mantém o controle de todas as versões dos arquivos nesse commit no que é chamado de . O manifesto também é um arquivo de revlog - ele armazena entradas correspondentes a determinados estados do repositório. Em vez de ter conteúdo de arquivo separado, como revlog, o manifesto armazena uma lista de nomes de arquivos e nós de nó que determinam quais versões do arquivo existem na versão do projeto. Essas entradas de manifesto também são compactadas e com hash. Os valores de hash também são chamados nodeid.

Finalmente, o Mercurial usa outro tipo de revlog chamado changelog, ou seja, um log de alterações. Esta é uma lista de entradas que associam cada confirmação às seguintes informações:

  • ID do nó do manifesto: um conjunto completo de versões de arquivos que existem em um momento específico.
  • um ou dois nós para o pai confirma: isso permite que o Mercurial construa uma linha do tempo ou ramo do histórico do projeto. Um ou dois IDs pai são armazenados, dependendo do tipo de confirmação (regular ou mesclagem).
  • Confirmar Autor
  • Data de confirmação
  • Confirmar mensagem

Cada entrada no registro de alterações também gera um hash conhecido como seu nodeid.

Equipas principais


  • hg init: inicializa o diretório atual como um repositório do Mercurial (cria uma pasta oculta .hge seu conteúdo).
  • hg clone <hg-url> : Faça o download de uma cópia do repositório Mercurial no URL especificado.
  • hg add <filename.ext> : Adicione um novo arquivo para acompanhar as alterações.
  • hg commit -m 'Commit message' : confirme o conjunto de arquivos e pastas alterados junto com a mensagem de confirmação.
  • hg status : exibe informações relacionadas ao status do diretório ativo, arquivos não rastreados, arquivos modificados etc.
  • hg update <revision> : extrai a ramificação especificada para o diretório de trabalho.
  • hg merge <branch> : mescla a ramificação especificada com a atual extraída para o diretório de trabalho.
  • hg pull : Baixe novas versões de um repositório remoto, mas não as mescle em um diretório ativo.
  • hg push : Transfira novas versões para o repositório remoto.
  • hg log : Mostra o histórico de confirmações e mensagens relacionadas para a ramificação ativa.

Arquivos mercuriais de exemplo


Manifesto:

 hey.txt208b6e0998e8099b16ad0e43f036ec745d58ec04 hi.txt74568dc1a5b9047c8041edd99dd6f566e78d3a42 

Registro de alterações (changelog):

 b8ee947ce6f25b84c22fbefecab99ea918fc0969 Jacob Stopak 1575082451 28800 hey.txt Add hey.txt 

Informações adicionais sobre o dispositivo Mercurial:

Source: https://habr.com/ru/post/pt478752/


All Articles