diff --git a/doc/devel/coding_guide.rst b/doc/devel/coding_guide.rst index 2ed7a0309720..ee1fdb9ffef0 100644 --- a/doc/devel/coding_guide.rst +++ b/doc/devel/coding_guide.rst @@ -163,6 +163,8 @@ C/C++ extensions docstrings, and the Numpydoc format is well understood in the scientific Python community. + + Style guide =========== diff --git a/doc/devel/gitwash/development_workflow.rst b/doc/devel/gitwash/development_workflow.rst index 6bc15bc0125c..aed61d7e980a 100644 --- a/doc/devel/gitwash/development_workflow.rst +++ b/doc/devel/gitwash/development_workflow.rst @@ -52,17 +52,17 @@ use:: git fetch origin git checkout -b my-new-feature origin/v1.0.x -Generally, you will want to keep this also on your public github_ fork -of matplotlib_. To do this, you `git push`_ this new branch up to your github_ +Generally, you will want to keep this also on your public GitHub_ fork +of matplotlib_. To do this, you `git push`_ this new branch up to your GitHub_ repo. Generally (if you followed the instructions in these pages, and -by default), git will have a link to your github_ repo, called -``origin``. You push up to your own repo on github_ with:: +by default), git will have a link to your GitHub_ repo, called +``origin``. You push up to your own repo on GitHub_ with:: git push origin my-new-feature You will need to use this exact command, rather than simply ``git push`` every time you want to push changes on your feature branch to -your github_ repo. However, in git >1.7 you can set up a link by +your GitHub_ repo. However, in git >1.7 you can set up a link by using the ``--set-upstream`` option:: git push --set-upstream origin my-new-feature @@ -114,7 +114,7 @@ In more detail faith |emdash| or see `why the -a flag?`_ |emdash| and the helpful use-case description in the `tangled working copy problem`_. The `git commit`_ manual page might also be useful. -#. To push the changes up to your forked repo on github_, do a ``git +#. To push the changes up to your forked repo on GitHub_, do a ``git push`` (see `git push`). Asking for code review |emdash| open a Pull Request (PR) @@ -144,10 +144,149 @@ sure your pull request is ready for merging. thread. +Rebasing a Pull Request (PR) +============================ + +When working on a PR, changes may occur in the parent branch (usually master). +This can lead to conflict with changes in your branch. The conflicts can be +trivial: for example both the parent branch and your branch add an entry to +the top of `CHANGELOG`. Git can not unambiguously tell what to do with both +changes (should one go above the other? if so, which order? should it try to +merge them?) so it declares the branches can not be merged +cleanly. GitHub can only automatically merge PR without conflicts, so you will +need to manually 'rebase'. This is the process of updating your branch with +upstream changes, and resolving conflicts. + +In git, rebasing is a mild form of re-writing history: it effectively forwards +all your commits to the updated upstream commit. For a much more detailed +explanation (with pictures!) see `this nice write up +`. The NumPy team has also +`documented how to do this +` +In general, re-writing history, particularly published history, is considered +bad practice, but in this case it is very useful. + +The following example assumes that the remote of _your_ GitHub +repository is called `origin` and the remote of the official +repository is called `matplotlib`. + +The first step is to make sure that your local copy of the upstream repository is +up-to-date:: + + $ git fetch matplotlib + +This updates your local copy of the repository, but does not change any files +in your working copy. Next, switch to the branch that you want to update:: + + $ git checkout backend_plt_refactor + +You are now ready to start the rebase of your branch onto the target +parent branch, in this case `matplotlib/master` :: + + $ git rebase matplotlib/master + +and git will then give a bunch of feed back:: + + First, rewinding head to replay your work on top of it... + Applying: first steps to extract FigureManager* and friends from pyplot + Applying: split backend_qt4 into two parts, with and without Gcf + ... + Applying: pep8 clean up on backend_gtk3.py + Using index info to reconstruct a base tree... + M lib/matplotlib/backends/backend_gtk3.py + Falling back to patching base and 3-way merge... + Auto-merging lib/matplotlib/backends/backend_gtk3.py + CONFLICT (content): Merge conflict in lib/matplotlib/backends/backend_gtk3.py + Failed to merge in the changes. + Patch failed at 0013 pep8 clean up on backend_gtk3.py + The copy of the patch that failed is found in: + /home/tcaswell/other_source/matplotlib/.git/rebase-apply/patch + + When you have resolved this problem, run "git rebase --continue". + If you prefer to skip this patch, run "git rebase --skip" instead. + To check out the original branch and stop rebasing, run "git rebase --abort". + +We see that a number of commits could be cleanly applied to the tip of +`matplotlib/master`. However, git may eventually hit a commit that +had conflicts: in the example above, this happens in the file +`lib/matplotlib/backends/backend_gtk3.py`). For more verbose +information run :: + + $ git status + + You are currently rebasing branch 'backend_plt_refactor' on 'e6f8993'. + (fix conflicts and then run "git rebase --continue") + (use "git rebase --skip" to skip this patch) + (use "git rebase --abort" to check out the original branch) + + Unmerged paths: + (use "git reset HEAD ..." to unstage) + (use "git add ..." to mark resolution) + + both modified: lib/matplotlib/backends/backend_gtk3.py + + no changes added to commit (use "git add" and/or "git commit -a") + +This tells you exactly where the conflict (caused by the target branch +and your commits modifying the same lines of code) is and provides +some advice on how to proceed. Opening up the file in question, you +will see blocks that look something like this:: + + <<<<<<< HEAD + ======= + self.__dict__.clear() # Is this needed? Other backends don't have it. + >>>>>>> pep8 clean up on backend_gtk3.py + +The block of code between `<<<<<<<` and `=======` is the code on the +target branch (in this case nothing) and the code between `=======` +and `>>>>>>>` is the code in the commit you are trying to rebase. The +rest of the code is either the same or the diff can be unambiguously +applied. You need to determine how to resolve the conflict (in this +case, the code on HEAD is correct). Once you have resolved all the +conflicts, `add` the file to the index:: + + $ git add lib/matplotlib/backends/backend_gtk3.py + +Repeat this for all of the files that have conflicts. When you are done with +that you can check the status:: + + $ git status + rebase in progress; onto e6f8993 + You are currently rebasing branch 'backend_plt_refactor' on 'e6f8993'. + (all conflicts fixed: run "git rebase --continue") + + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + modified: lib/matplotlib/backends/backend_gtk3.py + +which shows us that we have resolved all of the conflicts with this +commit and can continue:: + + $ git rebase --continue + +You now iterate the until you have made it through all of the commits +which have conflicts. Once you have successfully rebased your branch, +be sure to re-run the tests to make sure everything is still working +properly. + +Your branch is now rebased, however, because of the way git +determines the hash of each commit, it now shares no commits with your +old branch published on GitHub so you can not push to that branch as +you would when simply adding commits. In order to publish your newly +rebased (and tested!) branch you need to use the `--force` flag:: + + $ git push --force origin + +which will _replace_ all of the commits under your branch on GitHub +with the new versions of the commit. + +Congratulations, you have rebased your branch! + Staying up to date with changes in the central repository ========================================================= -This updates your working copy from the upstream `matplotlib github`_ +This updates your working copy from the upstream `matplotlib GitHub`_ repo. Overview @@ -158,9 +297,9 @@ Overview # go to your master branch git checkout master # pull changes from github - git fetch upstream - # merge from upstream - git merge --ff-only upstream/master + git fetch matplotlib + # merge from matplotlib + git merge --ff-only matplotlib/master In detail --------- @@ -198,7 +337,7 @@ Other integration branches -------------------------- Some people like to keep separate local branches corresponding to the -maintenance branches on github. At the time of this writing, ``v1.0.x`` +maintenance branches on GitHub. At the time of this writing, ``v1.0.x`` is the active maintenance branch. If you have such a local branch, treat is just as ``master``: don't commit on it, and before starting new branches off of it, update it from upstream:: @@ -247,7 +386,7 @@ make sure to reset the correct branch:: git reset --hard upstream/master -Deleting a branch on github_ +Deleting a branch on GitHub_ ============================ :: @@ -255,7 +394,7 @@ Deleting a branch on github_ git checkout master # delete branch locally git branch -D my-unwanted-branch - # delete branch on github + # delete branch on GitHub git push origin :my-unwanted-branch (Note the colon ``:`` before ``test-branch``. See also: @@ -274,7 +413,7 @@ To see a linear list of commits for this branch:: git log -You can also look at the `network graph visualizer`_ for your github_ +You can also look at the `network graph visualizer`_ for your GitHub_ repo. .. include:: links.inc