Git 2.3 has been released
The Git developers have just released a major new version of the Git command-line utility, Git 2.3.0. As usual, this release contains many improvements, performance enhancements, and bug fixes. Full…
The Git developers have just released a major new version of the Git command-line utility, Git 2.3.0.
As usual, this release contains many improvements, performance enhancements, and bug fixes. Full details about what’s included can be found in the Git 2.3.0 release notes, but here’s a look at what we consider to be the coolest new features in this release.
Push to deploy
One way to deploy a Git-based web project is to keep a checked-out working copy on your server. When a new version is ready, you log into the server and run git pull
to fetch and deploy the new changes. While this technique has some disadvantages (see below), it is very easy to set up and use, especially if your project consists mostly of static content.
With Git 2.3, this technique has become even more convenient. Now you can push changes directly to the repository on your server. Provided no local modifications have been made on the server, any changes to the server’s current branch will be checked out automatically. Instant deploy!
To use this feature, you have to first enable it in the Git repository on your server by running
$ git config receive.denyCurrentBranch updateInstead
When shouldn’t you use push-to-deploy?
Deploying by pushing to a Git repository is quick and convenient, but it is not for everybody. For example:
- Your server will contain a
.git
directory containing the entire history of your project. You probably want to make extra sure that it cannot be served to users! - During deploys, it will be possible for users momentarily to encounter the site in an inconsistent state, with some files at the old version and others at the new version, or even half-written files. If this is a problem for your project, push-to-deploy is probably not for you.
- If your project needs a “build” step, then you will have to set that up explicitly, perhaps via githooks.
See how this feature was implemented
Faster cloning by borrowing objects from existing clones
Cloning a remote repository can involve transferring a lot of data over the network. But if you already have another local clone of the same repository, it probably already has most of the history that the new clone will need. Now it is easy to use those local objects rather than transferring them again:
$ git clone --reference ../oldclone --dissociate https://github.com/gitster/git.git
The new --dissociate
option tells Git to copy any objects it can from local repository ../oldclone
, retrieving the remainder from the remote repository. Afterwards, the two clones remain independent; either one can be deleted without impacting the other (unlike when --reference
is used without --dissociate
).
See how this feature was implemented
More conservative default behavior for git push
If you run git push
without arguments, Git now uses the more conservative simple
behavior as the default. This means that Git refuses to push anything unless you have defined an “upstream” branch for your current branch and the upstream branch has the same name as your current branch. For example:
$ git config branch.autosetupmerge true
$ git checkout -b experimental origin/master
Branch experimental set up to track remote branch master from origin.
Switched to a new branch 'experimental'
$ git commit -a -m 'Experimental changes'
[experimental 43ca356] Experimental changes
$ git push
fatal: The upstream branch of your current branch does not match
the name of your current branch. To push to the upstream branch
on the remote, use
git push origin HEAD:master
To push to the branch of the same name on the remote, use
git push origin experimental
$
The new default behavior is meant to help users avoid pushing changes to the wrong branch by accident. In the case above, the experimental
branch started out tracking master
, but the user probably wanted to push the experimental
branch to a new remote branch called experimental
. So the correct command would be git push origin experimental
.
The default behavior can be changed by configuring push.default
. If you want to go back to the version 1.x behavior, set it to matching
:
$ git config --global push.default matching
See how this feature was implemented
More flexible ssh
invocation
Git knows how to connect to a remote host via the SSH protocol, but sometimes you need to tweak exactly how it makes the connection. If so, you can now use a new shell variable, GIT_SSH_COMMAND
, to specify the command (including arguments) or even an arbitrary snippet of Shell code that Git should use to connect to the remote host. For example, if you need to use a different SSH identity file when connecting to a Git server, you could enter
$ GIT_SSH_COMMAND='ssh -i git_id' git clone host:repo.git
See how this feature was implemented
The credential subsystem is now friendlier to scripting
When Git needs a password (e.g., to connect to a remote repository over http), it uses the credential subsystem to query any helpers (like the OS X Keychain helper), and then finally prompts the user on the terminal. When Git is run from an automated process like a cron
job, there is usually no terminal available and Git will skip the prompt. However, if there is a terminal available, Git may hang forever, waiting for the user to type something. Scripts which do not expect user input can now set GIT_TERMINAL_PROMPT=0
in the environment to avoid this behavior.
See how this feature was implemented
Other
Some other useful tidbits:
- Now Git is cleverer about not rewriting paths in the working tree unnecessarily when checking out particular commits. This will help reduce the amount of redundant work done during software builds and reduce the time that incomplete files are present on the filesystem (especially helpful if you are using push-to-deploy). See how this feature was implemented
- Now
git branch -d
supports a--force/-f
option, which can be used to delete a branch even if it hasn’t been merged yet. Similarly,git branch -m
supports--force/-f
, which allows a branch to be renamed even if the new name is already in use. This change makes these commands more consistent with the many other Git commands that support--force/-f
. See how these features were implemented
Additional resources
- The main Git website
- The book Pro Git (available online); including its chapter about installing Git
- GitHub’s Guide to setting up Git and other help articles
Don’t forget: an important Git security vulnerability was fixed last December. If you haven’t upgraded your Git client since then, we recommend that you do so as soon as possible. The new release, 2.3.0, includes the security fix, as do the maintenance releases 1.8.5.6, 1.9.5, 2.0.5, and 2.1.4, which were released in December.
Written by
Related posts
What the EU’s new software legislation means for developers
The EU Cyber Resilience Act will introduce new cybersecurity requirements for software released in the EU. Learn what it means for your open source projects and what GitHub is doing to ensure the law will be a net win for open source maintainers.
Game Off 2024 theme announcement
GitHub’s annual month-long game jam, where creativity knows no limits! Throughout November, dive into your favorite game engines, libraries, and programming languages to bring your wildest game ideas to life. Whether you’re a seasoned dev or just getting started, it’s all about having fun and making something awesome!
Highlights from Git 2.47
Git 2.47 is here, with features like incremental multi-pack indexes and more. Check out our coverage of some of the highlights here.