The open source Git project just released Git 2.19, with features and bug-fixes
from over 60 contributors.
Here’s a look at some of the most interesting features introduced in the latest
versions of Git.
Compare histories with
You might have used
git rebase, which is a powerful tool for rewriting history
by altering commits, commit order, or branch bases to name a few. Many people
do this to “polish” a series of commits before proposing to merge them into a
project. But how can we visualize the differences between two sets of commits,
before and after a rebase?
We can use
git diff to show the difference between the two end states, but
that doesn’t provide information about the individual commits. And if the base
on which the commits were built has changed, the resulting state might be
quite different, even if the changes in the commits are largely the same.
Git 2.19 introduces
git range-diff, a tool for comparing two sequences of
commits, including changes to their order, commit messages, and the actual
content changes they introduce.
In this example, we rewrote a series of three commits, and compared the tips of
each version using
git range-diff shows that we moved the
README.md to be first instead of second, amended both the
commit message and body of the typo fix, and introduced a new commit to add a
git grep‘s new tricks
When you search for a phrase using
git grep, it’s often helpful to have
additional information pertaining to each match, such as its line number and
In Git 2.19 you can now locate the first matching column of your query with
git grep --column.
If you’re using Vim, you can also try out
git-jump, a Git add-on that
converts useful locations in your code to jump locations in your text editor.
git-jump can take you to merge conflicts, diff hunks, and now, exact grep
git grep --column.
git grep also learned the new
-o option (meaning
--only-matching). This is
useful if you have a non-trivial regular expression and want to gather only the
matching parts of your search.
For example, if you want to count all of the various ways that the Git source
code spells “SHA-1” (e.g., “sha1”, “SHA1”, and so on):
(The other options
-hiI are to omit the filename, search case-insensitively,
and ignore matches in binary files, respectively.)
git branch command, like
git tag (and their scriptable counterpart,
git for-each-ref), takes a
--sort option to let you order the results by a number
of properties. For example, to show branches in the order of most recent update,
you could use
git branch --sort=-authordate. But if you always prefer that
order, typing that sort option can get tiresome.
Now, you can use the
branch.sort config to set the default ordering of
Note that by default,
git branch sorts by refname, hence
master is first and
newest is last. In the above example, we tell Git that we would instead prefer
the most recently updated branch first, and the rest in descending order. Hence,
newest is first and
master is last.
You might also want to try these other sorting options:
--sort=numparentshows merges by how awesome they are
--sort=refnamesorts branches alphabetically by their name (this is the
default, but may be useful to override in your configuration)
--sort=upstreamsorts branches by the remote from which they originate
Git has always detected renamed files as part of merges. For example, if one
branch moves a file from
B and another modifies content in
the resulting merge will apply that modification to the content’s new location
The same thing can happen with files in a directory. If one branch moves a
B but another adds a new file
A/file, we can infer
that the file should become
B/file when the two are merged. In Git 2.18,
git merge does this whenever rename detection is enabled (which is by default).
In Git v2.18, a remote code execution vulnerability in
fixed, where an attacker could execute scripts when the victim cloned with
--recurse-submodules. If you haven’t upgraded, please do! The fix was also
backported to v2.17.1, v2.16.4, v2.15.2, v2.14.4, and v2.13.7, so you’re safe
if you’re running one of those.
Have you ever run into a Git command line option that should have
tab-completed but didn’t? Keeping these up to date has long been an annoying
source of manual work for the project, but now the completion of options for
most commands is generated automatically (along with the list of commands
itself, the names of config options, and more).
gpgsigning and verification of commits and tags has been extended to work
gpgsm, which uses X.509 certificates instead of OpenPGP keys. These
certificates may be easier to manage for centralized groups (e.g., developers
working for a large enterprise).
To fetch a configuration variable with a “fallback” value, it’s common for
scripts to say
git config core.myFoo || echo <default>. But that doesn’t
give Git the opportunity to interpret
<default>for you. When it comes to
colors, this is especially important for instances where you ultimately need
the ANSI color code, for say, “bold red”, but don’t want to type