Usando o Git – parte 5

git-5_commit-via-atom.png

A ideia era de apenas acrescentar algumas informações e servir de complemento à série sobre Git — publicada há pouco mais de um ano — mas acabei me empolgando um pouco e ao invés de dividir um complemento, o que seria estranho, preferi integrá-lo logo de uma vez como uma nova parte. Nesta, um pouco mais sobre o histórico, configuração, ramos — branches — e “cabeças decepadas” 🙂

Histórico de atualizações

Algo que não tratei muito nas primeiras partes foi justamente o histórico de commits, através do o comando git log é possível visualizar o histórico de atualizações de um respectivo repositório — neste caso o mesmo repositório da Pastelaria:

$ git log
commit e027e0760a15392822f8e4d9296c742f25ad45d9
Author: Giovanni Nunes <░░░░░░░░░░░░░░@░░░░░░░░░>
Date: Sun Jul 24 18:31:18 2016 -0300

correção da URL da imagem

commit 1c6397b088898fcc66c6f3763a4c2ce0fde3c1a5
Author: Giovanni Nunes <░░░░░░░░░░░░░░@░░░░░░░░░>
Date: Sun Jul 24 17:48:01 2016 -0300

primeiro commit da filial

...

Mas esta listagem geralmente acaba ficando longa e de leitura um tanto cansativa, para ter uma lista resumida dos commits faça:

$ git log --oneline
e027e07 correção da URL da imagem
1c6397b primeiro commit da filial
cf81176 remoção dos arquivos monitorados
100465c adicionando o .gitignore
...

Algo interessante que o comando log pode também informar onde na linha do tempo eu me encontro. Por “onde” entenda a posição da HEAD e da master tanto no repositório local como no remoto:

$ git log --decorate --oneline
e027e07 (HEAD -> master, origin/master, origin/HEAD) correção da URL da imagem
1c6397b primeiro commit da filial
cf81176 remoção dos arquivos monitorados
100465c adicionando o .gitignore
...

Este exemplo não tem muita graça pois aqui todos apontam para um mesmo commit mas basta acrescentar alguma mudança ao repositório para modificar esta situação:

$ git log --decorate --oneline
d18dd88 (HEAD -> master) Inclusão do pastel de ricota
e027e07 (origin/master, origin/HEAD) correção da URL da imagem
1c6397b primeiro commit da filial
cf81176 remoção dos arquivos monitorados
100465c adicionando o .gitignore
...

Ao acrescentar o pastel de ricota ao cardápio e efetuar seu respectivo commit a HEAD do meu repositório local e também a posição da master foram deslocados passando a divergir da situação do remoto e, consequentemente, indicando atualizações a serem submetidas.

Aliás, e se eu fosse para um commit do passado? O que aconteceria?

$ git checkout 100465c
...
HEAD is now at 100465c... adicionando o .gitignore
$ git log --all --decorate --oneline
d18dd88 (master) Inclusão do pastel de ricota
e027e07 (origin/master, origin/HEAD) correção da URL da imagem
1c6397b primeiro commit da filial
cf81176 remoção dos arquivos monitorados
100465c (HEAD) adicionando o .gitignore
...

Neste caso é interessante acrescentar o parâmetro --all para que o Git  exiba também as modificações que estão (ou estarão?) no futuro do repositório. Use git checkout master para reposicionar a HEAD junto da master.

Outra informação interessante que pode ser obtida com o comando log é poder visualizar “graficamente” as ramificações:

$ git log --all --decorate --graph --oneline
* d18dd88 (master) Inclusão do pastel de ricota
* e027e07 (origin/master, origin/HEAD) correção da URL da imagem
* 1c6397b (HEAD) primeiro commit da filial
* cf81176 remoção dos arquivos monitorados
* 100465c adicionando o .gitignore
* 0348067 manutenção nos arquivos
* 341945d carne com ovo de volta à receita original
* 9c46bac mudança no carne com ovo
* 33726d3 mesclando 'doces'
|\ 
| * 55b2f39 pastéis doces
* | b939231 mesclando 'cardápio'
|\ \ 
| * | f428560 novos pastéis para teste
| |/ 
* | 712db28 inclusão das bebidas
|/ 
* 08df860 pastéis de carne e queijo
* d30c664 Abertura da pastelaria

A saída foi exibida integralmente para que ela pudesse ser comparada com esta imagem usada na parte 2.

git-2_pastelaria_2

E para terminar, é claro que escrever tudo isto aí é muito chato e para facilitar a vida é possível criar um apelido — alias — para este comando, neste caso o git lg.

$ git config --global alias.lg "log --all --decorate --graph --oneline"

E salvando-o para ser ficar disponível em todos os repositórios do usuário.

O repositório “sem cabeça”

No exemplo anterior, quando coloquei o repositório em um commit do passado, a saída do comando foi propositalmente suprimida e por um bom motivo.

$ git checkout 100465c
Note: checking out '100465c'.

You are in 'detached HEAD' state. You can look around, make
experimental changes and commit them, and you can discard any
commits you make in this state without impacting any branches by
performing another checkout.

