Jhonatan Pinheiro
Loading page...
Jhonatan Pinheiro
Loading page...
Jhonatan Pinheiro
Loading page...
Setup, commits, branches, merge and rebase, remotes, the undo chapter (reset, revert, reflog), bisect and blame: 100 commands with examples.
Git is the tool every developer uses and almost nobody masters in full. The good news: about 20 commands cover 95% of the work — the other 80 are what saves you on the day something goes wrong.
These 100 commands are in the order they show up in real life: configure, create, commit, branch, integrate, publish, undo and investigate.
Golden rule: until you have run
push, almost everything is reversible. After the push, prefer commands that add history (such asrevert) over the ones that rewrite it (such asrebaseand--force).
Done once per machine — and it is what prevents a commit with the wrong author.
This is what appears as the authorship of every commit. Without it, Git complains at the first commit.
git config --global user.name "Jhonatan Pinheiro"
git config --global user.email "voce@email.com"Lists everything in effect and where each value came from.
git config --list --show-originWithout --global, it applies only to the current project. Handy for separating a personal email from a corporate one.
git config user.email "voce@empresa.com"Defines what opens the commit message and the interactive rebase.
git config --global core.editor "code --wait"Makes every new repository start with main instead of master.
git config --global init.defaultBranch mainAvoids the classic giant diff between Windows and Linux.
git config --global core.autocrlf true # Windows
git config --global core.autocrlf input # Linux and macOSLong commands you repeat every day deserve a nickname.
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.lg "log --oneline --graph --decorate --all"Saves you from typing the token on every push.
git config --global credential.helper store # saves to disk
git config --global credential.helper manager # Windows (OS manager)Cryptographic proof of authorship — the Verified badge on GitHub.
git config --global user.signingkey SEU_ID_GPG
git config --global commit.gpgsign trueMakes git pull complain instead of creating a merge on its own. Avoids tangled history.
git config --global pull.rebase false
git config --global pull.ff onlyThe starting point: turning a folder into a repository or bringing in an existing one.
Turns the current folder into a Git repository (it creates the .git directory).
git initDownloads the project with its whole history and already configures the origin remote.
git clone https://github.com/usuario/projeto.gitSets the name of the destination directory.
git clone https://github.com/usuario/projeto.git minha-pastaBrings only the most recent commits. Far faster on a large repository — ideal in CI.
git clone --depth 1 https://github.com/usuario/projeto.gitDownloads only the branch you care about.
git clone --branch desenvolvimento --single-branch https://github.com/usuario/projeto.gitNo password/token to type, as long as your key is registered.
git clone git@github.com:usuario/projeto.gitLists what Git should ignore. Put dependencies, build output and secrets here.
# .gitignore
node_modules/
.env
.env.local
dist/
*.logAdding it to .gitignore does not remove what is already versioned.
git rm --cached .env
git commit -m "chore: remove .env do versionamento"See what changed, choose what goes in, and record it. Ninety per cent of Git usage.
Shows what changed, what is staged and which branch you are on. Always run it before committing.
git status
git status -s # short versionMoves the change into the staging area — the antechamber of the commit.
git add arquivo.ts
git add src/Adds everything that changed. Check with status first, so you do not take an unwanted file along.
git add .Picks chunk by chunk inside the same file. The best friend of the small commit.
git add -pThe difference between what is on disk and the last commit (not counting what is already staged).
git diffShows exactly what will go into the next commit.
git diff --stagedCompares any two points in the history.
git diff main..minha-feature
git diff main..minha-feature -- src/appRecords what is staged. The message is documentation: write the why.
git commit -m "feat: adiciona filtro por assunto no blog"A short title, a blank line, and the context underneath.
git commit -m "fix: corrige contraste do tema claro" -m "O primary ficava em 3,2:1 sobre o fundo, abaixo do minimo AA."Stages and commits already tracked files in one go. It does not pick up a new file.
git commit -am "refactor: extrai helper de datas"A convention that keeps the history readable and allows a changelog to be generated automatically.
# feat, fix, docs, style, refactor, perf, test, chore
git commit -m "perf(db): indexa pedidos por cliente_id"Fixes the last commit (message or content). Only before the push.
git commit --amend -m "mensagem corrigida"
git commit --amend --no-edit # only adds what is stagedWith no change at all — useful for triggering a CI pipeline.
git commit --allow-empty -m "chore: dispara build"Rename and remove while keeping the trail in the history.
git mv antigo.ts novo.ts
git rm obsoleto.tsBranching is cheap in Git. One branch per task is the pattern that avoids headaches.
Shows the local ones; with -a, the remote ones too.
git branch
git branch -a
git branch -vv # with the last commit and the remote of each oneCreates it from the current commit, without switching to it.
git branch minha-featureswitch is the modern command; checkout still works.
git switch minha-feature
git checkout minha-featureThe most used shortcut of the working day.
git switch -c minha-feature
git checkout -b minha-featureStarts from a specific point instead of the current commit.
git switch -c hotfix mainRenames the current one (-m) or a specific one.
git branch -m novo-nome
git branch -m nome-antigo novo-nome-d refuses if there is an unintegrated commit; -D forces it.
git branch -d minha-feature
git branch -D minha-featureRemoves the branch from the server after the merge.
git push origin --delete minha-featureThe - works just like in cd.
git switch -Lists what has been merged — safe candidates for deletion.
git branch --merged main
git branch --no-merged mainLinks the local branch to the server one, so push/pull need no arguments.
git branch --set-upstream-to=origin/minha-featureRemoves from your clone the branches that no longer exist on the server.
git fetch --pruneTwo branches open in different folders at the same time, without cloning again.
git worktree add ../projeto-hotfix hotfix
git worktree list
git worktree remove ../projeto-hotfixUseful inside a script and in a terminal prompt.
git branch --show-currentTwo ways of integrating work — and how to get out of a conflict without losing anything.
Brings the given branch into the current one, creating a merge commit when necessary.
git switch main
git merge minha-featureWith no divergence, Git just moves the pointer forward — linear history, no extra commit.
git merge --ff-only minha-featureForces the merge commit, preserving the existence of the branch in the history.
git merge --no-ff minha-featurePuts everything back to the state before the merge.
git merge --abortEdit the marked files, remove the markers, add and finish.
git status # lists the conflicts
# edit the files and remove <<<<<<< ======= >>>>>>>
git add arquivo-resolvido.ts
git commitAccepts your version or the incoming one, with no manual editing.
git checkout --ours arquivo.ts # the current branch's version
git checkout --theirs arquivo.ts # the version coming inOpens the conflict in a configured graphical tool.
git mergetoolReplays your commits on top of another branch. It keeps the history linear.
git switch minha-feature
git rebase mainReorders, squashes, edits and removes commits before you open the PR.
git rebase -i HEAD~5Resolved the conflict? Continue. Got complicated? Abort.
git rebase --continue
git rebase --skip
git rebase --abortTakes a specific commit to the current branch — the hotfix classic.
git cherry-pick a1b2c3d
git cherry-pick a1b2c3d..e4f5g6hRebase on your own branch before the PR; merge to integrate into main. Never rebase a shared branch.
# Good: updating your feature
git switch minha-feature && git rebase main
# Good: integrating into the main branch
git switch main && git merge --no-ff minha-featureSyncing your clone with the server — and understanding the difference between fetch and pull.
Shows the addresses configured for fetching and pushing.
git remote -vConnects the local repository to a server.
git remote add origin git@github.com:usuario/projeto.gitUsed when migrating from HTTPS to SSH or when changing organisation.
git remote set-url origin git@github.com:usuario/projeto.gitDownloads the news without touching your work. The safest command in Git.
git fetch originIt is fetch + merge in a single step. It brings the changes in and integrates them into your branch.
git pull origin mainIntegrates by replaying your commits on top — no merge commit halfway through.
git pull --rebase origin mainSends your commits to the server.
git push origin main-u links the local branch to the remote one; after that git push is enough.
git push -u origin minha-feature--force-with-lease refuses if someone has published something you have not seen yet. Always prefer this over --force.
git push --force-with-lease origin minha-featureTags do not go up with a normal push.
git push origin v1.2.0
git push origin --tagsHow many commits ahead or behind you are.
git fetch
git status -sb
git log --oneline origin/main..HEAD # what you have that they do notKeeps your fork up to date with the original project.
git remote add upstream https://github.com/original/projeto.git
git fetch upstream
git merge upstream/mainAlmost everything in Git is reversible. The difference lies in what has already been published.
Puts the file back to the last commit. You lose what was not saved.
git restore arquivo.ts
git checkout -- arquivo.ts # the old wayWipes the working directory. Use it knowingly.
git restore .Removes it from what is staged, but keeps the change in the file.
git restore --staged arquivo.ts
git reset arquivo.ts # the old wayUndoes the commit and keeps everything staged. Ideal for redoing the message or squashing commits.
git reset --soft HEAD~1Undoes the commit and unstages it, preserving the files. This is the default.
git reset HEAD~1Undoes the commit and deletes the changes. There is no undo — except through the reflog.
git reset --hard HEAD~1Creates a new commit that undoes another one. It is the correct way to revert something already published.
git revert a1b2c3dYou have to say which side is the main one (-m 1).
git revert -m 1 a1b2c3dIt records everywhere HEAD has been, including commits lost to a reset. It saves almost any situation.
git reflog
git reset --hard HEAD@{2}Brings back the version from a specific commit.
git restore --source=HEAD~3 arquivo.tsFind the commit in the reflog and recreate the branch on it.
git reflog
git branch minha-feature-recuperada a1b2c3dDeletes untracked files. Run it with -n first to see what would go.
git clean -n # simulates
git clean -fd # deletes files and directories
git clean -fdx # includes what is in .gitignoreOnly that file travels back in time; the rest stays as it is.
git checkout a1b2c3d -- caminho/arquivo.tsA committed .env stays in the history until it is rewritten — and the token has to be rotated either way.
git filter-repo --path .env --invert-paths
# then: git push --force-with-lease (agree it with the team first)Finding out when, why and because of which commit that thing broke.
The history. On its own it is far too verbose — the variations below are worth more.
git log
git log -5The most useful view: compact, with the branching drawn out.
git log --oneline --graph --decorate --allSlices the history by who and when.
git log --author="Jhonatan" --since="2 weeks ago"Finds the commit that introduced (or removed) a given snippet.
git log -S "getThemeSelection" --onelineOnly the commits that touched that path; --follow tracks renames.
git log --follow -p -- src/lib/theme/presets.tsShows a whole commit: message, author and diff.
git show a1b2c3dTells you who wrote each line and in which commit. Use it to understand, not to blame.
git blame src/app/page.tsx
git blame -L 40,60 src/app/page.tsxA binary search through the history: it finds the commit that broke things in a handful of steps.
git bisect start
git bisect bad # the current one is broken
git bisect good v1.0.0 # it worked here
# test, mark good/bad, repeat
git bisect resetA summary by author.
git shortlog -sn --allWithout switching branch or touching the directory.
git show a1b2c3d:src/app/page.tsxPutting half-finished work aside, marking versions and bringing repositories together.
Puts the changes away and clears the directory — for switching context in a hurry.
git stash
git stash push -m "meio da refatoração"pop applies it and removes it from the stack; apply keeps it stored.
git stash list
git stash pop
git stash apply stash@{1}By default the stash ignores what is not tracked.
git stash -uMarks a version with author, date and message. Prefer it to the plain tag.
git tag -a v1.2.0 -m "Release 1.2.0"
git push origin v1.2.0Deleting requires removing it locally and remotely.
git tag -l "v1.*"
git tag -d v1.2.0
git push origin --delete v1.2.0One repository inside another, pinned to a specific commit.
git submodule add https://github.com/usuario/lib.git libs/lib
git submodule update --init --recursive
git clone --recurse-submodules https://github.com/usuario/projeto.git