Aqui mostrarei os principais comandos e funções do Git através do Gitkraken. Focarei em como resolver problemas específicos que costumamos encontrar quando trabalhando com a Unity em conjunto com o Git.

Material auxiliar da própria Dev-U sobre Git: link

Criando um Repositório

Para criar um repositório, primeiro entre no GitHub com sua conta.

Github Login Page

Após entrar com sua conta, na tela inicial serão exibidos todos os seus repositórios. Junto a eles, um botão para criar um novo repositório.

Github First Page

A tela para criação de um novo repositório será como a seguinte:

Github New Repository

Principais Branches

Em nossos projetos, costumamos seguir algumas convenções de nomes para as Branches, de modo a manter a organização e para todos os membros consigam interagir em todos repositórios.

Geralmente, um projeto inicia-se com 3 Branches:

  1. Develop
  2. Pre-Release
  3. Release

Logo após a criação do repositório, só existirá a branch Master, sendo possível criar novas branches pelo menu onde é exibido os nomes das branches

Github Repository Page

Github Create Branch

Github Branches Created

Após criadas as branches, como mostrado na imagem acima, é necessário setar a branch Develop como a nossa nova branch principal de desenvolvimento, e também é necessário deletar a branch Master.

Primeiro, para setar a branch Develop como a nova padrão, entre nas Configurações do repositório, em Settings, e depois no menu lateral Branches. Na tela que aparecerá será possível alterar a branch principal do repositório.

Github Default Branch

Para deletar a branch Master, basta entrar em Code/branches e deletar a branch Master.

Github Delete Master

Definindo regras nas Branches

Caso o projeto em que deseja trabalhar tenha mais de 1 contribuidor, é interessante impedir que os seus usuários enviem commits diretamente para as 3 branches principais, precisando passarem pela avaliação de um Pull-Request. Para isso, é necessário configurar algumas regras para as branches.

Novamente no menu Settings/Branches, desta vez utilizaremos a opção Add Rule.

Github Add Rule

No caso, colocaremos a regra de que será necessário pelo menos 1 review através do Pull-Request para que o código seja aprovado para a Branch. Faça o procedimento abaixo para as branches Develop, Pre-Release e Release.

Github Add Rule2

Convidando usuários para o Repositório

Para adicionar um usuário do GitHub como colaborador, você deverá entrar no menu Settings/Collaborators. Então é só pesquisar pelo usuário.

Github Add Collaborator

Após adicionado, o usuário cadastrado receberá uma notificação de convite para contribuir ao repositório. Caso deseje, o link de convite gerado por ser copiado na mesma tela, para que seja enviado manualmente para o usuário.

Github Add Collaborator Link

Clonando um Projeto

Para clonar um projeto pelo Gitkraken, você deve seguir as seguintes opções:

GitKraken Clone

O mesmo pode ser obtido pelo comando:

git clone https://github.com/dev-u/emburradinho_prototipo.git

Abrindo um Projeto já clonado

Para abrir um projeto já clonado pelo GitKraken,

GitKraken Open

Criando uma nova Branch

Pelo GitKraken:

GitKraken Branch

Pela linha de comando

git checkout -b nome_da_branch

Boas Práticas e Padrões 1

O primeiro ponto a levar em consideração quando se fala de padrões é a nomenclatura. O padrão incorporado pela Dev-U é o padrão usando em empresas.

  • feature/nome_da_feature –> Nome de branches para novas features desenvolvidas;
  • imp/nome_da_melhoria –> IMP vem de improvement, onde essa branch seria focado na melhoria de alguma feature existente;
  • fix/nome_do_fix –> Branches dedicadas à correção de BUGs;

Outro ponto importante, fugindo de padrões e indo mais para o que é certo, é de onde uma branch deve ser criada.

Resumidamente, todas as novas branches deverão ser criadas a partir da branch DEVELOP.

Enviando Commits

Quando algum arquivo for criado\removido ou modificado na pasta do projeto, o Gitkraken manterá uma notificação de arquivos modificados.

GitKraken Changes

Ao clicar em View Changes, será aberto um menu para seleção do quais itens deverão ir de Unstaged para Staged:

