Git Básico

Git Básico

Neste artigo apresento uma visão introdutória de Git, o básico dos comandos para iniciar o trabalho de versionamento com ele. É o sistema base para gestão de repositórios em serviços de nuvem como o Github e Gitlab.

Porém, antes de mais nada, você consegue responder à seguinte pergunta: O que é “controle de versão”, ou que é “versionamento de software”?

Conceito de Versionamento de Software

Um sistema de controle de versão registra alterações em um arquivo ou conjunto de arquivos ao longo do tempo, para que versões específicas possam ser recuperadas e gerenciadas. Esta é uma definição muito resumida sobre versionamento de software e você deveria aprofundar o conhecimento no artigo sobre “Gerencia de Configuração de Software” (em desenvolvimento)

Git é hoje o sistema de controle de versão de fato do mercado de desenvolvimento de softwares.

Para uma leitura completa, em uma apresentação diferente de documentação, recomendo o Git Pro – livro oficial do Git que cobre do básico ao avançado.

Assista também a vídeo aula deste artigo e baixe os slides. No vídeo aprofundo as explicações para os fundamentos, e apresento de forma pratica o uso dos comandos essenciais.

Git – como funciona?

Acima de tudo, é necessário compreender como funcioná o Git, para desta forma não se tornar apenas um executor de comandos como se seguisse uma receita passo-a-passo sem a real compreensão da gestão por trás do processo.

Git considera que os dados são como um conjunto de snapshots (captura de algo em um determinado instante, como em uma foto). Portanto, é possível navegar em diferentes instantes pelo tempo de seu projeto.

Cada vez que você salva ou consolida – ou seja, realiza um commit, o estado do seu projeto no Git, em resumo, é como se ele tirasse uma foto de todos os seus arquivos naquele momento e armazenasse uma referência para essa captura.

Com o propósito de ser eficiente, se nenhuma alteração foi realizada em um determinado arquivo, em um instante de versionamento, a informação deste arquivo não é armazenada novamente. Em outras palavras, apenas um link para o arquivo idêntico anterior que já foi armazenado. Dessa forma o sistema garante economia eficiente de espaço, além de performance.

Checkins, commits no tempo
Visão de registros de versionamento em um repositório

Características

A princípio, as principais características são:

  • Quase todas operações são locais
  • Git tem integridade checksum
  • Git geralmente só adiciona dados

Estados dos arquivos

  • consolidado (committed): quando estão seguramente armazenados em sua base de dados local
  • modificado (modified): quando houve uma alteração que ainda não está consolidada
  • preparado (staged): quando um arquivo modificado é marcado para fazer parte de um commit

Workflow

O fluxo básico de trabalho pode ser descrito com os seguintes passos:

  1. Você modifica arquivos no seu diretório de trabalho.
  2. Você seleciona os arquivos, adicionando snapshots deles para sua área
    de preparação.
  3. Você faz um commit, que leva os arquivos como eles estão na sua área
    de preparação e os armazena permanentemente no seu diretório Git.
Fluxo de operações local

Seus repositórios locais consistem em três “árvores” mantidas pelo git.

  • Working Directory que contém os arquivos vigentes.
  • Index que funciona como uma área temporária (stage)
  • HEAD que aponta para o último commit (confirmação) que você fez.
Árvores de organização do git

A partir de um estado “não gerenciado”, os arquivos entram em um ciclo de alterações de estado a cada modificação e posterior consolidação.

Fluxo do Git básico

Instalando o Git – básico por sistema

Em sistemas operacionais Linux baseados em Debian, ou seja: Ubuntu, Linux Mint:

sudo apt-get install git

Em Windows, baixe o arquivo no git for Windows e siga os passos de instalação.

Dica: as aspas simples dos comandos nos slides devem ser trocadas por aspas duplas no Windows.

Configuração básica do Git

Para utilizar o git em sua máquina, em primeiro lugar é necessário configurar com seus dados de autor. Uma vez que todos os commits devem ser identificados.

O arquivo /etc/gitconfig contém valores de configuração para todos usuários do sistema e todos os seus repositórios. Se você passar a opção --system para git config, ele lerá e escreverá a partir deste arquivo especificamente.

O arquivo ~/.gitconfigé específico para seu usuário. Você pode fazer o Git ler e escrever a partir deste arquivo passando a opção --global.

O arquivo de configuração no diretório git (ou seja, no repositório local) .git/config é específico para aquele único repositório. Cada nível sobrepõem o valor do nível anterior, sendo assim valores em .git/config sobrepõem aqueles em /etc/gitconfig.

Em sistemas Windows, Git procura pelo arquivo .gitconfig no diretório $HOME. Isto significa um dos diretórios a seguir: C:\Documents e Settings\$USER, para a maioria dos usuários.

