aragost Trifork: Mercurial Kick Start Exercises


Repositórios Remotos

Este guia mostrará como o Mercurial pode ser usado para conversar com repositórios remotos usando HTTP e SSH.

Contents

In the Basic Mercurial guide, you saw how Alice and Bob could push and pull between each other on the same filesystem. This is a fine setup when Alice and Bob share a filesystem between them, but most users don’t have direct access to each other’s files like that. This is why Mercurial can access remote repositories over a network connection.

O Mercurial fala dois protocolos de rede:

Trabalhando com Repositórios sobre HTTP

Começaremos olhando como você pode interagir com repositórios sobre HTTP. Este protocolo é muito popular já que se integra bem com a maioria das infraestruturas das empresas: quando você tem um servidor web funcional que pode ser acessado pela porta 80, então você tem tudo o que precisa para servir os repositórios do Mercurial também.

Clonagem sobre HTTP

Alice clona um repositório que contém um pequeno exemplo:

alice$ hg clone https://bitbucket.org/aragost/hello
destination directory: hello
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

Como você pode ver, não é realmente diferente de clonar um repositório a partir de um caminho no sistema de arquivos: em ambos os casos, Alice acaba com uma cópia completa do repositório e o ramo default é escolhido.

Internamente, o Mercurial é capaz de fazer uma clonagem local muito mais eficiente que uma clonagem pelo HTTP. Isto não é apenas pelo fato de que ler dados pela rede é mais lento que ler de um disco, mas também porque um clone local pode reusar o espaço do diretório .hg através de hardlinks entre os arquivos. Os dois clones compartilharão o espaço de disco usado pelos dois diretórios .hg e apenas as cópias de trabalho que tomam novo espaço em disco. Isto é o que torna possível criar tantas cópias locais descartáveis quanto se queira.

Alice pode fazer suas consolidações no seu clone:

alice$ cd hello
alice$ echo "Hello, World!" > hello.txt
alice$ hg commit -m "Add comma" 

This is the essence of distributed revision control — Alice can get her own independent copy of the repository and work on it locally. She can compare her clone with the remote server:

alice$ hg outgoing
comparing with https://bitbucket.org/aragost/hello
searching for changes
changeset:   1:61c1daa1d929
tag:         tip
user:        Alice <alice@example.net>
date:        Sat Jan 22 10:00:00 2011 +0000
summary:     Add comma

Ela não pode empurrar seu changeset para o servidor pois não tem permissão de escrita para este repositório.

Servindo um Repositório pelo HTTP

Como mencionado antes, o Mercurial tem um servidor web embutido. Você pode usá-lo para um compartilhamento rápido de um repositório com outra máquina pela LAN, ou mesmo para navegar pelo histórico você mesmo.

Alice disponibiliza seu clone do repositório hello:

alice$ hg serve 
listening at http://localhost:8000/ (bound to 127.0.0.1:8000)

O repositório pode ser navegado com um browser normal a partir do endereço http://localhost:8000/. Lá, pode-se ver o histórico do projeto e o grafo de changesets. Pode-se examinar changesets individuais, ver a lista de rótulos e ramos, anotações dos arquivos e pode-se recuperar qualquer revisão na forma de um arquivo tar ou zip. Em outras palavras, o servidor web embutido é bastante conveniente para humanos, tanto quanto para computadores :-)

Bob pode fazer um clone do repositório de Alice:

bob$ hg clone http://localhost:$HGPORT hello
requesting all changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
bob$ cd hello
bob$ cat hello.txt
Hello, World!

Se Bob fizer uma mudança e tentar empurrar de volta, ele encontra o seguinte erro:

bob$ hg push
pushing to http://localhost:8000/
searching for changes
remote: ssl required
remote: ssl required
updating 61c1daa1d929 to public failed!

O que acontece é que o webserver do Mercurial não deixa você empurrar sobre HTTP por padrão. Ele precisa que você use uma URL em HTTPS. Alice pode desabilitar esta exigência através da opção --config web.push_ssl=No pela linha de comando quando ela inicia o servidor embutido. Ela primeiro interrompe o processo do hg serve antigo e então começa um novo:

alice$ hg serve --config web.push_ssl=No 
listening at http://localhost:8000/ (bound to 127.0.0.1:8000)

Quanto Bob tenta novamente, ele encontra um novo erro devido aos repositórios serem apenas para leitura por padrão:

bob$ hg push
pushing to http://localhost:8000/
searching for changes
abort: authorization failed

Note que a operação de push foi abortada sem dar a Bob a chance de fornecer o nome do usuário ou a senha. A razão disso é que o servidor web embutido não suporta autenticação. Isto é, não possui gerenciamento de usuários. Isto pode parecer estranho, mas a ideia é que você não executará hg serve em um ambiente de produção. Ao invés disso, você executaria o script hgweb.cgi fornecido com o Mercurial em um servidor web de verdade como o Apache. Este servidor web teria a infraestrutura necessária para fazer apropriadamente a autenticação de usuário. Uma vantagem dessa configuração é que você pode fazer a autenticação usando o método que preferir: se já tiver uma autenticação baseada em LDAP, então é possível reusar essa autenticação para o Mercurial também.