GitKraken Staged

  • No menu lateral de Commit, em Unstaged são listados os arquivos que foram modificados, desde o último Commit;
  • Em Staged serão colocados os arquivos que entrarão no próximo Commit.

É importante tomar cuidado para que apenas os arquivos que realmente farão parte do commit entrem no commit. Não só os arquivos, mas também devem entrar no próximo commit SOMENTE as linhas que fazendo sentido entrar no Commit.

A tela de commit com a visualização das linhas pode ser visto na imagem abaixo.

Como fazer o mesmo procedimento pela linha de comando

Para visualizar quais arquivos foram modificados desde o último commit, poderá ser utilizada a ferramenta TIG:

tig

Bash TIG

Caso existam dúvidas sobre como se movimentar no ambiente VIM utilizado pelo TIG, siga este link.

GitKraken Branch

Vistas as alterações, pela própria ferramenta TIG é possível selecionar e adicionar linhas e\ou arquivos de UNSTAGED para STAGED para o próximo commit.

Uma outra maneira mais simples de visualizar os arquivos modificados desde o último commit é pelo commando git status:

git status

Uma maneira mais fácil de adicionar arquivos separadamente é pelo commando git add:

git add caminho/do/arquivo/nomedoarquivo.formato

Para enviar o commit:

git commit -m "NomeDoCommit"

Um exemplo prático de fluxo de um commit pela linha de comando:

Bash Commit

Boas Práticas e Padrões 2

Para os commits, costumamos colocar uma TAG padrão no início da mensagem de commit, estamos utilizando os seguintes padrões:

  • [ADD] - Para commits que estão adicionando arquivos e\ou funcionalidades;
  • [RMV] - Para commits que estão apenas removendo arquivos e\ou funcionalidades;
  • [IMP] - Para commits que estão implementando melhorias em uma funcionalidade já existente;
  • [REF] - Para commits que estão apenas refatorando códigos existentes, isto é, renomeando ou movendo arquivos\códigos;
  • [WIP] - Para commits que ainda estão em desenvolvimento, ou seja, estão incompletos.

Exemplos de commits:

  • [ADD] Adicionada uma nova cena;
  • [ADD] Adicionada a funcionalidade do player pular;
  • [RMV] Removidas algumas variáveis que não estavam sendo utilizadas;
  • [IMP] Otimizado o script que checava a colisão entre o player e os inimigos;
  • [IMP] Foi diminuído o número de variáveis responsáveis pelo tratamento de erros no sistema de importação de arquivos;
  • [REF] Script de movimentação do player foi movido para um novo arquivo dedicado a isso;
  • [WIP] Avanço na implementação do sistema procedural de plataformas.

  • Voltar ao Início

Amend - Alterando seu último commit

Em poucas palavras, amend é uma forma de alterar o último commit realizado em uma branch de um repositório.

Situação hipotética:

  • Você, usuário, acabou de commitar uma alteração trabalhando no script de gerenciamento de plataformas;
  • Após algum tempo de reflexão, você percebe que faltou a adição de uma linha de código para o commit em questão;
  • No lugar de criar um novo commit para incluir a adição da nova linha, você pode alterá-lo adicionando a nova linha e, até mesmo, alterando a mensagem de commit.

Como criar um Ammend:

Pelo Gitkraken

Gitkraken Ammend

Para enviar o commit forçando a reconstrução dos commits remotos.

Gitkraken Force Push

Pela linha de comando:

git add .
git commit --ammend

Para enviar o commit forçando a reconstrução dos commits remotos.

git push origin nomeDaBranch -f 

Duas observações sobre amend:

  1. Caso NÃO tenha sido dado PUSH no commit anterior, o amend não trará nenhuma consequência negativa;
  2. Caso tenha sido dado PUSH no commit anterior, o amend fará com que seja necessário forçar uma reconstrução dos commits remotos.
    • Por que isso é um problema? Porque, caso tenha mais alguém trabalhando na mesma branch em que o amend foi realizado, caso essa pessoa já tenha dado um Pull e baixado para sua branch local as alterações que você está modificando, será necessário que essa pessoa reconstrua os commits locais dela.

Stash - Guardando alterações para mais tarde

A Stash é uma pilha usada para guardar alterações feitas em um repositório local.

