Guia Prático Git
No items found.

Todos sabemos que versionamento de código é algo super importante nos dias de hoje. Este artigo abordará tópicos simples até tópicos um pouco mais avançados na utilização da ferramenta de Git, não irei falar sobre steps de configuração do Git nesse artigo. Além disso no final, comentarei sobre algumas dicas e ferramentas para ajudar no seu dia a dia.

Vantagens de utilizar o git

  • Facilidade na colaboração no desenvolvimento.
  • Redução de erros resultado por conflitos de arquivos.
  • Visualização do que realmente está sendo adicionado e removido dentro de cada arquivo.
  • Acesso a qualquer versão passada existente no histórico de seu repositório. Podendo restaurar a uma versão antiga se necessário.

Basico

Inicialização

Para criação de um novo repositório, crie uma pasta onde você gostaria que o repositório fique localizado. Após isso abra o terminal onde poderá fazer o init do mesmo.

git init

Após isso seu diretório será trackeado como parte do git com as funcionalidades do .git, entretanto não há nenhum arquivo para ser tracked no momento.

Local vs Remoto

No momento em que seu repositório é criado há duas fontes de verdade do seu repositório:

  1. Remoto — O que está no servidor onde você está salvando seu repositório na internet (GitHub, GitLab, Bitbucket …) esse é o seu repositório onde qualquer outro usuário que tenha acesso ao mesmo conseguirá acessar as mudanças.
  2. Local — O que está na sua máquina (seu computador) onde está fazendo suas mudanças e aplicando as mesmas em seu repositório local.

Commit

Commit é o nome dado ao ato de adicionar as mudanças feitas em seu repositório. Quando um commit é criado essas mudanças ficam salvas indefinitivamente em seu repositório, ou seja é um estado dos arquivos que pode ser acessado a qualquer momento a partir de sua criação. Isso permite a fácil reversão caso necessário.

É preciso especificar quais arquivos você quer que entre em seu commit. Arquivos não especificados irão ficar listados como mudanças que não estão dentro do repositório.

// Adicionar um arquivo ao commit
git add <arquivo>// Adicionar todos arquivos ao commit
git add .// Listagem dos arquivos que estão fora/dentro do seu commit atual
git status// Fazer o commit com uma mensagem.
git commit -m "Meu primeiro commit"

Obs: Existem muitos outros parâmetros para utilização do git add e git commit.

Com esses comandos você adicionou seu primeiro commit a seu repositório local. 🎉

Push

Agora que seu commit foi adicionado ao repositório local, como enviar ele para o repositório remoto?

git push origin master

Caso não esteja conseguindo realizar um git push, isso deve siginificar que não está com um repositório remoto linkado ao seu local, é necessário fazer esse step de configuração.

Com isso, você acaba de enviar para o seu repositório tudo que está em seu repositório local 🚀. Agora… como vamos pegar as mudanças do repositório remoto para o repositório local caso alguém tenha adicionado algo lá?

Fetch & Pull

Fetch é o comando utilizado para fazer o download do repositório remoto para sua máquina local sem fazer alterações em suas mudanças atuais, com isso é possível uma visualização do que está ocorrendo no remoto. Basicamente ele serve para atualizar o repositório para este momento atual, entretanto não irá aplicar nenhuma dessas mudanças baixadas.

Pull é o comando mais conhecido e normalmente mais utilizado pois é um modo simplificado de buscar e aplicar as mudanças no repositório remoto em uma só tacada. Entretanto, ele não é nada mais nada menos que um fetch seguido de um merge. É por causa desse merge que ocorre conflitos no seu repositório quando realiza um git pull onde pessoas estão mexendo nos mesmos arquivos que você.

git fetchgit pull

Fluxo básico

Controle de Ramos

Branches

Normalmente por convenção definimos que nossa branch master deve ter apenas código estável/funcional e branches secundárias são aquelas onde cada desenvolvedor fará suas mudanças de feature. Em casos de projetos maiores, normalmente temos uma branch master (versão estável vista pelos utilizadores do código/produto), uma branch develop (versão estável utilizada pelos desenvolvedores do código) e branches secundárias que saem da develop (features onde cada desenvolvedor(es) está trabalhando).

