Idioma
Categoria
Pesquisar

Usando Git para compartilhar e colaborar em um projeto

Como clonar um projeto, fazer as alterações e mesclá-las, personalizar consultas ao histórico, nomear commits como versões e compara-las, pesquisar usando Git e mais comandos úteis

Em Terminal Por Rudi Drusian Lange
Publicado em
Última atualização

Antes de começar

Este texto aborda o uso do Git para colaboração em projetos e pressupõe o conhecimento de informações abordadas na primeira parte deste artigo: Entendendo o funcionamento básico do git e o uso de branches, leia antes para facilitar o entendimento do texto adiante.

Começando

Neste artigo serão usados dois personagens fictícios: A Bruna, que iniciou um novo projeto com repositório Git localizado em /home/bruna/projeto, e o Andrei, que possui um usuário no mesmo sistema e deseja contribuir com o projeto usando o diretório /home/andrei/projeto-bruna.

Pressupondo que o repositório Git da Bruna já foi criado, Andrei começa clonando o projeto da Bruna em seu diretório de contribuição:

Andrei

cd /home/andrei/
git clone /home/bruna/projeto projeto-bruna

Depois o Andrei faz as suas alterações:

Andrei

# (Edita arquivos)
git commit -a

Ao final ele pede a Bruna para aplicar as atualizações no repositório original. Então a Bruna executa:

Bruna

cd /home/bruna/projeto
git pull /home/andrei/projeto-bruna

Isso faz com que as atualização dos arquivos feitas no branch master do repositório do Andrei sejam aplicadas no branch em que a Bruna estava quando executou o comando. O comando git pull busca as alterações feitas do repositório remoto e depois mescla com o branch atual.

Caso ocorra um conflito, a Bruna terá que resolvê-los localmente em seu diretório, o Git ainda irá buscar as alterações porém se recusará a mescla-las até que as correções sejam feitas.

A Bruna pode verificar as alterações feitas pelo Andrei antes de aplicá-las usando o comando git fetch:

Bruna

git fetch /home/andrei/projeto-bruna
git log -p HEAD..FETCH_HEAD

Para ver todas as alterações que o Andrei fez desde que o projeto foi clonado, ela pode usar o comando:

Bruna

gitk HEAD..FETCH_HEAD

Repare que esta notação com dois pontos .. pode ser usada tanto com o comando git log como com gitk. Se a Bruna quiser ver tanto as alterações que ela fez quanto as que o Andrei fez desde que o projeto foi clonado, ela pode usar a notação ... com 3 pontos.

Bruna

gitk HEAD...FETCH_HEAD

Se a Bruna decidir que não há nenhuma alteração relevante feita pelo Andrei, ela pode continuar a trabalhar normalmente, já se o histórico do Andrei mostre algo que ela realmente precise, ela pode executar o git pull e continuar trabalhando contando com as alterações recentes feitas pelo Andrei.

Dependendo do projeto pode haver a necessidade de interagir com o repositório remoto constantemente, para facilitar este processo é possível criar um apelido:

Bruna

git remote add andrei /home/andrei/projeto-bruna

# E então
git fetch andrei

A criação do apelido possibilita usar a forma andrei/master para acessar informações já buscadas com o commando git fetch, como no exemplo:

Bruna

git log -p master..andrei/master

O comando acima mostra uma lista de todas alterações feitas pelo Andrei desde que o primeiro clone foi feito. Depois de analisar estas alterações a Bruna poderia aplica-las com:

Bruna

git merge andrei/master

# ou buscar em seus branches remotos
git pull . remotes/andrei/master 

Mais tarde o Andrei pode querer buscar as últimas atualizações da Bruna e ele o faz com o comando:

Andrei

git pull

Como o repositório do Andrei foi clonado a partir da Bruna, não precisa informar o caminho para o repositório, o Git já armazena esta informação e usa no comando git pull.

Andrei

# Pega o caminho do projeto original
git config --get remote.origin.url /home/bruna/projeto # Mostra as configurações criadas pelo git clone git config -l # Git guarda uma cópia do branch master da Bruna chamado origin/master git branch -r
# Andrei pode continuar trabalhando de outro pc usando ssh git clone bruna.org:/home/bruna/projeto projeto-bruna