Para o nosso exemplo, vamos deixar Alice desabilitar a verificação de autenticação com uma outra opção de linha de comando:

alice$ hg serve --config web.push_ssl=No --config "web.allow_push=*" 
listening at http://localhost:8000/ (bound to 127.0.0.1:8000)

Bob agora consegue empurrar seu changeset para Alice:

bob$ hg push
pushing to http://localhost:8000/
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files

Aqui não há autenticação alguma, mas para a maior parte dos repositórios reais você terá de autenticar para empurrar seus changesets (e algumas vezes também para puxá-los). Vamos discutir o armazenamento de credenciais HTTP(S) abaixo.

Permissões no Sistema de Arquivos

Quando você acessa um repositório através do script hgweb.cgi, então o acesso é feito realmente pelo servidor web. O processo do servidor web executa como um certo usuário no servidor e este usuário deve ter acesso de leitura aos arquivos do repositório para que possa servi-los.

Quando as pessoas empurram changesets de volta pelo HTTP, também é o processo do servidor web que escreve os arquivos no diretório .hg. Os nomes de usuários embutidos nos changesets não tem nenhum significado aqui.

Trabalhando com Repositórios pelo SSH

O outro protocolo de rede suportado pelo Mercurial é o SSH. Quando se usa URLs de SSH, o Mercurial se registra no servidor e estabelece um túnel SSH entre dois processos do Mercurial. Estes processos podem então comunicar um com o outro para empurrar ou puxar changesets.

Isto implica a necessidade de haver uma conta SSH no servidor. Muitos administradores de sistemas preferem, portanto, uma configuração baseada em HTTP ao invés porque ela já se adequa à configuração existente do servidor web.

Contudo, se você tiver uma conta no servidor e se o Mercurial está instalado no sistema, então o protocolo SSH é muito suave para o usuário. A única coisa que precisa ser lembrada é que a sintaxe é a de uma URL e não um caminho SSH como usado em scp ou rsync. Então, deve-se escrever:

$ hg clone ssh://server/caminho/para/repositorio

e não:

$ hg clone server:caminho/para/repositorio

Note também que caminho/para/repositório é relativo ao seu diretório de usuário no servidor. Se você quiser usar um caminho absoluto no servidor, então use uma URL como esta:

$ hg clone ssh://server//caminho/absoluto/para/repositorio

A primeira barra é parte da sintaxe de URL, a segunda é parte do caminho no servidor, de modo que a URL acima se refere a caminho/absoluto/para/repositorio no servidor.

Diferente de URLs com HTTP, você pode usar URL com SSH como alvo para hg clone. Isto permite que você faça:

$ hg clone . ssh://server/path/to/repository

para clonar o repositório atual para o servidor.

Permissões no Sistema de Arquivos

Como o Mercurial faz um login no servidor, é o usuário no servidor que precisa ter acesso à leitura aos arquivos do repositório para fazer um clone ou puxar changesets. Do mesmo modo, é o usuário no servidor que precisa ter acesso à escrita aos arquivos do repositório para empurrar changesets de volta.

Se acontecer algum erro na operação de empurrar mudanças pelo SSH, então adicione --debug ao comando para ver o que o Mercurial está fazendo. Tente logar pelo SSH com o mesmo usuário e verifique se você pode acessar os arquivos.

Armazenando Credenciais HTTP(S)

Durante a conversa, o servidor web pede ao Mercurial um nome de usuário e uma senha para autenticação. Será pedido que você forneça esta informação pelo prompt:

$ hg clone https://bitbucket.org/aragost/private
http authorization required
realm: Bitbucket.org HTTP
user: aragost
password: <secret>
abort: http authorization required

Já que é necessário autenticar a cada comando que envolve o repositório remoto (isto é, comandos como hg clone, hg pull, hg push, hg incoming e hg outgoing), esse pedido se torna repetitivo e cansativo. Há várias maneiras de fazer o Mercurial salvar as credenciais. Vamos apresentá-las em ordem de preferência.

Tip

Você pode estar imaginando como fazer o Mercurial armazenar sua frase de segurança do SSH. A resposta é que não pode — a autenticação do SSH é externa ao Mercurial e você deve usar um agente SSH para armazenar a frase.

Um agente SSH é um programa que roda no plano de fundo e mantém uma versão descriptografada da sua chave privada do SSH na memória. Sempre que você precisa fazer uma conexão SSH, o ssh pergunta primeiro ao agente se ele tem uma chave descriptografada adequada. Se tiver, a conexão pode ser feita sem fornecer nenhuma senha, caso contrário o ssh pedirá a senha.

Você pode adicionar o agente SSH com o comando ssh-add no Linux e no Mac OS X e usar o Pageant quando usar o Putty no Windows.