If you want to create a new branch to retain commits you create,
you may do so (now or later) by using -b with the checkout command
again. Example:

git checkout -b 

HEAD is now at 100465c... adicionando o .gitignore

Fazer checkout diretamente a um commit coloca o repositório em um  estado especial onde a HEAD está destacada de um um branch, ou seja, o repositório fica “sem cabeça”… 🙂

Este estado especial é útil para testar/experimentar modificações ou até mesmo efetuar novos commits que poderão ser descartados sem prejuízo ao repositório. Mas, como o próprio comando já informa, caso sua ideia seja de preservá-los é útil que logo em seguida seja criado um novo branch para armazená-los.

Nesta situação de HEAD destacada foram feitos dois commits.

$ git lg
* 2652c6c (HEAD) Inclusão do pastel de brócolis no cardápio
* 1602fad Pastel de brócolis
| * d18dd88 (master) Inclusão do pastel de ricota
| * e027e07 (origin/master, origin/HEAD) correção da URL da imagem
| * 1c6397b primeiro commit da filial
| * cf81176 remoção dos arquivos monitorados
|/ 
* 100465c adicionando o .gitignore
...

Mais precisamente dois commits2652c6c e 1602fad — que agora encontram-se completamente destacados do resto do repositório.

Como se resolve isto? Para voltar a HEAD para o lugar correto basta fazer:

$ git checkout master
Warning: you are leaving 2 commits behind, not connected to
any of your branches:

2652c6c Inclusão do pastel de brócolis no cardápio
 1602fad Pastel de brócolis

If you want to keep them by creating a new branch, this may be a
good time to do so with:

git branch  2652c6c

Switched to branch 'master'
Seu ramo está à frente de 'origin/master' por 1 submissão.
 (use "git push" to publish your local commits

Porém isto não resolverá automaticamente aqueles dois commits que continuarão “soltos” dentro do repositório e uma forma de resolver este problema é mesclar as modificações deles na master:

$ git status
No ramo master
Seu ramo está à frente de 'origin/master' por 1 submissão.
 (use "git push" to publish your local commits)
nada a submeter, diretório de trabalho vazio
$ git merge 1602fad
Merge made by the 'recursive' strategy.
 pastel_de_brocolis_e_bacon.md | 9 +++++++++
 1 file changed, 9 insertions(+)
 create mode 100644 pastel_de_brocolis_e_bacon.md

E pronto, isto produzirá um novo commit e deixará a HEAD apontando novamente para a master.

$ git lg
* 38c83e0 (HEAD -> master) Inclusão do pastel de brócolis e bacon
|\ 
| * 1602fad Pastel de brócolis
* | d18dd88 Inclusão do pastel de ricota
* | e027e07 (origin/master, origin/HEAD) correção da URL da imagem
* | 1c6397b primeiro commit da filial
* | cf81176 remoção dos arquivos monitorados
|/ 
* 100465c adicionando o .gitignore
...

Mas e quanto ao outro commit? Ele foi intencionalmente preservado para a próxima parte.

Atualização de repositórios remotos

A partir da versão 2.0 do Git o comportamento padrão da ferramenta no envio de atualizações para repositórios remotos foi alterada. Isto é facilmente verificado ao se executar o comando push sem especificar exatamente que branches atualizar.

$ git push
warning: push.default is unset; its implicit value has changed in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the traditional behavior, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

When push.default is set to 'matching', git will push local branches
to the remote branches that already exist with the same name.

Since Git 2.0, Git defaults to the more conservative 'simple'
behavior, which only pushes the current branch to the corresponding
remote branch that 'git pull' uses to update the current branch.

See 'git help config' and search for 'push.default' for further
information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of
Git)

A explicação é simples, acontece que até a versão 2.x o Git, neste caso, atualizaria todos os branches remotos que tenham modificações locais, ou seja, você fez commits distintos em cinco ramificações diferentes e ele atualizará tudo de uma vez — o que pode não ser uma boa ideia em alguns casos.

Neste caso, para manter este comportamento use:

$ git config --global push.default matching

Mas se preferir que o Git apenas atualize o branch padrão, use:

$ git config --global push.default simple

E em ambos os casos a mensagem acima deixará de aparecer.

Fim desta parte

E por enquanto é só! Para não perder o costume a atualização do repositório remoto no GitHub com os dados deste repositório local.

$ git push origin master
Counting objects: 9, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 1.11 KiB | 0 bytes/s, done.
Total 9 (delta 4), reused 0 (delta 0)
remote: Resolving deltas: 100% (4/4), completed with 2 local objects.
To git@github.com:plainspooky/pastelaria.git
 e027e07..38c83e0 master -> master

Na próxima parte será a vez a vez de tratar de resolução de conflitos, quando o Git encontra alterações em um mesmo ponto do arquivo e também algumas palavras sobre rebase.

Até!

Anúncios

Um comentário sobre “Usando o Git – parte 5

  1. Pingback: Usando o Git – parte 6 | giovannireisnunes

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s