Enhancing Git Workflow: Essential Command Line Tools and GUIs
Compare everyday Git CLI commands with helpful tools like lazygit, delta, tig, and GUI clients for review and history work.
Enhancing Git Workflow: Essential Command Line Tools and GUIs
Git, as a fast, scalable, distributed revision control system, forms the backbone of modern software development workflows. While its core command-line interface provides robust control over versioning, understanding and leveraging its extensive command set, along with specialized command-line tools and graphical user interfaces (GUIs), can significantly enhance productivity and simplify complex tasks. This guide focuses on tools that solve real workflow problems: staging clean commits, reading history, reviewing diffs, and handling branches without losing track of what changed.
You do not need every tool here. Pick the smallest set that makes your daily work clearer.
Core Git Workflow: Essential Command-Line Operations
Git offers a rich command set, categorized into high-level "porcelain" commands for end-users and low-level "plumbing" commands for scripting and internal object management. Here, we'll focus on the essential porcelain commands for daily tasks.
Getting Started with a Repository
To begin a new project or join an existing one, these commands are your starting point:
- Initialize a new Git repository:
git init - Clone an existing repository from a URL:
git clone <url>
Managing Changes (Staging and Committing)
Before you commit, Git uses a "staging area" (also known as the index) to prepare changes. This gives you fine-grained control over what goes into each commit.
- Add specific files to the staging area:
git add <file> - Add all untracked and modified files to the staging area:
git add . - Interactively stage parts of a file (hunks):
git add -p - Move or rename a file:
git mv <old> <new> - Delete a file from the working directory and staging area:
git rm <file> - Remove a file from Git tracking without deleting it from the file system:
git rm --cached <file> - Unstage a specific file:
git reset <file> - Unstage all changes:
git reset - Check the status of your working directory and staging area:
git status
Once changes are staged, you can commit them:
- Commit staged changes (opens editor for message):
git commit - Commit staged changes with a message:
git commit -m 'Your commit message' - Commit all tracked, unstaged changes directly (bypasses
git addfor modifications):git commit -am 'Your commit message'
Branching and Merging
Branches are fundamental to Git's distributed nature, allowing parallel development. Merging and rebasing are ways to integrate changes.
- Switch to an existing branch:
git switch <name> # OR (older syntax) git checkout <name> - Create and switch to a new branch:
git switch -c <name> # OR (older syntax) git checkout -b <name> - List all local branches:
git branch - List branches by most recently committed to:
git branch --sort=-committerdate - Delete a local branch (only if merged):
git branch -d <name> - Force delete a local branch (even if unmerged):
git branch -D <name> - Merge one branch into your current branch:
git merge <branch-to-merge> - Merge one branch into your current branch as a single commit (squash merge):
git merge --squash <branch-to-merge> git commit -m 'Squashed commit message' - Rebase your current branch onto another (rewrites history):
git rebase <base-branch>
Collaboration with Remotes
Git excels in collaborative environments, pushing and pulling changes from remote repositories.
- Add a new remote repository:
git remote add <name> <url> - Push your current branch to its remote tracking branch:
git push - Push a new branch for the first time, setting upstream:
git push -u origin <name> - Force push (use with extreme caution, overwrites remote history):
git push --force-with-lease - Fetch changes from a remote (does not integrate them into your local branches):
git fetch origin main - Fetch changes and then merge them into your current branch:
git pull origin main # OR (if tracking branch is set) git pull - Fetch changes and then rebase your current branch:
git pull --rebase
Inspecting History and Diffs
Understanding what has changed and who made those changes is crucial for debugging and review.
- Show a summary of all staged and unstaged changes:
git diff HEAD - Show diff of just staged changes:
git diff --staged - Show diff of just unstaged changes:
git diff - View commit logs (various options):
git log # Full log git log --graph # ASCII art tree of history git log --oneline # Concise one-line per commit git log <file> # History of a specific file git log --follow <file> # History including renames git log -G <pattern>git log -G <pattern>finds commits where the number of matching lines changed. For example,git log -G "timeout" -- app/is useful when you need to know when timeout handling changed in a service directory.
Command-Line Tools That Make Git Easier
The plain Git CLI should stay your baseline. Extra tools are best when they make state easier to see, not when they hide what Git is doing.
lazygit gives you an interactive terminal UI for staging hunks, browsing commits, resolving simple conflicts, and pushing branches. It is useful when you want a visual overview but still work in the terminal.
tig is a fast text UI for browsing history. It is especially good on servers or remote development boxes where a full desktop GUI is not available.
delta improves Git diffs with syntax highlighting and clearer moved-line display. After installing it, a common setup is:
git config --global core.pager delta
git config --global interactive.diffFilter "delta --color-only"
Check delta's documentation for options that match your terminal colors. Keep the configuration small at first so plain Git output is still easy to recover.
For repository cleanup or sensitive history removal, git-filter-repo is generally preferred over the older git filter-branch. Treat any history rewrite as a team operation. It changes commit IDs and forces everyone who uses the repository to resync carefully.
When a GUI Is the Better Tool
A GUI can be the right choice for reviewing broad changes, comparing branches, or teaching Git concepts to someone who thinks visually. Tools such as GitHub Desktop, GitKraken, Sourcetree, Fork, and IDE integrations can make staging and history inspection easier.
Use a GUI when it helps you answer concrete questions:
- Which files changed in this branch?
- Which commits are unique to this branch?
- What did this rename or refactor actually touch?
- Which side of a conflict should I keep?
Do not use a GUI as a substitute for understanding basic commands. When a push fails, a rebase conflicts, or CI checks out a detached commit, the error messages and recovery steps are still Git concepts.
A Practical Setup for Daily Work
A balanced workflow might look like this:
git status
git add -p
git diff --staged
git commit -m "Add health check endpoint"
git pull --rebase
git push -u origin feature/health-check
Then use git log --oneline --graph --decorate --all or a GUI to inspect how the branch fits into the wider history.
If you add aliases, keep them obvious:
git config --global alias.st status
git config --global alias.lg "log --oneline --graph --decorate --all"
git config --global alias.unstage "restore --staged"
Aliases should shorten commands you already understand. Avoid aliases that perform destructive actions unless the name is unmistakable.
Final Takeaway
Use the Git CLI for the operations you need to understand under pressure: status, diff, add, commit, branch, fetch, pull, push, merge, and rebase. Add terminal tools or GUIs where they improve visibility. The best workflow is not the one with the most tools; it is the one that lets you see your changes clearly before you share them.