Suponha a seguinte situação:

  • Você está trabalhando na criação da I.A. dos inimigos de seu jogo;
  • Algum parceiro de equipe te pede para ajudá-lo em uma funcionalidade que ele está trabalhando;
  • Você interrompe seu trabalho para ajudá-lo, mas precisa guardar suas alterações em algum lugar, antes de mudar para a branch de seu colega;
  • Como fazer isso?

Uma alternativa é commitar todas suas alterações para um commit temporário, para então mudar para a branch de seu amigo.

Mas uma alternativa melhor é a utilização da Stash para guardar seu atual trabalho.

A Stash funciona da seguinte maneira:

  1. Você joga na Stash suas modificações atuais na branch a qual está trabalho;
  2. A Stash cuida para criar um ‘commit’ temporário nela, que pode ser acessado mais tarde;
  3. Quando quiser voltar ao trabalho de onde parou, basta pedir para a Stash as suas modificações que foram salvas, o Git se encarregará de atualizar seu repositório local com as alterações salvas anteriormente.

Notas:

  • A Stash consegue salvar arquivos inteiros inseridos ou removidos durante o trabalho;
  • A Stash também consegue salvar apenas linhas adicionadas ou removidas durante o trabalho;
  • Apesar de ser uma pilha, você não necessariamente terá acesso apenas ao último elemento adicionado na Stash.

Pelo Gitkraken

Primeiro, tendo alterações para serem commitadas, basta clicar no botão Stash, no topo do programa.

Gitkraken Stash Button

Após isso, será adicionado um novo elemento no submenu Stash, no menu lateral esquerdo. Clicando-se na stash criada serão mostradas as alterações no menu lateral direito do programa.

Gitkraken Stash

Para aplicar as alterações da Stash novamente no código, basta ir na opção Apply ou na opção POP.

  • A opção Apply aplicará as alterações da Stash no seu trabalho atual, mantendo a Stash intacta;
  • A opção POP aplicará as alterações da Stash no seu trabalho atual, porém removendo o item da Stash.

Gitkraken Stash Popup

Pela linha de Comando

Pela linha de comando, apenas 3 comandos são necessários:

  • git stash - Guardará o trabalho atual na Stash
git stash 
  • git stash pop - Recuperará o trabalho a partir do último item da Stash, removendo-o da Stash
git stash pop
  • git stash apply - Recuperará o trabalho a partir do último item da Stash, mantendo-o na Stash
git stash apply

Bash Stash

Para trabalhar com itens da Stash mais antigos, é necessário mais um parâmetro nos dois comandos anteriores.

  • git stash list - Lista os itens salvos na Stash
git stash list
  • git stash pop\apply stash@{indice} - Aplica o item passado pelo parâmetro indice da Stash no trabalho atual
git stash pop stash@{indice}
git stash apply stash@{indice}

Rebase - Alterando Commits antigos

O Rebase é utilizado em muitas situações. No momento me limitarei a usá-lo com o intuito de alterar um ou mais commits antigos.

Pela linha de comando:

Primeiro, deve-se utilizar a ferramenta TIG para procurar até qual commit o rebase atuará.

tig 

Bash TIG

No menu do tig, navegue até o commit anterior ao commit que se deseja modificar. No caso da imagem acima, queremos modificar a mensagem do commit [WIP], então entramos no commit [ADD] Gitkraken Empty Post.

Estando no commit desejado, devemos copiar a HASH do commit, que é o valor hexadecimal que representa o commit no servidor remoto.

Com a hash copiada, damos o comando rebase, passando como parâmetro a hash copiada e o parâmetro -i, para que o rebase seja feito iterativamente.

git rebase -i 85cfe54448545ef65072dd5f8a2f5e3958cc00e1

Com isso, será aberta uma tela com instruções sobre como fazer um rebase.

Bash Rebase

Como queremos apenas renomear o commit [WIP], utilizaremos a palavra reword na frente do mesmo, seguido de CTRL + X para continuar o processo.

Em seguida, uma tela para modificar o texto do commit especificado se abrirá, bastando modificar a mensagem de commit, como na imagem abaixo.

Bash Rebase Reword

