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.

Você vai aprender
  • 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

LugarO que éComo algo chega lá
Pasta de trabalhoOs arquivos como você os vê e editaVocê edita
Área de preparação (staging)O que vai entrar no próximo commitgit add
Histórico (repositório)Os commits salvos, na pasta oculta .gitgit 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
Mensagens em português e inglês

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
Atenção: não apague a pasta .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
Boas mensagens de commit

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

FormaO que entraMelhor quando…
git add arquivoUm arquivoVocê quer commits pequenos e separados.
git add .Tudo da pasta atual para baixoTodas as mudanças são do mesmo assunto.
git add -pPedaço por pedaço, perguntandoUm arquivo tem duas mudanças de assuntos diferentes.
git commit -am "…"Tudo que já era acompanhadoMudanç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çãoComando
Desfazer mudança não preparada num arquivogit restore index.html (perde a mudança!)
Tirar da preparação, sem perder a mudançagit 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 antigagit 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
  1. 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 <<<<<<< HEAD e ======= está a versão do ramo atual (main); entre ======= e >>>>>>> cores, a do outro ramo.
  2. 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>
  3. 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.
Publicar este guia

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
Atenção: .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

"fatal: not a git repository"
$ 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.

"Author identity unknown"
$ 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.

"Permission denied (publickey)" no push
$ 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).

Push rejeitado: "fetch first"
$ 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

ComandoO que faz
git initCria repositório na pasta atual
git clone URL [pasta]Copia um repositório remoto
git statusEstado atual e próximo passo
git add ARQ / . / -pPrepara mudanças
git commit -m "msg" / -amSalva uma versão
git diff / --stagedDiferenças não preparadas / preparadas
git log --oneline --graphHistórico compacto, com desenho dos ramos
git restore ARQDescarta mudança não preparada
git switch -c RAMO / git switch RAMOCria e troca / troca de ramo
git merge RAMOJunta outro ramo no atual
git remote -vLista remotos
git push / git pullEnvia / recebe commits
git revert IDDesfaz um commit com outro commit

Exercícios

1. O ciclo

Complete os dois comandos para preparar e salvar o arquivo notas.md:

git notas.md git -m "Adiciona notas"

2. Ramo novo

Complete para criar o ramo menu e já trocar para ele:

git switch menu

3. Primeiro envio

git push origin main

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.email e init.defaultBranch uma vez.
  • Ciclo: editar → git status → git add → git commit -m.
  • git log --oneline e git diff mostram o histórico e as mudanças.
  • Ramos isolam tarefas; git merge junta. Conflito = editar, add, commit.
  • GitHub com chave SSH: remote add, push -u na primeira vez, depois push e pull.
  • Segredos no .gitignore desde o início.