<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Working with Git and GitHub — Django 1.5.9 documentation</title> <link rel="stylesheet" href="../../../_static/default.css" type="text/css" /> <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../../../', VERSION: '1.5.9', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../../../_static/jquery.js"></script> <script type="text/javascript" src="../../../_static/underscore.js"></script> <script type="text/javascript" src="../../../_static/doctools.js"></script> <link rel="top" title="Django 1.5.9 documentation" href="../../../index.html" /> <link rel="up" title="Writing code" href="index.html" /> <link rel="next" title="Writing documentation" href="../writing-documentation.html" /> <link rel="prev" title="Submitting patches" href="submitting-patches.html" /> <script type="text/javascript" src="../../../templatebuiltins.js"></script> <script type="text/javascript"> (function($) { if (!django_template_builtins) { // templatebuiltins.js missing, do nothing. return; } $(document).ready(function() { // Hyperlink Django template tags and filters var base = "../../../ref/templates/builtins.html"; if (base == "#") { // Special case for builtins.html itself base = ""; } // Tags are keywords, class '.k' $("div.highlight\\-html\\+django span.k").each(function(i, elem) { var tagname = $(elem).text(); if ($.inArray(tagname, django_template_builtins.ttags) != -1) { var fragment = tagname.replace(/_/, '-'); $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>"); } }); // Filters are functions, class '.nf' $("div.highlight\\-html\\+django span.nf").each(function(i, elem) { var filtername = $(elem).text(); if ($.inArray(filtername, django_template_builtins.tfilters) != -1) { var fragment = filtername.replace(/_/, '-'); $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>"); } }); }); })(jQuery); </script> </head> <body> <div class="document"> <div id="custom-doc" class="yui-t6"> <div id="hd"> <h1><a href="../../../index.html">Django 1.5.9 documentation</a></h1> <div id="global-nav"> <a title="Home page" href="../../../index.html">Home</a> | <a title="Table of contents" href="../../../contents.html">Table of contents</a> | <a title="Global index" href="../../../genindex.html">Index</a> | <a title="Module index" href="../../../py-modindex.html">Modules</a> </div> <div class="nav"> « <a href="submitting-patches.html" title="Submitting patches">previous</a> | <a href="../../index.html" title="Django internals" accesskey="U">up</a> | <a href="../writing-documentation.html" title="Writing documentation">next</a> »</div> </div> <div id="bd"> <div id="yui-main"> <div class="yui-b"> <div class="yui-g" id="internals-contributing-writing-code-working-with-git"> <div class="section" id="s-working-with-git-and-github"> <span id="working-with-git-and-github"></span><h1>Working with Git and GitHub<a class="headerlink" href="#working-with-git-and-github" title="Permalink to this headline">¶</a></h1> <p>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 <a class="reference internal" href="../committing-code.html"><em>Committing code</em></a>.</p> <p>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.</p> <p>You could also upload a traditional patch to Trac, but it’s less practical for reviews.</p> <div class="section" id="s-installing-git"> <span id="installing-git"></span><h2>Installing Git<a class="headerlink" href="#installing-git" title="Permalink to this headline">¶</a></h2> <p>Django uses <a class="reference external" href="http://git-scm.com/">Git</a> for its source control. You can <a class="reference external" href="http://git-scm.com/download">download</a> Git, but it’s often easier to install with your operating system’s package manager.</p> <p>Django’s <a class="reference external" href="https://github.com/django/django/">Git repository</a> is hosted on <a class="reference external" href="https://github.com/">GitHub</a>, and it is recommended that you also work using GitHub.</p> <p>After installing Git the first thing you should do is setup your name and email:</p> <div class="highlight-python"><pre>$ git config --global user.name "Your Real Name" $ git config --global user.email "you@email.com"</pre> </div> <p>Note that <tt class="docutils literal"><span class="pre">user.name</span></tt> should be your real name, not your GitHub nick. GitHub should know the email you use in the <tt class="docutils literal"><span class="pre">user.email</span></tt> field, as this will be used to associate your commits with your GitHub account.</p> </div> <div class="section" id="s-setting-up-local-repository"> <span id="setting-up-local-repository"></span><h2>Setting up local repository<a class="headerlink" href="#setting-up-local-repository" title="Permalink to this headline">¶</a></h2> <p>When you have created your GitHub account, with the nick “github_nick”, and forked Django’s repository, create a local copy of your fork:</p> <div class="highlight-python"><pre>git clone git@github.com:github_nick/django.git</pre> </div> <p>This will create a new directory “django”, containing a clone of your GitHub repository.</p> <p>Your GitHub repository will be called “origin” in Git.</p> <p>You should also setup django/django as an “upstream” remote (that is, tell git that the reference Django repository was the source of your fork of it):</p> <div class="highlight-python"><pre>git remote add upstream git@github.com:django/django.git git fetch upstream</pre> </div> <p>You can add other remotes similarly, for example:</p> <div class="highlight-python"><pre>git remote add akaariai git@github.com:akaariai/django.git</pre> </div> </div> <div class="section" id="s-working-on-a-ticket"> <span id="working-on-a-ticket"></span><h2>Working on a ticket<a class="headerlink" href="#working-on-a-ticket" title="Permalink to this headline">¶</a></h2> <p>When working on a ticket create a new branch for the work, and base that work on upstream/master:</p> <div class="highlight-python"><pre>git checkout -b ticket_xxxxx upstream/master</pre> </div> <p>The -b flag creates a new branch for you locally. Don’t hesitate to create new branches even for the smallest things - that’s what they are there for.</p> <p>If instead you were working for a fix on the 1.4 branch, you would do:</p> <div class="highlight-python"><pre>git checkout -b ticket_xxxxx_1_4 upstream/stable/1.4.x</pre> </div> <p>Assume the work is carried on ticket_xxxxx branch. Make some changes and commit them:</p> <div class="highlight-python"><pre>git commit</pre> </div> <p>When writing the commit message, follow the <a class="reference internal" href="../committing-code.html#committing-guidelines"><em>commit message guidelines</em></a> to ease the work of the committer. If you’re uncomfortable with English, try at least to describe precisely what the commit does.</p> <p>If you need to do additional work on your branch, commit as often as necessary:</p> <div class="highlight-python"><pre>git commit -m 'Added two more tests for edge cases'</pre> </div> <div class="section" id="s-publishing-work"> <span id="publishing-work"></span><h3>Publishing work<a class="headerlink" href="#publishing-work" title="Permalink to this headline">¶</a></h3> <p>You can publish your work on GitHub just by doing:</p> <div class="highlight-python"><pre>git push origin ticket_xxxxx</pre> </div> <p>When you go to your GitHub page you will notice a new branch has been created.</p> <p>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.</p> <p>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 <tt class="docutils literal"><span class="pre">git</span> <span class="pre">rebase</span></tt> for example. Other people shouldn’t base their work on such a branch, because their clone would become corrupt when you edit commits.</p> <p>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 <tt class="docutils literal"><span class="pre">master</span></tt> and <tt class="docutils literal"><span class="pre">stable/A.B.x</span></tt> branches in the django/django repository.</p> <p>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:</p> <ul class="simple"> <li>commits with one logical change in each, following the <a class="reference internal" href="coding-style.html"><em>coding style</em></a>,</li> <li>well-formed messages for each commit: a summary line and then paragraphs wrapped at 72 characters thereafter – see the <a class="reference internal" href="../committing-code.html#committing-guidelines"><em>committing guidelines</em></a> for more details,</li> <li>documentation and tests, if needed – actually tests are always needed, except for documentation changes.</li> </ul> <p>The test suite must pass and the documentation must build without warnings.</p> <p>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”.</p> <p>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.</p> </div> <div class="section" id="s-rebasing-branches"> <span id="rebasing-branches"></span><h3>Rebasing branches<a class="headerlink" href="#rebasing-branches" title="Permalink to this headline">¶</a></h3> <p>In the example above you created two commits, the “Fixed ticket_xxxxx” commit and “Added two more tests” commit.</p> <p>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.</p> <p>To rework the history of your branch you can squash the commits into one by using interactive rebase:</p> <div class="highlight-python"><pre>git rebase -i HEAD~2</pre> </div> <p>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”.</p> <p>Change 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.</p> <p>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:</p> <div class="highlight-python"><pre>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.</pre> </div> <p>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:</p> <div class="highlight-python"><pre>git push -f origin ticket_xxxxx</pre> </div> <p>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.</p> </div> <div class="section" id="s-after-upstream-has-changed"> <span id="after-upstream-has-changed"></span><h3>After upstream has changed<a class="headerlink" href="#after-upstream-has-changed" title="Permalink to this headline">¶</a></h3> <p>When upstream (django/django) has changed, you should rebase your work. To do this, use:</p> <div class="highlight-python"><pre>git fetch upstream git rebase</pre> </div> <p>The work is automatically rebased using the branch you forked on, in the example case using upstream/master.</p> <p>The rebase command removes all your local commits temporarily, applies the upstream commits, and then applies your local commits again on the work.</p> <p>If there are merge conflicts you will need to resolve them and then use <tt class="docutils literal"><span class="pre">git</span> <span class="pre">rebase</span> <span class="pre">--continue</span></tt>. At any point you can use <tt class="docutils literal"><span class="pre">git</span> <span class="pre">rebase</span> <span class="pre">--abort</span></tt> to return to the original state.</p> <p>Note that you want to <em>rebase</em> on upstream, not <em>merge</em> the upstream.</p> <p>The reason for this is that by rebasing, your commits will always be <em>on top of</em> the upstream’s work, not <em>mixed in with</em> the changes in the upstream. This way your branch will contain only commits related to its topic, which makes squashing easier.</p> </div> <div class="section" id="s-after-review"> <span id="after-review"></span><h3>After review<a class="headerlink" href="#after-review" title="Permalink to this headline">¶</a></h3> <p>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.</p> <p>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:</p> <div class="highlight-python"><pre>git rebase -i HEAD~2</pre> </div> <p>Squash the second commit into the first. Write a commit message along the lines of:</p> <div class="highlight-python"><pre>Made changes asked in review by <reviewer> - Fixed whitespace errors in foobar - Reworded the docstring of bar()</pre> </div> <p>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:</p> <div class="highlight-python"><pre>git push origin ticket_xxxxx</pre> </div> <p>Your pull request should now contain the new commit too.</p> <p>Note that the committer is likely to squash the review commit into the previous commit when committing the code.</p> </div> </div> <div class="section" id="s-working-on-a-patch"> <span id="working-on-a-patch"></span><h2>Working on a patch<a class="headerlink" href="#working-on-a-patch" title="Permalink to this headline">¶</a></h2> <p>One of the ways that developers can contribute to Django is by reviewing patches. Those patches will typically exist as pull requests on GitHub and can be easily integrated into your local repository:</p> <div class="highlight-python"><pre>git checkout -b pull_xxxxx upstream/master curl https://github.com/django/django/pull/xxxxx.patch | git am</pre> </div> <p>This will create a new branch and then apply the changes from the pull request to it. At this point you can run the tests or do anything else you need to do to investigate the quality of the patch.</p> <p>For more detail on working with pull requests see the <a class="reference internal" href="../committing-code.html#handling-pull-requests"><em>guidelines for committers</em></a>.</p> </div> <div class="section" id="s-summary"> <span id="summary"></span><h2>Summary<a class="headerlink" href="#summary" title="Permalink to this headline">¶</a></h2> <ul class="simple"> <li>Work on GitHub if you can.</li> <li>Announce your work on the Trac ticket by linking to your GitHub branch.</li> <li>When you have something ready, make a pull request.</li> <li>Make your pull requests as good as you can.</li> <li>When doing fixes to your work, use <tt class="docutils literal"><span class="pre">git</span> <span class="pre">rebase</span> <span class="pre">-i</span></tt> to squash the commits.</li> <li>When upstream has changed, do <tt class="docutils literal"><span class="pre">git</span> <span class="pre">fetch</span> <span class="pre">upstream;</span> <span class="pre">git</span> <span class="pre">rebase</span></tt>.</li> </ul> </div> </div> </div> </div> </div> <div class="yui-b" id="sidebar"> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <h3><a href="../../../contents.html">Table Of Contents</a></h3> <ul> <li><a class="reference internal" href="#">Working with Git and GitHub</a><ul> <li><a class="reference internal" href="#installing-git">Installing Git</a></li> <li><a class="reference internal" href="#setting-up-local-repository">Setting up local repository</a></li> <li><a class="reference internal" href="#working-on-a-ticket">Working on a ticket</a><ul> <li><a class="reference internal" href="#publishing-work">Publishing work</a></li> <li><a class="reference internal" href="#rebasing-branches">Rebasing branches</a></li> <li><a class="reference internal" href="#after-upstream-has-changed">After upstream has changed</a></li> <li><a class="reference internal" href="#after-review">After review</a></li> </ul> </li> <li><a class="reference internal" href="#working-on-a-patch">Working on a patch</a></li> <li><a class="reference internal" href="#summary">Summary</a></li> </ul> </li> </ul> <h3>Browse</h3> <ul> <li>Prev: <a href="submitting-patches.html">Submitting patches</a></li> <li>Next: <a href="../writing-documentation.html">Writing documentation</a></li> </ul> <h3>You are here:</h3> <ul> <li> <a href="../../../index.html">Django 1.5.9 documentation</a> <ul><li><a href="../../index.html">Django internals</a> <ul><li><a href="../index.html">Contributing to Django</a> <ul><li><a href="index.html">Writing code</a> <ul><li>Working with Git and GitHub</li></ul> </li></ul></li></ul></li></ul> </li> </ul> <h3>This Page</h3> <ul class="this-page-menu"> <li><a href="../../../_sources/internals/contributing/writing-code/working-with-git.txt" rel="nofollow">Show Source</a></li> </ul> <div id="searchbox" style="display: none"> <h3>Quick search</h3> <form class="search" action="../../../search.html" method="get"> <input type="text" name="q" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <h3>Last update:</h3> <p class="topless">Aug 21, 2014</p> </div> </div> <div id="ft"> <div class="nav"> « <a href="submitting-patches.html" title="Submitting patches">previous</a> | <a href="../../index.html" title="Django internals" accesskey="U">up</a> | <a href="../writing-documentation.html" title="Writing documentation">next</a> »</div> </div> </div> <div class="clearer"></div> </div> </body> </html>