Comandos para configurar nome e email

Definir seu nome e email para serem adicionados como autor nos commits.

Para configuração global no sistema atual, por exemplo usando meus dados:

git config --global user.name "Ademir Mazer Junior"
git config --global user.email ademirmazerjr@servidor.com

Configurar o Prompt colorido:

git config --global color.ui true

Comandos para listar configurações

Para listar todas as configurações

git config --list

Para listar uma configuração específica, por exemplo o user.name:

git config user.name

Pedindo Ajuda

Para listar comandos (ações) disponíveis e abrir o manual de help para cada ação, use os comandos a seguir:

git

Digitar apenas git lista todas as ações disponíveis com uma explicação resumida de seu objetivo. Desta maneira é possível ter uma visão geral dos comandos existentes.

git help <ação>

Abre a página de manual da ação especificada, por exemplo: git help commit

Criando um repositório

Para criar um novo repositório:

git init
  • crie uma nova pasta (pode ser criado um novo repositório em uma pasta com arquivos existentes)
  • acesse a nova pasta pela linha de comando
  • digite o comando de criação de repositório

Por exemplo, em um sistema linux:

mkdir novodiretorio
cd novodiretorio
git init

Verificando o status

Para verificar o status do repositório, isto é, em que branch e quais arquivos estão modificados, utilize:

git status

Obtendo um repositório

Primeiramente, obter um repositório significa realizar um clone de um repositório remoto, com a finalidade de baixar e conectar seu diretório de trabalho git local com ele.

O clone será criado a partir do diretório onde você está situado, dessa forma, tenha certeza que o subdiretório estará no local que deseja.

Para criar uma cópia de trabalho em um repositório local executando o comando:

git clone /caminho/para/o/repositório

Por exemplo, quando usar um servidor remoto Github, seu comando poderá ser

git clone https://github.com/uepg/laravel-sybase.git

Desse modo o comando acima criará o subdiretório laravel-sybase a partir do ponto em que você está no sistema de arquivos.

Adicionar e confirmar alterações

As ações de: adicionar arquivos para serem rastreados, informar mudanças e consolidar estas alterações; é o núcleo do fluxo de trabalho de versionamento com Git. Em resumo, é o seu fluxo básico, ou seja, o que você faz diariamente para garantir este controle.

Para adicionar (propor) mudanças, isto é, adicioná-las ao Index, este é o primeiro passo no fluxo de trabalho básico do git, use a ação git add, por exemplo:

git add <arquivo>
git add *

Usando o coringa tudo ( * ) você adiciona todas as alterações e novos arquivos. Mas pode, e geralmente, deve, selecionar o conjunto de arquivos indicando-os individualmente ou em conjunto.

Para realmente confirmar estas mudanças, isto é, consolidar no repositório local, use commit. Como boa prática, sempre com comentários, por exemplo:

git commit -m “comentários das alterações”

Como resultado o arquivo é “enviado” para o HEAD, no repositório local, no entanto, ainda não para o repositório remoto.

Em resumo: ao criar ou alterar arquivos, git add, em seguida, consolida-se com git commit.

Ignorando arquivos

Primeiramente é necessário entender que rastrear arquivos binários, como executáveis, ou diretórios e arquivos de configuração de IDEs, por exemplo, não são boas práticas, pois o repositório usará muito recurso de espaço e aumentará o uso de tempo para processar suas ações. Por consequência degradando seu desempenho se tornando menos eficiente.

Dessa forma informar ao Git que certos arquivos ou diretórios devem ser ignorados é uma boa prática para gestão de repositórios.

Para ignorar arquivos, crie padrões dentro de um arquivo .gitignore no raiz do repositório. Por exemplo:

# Compiled source #
*.com
*.class
*.dll
*.exe
*.o
*.so

Os arquivos .ignore podem ser usados no raiz do projeto, ou em subdiretórios se isto facilitar a sua gestão.

Com o intuito de oferecer um conjunto de arquivos comuns a serem ignorados, o gist a seguir, do Octocat no Github, por exemplo, possui uma série de arquivos .ignore que podem servir de base inicial para seu repositorio

https://gist.github.com/octocat/9257657

Atenção: Arquivos que já estão sendo rastreados não são afetados pelas regras do .gitignore, dessa forma, não adianta incluir um arquivo nas regras depois que ele já estiver sendo gerenciado pelo Git.

Enviando alterações ao repositório remoto

Suas alterações agora estão no HEAD da sua cópia de trabalho local, ou seja, o repositório remoto não contém estas alterações. Para envia-las ao seu
repositório remoto, por exemplo, enviar a branch master, execute

