Ubuntu Git
O Git guarda o histórico de uma pasta: cada versão salva (um commit) fica registrada com data, autor e descrição, e você pode voltar a qualquer uma. É a ferramenta padrão para código, mas serve para qualquer texto: scripts, configurações do servidor, documentação e até este guia.
- Os três "lugares" do Git: pasta de trabalho, área de preparação e histórico.
- O ciclo
status→add→commit, lendo cada saída. - Ver o histórico e as diferenças (
log,diff). - Trabalhar em ramos (
branch,switch,merge) e resolver um conflito. - Enviar para o GitHub com chave SSH (
push,pull).
Os exemplos acontecem na máquina fictícia notebook, usuária ana. IDs de commit (como 3f2a1b9) são diferentes em cada computador.
Conceito: os três lugares
| Lugar | O que é | Como algo chega lá |
|---|---|---|
| Pasta de trabalho | Os arquivos como você os vê e edita | Você edita |
| Área de preparação (staging) | O que vai entrar no próximo commit | git add |
| Histórico (repositório) | Os commits salvos, na pasta oculta .git | git commit |
Pense numa mudança de casa: você edita (arruma as coisas), prepara (põe o que vai levar na caixa) e faz o commit (fecha a caixa com uma etiqueta). A área de preparação existe para você escolher o que entra em cada caixa.
Instalar e configurar
$ sudo apt install git $ git --version git version 2.53.0
Antes do primeiro commit, diga ao Git quem você é. Isso fica gravado em cada commit.
- git config
- Lê ou grava configurações.
- --global
- Vale para todos os seus repositórios (grava em
~/.gitconfig). - user.name
- A chave da configuração.
- "Ana Souza"
- O valor. Aspas porque tem espaço.
$ git config --global user.name "Ana Souza" $ git config --global user.email "ana@exemplo.com" $ git config --global init.defaultBranch main « o ramo inicial se chamará "main" $ git config --global core.editor nano « editor para mensagens (veja nano e vim) $ git config --list --global user.name=Ana Souza user.email=ana@exemplo.com init.defaultbranch=main core.editor=nano
No Ubuntu em português, a tradução do Git está incompleta: a maioria das mensagens sai em inglês e algumas frases em português (ex.: "Mudanças a serem submetidas:"). Nesta página as saídas aparecem em inglês. Se preferir o Git sempre em inglês, acrescente ao ~/.bashrc: alias git='LANGUAGE=en git'.
Criar um repositório: git init
$ mkdir ~/site && cd ~/site $ git init Initialized empty Git repository in /home/ana/site/.git/ $ ls -a . .. .git « aqui dentro fica todo o histórico
.git
Apagar .git apaga todo o histórico. Os arquivos atuais ficam, mas as versões antigas somem.
O ciclo do dia a dia
1. git status: o que mudou?
$ echo "<h1>Site da Ana</h1>" > index.html $ git status On branch main « você está no ramo main No commits yet « nenhum commit ainda Untracked files: « arquivos que o Git não acompanha (use "git add <file>..." to include in what will be committed) index.html nothing added to commit but untracked files present (use "git add" to track)
O git status é o comando mais importante: ele sempre diz em que estado você está e qual o próximo comando (as linhas entre parênteses). Leia-o sempre.
2. git add: preparar
- git add
- Coloca mudanças na área de preparação.
- index.html
- Qual arquivo. Use
.para "tudo nesta pasta".
$ git add index.html $ git status On branch main No commits yet Changes to be committed: « pronto para o commit (use "git rm --cached <file>..." to unstage) new file: index.html
3. git commit: salvar a versão
- git commit
- Grava o que está preparado como uma versão nova.
- -m "…"
- A mensagem. Sem
-m, o Git abre o editor para você escrever.
$ git commit -m "Cria a página inicial" [main (root-commit) 3f2a1b9] Cria a página inicial « 3f2a1b9 = ID curto do commit 1 file changed, 1 insertion(+) create mode 100644 index.html $ git status On branch main nothing to commit, working tree clean « tudo salvo
Escreva no imperativo e diga o quê e por quê: "Corrige link quebrado do menu" é melhor que "ajustes". Daqui a seis meses, você vai agradecer.
Mudar um arquivo e ver a diferença: git diff
$ echo "<p>Bem-vindo!</p>" >> index.html $ git diff diff --git a/index.html b/index.html index 5c1d2e3..8a9b0c1 100644 --- a/index.html « versão salva +++ b/index.html « versão atual @@ -1 +1,2 @@ <h1>Site da Ana</h1> +<p>Bem-vindo!</p> « + = linha nova; - = linha removida $ git commit -am "Adiciona boas-vindas" [main a7c3e21] Adiciona boas-vindas 1 file changed, 1 insertion(+)
O -a do commit -am faz o add automático de arquivos que o Git já acompanha. Arquivos novos ainda precisam de git add.
Formas de preparar mudanças
| Forma | O que entra | Melhor quando… |
|---|---|---|
git add arquivo | Um arquivo | Você quer commits pequenos e separados. |
git add . | Tudo da pasta atual para baixo | Todas as mudanças são do mesmo assunto. |
git add -p | Pedaço por pedaço, perguntando | Um arquivo tem duas mudanças de assuntos diferentes. |
git commit -am "…" | Tudo que já era acompanhado | Mudanças rápidas, sem arquivos novos. |
O histórico: git log
$ git log --oneline
a7c3e21 (HEAD -> main) Adiciona boas-vindas « HEAD = onde você está agora
3f2a1b9 Cria a página inicial
$ git log -1
commit a7c3e21f0b9d8c7e6a5b4c3d2e1f0a9b8c7d6e5f (HEAD -> main)
Author: Ana Souza <ana@exemplo.com>
Date: Thu Oct 15 10:42:17 2026 -0300
Adiciona boas-vindas
$ git show 3f2a1b9 --stat
commit 3f2a1b9…
…
index.html | 1 +
1 file changed, 1 insertion(+)
Desfazer: formas diferentes para situações diferentes
| Situação | Comando |
|---|---|
| Desfazer mudança não preparada num arquivo | git restore index.html (perde a mudança!) |
| Tirar da preparação, sem perder a mudança | git restore --staged index.html |
| Corrigir a mensagem do último commit (ainda não enviado) | git commit --amend -m "nova mensagem" |
| Desfazer um commit já enviado, criando um commit "ao contrário" | git revert a7c3e21 |
| Ver um arquivo como era numa versão antiga | git show 3f2a1b9:index.html |
Ramos: branch, switch e merge
Um ramo (branch) é uma linha de trabalho separada. Você cria um ramo para uma tarefa, trabalha nele sem mexer no main e, quando estiver bom, junta (merge).
- git switch
- Troca de ramo.
- -c
- create: cria o ramo antes de trocar.
- contato
- O nome do ramo novo.
$ git switch -c contato Switched to a new branch 'contato' $ echo "<p>Email: ana@exemplo.com</p>" > contato.html $ git add contato.html && git commit -m "Cria página de contato" [contato c41d0e8] Cria página de contato 1 file changed, 1 insertion(+) create mode 100644 contato.html $ git branch * contato « o * marca o ramo atual main $ git switch main Switched to branch 'main' $ ls index.html « contato.html "sumiu": ele só existe no outro ramo $ git merge contato Updating a7c3e21..c41d0e8 Fast-forward « o main só "andou para frente" contato.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 contato.html $ git branch -d contato Deleted branch contato (was c41d0e8).
Resolver um conflito, passo a passo
Conflito acontece quando os dois ramos mudaram a mesma linha de formas diferentes. O Git não adivinha qual vale e pede a sua decisão.
$ git merge cores Auto-merging index.html CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result. $ git status On branch main You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: index.html « os dois mexeram aqui
- Abra o arquivo. O Git marcou o trecho em disputa:
<<<<<<< HEAD <h1 style="color: blue">Site da Ana</h1> ======= <h1 style="color: orange">Site da Ana</h1> >>>>>>> cores <p>Bem-vindo!</p>
Entre<<<<<<< HEADe=======está a versão do ramo atual (main); entre=======e>>>>>>> cores, a do outro ramo. - Edite para ficar como deve ser e apague as três linhas de marcação:
<h1 style="color: orange">Site da Ana</h1> <p>Bem-vindo!</p>
- Marque como resolvido e conclua:
$ git add index.html $ git commit -m "Junta o ramo cores" [main 9e8d7c6] Junta o ramo cores
Se ficou confuso, git merge --abort volta tudo para antes do merge.
GitHub: enviar e receber
Passo 1: chave SSH
O GitHub não aceita senha no terminal. Use uma chave SSH (veja SSH):
$ ssh-keygen -t ed25519 -C "ana@exemplo.com" $ cat ~/.ssh/id_ed25519.pub ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK3p… ana@exemplo.com « copie esta linha inteira
No GitHub: Settings → SSH and GPG keys → New SSH key, cole a linha e salve. Depois teste:
$ ssh -T git@github.com Hi ana! You've successfully authenticated, but GitHub does not provide shell access.
Passo 2: ligar o repositório e enviar
Crie um repositório vazio no GitHub (sem README) e copie o endereço SSH.
- git remote add
- Registra um repositório remoto.
- origin
- O apelido do remoto. "origin" é o nome tradicional.
- git@github.com:ana/site.git
- O endereço SSH do repositório.
$ git remote add origin git@github.com:ana/site.git $ git push -u origin main Enumerating objects: 9, done. Counting objects: 100% (9/9), done. Delta compression using up to 8 threads Compressing objects: 100% (6/6), done. Writing objects: 100% (9/9), 812 bytes | 812.00 KiB/s, done. Total 9 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0) To github.com:ana/site.git * [new branch] main -> main branch 'main' set up to track 'origin/main'. « -u: daqui pra frente, basta "git push"
Receber mudanças: git pull e git clone
$ git pull Updating 9e8d7c6..1b2c3d4 Fast-forward README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 README.md
$ git clone git@github.com:ana/site.git site-copia Cloning into 'site-copia'... … Resolving deltas: 100% (2/2), done.
Com o repositório no GitHub, ative Settings → Pages e escolha a branch main. É assim que se hospeda um site estático, como este guia, no GitHub Pages.
Não versionar o que não deve: .gitignore
Senhas, logs e arquivos gerados não devem ir para o histórico. Liste-os num arquivo .gitignore na raiz do projeto:
# segredos .env *.key # arquivos gerados node_modules/ *.log dist/ # lixo do sistema e de editores .DS_Store *.swp
$ git check-ignore -v .env .gitignore:2:.env .env « ignorado pela linha 2
.gitignore não apaga o passado
Se uma senha já entrou num commit, ela continua no histórico mesmo depois de adicionada ao .gitignore. Troque a senha imediatamente; considere-a vazada se o repositório foi enviado.
Quando não funciona
$ git status fatal: not a git repository (or any of the parent directories): .git
O que aconteceu: você não está dentro de uma pasta com repositório. Como resolver: cd para a pasta do projeto, ou git init se for um projeto novo.
$ git commit -m "teste" Author identity unknown *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" …
Como resolver: rode os dois git config --global com seus dados e repita o commit.
$ git push git@github.com: Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.
O que aconteceu: o GitHub não reconheceu a sua chave. Como confirmar: ssh -T git@github.com. Como resolver: cadastre a chave pública no GitHub e confira se o endereço do remoto está certo (git remote -v).
$ git push To github.com:ana/site.git ! [rejected] main -> main (fetch first) error: failed to push some refs to 'github.com:ana/site.git' hint: Updates were rejected because the remote contains work that you do not hint: have locally. …
O que aconteceu: alguém (ou você, por outro computador) enviou commits que você ainda não tem. Como resolver: git pull, resolva conflitos se houver, e git push de novo. Não use git push --force num ramo compartilhado: ele apaga o trabalho dos outros.
Referência
| Comando | O que faz |
|---|---|
git init | Cria repositório na pasta atual |
git clone URL [pasta] | Copia um repositório remoto |
git status | Estado atual e próximo passo |
git add ARQ / . / -p | Prepara mudanças |
git commit -m "msg" / -am | Salva uma versão |
git diff / --staged | Diferenças não preparadas / preparadas |
git log --oneline --graph | Histórico compacto, com desenho dos ramos |
git restore ARQ | Descarta mudança não preparada |
git switch -c RAMO / git switch RAMO | Cria e troca / troca de ramo |
git merge RAMO | Junta outro ramo no atual |
git remote -v | Lista remotos |
git push / git pull | Envia / recebe commits |
git revert ID | Desfaz um commit com outro commit |
Exercícios
1. O ciclo
Complete os dois comandos para preparar e salvar o arquivo notas.md:
2. Ramo novo
Complete para criar o ramo menu e já trocar para ele:
3. Primeiro envio
4. No meio de um conflito, depois de editar o arquivo e apagar as marcações, o que você faz?
5. Uma senha foi commitada e enviada ao GitHub. O que é mais importante fazer?
Resumo
- Configure
user.name,user.emaileinit.defaultBranchuma vez. - Ciclo: editar →
git status→git add→git commit -m. git log --onelineegit diffmostram o histórico e as mudanças.- Ramos isolam tarefas;
git mergejunta. Conflito = editar,add,commit. - GitHub com chave SSH:
remote add,push -una primeira vez, depoispushepull. - Segredos no
.gitignoredesde o início.