Explorando o Histórico

O histórico do Git é representado como uma série de commits que podem ser visualizados com o comando:

git log

commit 82407449e223ddfd0b8e9ef6df95c8cd156e82b1
Author: Andrei <andrei@email.org>
Date:   Tue May 14 21:37:07 2024 -0300 merge: Adicionado comentário ao código

O código informado na linha commit pode ser usado com o comando git show para mostrar mais detalhes sobre este commit:

git show 82407449e223ddfd0b8e9ef6df95c8cd156e82b1

Usar o começo do código também funciona, desde que seja único, neste exemplo usando somente os números abaixo foram suficientes.

git show 82407

Todo commit possui um parente que representa o estado anterior do projeto.

# Mostra último commit do branch atual
git show HEAD

# Último commit do branch experimental
git show experimental    

# Mostra parente de HEAD
git show HEAD^

# Parente do parente de HEAD
git show HEAD^^

# Mostra o quarto na hierarquia
git show HEAD~4

# Commits mesclados com merge podem ter mais de um parente

# Mostra o primeiro parente de HEAD
git show HEAD^1

# Segundo parente de HEAD
git show HEAD^2

Nomeando commits

Você pode nomear um commit com:

git tag v2.5 82407

Agora é possível se referir ao commit que começa com 82407 usando o nome v2.5. Para que este nome seja válido para outras pessoas é preciso criar um objeto tag e talvez assina-lo, procure detalhes sobre o comando git tag usando git help tag.

Os nomes podem ser usados nos comandos Git sempre que precisar se referir a um commit, exemplos:

# Compara HEAD com commit v2.5
git diff v2.5 HEAD

# Inicia um novo branch chamado stable baseado no commit v2.5
git branch stable v2.5

# Restabelece o estado do branch e diretório atual para o estado no commit HEAD^
git reset --hard HEAD^

Cuidado com o comando reset: Além de perder qualquer alteração que ainda não foi salva, também removerá os últimos commits deste branch, se este branch for o único a ter estes commits eles serão perdidos. Também não use git reset em um branch público visível que outros desenvolvedores utilizem como fonte. Se precisar reverter alterações aplicadas com push, utilize git revert.

Usando intervalo com git log

# commits entre v2.5 e v2.6
git log v2.5..v2.6

# commits desde v2.5
git log v2.5..

# commits das últimas duas semanas
git log --since="2 weeks ago"

# commits desde v2.5 onde houve alterações no arquivo Makefile
git log v2.5.. Makefile

Se os branches stable e master divergiram de um ponto em comum algum tempo atrás:

# Lista os commits feitos em master mas não no branch stable
git log stable..master

# Contrário do comando acima
git log master..stable

O comando git log possui uma fraqueza: apresenta os commits em formato de lista. Quando o histórico possui linhas de desenvolvimento que divergiram e depois se mesclaram novamente, a ordem mostrada no comando é irrelevante.

Nestes casos o comando gitk é melhor para visualizar históricos.

# Commits das últimas semanas com alterações em arquivos na pasta drivers
gitk --since="2 weeks ago" drivers/

Usando a versão junto com arquivos:

# Compara arquivos em diferentes versões
git diff v2.5:Makefile HEAD:Makefile.in

# Visualiza o arquivo em uma versão específica
git show v2.5:Makefile

Pesquisando

O comando git grep é usado para procurar textos(strings) nos arquivos do projeto:

# Procura recursivamente por "import" em arquivos do diretório atual
git grep "import" 

# Procura por "import" na versão v2.5
git grep "import" v2.5

Concluindo

Somando este tutorial e sua primeira parte deve ser o suficiente para ter um controle básico de revisão distribuída para seus projetos. Duas ideias simples ajudam a entender a profundidade e o poder do Git:

  • O banco de dados de objetos é o sistema usado para armazenar o histórico de seus projetos, arquivos, diretórios e commits.
  • O arquivo index é um cache do estado da árvore de arquivos e diretórios e é usado nos commits, ele é responsável por verificar os diretórios de trabalho e manter as várias árvores envolvidas em uma mesclagem.

Referências