No final, é necessário realizar um pull forçado pelo parâmetro -f, lembrando que isso reconstruirá a sequência dos commits remotos, o que pode quebrar o trabalho de outra pessoa que esteja atuando na mesma branch:

git push origin nomeDaBranch -f 

Criando Pull-Requests

Quando se está trabalhando em uma Branch separada, após o trabalho ter terminado, é necessário juntar o código feito com o código da Branch de desenvolvimento que o resto da equipe está utilizando. Para isso, utilizamos os Pull-Requests.

Pelo Gitkraken

Basta utilizar o botão + no submenu Pull-Requests

GitKraken Pull-Request

Pelo site do Github

Pelo site também é bem simples, bastando ir no menu Pull-Request e clicar no botão New Pull-Request:

Github Pull-Request

Github Pull-Request

Note, nessa última imagem, que existe a mensagem “Can’t Automatically Merge”. Isso significa que existe algum conflito impossibilitando o merge do Pull-Request.

Para tratar essa situação, veja o tópico “Tratando Conflitos”.

Boas Práticas e Padrões 3

Na imagem de criação de Pull-Requests do tópico anterior, pode ser visto alguns campos a serem preenchidos.

GitKraken Pull-Request

Esses campos são:

  • Title - O título do Pull-Request. Aqui você colocará uma mensagem curta, resumindo o que o Pull-Request se propõe;
  • Description - Caso necessário, uma descrição detalhada do problema a ser resolvido pelo Pull-Request criado. E mais importante, explicando como esse Pull-Request deve ser testado, quais os passos para fazê-lo funcionar.
  • Reviewers - Caso necessário, marque os amiguinhos para que eles recebam notificações para testar seu Pull-Request;
  • Assignees - Neste campo devem ser marcadas as pessoas que trabalharam no Pull-Request;
  • Labels - Este campo varia de projeto para projeto. No jogo em que estou trabalhando no momento, criamos labels para diferenciar o assunto de cada Issue e de cada Pull-Request.

Tratando Conflitos - Separando crianças de adultos

Conflitos ocorrem quando se está tentando aplicar uma alteração de código em outro código também já alterado. Basicamente um conflito ocorre quando o mesmo trecho de código foi alterado por 2 ou mais pessoas e as duas alterações estão sendo combinadas.

Exemplos de situações:

  • Ao tentar aplicar o código da Stash em cima de um código seu;
  • Ao tentar dar Merge de uma branch em cima de outra branch.

Sobre este último exemplo, explicarei com uma situação hipotética:

  1. Sua equipe está trabalhando com a branch Develop como branch de desenvolvimento;
  2. Você cria uma nova branch chamada fix/player_jump, a partir da Develop, com o intuito de corrigir um BUG no pulo do player;
  3. Um outro membro da equipe cria uma branch chamada feature/player_score, a partir da Develop, para implementar o sistema de Score do player;
  4. Você termina de implementar a correção, fazendo um Pull-Request e dando Merge do mesmo na branch Develop;
    • Neste momento, a branch feature/player_score está ATRÁS da Develop, pois os Commits recebidos por ela da branch fix/player_jump a colocaram mais à frente.
  5. O outro membro da equipe, enquanto implementava o sistema de Score, percebe o BUG no pulo do player e resolve corrigí-lo com um Commit;
  6. Ao tentar fazer um Pull-Request, o outro membro da equipe receberá um aviso de conflito, pois o commit de correção do pulo do player está em conflito com o código já feito por você, na branch fix/player_jump.

O que fazer nessa situação?

Tratar conflitos nada mais é, neste caso, do que trazer as novas alterações da Develop para a branch feature/player_score, escolhendo qual código de correção do pulo do player será usado, o já existente na Develop ou o novo, fornecido pela feature/player_score.

Tratando conflitos pelo site do Github

Na situação demonstrada no tópico anterior, onde surgiram conflitos a serem resolvidos, irei mostrar como tratá-los pelo site do Github.

Na tela do Pull-Request criado no github, descendo um pouco, será possível visualizar quais arquivos estão conflitantes, seguido do botão Resolve Conflicts.

Github Pull-Request

Ao clicar no botão Resolve Conflicts, será aberta uma nova tela mostrando o código em questão.

Github Pull-Request

