Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
373 lines (288 sloc) 17.1 KB
<!DOCTYPE html>
<html lang="pt">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Uma Referência Visual de Git</title>
<link rel='stylesheet' type='text/css' href='visual-git-guide.css'>
<script type="text/javascript" src='visual-git-guide.js'></script>
</head>
<body onload="replace_all_PNGs();">
<h1 id="top">Uma Referência Visual do Git</h1>
<div id="language-box">
<a>Outros Idiomas:</a>
<ul>
<li><a href='index-de.html'>Deutsch</a></li>
<li><a href='index-en.html'>English</a></li>
<li><a href='index-es.html'>Español</a></li>
<li><a href='index-fr.html'>Français</a></li>
<li><a href='index-it.html'>Italiano</a></li>
<li><a href='index-ja.html'>日本語</a></li>
<li><a href='index-ko.html'>한국어</a></li>
<li><a href='index-pl.html'>Polski</a></li>
<li class="selected">Português</li>
<li><a href='index-ru.html'>Русский</a></li>
<li><a href='index-sk.html'>Slovenčina</a></li>
<li><a href='index-vi.html'>Tiếng Việt</a></li>
<li><a href='index-zh-cn.html'>简体中文</a></li>
<li><a href='index-zh-tw.html'>正體中文</a></li>
</ul>
</div>
<p id="link-to-png">Se as figuras não funcionarem, você pode tentar a
versão <a href="?no-svg">sem SVG</a> desta página.</p>
<p id="link-to-svg">As figuras SVG foram desabilitadas. <a
href="index.html">(Reabilitar as figuras SVG)</a></p>
<p>Esta página fornece uma breve referência visual para os comandos mais
comuns do git. Uma vez que você saiba um pouco sobre como o git
funciona, esta página pode consolidar o seu entendimento. Se você está
interessado em saber como esta página foi criada, veja o meu <a
href='http://github.com/MarkLodato/visual-git-guide'>repositório no
GitHub</a>.</p>
<h2 id="contents">Conteúdo</h2>
<ol>
<li><a href="#basic-usage">Uso Básico</a></li>
<li><a href="#conventions">Convenções</a></li>
<li><a href="#commands-in-detail">Comandos em Detalhe</a>
<ol>
<li><a href="#diff">Diff</a></li>
<li><a href="#commit">Commit</a></li>
<li><a href="#checkout">Checkout</a></li>
<li><a href="#detached">Comitando com um HEAD detachado</a></li>
<li><a href="#reset">Reset</a></li>
<li><a href="#merge">Merge</a></li>
<li><a href="#cherry-pick">Cherry Pick</a></li>
<li><a href="#rebase">Rebase</a></li>
</ol>
</li>
<li><a href="#technical-notes">Observações Técnicas</a></li>
</ol>
<h2 id="basic-usage">Uso Básico</h2>
<div class="center"><img src='basic-usage.svg.png'></div>
<p>Os quatro comandos acima copiam arquivos entre o diretório de
trabalho, o <em>stage</em> (também chamado de índice), e o histórico (na forma de
<em>commits</em>).</p>
<ul>
<li><code>git add <em>arquivos</em></code> copia <em>arquivos</em> (em
seus estados atuais) para o <em>stage</em>.</li>
<li><code>git commit</code> salva uma cópia do <em>stage</em> como um
<em>commit</em>.</li>
<li><code>git reset -- <em>arquivos</em></code> remove arquivos do
<em>stage</em>; isto é, copia <em>arquivos</em> do último <em>commit</em> para o <em>stage</em>.
Use esse comando para "desfazer" um <code>git add
<em>arquivos</em></code>. Você também pode executar <code>git
reset</code> para remover todos os arquivos do <em>stage</em>.</li>
<li><code>git checkout -- <em>arquivos</em></code> copia
<em>arquivos</em> do <em>stage</em> para o diretório de trabalho. Use isso
para descartar alterações locais.</li>
</ul>
<p>Você pode usar <code>git reset -p</code>, <code>git checkout
-p</code>, ou <code>git add -p</code> em vez de (ou além de) especificar
arquivos para selecionar interativamente partes de arquivos para
copiar.</p>
<p>Também é possível passar por cima do <em>stage</em> e copiar (checkout)
arquivos diretamente do histórico ou de <em>commits</em> sem copiar o aquivo para
o <em>stage</em>.</p>
<div class="center"><img src='basic-usage-2.svg.png'></div>
<ul>
<li><code>git commit -a </code> é equivalente a executar <tt>git
add</tt> em todos os arquivos que existiam no último <em>commit</em>, e
então executar <tt>git commit</tt>.</li>
<li><code>git commit <em>arquivos</em></code> cria um novo <em>commit</em> com
o conteúdo do último <em>commit</em>, mais uma cópia de <em>arquivos</em> no
diretório de trabalho. Além disso, os <em>arquivos</em> são copiados
para o <em>stage</em>.</li>
<li><code>git checkout HEAD -- <em>arquivos</em></code> copia os
<em>arquivos</em> do último <em>commit</em> para ambos o <em>stage</em> e o diretório de
trabalho.</li>
</ul>
<h2 id="conventions">Convenções</h2>
<p>No restante deste documento, nós vamos usar gráficos no seguinte
formato.</p>
<div class="center"><img src='conventions.svg.png'></div>
<p><em>commits</em> são mostrados em verde com uma identidade de 5 caracteres, e
eles apontam para os seus pais (parents). Os ramos (branches) são
mostrados em laranja, e eles apontam para <em>commits</em> específicos. O ramo
atual é identificado pela referência especial <em>HEAD</em>, que está
unida àquele ramo. Nessa imagem, os últimos cinco <em>commits</em> são
mostrados, sendo <em>ed489</em> o mais recente. <em>master</em> (o ramo
atual) aponta para esse <em>commit</em>, enquanto <em>maint</em> (outro ramo)
aponta para um ancestral do <em>commit</em> do <em>master</em>.
<h2 id="commands-in-detail">Comandos em Detalhe</h2>
<h3 id="diff">Diff</h3>
<p>Existem várias formas de ver as diferenças entre <em>commits</em>. Abaixo
estão alguns exemplos comuns. Qualquer desses comandos pode
opcionalmente receber nomes de arquivos como argumentos que restringem as
diferenças a esses arquivos.</p>
<div class="center"><img src='diff.svg.png'></div>
<h3 id="commit">Commit</h3>
<p>Quando você comita, o git cria um novo <em>commit</em> usando os arquivos do
<em>stage</em> e define os pais como o <em>commit</em> atual. Então ele aponta o ramo
atual para esse novo <em>commit</em>. Na figura abaixo, o ramo atual é o
<em>master</em>. Antes do comando ser executado, <em>master</em>
apontava para <em>ed489</em>. Após, um novo <em>commit</em>, <em>f0cec</em>, foi
criado, com ancestral <em>ed489</em>, e então <em>master</em> foi movido
para o novo <em>commit</em>.</p>
<div class="center"><img src='commit-master.svg.png'></div>
<p>Esse mesmo processo ocorre também quando o ramo atual é um
ancestral de outro ramo. Abaixo, um <em>commit</em> ocorre no ramo
<em>maint</em>, o qual era um ancestral de <em>master</em>, resultando
em <em>1800b</em>. Após, <em>maint</em> não é mais um ancestral de
<em>master</em>. Para juntar as duas histórias, um <a
href='#merge'>merge</a> (ou <a href='#rebase'>rebase</a>) será
necessário.</p>
<div class="center"><img src='commit-maint.svg.png'></div>
<p>As vezes um engano ocorre em um <em>commit</em>, mas isso é fácil de corrigir
com <code>git commit --amend</code>. Quando você usa esse comando, o git
cria um novo <em>commit</em> com os mesmos pais do <em>commit</em> atual. (O <em>commit</em> antigo
será descartado se nada fizer referência a ele.)</p>
<div class="center"><img src='commit-amend.svg.png'></div>
<p>Um quarto caso é comitar com o <a href="#detached">HEAD
detachado</a>, como explicado mais tarde.</p>
<h3 id="checkout">Checkout</h3>
<p>O comando checkout é usado para copiar arquivos do histórico, ou
<em>stage</em>, para o diretório de trabalho, e opcionalmente mudar de ramo.</p>
<p>Quando um nome de arquivo (e/ou <code>-p</code>) é fornecido, o git
copia esse arquivo do <em>commit</em> para o <em>stage</em> e para o diretório de trabalho.
Por exemplo, <code>git checkout HEAD~ foo.c</code> copia o arquivo
<code>foo.c</code> do <em>commit</em> chamado <em>HEAD~</em> (os pais do <em>commit</em>
atual) para o diretório de trabalho, e também para o <em>stage</em>. (Se nenhum
<em>commit</em> é fornecido, os arquivos são copiados do <em>stage</em>.) Note que não há
mudança no ramo.</p>
<div class="center"><img src='checkout-files.svg.png'></div>
<p>Quando um nome de arquivo <em>não</em> é fornecido mas a referência é
um ramo (local), <em>HEAD</em> é movido para aquele ramo (isto é, nós
passamos para aquele ramo), e então o <em>stage</em> e o diretório de trabalho
são modificados para coincidir com o conteúdo daquele <em>commit</em>. Qualquer
arquivo que existe no novo <em>commit</em> (<em>a47c3</em> abaixo) é copiado;
qualquer arquivo que existe no antigo <em>commit</em> (<em>ed489</em>) mas não no
novo <em>commit</em> é excluído; e qualquer arquivo que não existe em ambos é
ignorado.</p>
<div class="center"><img src='checkout-branch.svg.png'></div>
<p>Quando um nome de arquivo <em>não</em> é fornecido e a referência
<em>não</em> é um ramo (local) &mdash; por exemplo, é uma etiqueta
(tag), um ramo remoto, uma identidade SHA-1, ou algo como
<em>master~3</em> &mdash; nós obtemos um ramo anônimo, chamado <em>HEAD
detachado</em>. Isso é útil para se mover ao longo do histórico. Por
exemplo, suponha que você queira compilar a versão 1.6.6.1 do git. Você
poder executar <code>git checkout v1.6.6.1</code> (que é uma etiqueta,
não um ramo), compilar, instalar, e então passar de volta para outro
ramo, por exemplo executado <code>git checkout master</code>. Todavia,
efetuar um <em>commit</em> funciona um pouco diferente em um HEAD detachado; isso
é discutido <a href="#detached">abaixo</a>.</p>
<div class="center"><img src='checkout-detached.svg.png'></div>
<h3 id="detached">Comitando com um HEAD detachado</h3>
<p>Quando o <em>HEAD</em> está detachado, comitar funciona da maneira
usual, exceto que nenhum ramo com nome é modificado. (Você pode pensar
nisso como um ramo anônimo.)</p>
<div class="center"><img src='commit-detached.svg.png'></div>
<p>Uma vez que você fizer um checkout de alguma coisa, por exemplo
<em>master</em>, o <em>commit</em> (presumivelmente) não recebe outra referência,
e acaba excluído. Note que após o comando, não há nada fazendo
referência para <em>2eecb</em>.</p>
<div class="center"><img src='checkout-after-detached.svg.png'></div>
<p>Se, por outro lado, você quiser salvar esse estado, você pode criar
um novo ramo com nome usando <code>git checkout -b
<em>nome</em></code>.</p>
<div class="center"><img src='checkout-b-detached.svg.png'></div>
<h3 id="reset">Reset</h3>
<p>O comando reset move o ramo atual para uma nova posição, e
opcionalmente atualiza o <em>stage</em> e o diretório de trabalho. Ele também é
usado para copiar arquivos do histórico para o <em>stage</em> sem alterar o
diretório de trabalho.</p>
<p>Se um <em>commit</em> é realizado sem um nome de arquivo, o ramo atual é
movido para aquele <em>commit</em>, e então o <em>stage</em> é atualizado para coincidir
com esse <em>commit</em>. Se <code>--hard</code> é fornecido, o diretório de
trabalho também é atualizado. Se <code>--soft</code> é fornecido,
nem o <em>stage</em> nem o diretório de trabalho são atualizados.</p>
<div class="center"><img src='reset-commit.svg.png'></div>
<p>Se um <em>commit</em> não é fornecido, será usado o <em>HEAD</em>. Nesse
caso, o ramo não é alterado, mas o <em>stage</em>, e opcionalmente o diretório de
trabalho se <code>--hard</code> é fornecido, são atualizados com o
conteúdo do último <em>commit</em>.</p>
<div class="center"><img src='reset.svg.png'></div>
<p>Se um nome de arquivo (e/ou <code>-p</code>) é fornecido, então o
comando funciona similarmente ao comando <a
href='#checkout'>checkout</a> com um nome de arquivo, exceto que
apenas o <em>stage</em> (e não o diretório de trabalho) é atualizado. (Você pode
também especificar o <em>commit</em> a partir do qual copiar os arquivos, em vez
de <em>HEAD</em>.)</p>
<div class="center"><img src='reset-files.svg.png'></div>
<h3 id="merge">Merge</h3>
<p>Um merge cria um novo <em>commit</em> que incorpora mudanças de outros
<em>commits</em>. Antes de executar um merge, o <em>stage</em> deve estar igual ao último
<em>commit</em>. O caso trivial é quando o outro <em>commit</em> é um ancestral do <em>commit</em>
atual; em tal caso nada ocorre. O próximo caso mais simples é quando o
<em>commit</em> atual é um ancestral do outro <em>commit</em>. Isso resulta em um merge
<em>fast-forward</em>. A referência é simplesmente movida, e então é
efetuado um checkout do novo <em>commit</em>.</p>
<div class="center"><img src='merge-ff.svg.png'></div>
<p>Caso contrário, um merge "real" deve ocorrer. Você pode selecionar
outras estratégias, mas o padrão é efetuar um merge "recursivo", o qual
basicamente considera o <em>commit</em> atual (<em>ed489</em> abaixo), o outro
<em>commit</em> (<em>33104</em>), e o ancestral comum a ambos (<em>b325c</em>), e
efetua um <a href='http://en.wikipedia.org/wiki/Three-way_merge'>merge
three-way</a>. O resultado é salvo no diretório de trabalho e no
<em>stage</em>, e então um <em>commit</em> é executado, com um ancestral adicional
(<em>33104</em>) para o novo <em>commit</em>. </p>
<div class="center"><img src='merge.svg.png'></div>
<h3 id="cherry-pick">Cherry Pick</h3>
<p>O comando cherry-pick "copia" um <em>commit</em>, criando um novo <em>commit</em> no ramo
atual com a mesma mensagem e modificações de outro <em>commit</em>.</p>
<div class="center"><img src='cherry-pick.svg.png'></div>
<h3 id="rebase">Rebase</h3>
<p>Um rebase é uma alternativa a um <a href='#merge'>merge</a> para
combinar vários ramos. Enquanto um merge cria um único <em>commit</em> com dois
pais, gerando um histórico não-linear, um rebase efetua os <em>commits</em> do
ramo atual em outro ramo, gerando um histórico linear. Em essência, isso
é uma forma automática de executar vários <a
href='#cherry-pick'>cherry-pick</a>s em sequência.</p>
<div class="center"><img src='rebase.svg.png'></div>
<p>O comando acima considera todos os <em>commits</em> que existem em
<em>topic</em> mas não em <em>master</em> (a saber <em>169a6</em> e
<em>2c33a</em>), executa esses <em>commits</em> em <em>master</em>, e então move
o HEAD para o novo <em>commit</em>. Note que os <em>commits</em> antigos serão descartados
se nada mais fizer referência a eles.</p>
<p>Para limitar quanto se quer ir para trás, use a opção
<code>--onto</code>. O seguinte comando executa em <em>master</em> os
<em>commits</em> mais recentes do ramo atual desde <em>169a6</em>
(exclusivamente), a saber <em>2c33a</em>.</p>
<div class="center"><img src='rebase-onto.svg.png'></div>
<p>Existe também o comando <code>git rebase --interactive</code>, o qual
permite fazer coisas mais complicadas do que simplesmente executar
novamente <em>commits</em>, a saber, remover, reordenar, modificar, e "amassar"
<em>commits</em> (squashing). Não existe uma figura clara para representar isso;
veja <a
href='http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html#_interactive_mode'>git-rebase(1)</a>
para mais detalhes.</p>
<h2 id="technical-notes">Observações técnicas</h2>
<p>O conteúdo dos arquivos não é na verdade armazenado no index
(<em>.git/index</em>) ou em objetos <em>commit</em>. Em vez disso, cada arquivo
é armazenado na base-de-dados de objetos (<em>.git/objects</em>) como um
<em>blob</em>, identificado pelo seu código hash SHA-1. O arquivo index
lista os nomes de arquivos juntamente com o identificador do blob
associado, bem como alguns outros dados. Para <em>commits</em>, existe um tipo de
dado adicional, uma <em>árvore</em>, também identificado pelo seu código
hash. Árvores correspondem aos diretórios no diretório de trabalho, e
contém uma lista das árvores e blobs correspondentes a cada nome de
arquivo naquele diretório. Cada <em>commit</em> armazena o identificador da sua
árvore, que por sua vez contém todos os blobs e outras árvores
associadas àquele <em>commit</em>. </p>
<p>Se você realiza um <em>commit</em> usando um HEAD detachado, o último <em>commit</em> é
na verdade referenciado por algo: o reflog para o HEAD. Todavia, esse
possui data de validade, logo em algum momento posterior o <em>commit</em>
será finalmente excluído, de forma similar aos <em>commits</em> excluídos com
<code>git commit --amend</code> ou <code>git rebase</code>.</p>
<hr>
<p>Copyright &copy; 2010,
<a href='mailto:lodatom@gmail.com'>Mark Lodato</a>.
Portuguese translation &copy; 2014,
<a href='mailto:goliveira5d@gmail.com'>Gustavo de Oliveira</a>
</p>
<p><a rel="license"
href="https://creativecommons.org/licenses/by-nc-sa/3.0/us/deed.pt_BR">
<img alt="" src="https://i.creativecommons.org/l/by-nc-sa/3.0/us/80x15.png"></a>
Este trabalho está sob a licença <a rel="license"
href="https://creativecommons.org/licenses/by-nc-sa/3.0/us/deed.pt_BR">
Atribuição-NãoComercial-CompartilhaIgual 3.0 Estados Unidos</a>.</p>
<p><a href='translate-en.html'>Gostaria de traduzir para outro idioma?</a></p>
</body>
</html>