Source

trabalho_dvcs / mercurial.tex

% falar o que é o Mercurial
% como ele funciona

\section{Mercurial DCVS}

O Mercurial é um projeto de software livre que surgiu em abril de 2005. Surgiu originalmente para Linux, tendo sido portado para Windows, Mac OS X e outros sistemas Unix-like. Seu código foi escrito praticamente todo em Python a exceção da implementação do diff, feita em C. Seus maiores objetivos incluem a alta performace e escalabilidade, descentralidade, ser totalmente distribuído de maneira colaborativa, ter um suporte robusto tanto para arquivos de texto quanto binários e capacidades avançadas de branching e merging, mantendo-se conceitualmente simples.

O Mercurial funciona basicamente via linha de comando. Seus comandos sempre começam com “hg”, uma referência ao elemento químico Mercúrio, cujo símbolo é o Hg. Seus comandos básicos são:
\begin{description}
\item[hg add nomedoarquivo] adiciona o arquivo ao repositório
\item[hg commit] consolida as modificações feitas no repositório
\item[hg diff] sinaliza as modificações que já foram feitas no arquivo que está no repoisitório local
\item[hg merge] faz o merge automático dos branches
\item[hg push] coloca os arquivos do repositório local no repositório global
\item[hg pull] busca os arquivos no repositório global e os coloca no repositório local
\item[hg status] mostra as modificações existentes entre os arquivos do repositório local e os do repositório global
\item[hg update] busca as modificações existentes nos arquivos do repositório global e os colocam no repositório local
\end{description}

Uma parte interessante do Mercurial, conforme consta em \cite{HgBook}, é a forma como ele gerencia as mudanças que acontecem nos arquivos. Quando ele percebe que ocorreu alguma mudança em um arquivo, ele guarda o histórico deste em um objeto de metadados chamado \emph{filelog}. Cada entrada no filelog contém informações suficientes para reconstruir uma revisão do arquivo. Quando esse histórico é grande, esse filelog é divido em duas partes, uma de dados e uma de índice.

O Mercurial também utiliza uma estrutura chamada \emph{manifesto} onde ele coleta as informações sobre os arquivos que estão sendo monitorados. Cada entrada no manifesto contém informações sobre os arquivos presentes em cada \emph{changeset}, bem como a revisão de cada arquivo e algumas partes dos arquivos de metadados. Já os \emph{changelogs} contém informações sobre cada changeset. cada revisão do changelog possui quem fez o commit, o comentário do changeset, outras informações relacionadas ao changeset e a revisão do manifesto em uso.

Outro item realçado no livro é sobre os relacionamentos entre as revisões. Cada revisão guarda consigo ponteiros para o nodo pai (ou pais, caso seja proveniente de um merge). Existem também relacionamentos entre revisões através dessas estruturas e são hierárquicas por natureza. Para cada changeset do repositório, existe um exatamente uma revisão guardada no changelog. Cada revisão do changelog possui um ponteiro para uma única revisão do manifesto. Uma revisão do manifesto tem um ponteiro para uma única revisão de cada filelog monitorado quando aquela changeset foi criado\ref{mercurial:metadata}. 
%A figura abaixo ilustra essa relação:
\begin{figure}[h!]
    \centering
    \includegraphics[scale=0.5]{metadata}
    \caption{Relacionamento entre metadados}
    \label{mercurial:metadata}
\end{figure}

Como pode-se perceber, caso algum arquivo não seja modificado entre dois changesets, as entradas para esse arquivo nas duas revisões do manifesto apontarão para a mesma revisão do filelog do arquivo.

Todos esses metadados citados ficam sobre uma única estrutura chamada \emph{revlog}. O revlog provê um armazenamento eficiente das revisões usando um mecanismo baseado em \emph{deltas}. Quando as mudanças ocorridas são pequenas, um novo delta é criado, visto que eles ocupam normalmente uma pequena fração do tamanho de uma cópia completa de um arquivo. Quando as modificações ocorridas superam um limiar preestabelecido, um \emph{snapshot} é criado ao invés de um novo delta, visto que ele é capaz de guardar uma maior quantidade de informações. Além disso, toda operação realizada em um revlog é atômica e os dados sempre são adicionados no final, não modificando as seções já existentes\ref{mercurial:snapshot}.
%A figura abaixo ilustra como fica um revlog com deltas e snapshots:
\begin{figure}[h!]
    \centering
    \includegraphics[scale=0.5]{snapshot}
    \caption{Snapshot de um revlog com deltas incrementais}
    \label{mercurial:snapshot}
\end{figure}

Essa forma implementada evita um problema comum aos RCSs anteriores: a busca ineficiente. Como ele mantém snapshots e deltas, isso permite que qualquer revisão de um arquivo possa ser reconstruída rapidamente, bastando buscar o snapshot e um pequeno número de deltas posteriores. Essa idéia é baseada na compressão de vídeo MPEG, onde é gerado um \emph{frame} principal e determinado número de deltas que são apenas pequenas modificações sobre aquele frame.

Um fator que pode ser determinante para seu sucesso é a facilidade de uso. Usando-se apenas os comandos add, commit, push, pull e upgrade é possível fazer com que toda uma equipe compartilhe seus documentos. No universo Windows isso pode ser ainda mais simples: usando a ferramenta \emph{TortoiseHG}\cite{THg}, basta clicar na pasta compartilhada e, no menu de contexto, escolher o que fazer. Uma janela é aberta e as operações são apresentadas. A figura abaixo mostra como isso pode ser visto no Windows.
\begin{figure}
    \centering
    \includegraphics[scale=0.4]{tortoisehg}
    \caption{Tela principal do TortoiseHg e janela de revisões}
    \label{mercurial:tortoisehg}
\end{figure}