Na imagem acima, existem dois pontos no código que foram criados pelo github para separar o conflito em duas partes: o código da Develop e o código de onde se deseja dar merge.

  • «««< feature/vertical_platform - Esta seção mostra o código da Branch feature/vertical_platform;
  • »»»> develop - Esta seção mostra o código da Branch Develop.

Quem for tratar o conflito deve, manualmente, editar o código pelo próprio Github, afim de escolher qual será o trecho de código utilizado.

O mesmo deverá ser feito para todos os arquivos conflitantes do Pull-Request.

Tratando conflitos pelo Gitkraken

No Gitkraken é possível tratar conflitos de uma maneira mais eficiente do que a vista no site do Github.

No programa, o que será feito é aplicar os commits da branch Develop na branch em que estamos trabalhando. Para cada Commit aplicado, teremos que tratar os possíveis conflitos.

Primeiro, deve-se entrar na Branch a qual se está trabalhando, clicar com o botão direito na branch REMOTA Develop e selecionar a opção Rebase.

Gitkraken Pull-Request

Feito isso, caso não hajam conflitos, você não precisa continuar neste tópico :P. Agora, havendo conflitos, o próprio Gitkraken trará um aviso, no menu lateral esquerdo.

Gitkraken Pull-Request

Ao clicar no botão View Conflict, serão mostrados os arquivos com conflitos. Você terá que clicar em cada um deles e resolver seus conflitos.

Gitkraken Pull-Request

Na tela de resolução de conflitos, a visualização será repartida em 3 seções.

  • Lado esquerdo - É mostrado o código da branch Develop;
  • Lado direito - É mostrado o código da branch que se está trabalhando;
  • Parte Inferior - É mostrado o código resultante da combinação escolhida dos códigos das duas branches.

Assim como no tratamento de conflitos pelo site do Github, será necessário escolher quais partes do código deverão entrar no código final, escolhendo entre as telas dos lados direito e esquerdo. Após terminar, basta clicar no botão Save.

Gitkraken Pull-Request

Após salvas as alterações, você será redirecionado para a tela anterior, onde eram mostrados os arquivos com conflito. Nesta tela, basta clicar no botão Continue Rebase, para que seja continuado o tratamento de conflitos.

Gitkraken Pull-Request

Provavelmente será necessário repetir os passos anteriores para cada vez que forem identificados novos conflitos. Sempre clicando em Continue Rebase.

Após terminar de resolver todos os conflitos, será necessário dar um novo Push, forçando o envio de alterações para o servidor remoto, pois o histórico de Commits foi reescrito, para a Branch em que se está trabalhando.

Gitkraken Pull-Request

Tratando conflitos pelo Visual Studio

O Visual Studio tem uma ferramenta interna para tratar conflitos Git. Deixarei um link de um vídeo muito bom ensinando como isso é feito.

Handling Merge Conflicts with Visual Studio and SourceTree

Unity Smart Merge

Quando estamos tratando conflitos, faz sentido os arquivos conflitantes serem códigos. Mas o que acontece quando existe conflitos em outros arquivos, como os arquivos .unity e .prefab????

A dica é: TENTE EVITAR CONFLITOS NESTES ARQUIVOS.

Como fazer isso? Para evitar conflito em arquivos .unity, basta SEMPRE criar uma nova cena para trabalhar em alguma branch nova, pois assim nunca duas pessoas trabalharão no mesmo arquivo .unity.

Para evitar conflitos nos arquivos .prefab, a dica é… converse com seu grupo sempre, e evite ter mais de uma pessoa trabalhando nos mesmos prefabs.

Mas e se já existirem conflitos, como tratá-los?

Ahhh, jovem. A maneira mais simples neste caso é Recriar o que estiver fazendo do ZERO, tentando evitar os conflitos. Mas, caso esta não seja uma opção, existe uma ferramenta chamada Smart Merge.

Smart Merge é um Merge Tool especial para Sistemas de Controle de Versão que estejam trabalhando com a Unity, o que ele faz é Magicamente tratar conflitos de arquivos .prefab e .unity.

Me limitarei a deixar um link sobre o assunto. Caso algum dia seja necessário, farei um novo tópico sobre ele: Smart Merge