TutoriaGit/readme.md
2025-03-18 16:23:28 -03:00

14 KiB

🎯 Objetivo

Este repositório é um guia de referência para aprender Git e GitLab, desde os primeiros passos até tópicos avançados. Ideal para estudantes, desenvolvedores iniciantes ou quem deseja reforçar conceitos de versionamento de código em projetos individuais ou em equipe.

Introdução ao git


O git é um sistema de controle de versão distribuído amplamente utilizado para rastrear mudanças em arquivos de código-fonte durante o desenvolvimento de software.

  • O Git permite que múltiplos desenvolvedores trabalhem juntos em um projeto, fornecendo ferramentas para colaborar sem sobrescrever o trabalho uns dos outros.
  • Ele armazena o histórico de versões em um repositório local, permitindo que os usuários revertam para versões anteriores dos arquivos.
  • Os principais conceitos do git incluem 'commit', 'branch', 'merge', e 'pull request'.

Configuração inicial do git


Antes de começar a usar o git, é necessário configurar seu ambiente de usuário.

  • Instalação do git: Pode ser feita através de gerenciadores de pacotes ou baixando o instalador do site oficial.
  • Configuração de usuário: Defina seu nome de usuário e endereço de email com os comandos git config --global user.name "Seu Nome" e git config --global user.email "seuemail@exemplo.com".
  • Geração de chave SSH: Para conexões seguras com repositórios remotos, é recomendável gerar uma chave SSH.

Comandos básicos do git


O git possui uma série de comandos essenciais para gerenciar repositórios e controlar versões.

  • git init: Inicializa um novo repositório Git local.
  • git clone [URL]: Clona um repositório remoto para o local.
  • git add [arquivo]: Adiciona arquivos à área de preparação (staging area).
  • git commit -m "mensagem": Grava as mudanças na área de preparação em um novo commit.
  • git status: Mostra o status atual do repositório, incluindo arquivos modificados ou adicionados.

Trabalhando com branches no git


Branches são fundamentais no Git para permitir o desenvolvimento paralelo de recursos ou correções.

  • git branch [nome]: Cria uma nova branch.
  • git checkout [nome]: Muda para a branch especificada.
  • git merge [nome]: Mescla as mudanças da branch especificada na branch atual.
  • Estratégia de branches: É comum usar uma branch 'master' ou 'main' para o código estável e criar branches separadas para desenvolvimento de recursos ou correções.

Gerenciamento de conflitos no git


Durante o merge de branches, podem ocorrer conflitos quando as mesmas linhas de código são alteradas de maneiras diferentes.

  • O Git sinaliza os arquivos com conflitos e o desenvolvedor precisa resolver manualmente.
  • A resolução de conflitos envolve editar os arquivos para escolher as alterações desejadas e, em seguida, fazer um novo commit.
  • Ferramentas de merge podem ajudar na visualização e resolução de conflitos.

Git rebase para histórico linear


O comando git rebase é usado para reescrever o histórico de commits, criando um histórico linear mais limpo.

  • O rebase move os commits de uma branch para o topo da outra, evitando merges desnecessários.
  • É útil para atualizar uma branch de recurso com as últimas alterações da branch principal.
  • Deve ser usado com cautela, pois altera o histórico de commits.

Trabalhando com repositórios remotos


Repositórios remotos são versões de seu repositório hospedadas em um servidor, como GitHub ou GitLab.

  • git remote add [nome] [URL]: Adiciona um novo repositório remoto.
  • git push [remoto] [branch]: Envia commits da branch local para a remota.
  • git pull [remoto] [branch]: Atualiza a branch local com as últimas alterações da remota.
  • É importante manter o repositório local sincronizado com o remoto para evitar conflitos.

Git stash para salvar mudanças temporárias


O comando git stash é usado para salvar temporariamente alterações não finalizadas, permitindo trocar de branch sem commitar.

  • git stash push: Salva as mudanças atuais em uma pilha temporária.
  • git stash list: Lista todas as entradas na pilha de stashes.
  • git stash pop: Aplica a última entrada da pilha e a remove.
  • Útil para interromper rapidamente o trabalho atual e mudar para outra tarefa.

Estratégias de workflow no git


Existem várias estratégias de workflow no git, como git flow e forking forkflow, que organizam o processo de desenvolvimento.

  • git flow: Define um modelo estrito com branches específicas para desenvolvimento, recursos, lançamentos e correções.
  • forking workflow: Cada desenvolvedor tem seu próprio repositório, e as contribuições são feitas através de pull requests.
  • Escolher uma estratégia de workflow depende das necessidades da equipe e do projeto.