git push origin master

Altere master para qualquer ramo (branch) desejado, enviando suas alterações para ele.

Porém, se você não clonou, isto é, não criou o repositório a partir de um repositório existente e deseja conectar seu repositório a um servidor remoto, você deve adicioná-lo com o comando

git remote add origin <servidor>

Dessa forma agora você é capaz de enviar suas alterações para o servidor remoto selecionado.

Log do repositório

Para consultar o histórico (log) das alterações, commits, tags criadas, isto é, se você deseja verificar o log de alterações de um repositório (tag, branch), basta usar o comando

git log

Este comando irá listar a atividade em ordem cronológica do mais recente para mais antiga. A listagem é apresentada possibilitando sua navegação, por exemplo, usando setas para cima e para baixo. Para sair desta navegação utilize a tecla q (que).

Atualizar e mesclar alterações

Para atualizar seu repositório local, isto é, “puxar” as alterações mais novas de versionamento, provavelmente de seus colegas de equipe, do repositório remoto, execute o comando a seguir na sua
pasta de trabalho. Este comando executará duas ações: obter as alterações remotas e fazer merge (mesclar) com as alterações locais.

git pull

Para fazer merge de um outro branch em seu branch ativo, por exemplo, se você está no branch feature-200 e deseja incorporar as alterações já aceitas no dev:

git merge <branch>
// seguindo o exemplo descrito
git merge dev

Conflitos

Quando um merge resulta em conflitos, isto é, porções do mesmo código foram alteradas por usuários diferentes, ou em branches diferentes; você é responsável por fazer o merge destes conflitos manualmente editando os arquivos exibidos pelo git.

Depois de realizar as alterações de ajuste dos conflitos, é necessário marcá-los como merged com o comando git add <arquivo> antes de fazer o merge das alterações.

Estou escrevendo um artigo exclusivamente para tratar de mesclagem de códigos e gestão de conflitos com Git, me siga no twitter para receber a atualização quando for lançado

Ramificações

Primeiramente, o que são ramos? Branches ou “ramos” são utilizados para desenvolver funcionalidades isoladas umas das outras. O branch master é o ramo “padrão” quando você cria um
repositório. De forma geral, uma boa prática, é utilizar outros branches para desenvolver e mescla-los (merge) ao branch master após a conclusão das alterações. Como por exemplo demonstrado na imagem a seguir

Representação simples de um branch/merge
Demonstração de uma ramificação do master e posterior merge

O “mapa” visual mais comum para representar os ramos de um repositório seguem o exemplo a seguir

Representação de ramificações em um repositório Git
Representação de ramificações em um repositório Git

Criando branches e navegando entre eles

Em primeiro lugar, é importante saber que a criação de um novo branch é realizada como uma cópia do “momento” em que você está em seu diretório de trabalho do repositório.

Utilizo com frequência a ação de navegar entre ramos:- git checkout, copm a opção -b, para criar um novo branch, por exemplo, se quero criar um ramo chamado funcionalidade_x, a partir do ponto em que estou, uso o comando

git checkout -b funcionalidade_x

Como resultado, o branch funcionalidade_x é criado e o git altera o diretório de trabalho para ele. Dessa forma, ao alterar arquivos e realizar os commits, as alterações serão consolidades neste ramo.

Se precisar navegar, isto é, alterar o seu diretório de trabalho em outro branch, use checkout sem o -b, por exemplo, para voltar ao branch master

git checkout master

Se precisar excluir, ou seja, remover um ramo do diretório de trabalho local, use a opção -d da ação branch. Por exemplo para excluir o ramo funcionalidade_x

git branch -d funcionalidade_x

Fique atento à atualização do repositório central se necessitar disponibilizar um branch aos demais integrantes da equipe, ele não estará disponível a menos que você o envie ao remoto

git push origin <nome-do-branch>

Como visto neste artigo, Git é um sistema de versionamento eficaz e eficiente para a Gestão de Configuração em seu projeto de software. Esta foi uma introdução que demonstrou um panorama geral do uso diário e mais comum das duas funções.

Em breve disponibilizarei novos artigos e material de estudos aprofundados cobrindo tópicos e ações específicas no fluxo de trabalho com Git.

Não deixe de realizar a prática inicial guiada, que está disponível no final do conjunto de slides do arquivo a seguir. Também assista a vídeo aula onde explico com mais detalhes os itens e conceitos descritos neste artigo.

Deixe uma resposta

Ademir Mazer Junior

Engenheiro de Software. desenvolvedor com aproximadamente 30 anos de experiência. Professor universitário. Especialista em Arquitetura de Software, PHP, Laravel, Processos de Desenvolvimento de Software.