Extensão Chaveiro

In short:

Pros: passwords are stored in a OS-specific secure backend, most secure option.

Cons: requires third-party extension.

The keyring extension will hook into Mercurial and intercept password requests. The passwords you enter a then stored securely in an OS-specific password database and you won’t have to enter them again. It stores passwords used for HTTP(S) authentication and SMTP authentication (as done by the patchbomb extension among others).

Esta solução é a padrão para Windows quando se usa TortoiseHg, que já vem com tanto com a extensão quanto as bibliotecas extras necessárias para conversar com o Windows. Em outros sistemas, você precisará instalar instalar as bibliotecas extras por si mesmo.

Armazenado no Arquivo de Configuração do Usuário

In short:

Pros: standard feature in Mercurial. Makes it easy to setup the password used for all repositories on a given host.

Cons: passwords are stored in a plaintext configuration file. Care must be used if the file is shared with others.

You can save the credentials directly in your Mercurial configuration file. You do this with the auth section:

[auth]
bb.prefix = https://bitbucket.org/
bb.username = alice
bb.password = <secret>

A seção [auth] pode conter várias declarações, e essas declarações são agrupadas por uma chave arbitrária definida por você. Acima, foi usado bb como a chave para o BitBucket, mas poderia ter sido qualquer coisa. Se você tiver mais sites para os quais deseja armazenar a senha, então você deve usar diferentes chaves para cada host:

[auth]
site-a.prefix = https://hg.site-a.net/
site-a.username = userA
site-a.password = <secret-a>

site-b.prefix = https://site-b.org/repos/
site-b.username = userB
site-b.password = <secret-b>

Embutida na URL de Push/Pull

In short:

Pros: requires no out-side configuration.

Cons: password is stored in plaintext.

Esta maneira tira vantagem da característica própria da especificação de URLs: é possível definir diretamente o nome do usuário e a senha nelas. A sintaxe é a seguinte:

scheme://username:password@domain:port/path

Você pode executar:

hg clone https://alice:<secret>@bitbucket.org/aragost/private

O Mercurial automaticamente usará alice como nome de usuário e <secret> como senha quando logar no Bitbucket. Se o clone for bem sucedido, então a URL inteira é armazenada como caminho padrão no arquivo .hg/hgrc. Como tanto o nome do usuário quanto a senha são armazenados na URL, invocações futuras de hg pull e hg push farão a autenticação automaticamente, sem pedir nada.

Configurando Atalhos para Esquemas de URL

Quando você trabalha em muitos repositórios no mesmo endereço de hospedagem, então se torna chato digitar repetidamente:

hg clone https://hg.my-long-servername.com/repos/

Encurtando URLs HTTP

Mercurial tem uma extensão padrão que ajuda encurtar essas URLs. Você pode habilitar a extensão schemes e pode adicioná-la ao seu arquivo de configuração:

[schemes]
bb = https://bitbucket.org/

Isto permite que você escreva:

hg clone bb://aragost/private

ao invés da longa:

hg clone https://bitbucket.org/aragost/private

Veja hg help schemes depois de habilitar a extensão para a sintaxe completa.

Encurtando URLs SSH

Você pode usar a extensão schemes para encurtar URLs SSH também, mas é interessante notar que o OpenSSH tem seu próprio modo de encurtar URLs. Adicione estas linhas ao arquivo ~/.ssh/config (criando-o se for necessário):

Host bb
Compression yes
HostName bitbucket.org
User hg

Isto permitirá escrever:

hg clone ssh://bb/aragost/private

ao invés de:

hg clone ssh://hg@bitbucket.org/aragost/private

Note como esta configuração define até mesmo o nome do usuário, algo particularmente fácil de esquecer quando se usa SSH com o Bitbucket. Nós também aproveitamos a oportunidade para habilitar a compressão pelo túnel SSH, que melhorará o desempenho geral.

Se você estiver usando o Putty no Windows (o TortoiseHg vem com o Putty instalado) então você pode fazer o mesmo configurando e salvando a conexão. Se você salvar a configuração sob o nome bb, então pode usar URLs no estilo ssh://bb/ com o Mercurial.

Exercícios

  1. Vá para https://bitbucket.org/ e crie uma conta para si.

  2. Crie um repositório particular chamado test e faça um clone para a sua máquina local.

  3. Adicione a consolide um arquivo no repositório e empurre-o de volta ao Bitbucket.

  4. Faça um clone de https://bitbucket.org/aragost/hello/ na sua máquina local.

  5. Crie um novo repositório no Bitbucket chamado hello e empurre o clone hello da sua máquina para o Bitbucket.

    Note que você pode empurrar changesets em um repositório vazio. Isto é porque você pode expandir um hg clone para um hg init seguido por um hg pull (exceto que você não terá os hardlinks descritos acima).

    O que acontece se você tentar empurrar do seu clone hello para seu clone test no Bitbucket? Como o Mercurial sabe se os repositórios são relacionados?