Git cherry-pick para aplicar commits específicos


O comando git cherry-pick permite aplicar as mudanças de commits específicos de uma branch para outra.

  • Útil para trazer correções ou recursos específicos para outra branch sem fazer um merge completo.
  • Use git cherry-pick [commit] para aplicar as mudanças do commit especificado.
  • Pode causar conflitos se as mudanças não se aplicarem limpa na branch de destino.

Reflog do git para recuperação de dados


O reflog do Git registra as atualizações feitas nas referências dos repositórios, como branches e tags, facilitando a recuperação de dados perdidos.

  • Use git reflog para exibir o histórico de alterações nas referências.
  • Cada entrada mostra a ação realizada (como um commit ou um checkout) e o hash do commit.
  • Para recuperar um estado anterior, use git reset --hard [reflog entry].
  • O reflog é uma ferramenta de segurança, pois permite reverter ações acidentais, como redefinições ou rebase.

Git clean para remover arquivos não rastreados


O comando git clean é usado para remover arquivos não rastreados do diretório de trabalho, ajudando a manter o repositório limpo.

  • Use git clean -n para fazer uma simulação e mostrar quais arquivos seriam removidos.
  • git clean -f remove os arquivos não rastreados.
  • git clean -fd remove também os diretórios não rastreados.
  • Use com cautela, pois essa ação é irreversível e pode resultar na perda de dados não rastreados.

Tags no git para versões de lançamento


As tags no Git são usadas para marcar pontos específicos no histórico do repositório, como versões de lançamento.

  • Use git tag [nome] para criar uma tag leve apontando para o commit atual.
  • Para uma tag anotada, que inclui informações adicionais como autor e data, use git tag -a [nome] -m "mensagem".
  • As tags podem ser enviadas para repositórios remotos com git push --tags.
  • Elas são úteis para marcar versões estáveis do software ou pontos de referência importantes no desenvolvimento.

Git revert para desfazer commits


O comando git revert cria um novo commit que desfaz as mudanças de um commit anterior, preservando o histórico.

  • Use git revert [commit] para gerar um commit que inverte as alterações do commit especificado.
  • Diferente do git reset, o revert não altera o histórico existente, tornando-o seguro para repositórios compartilhados.
  • Pode ser usado para desfazer alterações indesejadas ou erros sem reescrever o histórico de commits.

Git ignore para excluir arquivos do controle de versão


O arquivo .gitignore é usado para especificar arquivos ou diretórios que devem ser ignorados pelo Git, evitando que sejam rastreados.

  • Crie um arquivo chamado .gitignore no diretório raiz do repositório.
  • Adicione padrões de arquivo ou diretório que devem ser ignorados (por exemplo, *.log, build/).
  • Arquivos ignorados não aparecerão em git status e não serão adicionados ao repositório.
  • Útil para excluir arquivos temporários, de compilação ou sensíveis do controle de versão.

Entendendo a Relação entre Repositório Fonte e Cópia Sincronizada (fork)

Já imaginou como manter seu fork atualizado com as mudanças do projeto original? A chave está na configuração inteligente dos repositórios remotos!

!2025-03-18_15h22_34.png

🔄 Os Três Pilares do Versionamento

1. Repositório Fonte (Primário)

  • Função: Base oficial do projeto, geralmente mantido pelo autor original
  • Identificação no Git: Nomeado como upstream (referência à origem do fluxo)
  • Característica: Somente leitura para contribuidores externos

2. Cópia Pessoal (Derivado)

  • Origem: Criado através do botão "Fork" na interface do GitLab/GitHub
  • Identificação no Git: Chamado de origin após clonagem
  • Vantagem: Seu espaço seguro para experimentações

3. Ambiente Local

  • Finalidade: Máquina física onde o desenvolvimento acontece
  • Gestão: Conexão simultânea com origin e upstream

⚙️ Configuração Estratégica de Remotos

  1. Clonagem do Derivado

Obtenha sua cópia pessoal:

git clone git@gitlab.com:seu_usuario/cblc.git
cd cblc
  1. Vinculação com o fonte
git remote add upstream https://gitlab.com/blau_araujo/cblc.git
  1. Verificação de Conexões
git remote -v
# origin    git@gitlab.com:seu_usuario/cblc.git (push/fetch)
# upstream  https://gitlab.com/blau_araujo/cblc.git (push/fetch)