Mas qual a vantagem de utilizar uma branch separadas ao invés de todos trabalharmos na mesma? 🤔

  1. Organização. Separação de funcionalidades por ramo permite uma visão melhor das partes do todo.
  2. Testabilidade. Separação das funcionalidades permite que se teste cada uma sem influência de outros fatores.
  3. Independência. Assim como testabilidade, não há impacto de outras funcionalidades dentro da que está sendo feita agora, ou seja, conflitos de integração só irão na junção da branch origem ao código da branch principal.

// Criando uma nova branch local para se trabalhar.
git checkout -b <nome para sua branch>

// Faz o checkout para uma branch. Caso não possua a branch  //localmente, o comando criará uma versão local e irá para ela.
git checkout <branch existente no remoto/local>// Faz a publicação das mudanças de sua branch local para uma branch //remota origin/<sua branch>. Caso contrário não será possível //enviar suas mudanças para o remoto.
git push origin <sua branch>

Obs: A criação de branches é local até o momento onde ela é publicada ao repositório remoto. Mais funcionalidades do git checkout e git branch.

Merge

Essa é a funcionalidade do git que permite a junção de dois ramos diferentes em um mesmo, o que ocorre realmente é a geração de um commit na branch de destino com todas as mudanças realizadas na branch de origem. Este é o momento onde poderão ocorrer conflitos de código, e para o merge ser completo é necessário resolve-los antes. Na linha de comandos o processo é um pouco diferente do que foi explicado, é necessário ir para sua branch de destino e aplicar as mudanças da branch de origem nela.

// Primeiro é necessário ir para a branch de destino, no caso vamos //para a master.
git checkout master

//Agora use o comando de merge para juntar as mudanças.
git merge <nome de sua branch>

Rebase

Rebase é algo que muitos utilizadores de git tratam como opcional ou desconhecem a forma de utilização. Entretanto eu considero como uma funcionalidade essencial para se ter uma organização do seu repositório boa. Rebase é como o próprio nome diz mudar a base de origem da sua branch para o topo da branch desejada.

Qual a ideia por trás do rebase? Ele pega cada um dos seus commits da sua branch atual e os refaz em cima do final da branch desejada. Os conflitos são resolvidos commit a commit (um dos motivos que rebase causa a dor de cabeça em desenvolvedores é este). Abaixo temos uma representação visual, sendo sua funcionalidade os commits amarelos, e os novos commits da master sendo os verdes.

Como se realiza o rebase? Primeiro iremos para a branch onde quer se alterar a base, e depois indicamos que queremos fazer o rebase para o destino.

git checkout <branch que quer alterar a base>
git rebase origin/master

Isso irá fazer o rebase da sua branch local para a branch desejada. Bastante cuidado nessa parte pois a branch de origem ainda está da forma anterior ao rebase ou seja caso exista duas pessoas trabalhando na mesma branch, problemas poderão ocorrer caso o outro developer faça mudanças na branch de origem, pois é necessário utilizar um force push da sua branch para aplicar as mudanças atuais do rebase. O motivo do problema de duas pessoas trabalharem na branch que receberá o force push será por que o histórico de commits do git mudará fazendo assim que mudanças na origin que não foram consideradas serão apagadas do histórico da branch, para fazer a verificação que tudo está tranquilo antes de realizar o force push basta realizar um:

// Fazer download das mudanças no repositório remoto
git fetch// Verificar se houve commits novos no remoto que não estão //refletidos em seu repositório local.
git log origin<branch>

Não façam um git pull ao invés de git fetch, lembram que eu falei que o git pull aplica as mudanças automaticamente, pois então fazer o git pull vai fazer com que você fique com duas versões da sua branch com um merge de ambas. Vendo que está tudo tranquilo basta dar um git push origin <branch desejada>-f

Após o rebase feito poderá realizar um merge normalmente que resultará visualmente na imagem abaixo:

Rebase feito com a master e mergeado.

Isso é mais legível do que merge hell com multiplos merges sendo feitos por multiplas frentes diferentes. Mas vamos concordar que não é a melhor forma de visualização além do que parece que realizamos todos os commits dentro da master que não é algo que queremos. Queremos ter uma separação de linha do tempo com funcionalidades introduzidas a medida que esse tempo passa. Tem como fazer isso, me pergunta? Claro que tem 🚀

