This section explains how the community can contribute code to Django via pull
requests. If you’re interested in how core developers handle them, see
Committing code.

Below, we are going to show how to create a GitHub pull request containing the
changes for Trac ticket #xxxxx. By creating a fully-ready pull request you
will make the committers’ job easier, meaning that your work is more likely to
be merged into Django.

You could also upload a traditional patch to Trac, but it’s less practical for
reviews.

Note that user.name should be your real name, not your GitHub nick. GitHub
should know the email you use in the user.email field, as this will be
used to associate your commits with your GitHub account.

When you go to your GitHub page you will notice a new branch has been created.

If you are working on a Trac ticket, you should mention in the ticket that
your work is available from branch ticket_xxxxx of your github repo. Include a
link to your branch.

Note that the above branch is called a “topic branch” in Git parlance. You are
free to rewrite the history of this branch, by using gitrebase for
example. Other people shouldn’t base their work on such a branch, because
their clone would become corrupt when you edit commits.

There are also “public branches”. These are branches other people are supposed
to fork, so the history of these branches should never change. Good examples
of public branches are the master and stable/A.B.x branches in the
django/django repository.

When you think your work is ready to be pulled into Django, you should create
a pull request at GitHub. A good pull request means:

The test suite must pass and the documentation must build without warnings.

Once you have created your pull request, you should add a comment in the
related Trac ticket explaining what you’ve done. In particular you should note
the environment in which you ran the tests, for instance: “all tests pass
under SQLite and MySQL”.

Pull requests at GitHub have only two states: open and closed. The committer
who will deal with your pull request has only two options: merge it or close
it. For this reason, it isn’t useful to make a pull request until the code is
ready for merging – or sufficiently close that a committer will finish it
himself.

In the example above you created two commits, the “Fixed ticket_xxxxx” commit
and “Added two more tests” commit.

We do not want to have the entire history of your working process in your
repository. Your commit “Added two more tests” would be unhelpful noise.
Instead, we would rather only have one commit containing all your work.

To rework the history of your branch you can squash the commits into one by
using interactive rebase:

git rebase -i HEAD~2

The HEAD~2 above is shorthand for two latest commits. The above command
will open an editor showing the two commits, prefixed with the word “pick”.

Change “pick” on the second line to “squash” instead. This will keep the
first commit, and squash the second commit into the first one. Save and quit
the editor. A second editor window should open, so you can reword the
commit message for the commit now that it includes both your steps.

You can also use the “edit” option in rebase. This way you can change a single
commit, for example to fix a typo in a docstring:

git rebase -i HEAD~3
# Choose edit, pick, pick for the commits
# Now you are able to rework the commit (use git add normally to add changes)
# When finished, commit work with "--amend" and continue
git commit --amend
# reword the commit message if needed
git rebase --continue
# The second and third commits should be applied.

If your topic branch is already published at GitHub, for example if you’re
making minor changes to take into account a review, you will need to force-
push the changes:

git push -f origin ticket_xxxxx

Note that this will rewrite history of ticket_xxxxx - if you check the commit
hashes before and after the operation at GitHub you will notice that the
commit hashes do not match any more. This is acceptable, as the branch is merely
a topic branch, and nobody should be basing their work on it.

When upstream (django/django) has changed, you should rebase your work. To
do this, use:

git fetch upstream
git rebase

The work is automatically rebased using the branch you forked on, in the
example case using upstream/master.

The rebase command removes all your local commits temporarily, applies the
upstream commits, and then applies your local commits again on the work.

If there are merge conflicts you will need to resolve them and then use gitrebase--continue. At any point you can use gitrebase--abort to return
to the original state.

Note that you want to rebase on upstream, not merge the upstream.

The reason for this is that by rebasing, your commits will always be on
top of the upstream’s work, not mixed in with the changes in the upstream.
This way your branch will contain only commits related to its topic, which
makes squashing easier.

It is unusual to get any non-trivial amount of code into core without changes
requested by reviewers. In this case, it is often a good idea to add the
changes as one incremental commit to your work. This allows the reviewer to
easily check what changes you have done.

In this case, do the changes required by the reviewer. Commit as often as
necessary. Before publishing the changes, rebase your work. If you added two
commits, you would run:

git rebase -i HEAD~2

Squash the second commit into the first. Write a commit message along the lines
of:

Made changes asked in review by <reviewer>
- Fixed whitespace errors in foobar
- Reworded the docstring of bar()

Finally push your work back to your GitHub repository. Since you didn’t touch
the public commits during the rebase, you should not need to force-push:

git push origin ticket_xxxxx

Your pull request should now contain the new commit too.

Note that the committer is likely to squash the review commit into the previous
commit when committing the code.