💡 Por Que Esta Estrutura?

  • Sincronização Simplificada: Atualize seu fork com git fetch upstream
  • Controle de Versão: Mantenha histórico limpo entre suas alterações e as oficiais
  • Colaboração Eficiente: Envie alterações via origin sem afetar o projeto principal

Dica Pro: Use upstream para puxar atualizações e origin para enviar suas contribuições!

🔍 Fluxo de Atualização Básico

# Obter mudanças do projeto original
git fetch upstream main

# Mesclar com sua cópia local
git merge upstream/main

# Atualizar fork remoto
git push origin main

Esta estrutura garante que seu ambiente sempre reflita as mudanças mais recentes do projeto, enquanto mantém suas contribuições isoladas e organizadas.

Workflow Recomendado para acompanhar o curso

1. Sincronize o main do seu fork com o repositório do professor

Sempre que o professor atualizar o upstream/main, atualize seu fork:

git checkout main
git fetch upstream main         # Puxa as atualizações do professor
git reset --hard upstream/main  # Alinha seu main local com o upstream
git push origin main --force    # Atualiza seu fork no GitHub (origin)

2. Crie um branch para cada exercício

Nunca trabalhe diretamente no main. Para cada novo exercício:

git checkout main
git checkout -b exercicio-1  # Cria um branch a partir do main atualizado

3. Desenvolva no branch do exercício

Faça commits normalmente:

git add .
git commit -m "Resolução do exercício 1"

4. Atualize o branch do exercício com as mudanças do professor

Se o professor atualizar o upstream/main enquanto você está trabalhando:

git checkout main
git fetch upstream main
git reset --hard upstream/main
git push origin main --force

git checkout exercicio-1
git rebase main  # Atualiza seu branch com as mudanças do professor
  • Se houver conflitos, resolva-os durante o rebase.

Por que o git reset --hard upstream/main?

Quando você faz um fork de um projeto, seu repositório (origin) começa como uma cópia exata do projeto original (upstream). Com o tempo, o upstream/main (o branch principal do projeto original) pode ser atualizado com novos commits, enquanto seu fork (origin/main) pode ficar desatualizado ou acumular commits próprios.

O comando git reset --hard upstream/main serve para:

  1. Forçar seu branch local main a corresponder exatamente ao upstream/main.
  2. Descartar quaisquer commits locais ou alterações que não existam no upstream.
  3. Garantir que seu fork volte a ser um espelho perfeito do repositório original.

Quando isso é útil?

  • Você fez commits acidentais no main do seu fork (em vez de usar branches).
  • O upstream/main foi atualizado, e você quer sincronizar seu fork descartando alterações locais.
  • Você quer "limpar" o histórico do seu fork para evitar conflitos futuros.

Em resumo: desde que seus branches não estejam diretamente ligados ao main (ou você tenha backups), o git reset --hard não os afeta! 😊

5. Envie o branch para seu fork (GitHub)

git push origin exercicio-1

Fluxo Visual

           main (origin/main) → sempre igual ao upstream/main (professor)
          / 
upstream/main
          \
           exercicio-1 → seu branch de trabalho

Por que essa recomendação?

  • main limpo: Sempre reflete o estado oficial do professor.
  • Branches isolados: Cada exercício tem seu próprio histórico, sem interferir no main.
  • Atualizações seguras: O git rebase main mantém seu branch atualizado com as mudanças do professor.

Quando NÃO usar git reset --hard?

  • Se você tem commits locais que quer manter.
  • Se outros colaboradores dependem do histórico do seu fork.
  • Solução alternativa: Crie um branch novo para seus commits e sincronize o main sem perder trabalho

Dicas Importantes

  1. Nunca commite no main: Isso evitará divergências com o upstream.
  2. Use git fetch antes de trabalhar: Verifique se há atualizações do professor.
  3. Nomeie branches claramente: Ex: exercicio-1, projeto-final, etc.
  4. Apague branches antigos após a correção:
git branch -D exercicio-1             # Local
git push origin --delete exercicio-1  # Remoto

Se o Professor Pedir para Entregar o Exercício

  1. Envie o branch para seu fork (git push origin exercicio-1).
  2. Abra um Pull Request no repositório do professor (se for o processo definido por ele).
  3. Ou compartilhe o link do branch no seu fork (ex: https://github.com/seu-user/seu-fork/tree/exercicio-1).

Benefícios

  • Você mantém um histórico organizado.
  • O main do seu fork sempre estará pronto para receber novas atualizações do professor.
  • Seus exercícios ficam isolados e fáceis de gerenciar.

Esse workflow é amplamente usado em projetos open source e ambientes educacionais! 🚀