Git is a powerful tool, but it hasn’t always been the most intuitive. Some commands, like git checkout
try to do too many things at once, which can lead to confusion, even for experienced developers. To address this, Git introduced in latest versions new commands like git switch
and git restore
, splitting the functionality of git checkout
into more focused pieces. In this post, we’ll explore these and other modern Git commands that can help us work more confidently and efficiently.
From git checkout
to git switch
and git restore
For years, git checkout
was a generic command for switching branches or restoring files. While it worked, its dual purpose often caused confusion. With Git 2.23, git switch
and git restore
were introduced to split these tasks into two more specialised commands.
-
git switch
: This command is for switching branches only. It makes it clear that we’re changing context to work on a different branch. -
git restore
: This command is for restoring files from another branch, commit, or stash. It helps us reset or recover files without the risk of unintentionally switching branches.
Why the change?
The Git team realised that having one command do two very different things was a frequent source of errors. As the commit message introducing git switch explained:
git checkout
doing too many things is a source of confusion for many users (and it even bites old-timers sometimes).
Examples:
Switching to a branch:
git switch feature-branch
Restoring a file:
git restore component.js
Previously, both tasks would have been done using git checkout
, like this:
git checkout feature-branch
git checkout main -- component.js
By separating these commands, Git makes it easier to understand exactly what we're doing.
When to use them:
- Use
git switch
to change branches. - Use
git restore
to reset or recover specific files without altering our branch.
Managing Changes: git stash
→ git worktree
If you’ve ever needed to temporarily save changes, you’ve probably used git stash
. While useful, it’s not always the most efficient way to handle working on multiple branches.
Why use git worktree
:
Instead of stashing changes to switch branches, we can use git worktree
to create additional working directories for different branches. This enables us to work on multiple branches simultaneously without losing context or worrying about overwriting changes.
Examples:
Let’s say we're working on main
and then we need to check something on feature-branch
. With git stash
, the process would look like this:
git stash
git checkout feature-branch
# Work on feature-branch
git checkout main
git stash pop
With git worktree
, it’s much simpler:
git worktree add ../feature-branch feature-branch
This will create a new directory ../feature-branch
on the same level with our project directory, where we can work on feature-branch
without disrupting our changes on main. Once we are done with our changes there we can push them on feature-branch
and then delete the ../feature-branch
directory.
When to use it:
- When working on multiple branches in parallel.
- When we want a cleaner way to manage changes without constantly stashing and popping.
Undoing Changes: git reset
→ git restore
git reset
is a powerful command, but its ability to modify both the commit history and the working directory makes it risky for undoing simple changes.
Why use git restore
:
git restore
focuses only on the working directory, making it a safer choice for discarding uncommitted changes.
Examples:
Let’s say we made changes to file.html
but we now want to discard them.
With git reset
, we would use:
git reset HEAD file.html
This works, but it also interacts with the staging area. A simpler and safer option is:
git restore file.html
When to use it:
- Use
git restore
to undo changes in our working directory. - Save
git reset
for more advanced tasks like rewinding our commit history.
Simplify Status Checks: git status
→ git status -sb
git status
gives a detailed view of our repository, but the default output can be overwhelming.
Why use git status -sb
:
This shorthand provides a cleaner and more compact overview of our repository’s status.
Examples:
The regular git status
might output:
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: file1.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file2.txt
Using git status -sb
simplifies the output to:
## main
M file1.txt
M file2.txt
When to use it:
Anytime we want a quick and concise summary of our repository.
Cleaner Pulls: git pull
→ git pull --rebase
git pull
is a common way to fetch and merge changes from a remote repository. However, it often results in extra merge commits, making our history harder to read.
Why use git pull --rebase
:
This option applies remote changes on top of our local commits, creating a cleaner, linear history.
Examples:
With a regular git pull
, we might see:
* Merge branch 'main' of origin/main
* Our commit
* Remote commit
Using git pull --rebase
:
* Our commit
* Remote commit
Save the trouble of typing --rebase
every time:
We can configure Git to always rebase when pulling by setting the pull.rebase
option globally:
git config --global pull.rebase true
With this setting, every git pull
will automatically use --rebase
, ensuring a consistent and tidy commit history.
When to use it:
- When we want to avoid unnecessary merge commits.
- Particularly helpful in collaborative projects where clean history matters.
Why these modern commands matter
The newer Git commands like git switch
, git restore
, and git worktree
are about reducing confusion and making git easier to learn and use. By focusing on specific tasks, these commands help us avoid mistakes and keep our workflow organised.
If you’re still using the older commands, don’t worry, they’re not going anywhere. But trying these modern alternatives could make your git experience smoother and more intuitive.
Top comments (0)