Rebase + merge sem fast-forward

Merge é um comando que é fast-forward e isso significa que não é gerado um commit de merge da sua branch caso não haja mudanças da branch destino em relação a branch atual que é literalmente o que o rebase faz, move a base da branch atual para o fim da base de destino, o que resulta na imagem de cima. Então como ficaria o código para realizar isso:

git checkout master
git merge --no-ff <sua branch>

O no fast-forward força a criação de um commit de merge, como mostrado abaixo:

Rebase + merge sem fast-forward.

Os pontos vermelhos são os commits de merge gerados. Utilizando essa forma de junção de branches forçamos uma visão legível do histórico do git com as funcionalidades separadas de acordo com o tempo. Temos um exemplo abaixo visual de diferenciação de um histórico

Apenas merge vs rebase + merge no fast-forward

Observações sobre rebase + merge

Rebase não só garante uma visibilidade melhor da evolução do seu código como distribui as dores de cabeça de resolução de conflito para todo o time. Apenas lembre-se de que para garantir isso é sempre bom ter um ambiente de versionamento bem definido e que os rebases sejam feitos frequentementes para evitar conflitos, quanto maior tempo sem fazer o rebase com a branch de destino maior a chance de conflitios 😮

Comandos Auxiliares

Stash & Pop

Ferramenta de stash salva o estado atual dos arquivos modificados. Permite que o usuário consiga "salvar" suas mudanças sem necessidade de realizar o processo de seleção de arquivos e commit, o que salva bastante tempo e evita que usuários façam commits com pressa. Outra vantagem do stash é que é possível utilizar o mesmo em outra vertical que não a mesma que realizou o seu comando. Basicamente a vantagem do stash é manter o ambiente de trabalho dentro do git limpo de uma forma rápida

// Adiciona todas as mudanças atuais ao topo da pilha de stash
git stash// Aplica e deleta o stash que está no topo da pilha de stash
git stash pop// Apenas aplica o stash que está no topo da pilha.
git stash apply// Listagem de todos os stashes existentes em seu repositório local.
git stash list// Faz o pop de do segundo item da pilha. Por definição se não //especificado irá pegar o item stash@{0} que é o primeiro da pilha.
git stash pop stash@{1}

Obs: Git stash é um comando que salva localmente, ou seja não é possível utiliza-lo e tentar acessar de outro computador. Confira mais sobre git stash.

Cherry-pick

É um dos melhores comandos que alguns usuários de git nem conhecem. Muito útil quando se quer pegar um commit de uma outra branch sem ter que fazer um rebase, fazer um merge da branch base na sua ou esperar que o outro desenvolvedor faça merge com a branch base.

Como funciona? É bem simples na real, o cherry-pick pega o commit desejado (vamos imaginar que é um bugfix importante) e ele replica o commit na sua branch atual sem mais nem menos. Entretanto, assim como qualquer comando do git temos que ter cuidado pois nem sempre devemos usa-lo

// Achar o commit que quer fazer o cherry-pick
git log// Na branch que quer aplicar o cherry-pick
git cherry-pick <SHA do commit desejado>

Obs: Mais informações do git cherry-pick

Outros

Padrões de Commit

