Deploying with Git
Last updated 12 September 2017
Table of Contents
- Prerequisites: Installing Git and the Heroku CLI
- Tracking your app in Git
- Creating a Heroku remote
- Deploying code
- Build deploy ordering
- Detach from build process
- HTTP Git authentication
- SSH Git transport
- Multiple remotes and environments
- Build cache
- Repository size
- Other limits
- Using subversion or other revision control systems
- Additional resources
Heroku manages app deployments with Git, the popular version control system. You definitely don’t need to be a Git expert to deploy code to Heroku, but it’s helpful to learn the basics.
Prerequisites: Installing Git and the Heroku CLI
Tracking your app in Git
Before you can deploy your app to Heroku, you need to initialize a local Git repository and commit your application code to it.
The following example demonstrates initializing a Git repository for an app that lives in the
$ cd myapp $ git init Initialized empty Git repository in .git/ $ git add . $ git commit -m "My first commit" Created initial commit 5df2d09: My first commit 44 files changed, 8393 insertions(+), 0 deletions(-) create mode 100644 README create mode 100644 Procfile create mode 100644 app/controllers/source_file ...
Be sure to initialize the Git repository in your app’s root directory. If your app is in a subdirectory of your repository, it won’t run when it is pushed to Heroku.
Your app’s code is now tracked in a local Git repository. It has not yet been pushed to any remote servers.
Creating a Heroku remote
Git remotes are versions of your repository that live on other servers. You deploy your app’s code by pushing it to a special Heroku-hosted remote that’s associated with your app.
For a new Heroku app
heroku create CLI command creates a new empty application on Heroku, along with an associated empty Git repository. If you run this command from your app’s root directory, the empty Heroku Git repository is automatically set as a remote for your local repository.
$ heroku create Creating app... done, ⬢ thawing-inlet-61413 https://thawing-inlet-61413.herokuapp.com/ | https://git.heroku.com/thawing-inlet-61413.git
You can use the
git remote command to confirm that a remote named
heroku has been set for your app:
$ git remote -v heroku https://git.heroku.com/thawing-inlet-61413.git (fetch) heroku https://git.heroku.com/thawing-inlet-61413.git (push)
For an existing Heroku app
If you have already created your Heroku app, you can easily add a remote to your local repository with the
heroku git:remote command. All you need is your Heroku app’s name:
$ heroku git:remote -a thawing-inlet-61413 set git remote heroku to https://git.heroku.com/thawing-inlet-61413.git
By default, the Heroku CLI names all of the Heroku remotes it creates for your app
heroku. You can rename your remotes with the
git remote rename command:
$ git remote rename heroku heroku-staging
Renaming your Heroku remote can be handy if you have multiple Heroku apps that use the same codebase (for example, the staging and production versions of an app). In this case, each Heroku app has its own remote in your local repository.
The remainder of this article assumes your app has a single Heroku remote that is named
To deploy your app to Heroku, you typically use the
git push command to push the code from your local repository’s
master branch to your
heroku remote, like so:
$ git push heroku master Initializing repository, done. updating 'refs/heads/master' ...
Use this same command whenever you want to deploy the latest committed version of your code to Heroku.
Note that Heroku only deploys code that is pushed to the
master branch of your
heroku remote. Pushing code to another branch of the remote has no effect.
If you want to deploy code to Heroku from a non-
master branch of your local repository (such as
testbranch), use the following syntax to ensure it is pushed to the remote’s
$ git push heroku testbranch:master
Applications that rely on Git submodules are supported, in addition to many other dependency resolution strategies.
git lfs is not supported, and using it might cause pushes to fail.
Build deploy ordering
If multiple parallel builds are started for an app (either by the same user performing multiple pushes, by app collaborators pushing concurrently or because builds are created concurrently with other mechanisms like Build API or GitHub Sync), then the last build to complete will generally be the one that ends up being deployed for the app, even if that build was started before other builds.
Take an example of two builds, A and B: Build A is started, runs slowly and completes in 2 minutes. 30 seconds after build A is started, build B is started and completes in 1 minute. Build B is deployed for the app when it completes. 30 seconds later, build A completes and is deployed for the app. The end result is that build A is deployed on the app, even though build B was started later.
Detach from build process
When deploying code using
git push, you can detach from the build process by pressing Ctrl + C. However, your build will continue to process in the background and will create a new release as soon as it finished.
HTTP Git authentication
By default, Heroku uses HTTP as its Git transport. The Heroku CLI will automatically place credentials in the
.netrc file on
heroku login. The Git client uses cURL when interacting with HTTP remotes, and cURL will use the credentials from the
.netrc file. See the Authentication section and the CLI authentication article for details.
The Heroku HTTP Git endpoint only accepts API-key based HTTP Basic authentication. A username is not required and any value passed for username is ignored.
You cannot authenticate with the Heroku HTTP Git endpoint using your Heroku username (email) and password. Use an API key as described in this section
If, for any reason, you authenticate to the Git service with incorrect credentials, you’ll get this error:
remote: ! WARNING: remote: ! Do not authenticate with username and password using git. remote: ! Run `heroku login` to update your credentials, then retry the git command. remote: ! See documentation for details: https://devcenter.heroku.com/articles/git#http-git-authentication
When you do
heroku login, the CLI will write an entry for
git.heroku.com into your
.netrc file (or its Windows equivalent). Since the Git client uses cURL when interacting with HTTP Git remotes, correct authentication will now happen transparently.
If you’re using other Git clients, such as EGit or Tower, configure them to use an empty string for username (or any string you like – it’s ignored) and your account API key for password. The API key is available in the CLI and in Dashboard.
SSH Git transport
The default Git transport configured by the Heroku CLI is HTTP, but SSH transport is also supported. SSH and HTTP transport can be used interchangeably by the same user and by multiple users collaborating on the same app. To have the Heroku CLI configure SSH transport, you can pass a
--ssh-git flag to the
heroku git:remote and
heroku git:clone commands.
$ heroku create --ssh-git
To use SSH Git transport, you have to register your SSH key with Heroku. See the Managing SSH Keys article for details.
If you want to always use SSH Git with Heroku on a particular machine, you can add the following global config:
$ git config --global url.ssh://email@example.com/.insteadOf https://git.heroku.com/
HTTP URLs will still be written to
.git folders but Git will rewrite, on the fly, all Heroku HTTP Git URLs to use SSH.
To remove this rewrite setting, run:
$ git config --global --remove-section url.ssh://firstname.lastname@example.org/
SSH is not supported for SSO users. SSO users must use HTTPS as a git transport.
Multiple remotes and environments
The same techniques used to deploy to production can be used to deploy a development branch of your application to a staging application on Heroku, as described in Managing Multiple Environments for an App.
Buildpacks can optionally cache content for re-use between builds. A typical use-case for the buildpack is to speed up builds by caching dependencies so that they don’t have to be re-fetched on every build. This greatly speeds up builds.
If you suspect that a build-problem is related to this caching, you can use the
heroku-repo plugin to clear the cache.
While there is not a hard limit on your repository size, very large
repositories (over 600 MB) are not recommended; they may cause timeouts
and slow pushes overall. Running
heroku apps:info will show you your
repository size. The app build cache is stored inside the app repository, so
don’t be surprised if the repository is larger remotely than locally.
Common causes of large repositories are binary files checked into the
repository (Git is notoriously bad at handling binaries) or
constantly-changing development logs. Removing files committed by
accident can be done with
though after running it you will have to push with the
option, which is something that requires coordination among your team.
To protect the Git service, Heroku imposes certain limits on Git repository use and content size.
Users are limited to a rolling window of 75 Git requests per hour, per user, per app. Once this limit is reached, Git requests are denied until request levels drop below the limit for a few minutes, with the error message:
! Too many requests for this Git repo. Please try again later.
If you reach this limit, ensure there are not automated processes or scripts polling the Git repository.
In addition, the uncompressed size of a checkout of
HEAD from the repository, combined with the size of restored submodules, cannot exceed 1 GB.
Using subversion or other revision control systems
What if you’re already using Subversion or another revision control system to track your source code? Although we believe that Git is one of the best choices available for revision control, you don’t need to stop using your current revision control system. Git can be purely a deployment mechanism, existing side-by-side with your other tool.
You can learn much more about
.gitignore in our article on the topic.
For example, if you are using Subversion, initialize your Git repository as described above. Then, add a
.gitignore file to tell Git to ignore your Subversion directories.
$ git init $ echo .svn > .gitignore $ git add . $ git commit -m "using git for heroku deployment"
Now tell Subversion to ignore Git:
$ svn propset svn:ignore .git . property 'svn:ignore' set on '.' $ svn commit -m "ignoring git folder (git is used for heroku deployment)"
-f (force flag) is recommended in order to avoid conflicts with other developers’ pushes. Since you are not using Git for your revision control, but as a transport only, using the force flag is a reasonable practice.
Each time you wish to deploy to Heroku:
$ git add -A $ git commit -m "commit for deploy to heroku" ... $ git push -f heroku