*********************
Mercurial (hg)
*********************

Introduções
======================

O Mercurial (hg) é um sistema de controle de versões, assim como CVS, Subversion 
e Git. 

Assim como o Git, e diferentemente de CVS e Subversion, o Mercurial é baseado 
em uma estrutura de repositórios distribuídos, ou seja, não existe a dependência 
de que o repositório central esteja acessível para que transações de 
versionamento ocorram.

Para alcançar esta descentralização o Mercurial implementa repositórios locais 
que contém todo o histórico dos dados que ele versiona. Para quem está 
acostumado com o modus-operandi do Subversion, seria como se cada checkout se 
tornasse um repositório local contendo histórico de todas as transações 
anteriores e permitindo ao usuário a realização de commits, reverts, etc, 
localmente, sendo que este novo histórico de transações pode ser integrado ao 
repositório original a qualquer momento.

O objetivo deste texto é apresentar rapidamente o Mercurial e apontar para 
recursos nas interwebs onde seja possível se aprofundar no assunto.

É importante reforçar que, na Simples Consultoria, o Mercurial é o padrão para
controle de versões dos projetos a partir de abril de 2011. Projetos antigos em 
Subversion (https://simplesnet.com.br/svn/) serão gradualmente migrados para o 
Bitbucket (https://bitbucket.org).

.. warning::
    Projetos/Pacotes hospedados em repositórios do Plone ou do Zope, continuam  
    sendo mantidos com Subversion. Alguns projetos de clientes ainda usarão Git.


Instalando
======================

Caminho fácil
--------------

O jeito fácil e rápido de começar a trabalhar com o Mercurial é através do uso 
de uma ferramenta com interface gráfica. A mais famosa delas é o TortoiseHg.

Para sua instalação acesse http://tortoisehg.bitbucket.org/, baixe a versão 
para o seu sistema operacional e a instale.

Caso queira instalar apenas a linha de comando, use o gerenciador de pacotes 
do seu sistema operacional e/ou baixe o instalador diretamente do site do 
`Mercurial <http://mercurial.selenic.com/downloads/>`_

Configurações Básicas
=======================

Após a instalação é recomendável passar pelo processo de configuração do 
seu ambiente Mercurial.

Geralmente as configurações são armazenadas em um arquivo **.hgrc** na raiz 
de sua pasta de usuário (**Mercurial.ini** em ambientes Windows)

.. warning::
    Em sistemas operacionais como Linux e MacOS, este arquivo -- por ter seu 
    nome iniciando com um **.** -- é oculto por padrão.

Edite este arquivo com seu editor de preferência colocando, ao menos, as 
informações referentes a seu username e editor de texto de preferência::

    [ui]
    username = Douglas Adams <dontpanic@simplesconsultoria.com.br>
    editor = vim
    
Como exemplos de valores para a configuração de **editor**

    * Windows: **Notepad** ou **'C:/Program Files/Notepad++/notepad++.exe' 
      -multiInst -notabbar -nosession -noPlugin**

    * MacOS: **mate -w**

    * Linux: **gvim --nofork** ou **vim**

Melhorando a vida no Bitbucket
--------------------------------

Para evitar o trabalho de toda vez ter que informar usuário e senha de acesso 
ao Bitbucket, é recomendável realizar as seguintes configurações no seu 
arquivo de configuração do Mercurial::

    [auth]
    bitbucket.prefix = https://bitbucket.org
    bitbucket.username = meu_username

A configuração acima informa que para o prefixo https://bitbucket.org o 
Mercurial sempre utilizará o username definido em **bitbucket.username**

Outra ferramenta interessante é o uso da extensão que realiza a integração com 
o sistema de gerenciamento de senhas do sistema operacional. Esta extensão, 
**mercurial_keyring** vem com a instalação padrão do Mercurial e pode ser 
ativada com a sua adição à seção [extensions] do arquivo de configuração::

    [extensions]
    mercurial_keyring = 

Outras melhorias
-----------------

Extensões possibilitam a adição de novas funcionalidades ao Mercurial. Elas 
estão todas listadas em http://mercurial.selenic.com/wiki/UsingExtensions e 
das disponíveis na instalação padrão, duas se destacam::

    [extensions]
    color =
    convert = 

A Color extension habilita o uso de cores nas respostas de diffs e outros 
comandos do Mercurial.

Convert é a extensão usada para, como o nome indica, converter repositórios de 
outros formatos de controle de versão para o formato do Mercurial. Dado o 
histórico dos usos feitos na Simples Consultoria de Subversion e Git, é sábio 
deixar esta extensão configurada.

Mercurial 101
===================

.. note::
    Em vários momentos faremos alusões ao uso do Subversion, que podem ser 
    diligentemente ignoradas se você não tiver trabalhado com este sistema 
    durante os últimos anos.

Vamos apresentar o uso do Mercurial com base em dois cenários de partida. 

O primeiro é similar ao modelo Subversion, com um repositório central que será 
a base e referência para o trabalho. 

O cenário alternativo parte de um diretório local, que será convertido em 
repositório e que posteriormente pode ser colocado em um repositório central.

Antes de apresentarmos os cenários, vamos listar alguns dos comandos usuais.

Lista de comandos
-------------------

============ ===================================================================
Comando       Descrição
============ ===================================================================
init          Cria e inicializa repositório local
add           Adiona arquivos/diretórios a um repositório
clone         Clona localmente um repositório remoto
commit        Efetiva e documenta alterações
diff          Exibe diferenças no repositório ou em arquivos listados
log           Exibe histórico
status        Exibe alterações dos conteúdos no repositório local
revert        Reverte alterações para a rev anterior do diretório local
rollback      Desfaz sua última ação (pull, commit, import)
pull          Sincroniza com outro repositório
update        Atualiza a revisão local para a revisão do repositório principal
push          Publica modificações locais para outro repositório
merge         Realiza o merge com uma revisão específica
============ ===================================================================

Cenário: Repositório Central
------------------------------

Como no modelo centralizado do Subversion, vamos "baixar", inicialmente, os 
dados a partir de um repositório.

Para tanto, o comando a ser utilizado será::
    
    hg clone https://bitbucket.org/simplesconsultoria/products.zpyodbcda

Isto criará um **repositório local** chamado products.zpyodbcda na pasta atual. 
Assim como no Subversion é possível dar um nome arbitrário a cópia local dos 
dados::

    hg clone https://bitbucket.org/simplesconsultoria/products.zpyodbcda Products.ZPyODBCDA
    
Criará o repositório local com o nome de Products.ZPyODBCDA na pasta atual.

A diferença aqui é que não temos apenas uma **cópia de trabalho** do repositório
central e sim um **repositório local**, que contém todo o histórico do 
repositório central -- até o momento de sua clonagem -- e que suporta a 
realização de novas transações e a criação de seu histórico.

Por exemplo, após alterar o código do arquivo setup.py dentro de  
Products.ZPyODBCDA, é possível realizar um commit, da mesma maneira que 
seria feito no Subversion::

    hg commit setup.py

Gerando assim um novo REV, que é o número de revisão, e mantendo o histórico 
das versões anteriores -- possibilitando a volta a qualquer ponto arbitrário 
da história deste arquivo.

A diferença em relação ao Subversion é que esta revisão está apenas no nosso 
repositório local, não afetando assim o histórico do repositório central.

Este modelo distribuido permite, entre outras coisas, commits menores e mais 
constantes, possibilitando pequenas alterações caso necessário.

Para que as alterações de nosso repositório local sejam replicadas no 
repositório central, realizamos o push de nosso histórico::

    hg push
    
.. note::
    
    É possível manter diferentes repositórios sincronizados. Para tanto apenas 
    informe o endereço do repositório que estas alterações seram enviadas. Ex:
    hg push https://meuoutrorepos/

É importante que também nos mantenhamos atualizados com as alterações já 
enviadas por outros para o repositório central. Para tanto utilizamos o comando 
pull::

    hg pull
    
Que sincroniza, mas não aplica, as últimas alterações realizadas no repositório 
central.

Para colocar nossa revisão atual em sincronia com a do repositório central 
utilizamos  o comando update::

    hg update

E para realizar o merge entre as alterações do repositório central e as suas, 
utilizamos o comando merge::
    
    hg merge

Para resumir, o ciclo é::

     hg clone https://bitbucket.org/simplesconsultoria/products.zpyodbcda Products.ZPyODBCDA
     <modificações>
     hg commit
     <modificações>
     hg commit
     <envio para repositório central>
     hg push
     <sincronização>
     hg pull
     <coloca como última revisão>
     hg up
     <realiza merge>
     hg merge

Cenário: Repositório Local
------------------------------

Considere uma pasta local, que você deseja colocar sob controle de versão. Como 
exemplo vamos utilizar uma pasta, de produto recém criado pelo paster, chamada 
sc.base.example.

Manteremos esta pasta sob versionamento local até o momento em que seja 
desejável termos contribuição externa, quando enviaremos nosso histórico para 
um repositório central.

O primeiro passo é, dentro da pasta que desejamos versionar, crie um novo 
repositório digitando::

    hg init

A partir deste momento a pasta sc.base.example é um repositório Mercurial. 

Para cada arquivo ou diretório abaixo desta pasta, que você deseje manter sob 
controle de versão, é necessário realizar o comando **add** para adicioná-lo ao 
repositório. Este comando aceita coringas (wildcards) para facilitar seu uso. 
Veja alguns exemplos de uso::

    hg add MANIFEST.in
    hg.add setup.*
    hg add sc/

É possível realizar modificações, commitar e reverter alterações, como em um 
repositório -- ou mesmo sistema de versionamento -- qualquer::

    <modificações>
    hg commit
    <modificações>
    hg commit
    hg rollback

Quando você estiver pronto para colocar seu histórico em um repositório central, 
crie este novo repositório -- por exemplo, através da interface administrativa 
do BitBucket -- e faça o push do seu histórico para lá::

    hg push https://bitbucket.org/simplesconsultoria/sc.base.example

A partir realize as transações de pull, update, merge e commit normalmente.

.. warning::
    Seguindo estes passos, ao realizar um **hg push** sem especificar o caminho 
    o Mercurial reclamará informando que você não tem um repositório padrão para 
    push definido. Para resolver isto, edite o arquivo **hgrc** (ou o crie) 
    dentro da pasta **.hg** na raiz do repositório local e adicione a seção 
    [paths] e abaixo dela o atalho **default-push = <caminho-para-repositorio>**
    .