Padrões de commit são muito importantes para garantir a legibilidade da história do projeto e que funcionalidades estão sendo aplicadas em um estado do repositório. Algumas sugestões para melhorar a legibilidade dos seus commits:

  1. Separar o titulo do corpo do commit com uma linha em branco — Idealmente, não devemos fazer a inclusão de um corpo de texto do commit, commits são algo pequeno e resumido do que foi adicionado no mesmo. Entretanto surgem casos onde é necessário fazer a inclusão de uma explicação mais detalhada do motivo do commit. A separação com uma linha em branco deixa mais legível do que um texto gigante no titulo do commit.
  2. Limitar o titulo do commit para 50 caracteres — Isso não é uma regra absoluta, mas caso esteja passando de 50 já podemos começar a pensar em reescrever o commit em algo mais resumido. A plataforma GitHub faz um aviso quando o commit passa de 50 caracteres e trunca caso passe de 72.
  3. Capitalização da primeira letra do commit — Sempre deixe capitalizada a primeira letra do commit, certamente o faz mais legível.
  4. Não termine o título do commit com um . — Espaço é precioso quando se precisa manter o título resumido em 50 caracteres.
  5. Utilize ingles para fazer seus commits — Assim como em programação foi definido inglês a linguagem padrão, como o nosso repositório está diretamente relacionado ao nosso código e não sabemos quem um dia poderá mexer no código ou entrar em nosso time, melhor já nos precavermos e deixar na linguagem padrão.
  6. Use o imperativo no titulo do commit —Normalmente quando aplicamos commits tendemos a escrever na forma do passado como "Fixed X", "Added Y", "Refactored W", por convensão esse modo de título de commit é incorreto. Esse é um dos mais difíceis de se acostumar de usar, mas basicamente é fazer a leitura do commit por exemplo, "Refactor subsystem for new login functionality" da seguinte forma:

// Como devemos fazer a leitura do commit
If applied, this commit will refactor subsystem for new login functionality// Como é feito da outra maneira
If applied, this commit will refactored subsystem for new login functionality

Mas por que fazer a leitura do commit dessa forma? Pois tratamos um commit como um estado da aplicação então quando estamos aplicando um commit estamos basicamente dizendo que se esse commit for aplicado iremos refatorar (…).

Pull requests

Pull requests é uma ferramenta para garantir um controle visual do código que entra e sai da sua branch base, garantindo que todos os desenvolvedores se envolvam o com o projeto como um todo e garante que a qualidade do código permaneça boa a medida que o tempo passa. Além disso é possível anexar outras ferramentas que analisam o pull request garantindo a qualidade da feature que vai entrar dentro da branch base, tal como CI (Continous Integration) que garantem que o código novo não quebre o que está em dev, lints que garantem que o código está dentro dos padrões do lint estabelecido, assim como outras features…

Desenvolvedores devem tomar proveito em analise de pull requests de seus colegas para não só agir como keepseeker 🤓 do produto mas também como uma oportunidade de melhorar seus conhecimentos em geral. Por experiência pessoal posso afirmar que aprendi/descobri muita coisa realizando esse processo em PR de colegas de trabalho.

Fluxo de uma funcionalidade junto com PR

Ferramentas

Esse artigo descreveu como ocorre as funcionalidades do git em linhas de comandos de uma forma sucinta (ou seja tem mais coisa a se explorar, então por favor vão 🤓 👉 📖, o mundo de tecnologia é um interminável aprendizado), entretanto tem formas automatizadas que fazem esses processos descritos por baixo do pano com uma plataforma visual para auxiliar o processo do Git entretanto não remove a importância de aprender pelo terminal primeiro para entender como o processo ocorre. Segue uma lista de ferramentas que eu utilizei no decorrer da minha vida universitária e profissional e recomendo darem uma olhada:

Sourcetree

GitKraken

Git Tower

Esses foram os clientes que eu utilizei (atualmente utilizo o Git Tower), entretanto existem outros clientes fora desse que podem adequar melhor a suas necessidades. 🚀

Referências

Reference

Quick reference guides: GitHub Cheat Sheet | Visual Git Cheat Sheet

git-scm.com

How to Write a Git Commit Message

If you browse the log of any random Git repository, you will probably find its commit messages are more or less a mess…

chris.beams.io

Git Complete Full Course: The Definitive Guide to Git

Git Complete This course is designed to be a comprehensive approach to Git, which means no prior knowledge or…

www.udemy.com

Muito obrigado pela leitura 🚀

Posts relacionados

Vamos juntos construir seu próximo case de sucesso?

Obrigado por entrar em contato!
Oops! Erro ao enviar formulário...

Conheça nossos cases

Ver mais trabalhos
Vamos conversar?

Seja para desenvolver um ecommerce, um app para sua empresa ou uma plataforma para ajudar seu negócio a inovar, estamos disponíveis para te ajudar.

Letter image
contato@kobe.io
+55 51 3737 0203
Obrigado por entrar em contato!
Oops! Something went wrong while submitting the form.