1. ===========================
    
  2. Working with Git and GitHub
    
  3. ===========================
    
  4. 
    
  5. This section explains how the community can contribute code to Django via pull
    
  6. requests. If you're interested in how :ref:`mergers <mergers-team>` handle
    
  7. them, see :doc:`../committing-code`.
    
  8. 
    
  9. Below, we are going to show how to create a GitHub pull request containing the
    
  10. changes for Trac ticket #xxxxx. By creating a fully-ready pull request, you
    
  11. will make the reviewer's job easier, meaning that your work is more likely to
    
  12. be merged into Django.
    
  13. 
    
  14. You could also upload a traditional patch to Trac, but it's less practical for
    
  15. reviews.
    
  16. 
    
  17. Installing Git
    
  18. ==============
    
  19. 
    
  20. Django uses `Git`_ for its source control. You can `download
    
  21. <https://git-scm.com/download>`_ Git, but it's often easier to install with
    
  22. your operating system's package manager.
    
  23. 
    
  24. Django's `Git repository`_ is hosted on `GitHub`_, and it is recommended
    
  25. that you also work using GitHub.
    
  26. 
    
  27. After installing Git, the first thing you should do is set up your name and
    
  28. email::
    
  29. 
    
  30.   $ git config --global user.name "Your Real Name"
    
  31.   $ git config --global user.email "[email protected]"
    
  32. 
    
  33. Note that ``user.name`` should be your real name, not your GitHub nick. GitHub
    
  34. should know the email you use in the ``user.email`` field, as this will be
    
  35. used to associate your commits with your GitHub account.
    
  36. 
    
  37. .. _Git: https://git-scm.com/
    
  38. .. _Git repository: https://github.com/django/django/
    
  39. .. _GitHub: https://github.com/
    
  40. 
    
  41. Setting up local repository
    
  42. ===========================
    
  43. 
    
  44. When you have created your GitHub account, with the nick "GitHub_nick", and
    
  45. `forked Django's repository <https://github.com/django/django/fork>`__,
    
  46. create a local copy of your fork::
    
  47. 
    
  48.     git clone https://github.com/GitHub_nick/django.git
    
  49. 
    
  50. This will create a new directory "django", containing a clone of your GitHub
    
  51. repository. The rest of the git commands on this page need to be run within the
    
  52. cloned directory, so switch to it now::
    
  53. 
    
  54.     cd django
    
  55. 
    
  56. Your GitHub repository will be called "origin" in Git.
    
  57. 
    
  58. You should also set up ``django/django`` as an "upstream" remote (that is, tell
    
  59. git that the reference Django repository was the source of your fork of it)::
    
  60. 
    
  61.     git remote add upstream https://github.com/django/django.git
    
  62.     git fetch upstream
    
  63. 
    
  64. You can add other remotes similarly, for example::
    
  65. 
    
  66.     git remote add akaariai https://github.com/akaariai/django.git
    
  67. 
    
  68. Working on a ticket
    
  69. ===================
    
  70. 
    
  71. When working on a ticket, create a new branch for the work, and base that work
    
  72. on ``upstream/main``::
    
  73. 
    
  74.     git checkout -b ticket_xxxxx upstream/main
    
  75. 
    
  76. The -b flag creates a new branch for you locally. Don't hesitate to create new
    
  77. branches even for the smallest things - that's what they are there for.
    
  78. 
    
  79. If instead you were working for a fix on the 1.4 branch, you would do::
    
  80. 
    
  81.     git checkout -b ticket_xxxxx_1_4 upstream/stable/1.4.x
    
  82. 
    
  83. Assume the work is carried on the ticket_xxxxx branch. Make some changes and
    
  84. commit them::
    
  85. 
    
  86.     git commit
    
  87. 
    
  88. When writing the commit message, follow the :ref:`commit message
    
  89. guidelines <committing-guidelines>` to ease the work of the merger. If you're
    
  90. uncomfortable with English, try at least to describe precisely what the commit
    
  91. does.
    
  92. 
    
  93. If you need to do additional work on your branch, commit as often as
    
  94. necessary::
    
  95. 
    
  96.     git commit -m 'Added two more tests for edge cases'
    
  97. 
    
  98. Publishing work
    
  99. ---------------
    
  100. 
    
  101. You can publish your work on GitHub by running::
    
  102. 
    
  103.   git push origin ticket_xxxxx
    
  104. 
    
  105. When you go to your GitHub page, you will notice a new branch has been created.
    
  106. 
    
  107. If you are working on a Trac ticket, you should mention in the ticket that
    
  108. your work is available from branch ticket_xxxxx of your GitHub repo. Include a
    
  109. link to your branch.
    
  110. 
    
  111. Note that the above branch is called a "topic branch" in Git parlance. You are
    
  112. free to rewrite the history of this branch, by using ``git rebase`` for
    
  113. example. Other people shouldn't base their work on such a branch, because
    
  114. their clone would become corrupt when you edit commits.
    
  115. 
    
  116. There are also "public branches". These are branches other people are supposed
    
  117. to fork, so the history of these branches should never change. Good examples
    
  118. of public branches are the ``main`` and ``stable/A.B.x`` branches in the
    
  119. ``django/django`` repository.
    
  120. 
    
  121. When you think your work is ready to be pulled into Django, you should create
    
  122. a pull request at GitHub. A good pull request means:
    
  123. 
    
  124. * commits with one logical change in each, following the
    
  125.   :doc:`coding style <coding-style>`,
    
  126. 
    
  127. * well-formed messages for each commit: a summary line and then paragraphs
    
  128.   wrapped at 72 characters thereafter -- see the :ref:`committing guidelines
    
  129.   <committing-guidelines>` for more details,
    
  130. 
    
  131. * documentation and tests, if needed -- actually tests are always needed,
    
  132.   except for documentation changes.
    
  133. 
    
  134. The test suite must pass and the documentation must build without warnings.
    
  135. 
    
  136. Once you have created your pull request, you should add a comment in the
    
  137. related Trac ticket explaining what you've done. In particular, you should note
    
  138. the environment in which you ran the tests, for instance: "all tests pass
    
  139. under SQLite and MySQL".
    
  140. 
    
  141. Pull requests at GitHub have only two states: open and closed. The merger who
    
  142. will deal with your pull request has only two options: merge it or close it.
    
  143. For this reason, it isn't useful to make a pull request until the code is ready
    
  144. for merging -- or sufficiently close that a merger will finish it themselves.
    
  145. 
    
  146. Rebasing branches
    
  147. -----------------
    
  148. 
    
  149. In the example above, you created two commits, the "Fixed ticket_xxxxx" commit
    
  150. and "Added two more tests" commit.
    
  151. 
    
  152. We do not want to have the entire history of your working process in your
    
  153. repository. Your commit "Added two more tests" would be unhelpful noise.
    
  154. Instead, we would rather only have one commit containing all your work.
    
  155. 
    
  156. To rework the history of your branch you can squash the commits into one by
    
  157. using interactive rebase::
    
  158. 
    
  159.     git rebase -i HEAD~2
    
  160. 
    
  161. The HEAD~2 above is shorthand for two latest commits. The above command
    
  162. will open an editor showing the two commits, prefixed with the word "pick".
    
  163. 
    
  164. Change "pick" on the second line to "squash" instead. This will keep the
    
  165. first commit, and squash the second commit into the first one. Save and quit
    
  166. the editor. A second editor window should open, so you can reword the
    
  167. commit message for the commit now that it includes both your steps.
    
  168. 
    
  169. You can also use the "edit" option in rebase. This way you can change a single
    
  170. commit, for example to fix a typo in a docstring::
    
  171. 
    
  172.     git rebase -i HEAD~3
    
  173.     # Choose edit, pick, pick for the commits
    
  174.     # Now you are able to rework the commit (use git add normally to add changes)
    
  175.     # When finished, commit work with "--amend" and continue
    
  176.     git commit --amend
    
  177.     # Reword the commit message if needed
    
  178.     git rebase --continue
    
  179.     # The second and third commits should be applied.
    
  180. 
    
  181. If your topic branch is already published at GitHub, for example if you're
    
  182. making minor changes to take into account a review, you will need to force-push
    
  183. the changes::
    
  184. 
    
  185.     git push -f origin ticket_xxxxx
    
  186. 
    
  187. Note that this will rewrite history of ticket_xxxxx - if you check the commit
    
  188. hashes before and after the operation at GitHub you will notice that the commit
    
  189. hashes do not match anymore. This is acceptable, as the branch is a topic
    
  190. branch, and nobody should be basing their work on it.
    
  191. 
    
  192. After upstream has changed
    
  193. --------------------------
    
  194. 
    
  195. When upstream (``django/django``) has changed, you should rebase your work. To
    
  196. do this, use::
    
  197. 
    
  198.   git fetch upstream
    
  199.   git rebase upstream/main
    
  200. 
    
  201. The work is automatically rebased using the branch you forked on, in the
    
  202. example case using ``upstream/main``.
    
  203. 
    
  204. The rebase command removes all your local commits temporarily, applies the
    
  205. upstream commits, and then applies your local commits again on the work.
    
  206. 
    
  207. If there are merge conflicts, you will need to resolve them and then use ``git
    
  208. rebase --continue``. At any point you can use ``git rebase --abort`` to return
    
  209. to the original state.
    
  210. 
    
  211. Note that you want to *rebase* on upstream, not *merge* the upstream.
    
  212. 
    
  213. The reason for this is that by rebasing, your commits will always be *on
    
  214. top of* the upstream's work, not *mixed in with* the changes in the upstream.
    
  215. This way your branch will contain only commits related to its topic, which
    
  216. makes squashing easier.
    
  217. 
    
  218. After review
    
  219. ------------
    
  220. 
    
  221. It is unusual to get any non-trivial amount of code into core without changes
    
  222. requested by reviewers. In this case, it is often a good idea to add the
    
  223. changes as one incremental commit to your work. This allows the reviewer to
    
  224. easily check what changes you have done.
    
  225. 
    
  226. In this case, do the changes required by the reviewer. Commit as often as
    
  227. necessary. Before publishing the changes, rebase your work. If you added two
    
  228. commits, you would run::
    
  229. 
    
  230.     git rebase -i HEAD~2
    
  231. 
    
  232. Squash the second commit into the first. Write a commit message along the lines
    
  233. of::
    
  234. 
    
  235.     Made changes asked in review by <reviewer>
    
  236. 
    
  237.     - Fixed whitespace errors in foobar
    
  238.     - Reworded the docstring of bar()
    
  239. 
    
  240. Finally, push your work back to your GitHub repository. Since you didn't touch
    
  241. the public commits during the rebase, you should not need to force-push::
    
  242. 
    
  243.     git push origin ticket_xxxxx
    
  244. 
    
  245. Your pull request should now contain the new commit too.
    
  246. 
    
  247. Note that the merger is likely to squash the review commit into the previous
    
  248. commit when committing the code.
    
  249. 
    
  250. Working on a patch
    
  251. ==================
    
  252. 
    
  253. One of the ways that developers can contribute to Django is by reviewing
    
  254. patches. Those patches will typically exist as pull requests on GitHub and
    
  255. can be easily integrated into your local repository::
    
  256. 
    
  257.     git checkout -b pull_xxxxx upstream/main
    
  258.     curl -L https://github.com/django/django/pull/xxxxx.patch | git am
    
  259. 
    
  260. This will create a new branch and then apply the changes from the pull request
    
  261. to it. At this point you can run the tests or do anything else you need to
    
  262. do to investigate the quality of the patch.
    
  263. 
    
  264. For more detail on working with pull requests see the
    
  265. :ref:`guidelines for mergers <handling-pull-requests>`.
    
  266. 
    
  267. Summary
    
  268. =======
    
  269. 
    
  270. * Work on GitHub if you can.
    
  271. * Announce your work on the Trac ticket by linking to your GitHub branch.
    
  272. * When you have something ready, make a pull request.
    
  273. * Make your pull requests as good as you can.
    
  274. * When doing fixes to your work, use ``git rebase -i`` to squash the commits.
    
  275. * When upstream has changed, do ``git fetch upstream; git rebase``.