Git e Linux Básico - Primeiros Passos com Controle de Versão
O Que Você Vai Aprender
- Configurar o Git no Linux com a configuração mínima viavel
- Dominar o fluxo principal:
git init/add/commit/push - Evitar armadilhas específicas do Linux (permissões, quebras de linha, exec bit)
- Enviar para o GitHub ou GitLab via autenticação com chave SSH
Caminho Rápido (5 passos)
- Instalar:
sudo apt install git - Configurar:
git config --global user.name / user.email - Inicializar:
git initougit clone <url> - Iterar:
git status->git add->git commit -m "..." - Compartilhar:
git remote add->git push -u origin main
Ambiente Assumido
- Ubuntu / Linux baseado em Debian (22.04 ou posterior)
- bash ou zsh
- GitHub / GitLab / Git auto-hospedado via SSH
1. Instalar e Configurar
1-1. Instalar o Git
$ sudo apt update $ sudo apt install -y git $ git --version
git version 2.43.0
RHEL / Fedora: sudo dnf install git. macOS: brew install git.
1-2. Definir Configuração Global (única vez)
$ git config --global user.name "Your Name" $ git config --global user.email "you@example.com" $ git config --global init.defaultBranch main
init.defaultBranch main faz novos repositórios usarem main automaticamente (o padrão desde que o GitHub adotou em 2020).
1-3. Verificar Configuração
$ git config --list --global
--global grava em ~/.gitconfig. Para sobrescrever por repositório, execute o mesmo comando sem --global dentro do repositório (salvo em .git/config).
2. Criar ou Clonar um Repositório
2-1. Inicializar um Diretório Existente
$ cd ~/projects/myapp $ git init $ ls -la .git
O diretório está sob controle do Git assim que .git/ é criado. Normalmente você nunca precisa editá-lo diretamente.
2-2. Clonar um Remoto
# HTTPS (simples, mas requer PAT) $ git clone https://github.com/user/repo.git # SSH (recomendado depois que as chaves estiverem configuradas) $ git clone git@github.com:user/repo.git $ cd repo
O GitHub descontinuou a autenticação por senha HTTPS em 2021. Agora você precisa de um Personal Access Token (PAT) para HTTPS. SSH é mais prático para uso diário (veja a seção 6 para configuração).
3. Fluxo Principal: status -> add -> commit
O trabalho diário com Git é o loop "ver alterações -> incluí-las -> snapshot."
3-1. Verificar o Estado
$ git status
On branch main
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md
3-2. Adicionar Alterações ao Stage
$ git add README.md # arquivo unico $ git add src/ # diretorio inteiro $ git add -p # interativo, trecho por trecho
git add . é conveniente, mas facilmente inclui segredos como .env. Sempre execute git status primeiro.
3-3. Commit (Salvar o Snapshot)
$ git commit -m "Add README"
[main (root-commit) abc1234] Add README 1 file changed, 5 insertions(+) create mode 100644 README.md
Modelo mental
status= "qual é o estado atual?"add= "inclua isso no próximo commit"commit= "congele este snapshot"
4. Ver Histórico: log / diff
4-1. Histórico de Commits
$ git log --oneline --graph --decorate -10
* abc1234 (HEAD -> main) Add README * def5678 Initial commit
Um alias prático para uso diário:
$ git config --global alias.lg "log --oneline --graph --decorate --all -20" $ git lg
4-2. Diffs
$ git diff # arvore de trabalho vs stage $ git diff --staged # stage vs HEAD $ git diff HEAD~1 HEAD # commit anterior vs atual $ git diff main..feature # entre branches
4-3. Histórico de Arquivo
$ git log --follow -p src/index.js
--follow rastreia o arquivo mesmo após renomeações.
5. Trabalhar com Remotos: push / pull
5-1. Adicionar um Remoto
$ git remote add origin git@github.com:user/repo.git $ git remote -v
origin git@github.com:user/repo.git (fetch) origin git@github.com:user/repo.git (push)
5-2. Primeiro Push
$ git push -u origin main
-u (--set-upstream) permite omitir origin main nos comandos git push / git pull subsequentes.
5-3. pull / fetch
$ git pull # fetch + merge automaticamente $ git fetch # baixar sem fazer merge $ git log HEAD..origin/main # mostrar o que esta a frente
Acidente comum com pull em trabalho em equipe
git pullexecuta um merge automático, então conflitos com alterações locais são fáceis de provocar.- Quando não tiver certeza, divida em três passos:
git fetch->git log HEAD..origin/main->git merge. - Para workflow com rebase, considere
git config --global pull.rebase true.
6. Configurar Autenticação com Chave SSH
6-1. Gerar um Par de Chaves
$ ssh-keygen -t ed25519 -C "you@example.com" $ cat ~/.ssh/id_ed25519.pub
ed25519 é o padrão moderno -- rápido e compacto. Use -t rsa -b 4096 apenas para sistemas legados que não suportam ed25519.
Sempre defina uma passphrase para limitar danos se a chave vazar. Carregue-a no ssh-agent para não precisar digitá-la toda vez.
6-2. Registrar a Chave Pública no GitHub / GitLab
Copie o conteúdo de ~/.ssh/id_ed25519.pub (o arquivo .pub) e adicione em Settings -> SSH and GPG keys. Nunca compartilhe a chave privada id_ed25519.
6-3. Testar a Conexão
$ ssh -T git@github.com
Hi user! You've successfully authenticated, but GitHub does not provide shell access.
Esta mensagem significa sucesso (o código de saída é 1, mas isso é esperado).
7. .gitignore: Padrões Específicos do Linux
# SO / editores
.DS_Store
*~
.*.swp
.idea/
.vscode/
# Runtimes de linguagem
node_modules/
__pycache__/
*.pyc
target/
build/
dist/
# Segredos (mais importante)
.env
.env.*
*.key
*.pem
# Logs
*.log
logs/
O repositório oficial github/gitignore tem templates específicos por linguagem. Em caso de dúvida, copie de lá.
Arquivos já rastreados NÃO são excluídos pelo .gitignore
Se um arquivo foi commitado antes de ser adicionado ao .gitignore, o Git continua rastreando-o.
$ git rm --cached .env $ echo ".env" >> .gitignore $ git commit -m "Untrack .env"
Nota: isso apenas interrompe o rastreamento futuro. O arquivo permanece em commits anteriores. Se um segredo real vazou, você precisa reescrever o histórico (git filter-repo) e rotacionar as chaves.
8. Armadilhas Comuns Específicas do Linux
8-1. Permission Denied no Push
ERROR: Permission to user/repo.git denied to other-user. fatal: Could not read from remote repository.
Causas prováveis:
- A chave SSH não está registrada no GitHub
- Múltiplas chaves estão carregadas e a chave da conta errada é usada primeiro
- Você não tem acesso de escrita (não é colaborador)
Diagnóstico:
$ ssh -T git@github.com # como qual usuario voce esta autenticado? $ ssh-add -l # listar chaves carregadas no ssh-agent
Para múltiplas contas, use ~/.ssh/config para atribuir chaves por host.
8-2. Quebras de Linha Misturadas (CRLF / LF)
Arquivos vindos do Windows podem poluir o diff (arquivos inteiros aparecem alterados).
# No Linux / macOS: manter quebras de linha como estao (recomendado) $ git config --global core.autocrlf input
Para fixar a regra por repositório, adicione .gitattributes:
* text=auto eol=lf *.sh text eol=lf *.bat text eol=crlf
8-3. O Bit de Execução (chmod +x) Não é Registrado
$ chmod +x scripts/deploy.sh $ git status # pode nao mostrar alteracao
Force o Git a registrar a mudança de modo:
$ git update-index --chmod=+x scripts/deploy.sh $ git diff
old mode 100644 new mode 100755
Se core.fileMode = false está definido no repositório, o Git ignora mudanças de modo. Verifique com git config core.fileMode.
8-4. Diferenças de Caixa em Nomes de Arquivo
O sistema de arquivos Linux (ext4 etc.) é case-sensitive, mas macOS e Windows são case-insensitive por padrão. Confundir Readme.md com README.md vai quebrar CI baseado em Linux.
# Detectar incompatibilidades de caixa no repositorio $ git config --global core.ignorecase false
Uma convenção de nomenclatura no CONTRIBUTING.md mais revisão de PR é a correção realista.
9. Templates Seguros
Configuração inicial
git init echo "node_modules/" > .gitignore git add README.md .gitignore git commit -m "Initial commit" git remote add origin git@github.com:user/repo.git git push -u origin main
Loop diário
git status git diff git add -p # revisar e adicionar trechos git commit -m "feat: explain the change" git push
Operações de desfazer (da menos a mais destrutiva)
git restore <file> # descartar alteracoes na arvore de trabalho git restore --staged <file> # remover do stage (conteudo do arquivo mantido) git commit --amend # corrigir o ultimo commit (apenas antes do push) git revert <commit> # criar um commit inverso (seguro apos compartilhar)
Nunca faça isso
git push --forceem um commit compartilhado (reescreve o histórico de todos)git reset --hardsem confirmar (trabalho não commitado desaparece)- Commitar
.env, chaves privadas ou tokens de autenticação (muito difícil de remover do histórico) --no-verifypara pular hooks (engole silenciosamente falhas de lint ou testes)