Since Git was born in 2005, core commands such as clone, pull, push, merge, checkout, and commit have existed and supported daily development work. With the evolution of version control requirements, Git has been continuously iterated and updated, introducing many enhanced features and new commands. This article will focus on seven recently added Git commands and explore how they further improve work efficiency!

git switch: Safely Switch Branches

The git switch command was introduced in Git version 2.23.0 to address the problem of the git checkout command having too many responsibilities and to make Git commands more intuitive and easier to understand.

Before Git 2.23, git checkout was used both for switching branches and restoring file contents, which was easily confusing. By splitting the functions of git checkout, the Git team created two new, more specialized commands:

  • git switch: Specifically used for switching between branches.
  • git restore: Specifically used for restoring file contents.

Using git switch to switch branches is very simple. Here is the basic usage:

# Switch to an existing branch
$ git switch <branch-name>
# Create and switch to a new branch
$ git switch -c <new-branch-name>
# Create and track a local branch from a remote repository
$ git switch -c <new-branch-name> --track <remote>/<branch-name>
# Return to the previous branch
$ git switch -

Note: If you encounter the error message 'switch' is not a git command, it may be because your Git version is lower than 2.23.0. You can check the Git version by running git --version and upgrade to the latest version to use these new features.

git restore: Safely Undo Changes

The git restore command was also introduced in Git version 2.23.0 and is specifically used to restore the contents of files in the working directory.

git restore is mainly used to undo changes in the working directory. It can be used to discard uncommitted working tree modifications, restore deleted files, or reset files to a previous commit state. Here is the basic usage of git restore:

# Restore a file in the working directory to the state of the last commit
$ git restore <file>
# Restore a file from a specified commit to the working directory
$ git restore --source=<commit> <file>
# Unstage changes (similar to git reset HEAD <file>)
$ git restore --staged <file>
# Restore all files to the state of a specified commit
$ git restore --source=<commit>.
# Restore all deleted files
$ git restore -w -- *
# Discard changes in the staging area and the working directory (i.e., restore to the state of a specified commit)
$ git restore --staged --worktree <file>

When using git restore, you can optionally specify --staged to affect the staging area or --worktree to affect the working directory. If both options are specified, both the staging area and the working directory will be affected.

git restore is a relatively safe operation because it does not change the branch history. It only affects the working directory and/or the staging area.

git worktree: Work on Multiple Branches Simultaneously

The git worktree command was introduced in Git version 2.5. It allows you to create multiple working directories (worktrees) in the same repository, and each working directory can check out a different branch or commit. This provides developers with the ability to handle multiple tasks simultaneously, such as developing and testing on different branches without having to switch branches back and forth.

Here is the basic usage of git worktree:

# Add a new working directory and check out a specified branch
$ git worktree add <path> [<branch>]
# List all working directories
$ git worktree list
# Remove a working directory (you must first ensure that there are no uncommitted changes in the directory)
$ git worktree remove <path>
# Move a working directory to a new location
$ git worktree move <current-path> <new-path>

For example, if you want to add a new working directory to check out a branch named feature-branch, you can do the following:

$ git worktree add../my-feature-worktree feature-branch

This will create a new working directory under the ../my-feature-worktree directory and check out the feature-branch branch.

git sparse-checkout: Efficiently Handle Large Repositories

The git sparse-checkout was introduced in Git version 2.25.0. This function is a significant improvement over the previously existing sparse checkout mechanism. With git sparse-checkout, developers can more efficiently clone large repositories by checking out only some files or directories instead of the entire project.

To enable sparse-checkout, you first need to set the repository to use the sparse checkout mode:

# Enable sparse-checkout mode
$ git sparse-checkout init
# Set the patterns or paths you want to include
$ git sparse-checkout set <pattern>...

For example, if you only want to check out the files in the src directory and its subdirectories, you can do the following:

$ git sparse-checkout set src/

If you want to add multiple patterns or paths, you can list all the paths after the set command or call the command multiple times.

In addition to the set command, you can also use add and list to manage the sparse checkout mode:

# Add additional paths to the sparse checkout mode
$ git sparse-checkout add <pattern>...
# List the existing sparse checkout patterns
$ git sparse-checkout list

If you no longer need the sparse checkout mode, you can disable it and restore the full checkout state by using the following command:

# Disable sparse-checkout mode and restore full checkout
$ git sparse-checkout disable

git range-diff: Compare Changes Between Commit Ranges

The git range-diff command was introduced in Git version 2.19.0 and is used to compare the differences between two commit ranges. It can help developers understand what changes have occurred in a series of commits after a rebase, merge, or history rewrite operation.

The basic usage of git range-diff is as follows:

# Compare the last n commits on two branches
$ git range-diff A~n..A B~n..B
# Or a more common usage is to directly specify two ranges
$ git range-diff A..B C..D

Here, A..B and C..D represent two different commit ranges respectively. For example, if you want to compare the differences in the feature branch before and after a rebase, you can do the following:

# Assume that origin/feature is the state of the remote branch before the rebase
# and feature is the state of the local branch after the rebase
$ git range-diff origin/feature..feature~n feature~n..feature

git range-diff will output the summary information of each commit, including the commit message, author, date, etc., and highlight the differences between the commits in the two ranges. If the contents of the commits are exactly the same, it will only display the commit message and indicate that they are the same; if there are differences, it will list the differences in detail.

git maintenance: Automate Repository Health

The git maintenance command was introduced in Git version 2.30.0 and is used to manage and automate various maintenance tasks. This command aims to simplify and optimize the maintenance of the repository by providing a set of predefined tasks to help maintain the health and efficient performance of the repository.

git maintenance provides several subcommands to manage different maintenance tasks:

  • Enabling and disabling automatic maintenance:
# Enable automatic maintenance
$ git maintenance start
# Disable automatic maintenance
$ git maintenance stop
  • Performing one-time maintenance tasks: Manually trigger a one-time maintenance task, which is very useful for optimizing the repository at a specific time point (such as after a large commit).
# Execute all configured maintenance tasks
$ git maintenance run
# Execute a specific type of maintenance task
$ git maintenance run --task=<task>

Common maintenance tasks include:

  • gc: Run a full garbage collection, including compressing the object database.
  • commit-graph: Build or update the commit graph file to accelerate commit history queries.
  • loose-objects: Clean up loose objects and package them.
  • incremental-repack: Gradually repack objects to optimize storage.
  • prefetch: Prefetch new data of remote branches to accelerate future cloning and pulling operations.

Configuring the automatic maintenance schedule: You can set which tasks should be executed regularly and their execution frequencies through the configuration file. For example, add the following content to the .git/config file:

[maintenance "daily"]
task = prefetch
task = loose-objects
[maintenance "hourly"]
task = commit-graph
[maintenance "weekly"]
task = incremental-repack
[maintenance "monthly"]
task = gc

Then enable these schedules:

$ git maintenance start --schedule=daily
$ git maintenance start --schedule=hourly
$ git maintenance start --schedule=weekly
$ git maintenance start --schedule=monthly

git log --remerge-diff: Better Understand Merges

Starting from Git version 2.35, you can use the git log --remerge-diff command to better understand merge commits. Usually, a merge commit shows which branches were merged, but it does not always clearly explain the specific changes introduced during the merge process, especially the changes made when resolving merge conflicts.

git log --remerge-diff reconstructs the merge commit by replaying the recorded merge strategy and shows the exact changes introduced by the merge. This is very useful for debugging merge conflicts or reviewing complex merge histories.