Git Command Builder
Build Git commands interactively with options and flags. Learn branching, merging, rebasing with visualizations. Quick recipes for common Git workflows
Git has 150+ subcommands and the man page for each runs thousands of words; the day-to-day flow uses about 15 of them. The interesting friction is not "what does rebase do" but "what is the exact sequence to amend a PR after rebasing onto main while preserving co-author trailers". This builder walks you through common workflows interactively — interactive rebase, cherry-picking specific commits across branches, recovering "lost" commits from reflog, undoing a push without losing teammates' work — generating the exact commands with the flags you need.
Workflows ranked by how often people get them wrong
- Undoing the last commit — `git reset HEAD~1` keeps changes staged; `git reset --soft HEAD~1` keeps them in index; `git reset --hard HEAD~1` discards. Pick wrong and you lose work or keep noise.
- Recovering deleted commits — `git reflog` shows every HEAD position for 90 days. `git reset --hard <reflog-hash>` resurrects. "I lost my commits with reset --hard" is almost always recoverable via reflog.
- Squashing PR commits before merge — `git rebase -i main` with "fixup" or "squash" lines. Order matters; fixup keeps the first commit message, squash combines.
- Cherry-picking a single commit between branches — `git cherry-pick <hash>` with `-x` to record provenance.
- Resolving a rebase conflict — fix files, `git add`, then `git rebase --continue` (NOT git commit; the rebase machinery handles the commit creation).
- Stashing with name — `git stash push -m "before refactor"`. Default unnamed stashes pile up and become unidentifiable.
- Force-pushing safely — `git push --force-with-lease` instead of `--force`. The lease checks the remote has not advanced since you fetched; protects against overwriting teammate commits.
Working example: amending a published PR
Input
You pushed a PR. Reviewer asks for a typo fix in commit 2 of 5.
Output
Option A: amend with a fixup commit (cleanest) git commit --fixup <hash-of-commit-2> git rebase -i --autosquash main # auto-squashes; review the result git push --force-with-lease Option B: interactive rebase git rebase -i HEAD~5 # change "pick" to "edit" on commit 2 # rebase pauses; fix the typo git add . git commit --amend --no-edit git rebase --continue git push --force-with-lease Option C: amend latest commit only (wrong commit; do not use) git commit --amend # — this amends commit 5 (HEAD), not commit 2
Option A is the modern best practice: --fixup commits stack on the PR branch during dev; --autosquash collapses them into the right commit at the end. Reviewers see clean history; you do not waste time on interactive-rebase ceremony every iteration.
The commands you should bind to muscle memory
- git status — before every action. Tells you what is staged, unstaged, untracked.
- git log --oneline --graph --decorate -20 — visual recent history. Make this an alias (git lg).
- git diff [--staged] — see what changed. Add --staged for index vs HEAD.
- git stash, git stash pop — temporary work-saver. Always pop before forgetting which stash had what.
- git switch — modern replacement for "git checkout <branch>". Use git switch -c <new-branch> for creating + switching.
- git restore — modern replacement for "git checkout -- <file>". Use git restore --staged to unstage.
- git reflog — your safety net. Run it any time you think you lost something.
- git blame -L <range> <file> — see who wrote each line. Useful for archaeology, not blame.
Things you should almost never do
- git push --force on main / master — overwrites teammates' commits. Use --force-with-lease if you must force; never force-push to main.
- git rebase on a shared branch — rewrites history that others may have based on. Rebase only on local / your own PR branches.
- git pull --no-rebase by default on a feature branch — produces merge commits in your history. Use `git config pull.rebase true` once globally.
- git checkout -- . to "undo everything" — wipes local changes irreversibly. Stash first if there is anything worth keeping.
- git reset --hard without checking git status — if anything is uncommitted, it is gone.
- git clean -fd without -n first — removes untracked files immediately. Run with -n (dry run) first to see what would be deleted.
When to reach for this tool
- You know what you want to accomplish in git but cannot remember the exact command sequence.
- You are teaching a junior developer and want a reference for "the standard way to do X" without diving into man pages.
- You inherited a workflow that uses an unusual git command (e.g., reset with --merge or --keep) and want to understand what each flag does.
- You messed something up and want a recovery procedure (reflog-based) before assuming the work is gone.
What this tool will not do
- It will not execute commands. The output is the command(s) you should run yourself. Copy, verify in your terminal, and run.
- It will not understand your repo state. Generic commands generate; for project-specific advice (your team's branching strategy, your CI requirements), consult your team docs.
- It will not fix data loss without reflog. Once reflog ages out (default 90 days for reachable commits, 30 days for unreachable) the commits are garbage-collected and lost.
Frequently asked questions
What is the difference between merge and rebase?
Merge creates a new commit on the target branch that joins the histories — both lines are preserved. Rebase replays your commits onto the new base — linear history but rewrites commit hashes. Rebase makes for cleaner PR history; merge preserves true causality. Most modern teams: rebase feature branches onto main, then merge (or squash-merge) the PR.
Is `git pull` rebase or merge by default?
Merge by default. Many teams configure pull.rebase = true globally for cleaner history. `git pull --rebase` is the safer alternative when you have unpushed commits and someone else has pushed to the same branch.
How do I undo a `git commit --amend` that I have already pushed?
Find the original commit hash via `git reflog`. `git reset --hard <hash>`. Then `git push --force-with-lease`. If others have pulled the amended commit, communicate before re-pushing the original.
What does `--force-with-lease` actually check?
It verifies that the remote branch is at the commit you last fetched. If someone else pushed in between, the lease "expires" and the push fails — protecting their work. `--force` skips this check; `--force-with-lease` is almost always the right choice.
I deleted a branch. Are the commits gone?
Not yet — git keeps them in reflog for 30 days, then garbage collects. Within 30 days: `git reflog` to find the commit, `git branch <name> <hash>` to recreate the branch pointing at it. If you also ran `git gc --prune=now`, the commits are gone.
How do I find which commit broke a test?
`git bisect`. Mark a known-good commit and a known-bad commit; git checks out commits in between and you mark each as good or bad. Logarithmic search finds the offending commit in log2(N) tests. Automate by passing a script that returns 0/1.
Related tools
Generate conventional commit messages following Angular, Conventional Commits standards. Create semantic git commits. Free commit message builder
Generate .gitignore files for any project. Templates for Node, Python, Java, Go, React, Vue, and more. Free online gitignore generator
Build docker-compose.yml files visually. Add MySQL, PostgreSQL, Redis, MongoDB services. Free online Docker Compose YAML generator
Format and beautify JSON, XML, CSS, HTML, JavaScript, SQL code. Auto-indent and syntax highlight. Free online code beautifier and formatter
Last updated · E-Utils editorial team