Skip to content

Commit 0655bc5

Browse files
authored
Merge pull request #2742 from tacaswell/rebase_doc
Doc on how to rebase.
2 parents 9563001 + 9efe5e3 commit 0655bc5

File tree

2 files changed

+155
-14
lines changed

2 files changed

+155
-14
lines changed

doc/devel/coding_guide.rst

+2
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ C/C++ extensions
163163
docstrings, and the Numpydoc format is well understood in the
164164
scientific Python community.
165165

166+
167+
166168
Style guide
167169
===========
168170

doc/devel/gitwash/development_workflow.rst

+153-14
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,17 @@ use::
5252
git fetch origin
5353
git checkout -b my-new-feature origin/v1.0.x
5454

55-
Generally, you will want to keep this also on your public github_ fork
56-
of matplotlib_. To do this, you `git push`_ this new branch up to your github_
55+
Generally, you will want to keep this also on your public GitHub_ fork
56+
of matplotlib_. To do this, you `git push`_ this new branch up to your GitHub_
5757
repo. Generally (if you followed the instructions in these pages, and
58-
by default), git will have a link to your github_ repo, called
59-
``origin``. You push up to your own repo on github_ with::
58+
by default), git will have a link to your GitHub_ repo, called
59+
``origin``. You push up to your own repo on GitHub_ with::
6060

6161
git push origin my-new-feature
6262

6363
You will need to use this exact command, rather than simply ``git
6464
push`` every time you want to push changes on your feature branch to
65-
your github_ repo. However, in git >1.7 you can set up a link by
65+
your GitHub_ repo. However, in git >1.7 you can set up a link by
6666
using the ``--set-upstream`` option::
6767

6868
git push --set-upstream origin my-new-feature
@@ -114,7 +114,7 @@ In more detail
114114
faith |emdash| or see `why the -a flag?`_ |emdash| and the helpful use-case
115115
description in the `tangled working copy problem`_. The `git commit`_ manual
116116
page might also be useful.
117-
#. To push the changes up to your forked repo on github_, do a ``git
117+
#. To push the changes up to your forked repo on GitHub_, do a ``git
118118
push`` (see `git push`).
119119

120120
Asking for code review |emdash| open a Pull Request (PR)
@@ -144,10 +144,149 @@ sure your pull request is ready for merging.
144144
thread.
145145

146146

147+
Rebasing a Pull Request (PR)
148+
============================
149+
150+
When working on a PR, changes may occur in the parent branch (usually master).
151+
This can lead to conflict with changes in your branch. The conflicts can be
152+
trivial: for example both the parent branch and your branch add an entry to
153+
the top of `CHANGELOG`. Git can not unambiguously tell what to do with both
154+
changes (should one go above the other? if so, which order? should it try to
155+
merge them?) so it declares the branches can not be merged
156+
cleanly. GitHub can only automatically merge PR without conflicts, so you will
157+
need to manually 'rebase'. This is the process of updating your branch with
158+
upstream changes, and resolving conflicts.
159+
160+
In git, rebasing is a mild form of re-writing history: it effectively forwards
161+
all your commits to the updated upstream commit. For a much more detailed
162+
explanation (with pictures!) see `this nice write up
163+
<https://git-scm.com/book/en/Git-Branching-Rebasing>`. The NumPy team has also
164+
`documented how to do this
165+
<http://docs.scipy.org/doc/numpy/dev/gitwash/development_workflow.html#rebasing-on-master>`
166+
In general, re-writing history, particularly published history, is considered
167+
bad practice, but in this case it is very useful.
168+
169+
The following example assumes that the remote of _your_ GitHub
170+
repository is called `origin` and the remote of the official
171+
repository is called `matplotlib`.
172+
173+
The first step is to make sure that your local copy of the upstream repository is
174+
up-to-date::
175+
176+
$ git fetch matplotlib
177+
178+
This updates your local copy of the repository, but does not change any files
179+
in your working copy. Next, switch to the branch that you want to update::
180+
181+
$ git checkout backend_plt_refactor
182+
183+
You are now ready to start the rebase of your branch onto the target
184+
parent branch, in this case `matplotlib/master` ::
185+
186+
$ git rebase matplotlib/master
187+
188+
and git will then give a bunch of feed back::
189+
190+
First, rewinding head to replay your work on top of it...
191+
Applying: first steps to extract FigureManager* and friends from pyplot
192+
Applying: split backend_qt4 into two parts, with and without Gcf
193+
...
194+
Applying: pep8 clean up on backend_gtk3.py
195+
Using index info to reconstruct a base tree...
196+
M lib/matplotlib/backends/backend_gtk3.py
197+
Falling back to patching base and 3-way merge...
198+
Auto-merging lib/matplotlib/backends/backend_gtk3.py
199+
CONFLICT (content): Merge conflict in lib/matplotlib/backends/backend_gtk3.py
200+
Failed to merge in the changes.
201+
Patch failed at 0013 pep8 clean up on backend_gtk3.py
202+
The copy of the patch that failed is found in:
203+
/home/tcaswell/other_source/matplotlib/.git/rebase-apply/patch
204+
205+
When you have resolved this problem, run "git rebase --continue".
206+
If you prefer to skip this patch, run "git rebase --skip" instead.
207+
To check out the original branch and stop rebasing, run "git rebase --abort".
208+
209+
We see that a number of commits could be cleanly applied to the tip of
210+
`matplotlib/master`. However, git may eventually hit a commit that
211+
had conflicts: in the example above, this happens in the file
212+
`lib/matplotlib/backends/backend_gtk3.py`). For more verbose
213+
information run ::
214+
215+
$ git status
216+
217+
You are currently rebasing branch 'backend_plt_refactor' on 'e6f8993'.
218+
(fix conflicts and then run "git rebase --continue")
219+
(use "git rebase --skip" to skip this patch)
220+
(use "git rebase --abort" to check out the original branch)
221+
222+
Unmerged paths:
223+
(use "git reset HEAD <file>..." to unstage)
224+
(use "git add <file>..." to mark resolution)
225+
226+
both modified: lib/matplotlib/backends/backend_gtk3.py
227+
228+
no changes added to commit (use "git add" and/or "git commit -a")
229+
230+
This tells you exactly where the conflict (caused by the target branch
231+
and your commits modifying the same lines of code) is and provides
232+
some advice on how to proceed. Opening up the file in question, you
233+
will see blocks that look something like this::
234+
235+
<<<<<<< HEAD
236+
=======
237+
self.__dict__.clear() # Is this needed? Other backends don't have it.
238+
>>>>>>> pep8 clean up on backend_gtk3.py
239+
240+
The block of code between `<<<<<<<` and `=======` is the code on the
241+
target branch (in this case nothing) and the code between `=======`
242+
and `>>>>>>>` is the code in the commit you are trying to rebase. The
243+
rest of the code is either the same or the diff can be unambiguously
244+
applied. You need to determine how to resolve the conflict (in this
245+
case, the code on HEAD is correct). Once you have resolved all the
246+
conflicts, `add` the file to the index::
247+
248+
$ git add lib/matplotlib/backends/backend_gtk3.py
249+
250+
Repeat this for all of the files that have conflicts. When you are done with
251+
that you can check the status::
252+
253+
$ git status
254+
rebase in progress; onto e6f8993
255+
You are currently rebasing branch 'backend_plt_refactor' on 'e6f8993'.
256+
(all conflicts fixed: run "git rebase --continue")
257+
258+
Changes to be committed:
259+
(use "git reset HEAD <file>..." to unstage)
260+
261+
modified: lib/matplotlib/backends/backend_gtk3.py
262+
263+
which shows us that we have resolved all of the conflicts with this
264+
commit and can continue::
265+
266+
$ git rebase --continue
267+
268+
You now iterate the until you have made it through all of the commits
269+
which have conflicts. Once you have successfully rebased your branch,
270+
be sure to re-run the tests to make sure everything is still working
271+
properly.
272+
273+
Your branch is now rebased, however, because of the way git
274+
determines the hash of each commit, it now shares no commits with your
275+
old branch published on GitHub so you can not push to that branch as
276+
you would when simply adding commits. In order to publish your newly
277+
rebased (and tested!) branch you need to use the `--force` flag::
278+
279+
$ git push --force origin
280+
281+
which will _replace_ all of the commits under your branch on GitHub
282+
with the new versions of the commit.
283+
284+
Congratulations, you have rebased your branch!
285+
147286
Staying up to date with changes in the central repository
148287
=========================================================
149288

150-
This updates your working copy from the upstream `matplotlib github`_
289+
This updates your working copy from the upstream `matplotlib GitHub`_
151290
repo.
152291

153292
Overview
@@ -158,9 +297,9 @@ Overview
158297
# go to your master branch
159298
git checkout master
160299
# pull changes from github
161-
git fetch upstream
162-
# merge from upstream
163-
git merge --ff-only upstream/master
300+
git fetch matplotlib
301+
# merge from matplotlib
302+
git merge --ff-only matplotlib/master
164303

165304
In detail
166305
---------
@@ -198,7 +337,7 @@ Other integration branches
198337
--------------------------
199338

200339
Some people like to keep separate local branches corresponding to the
201-
maintenance branches on github. At the time of this writing, ``v1.0.x``
340+
maintenance branches on GitHub. At the time of this writing, ``v1.0.x``
202341
is the active maintenance branch. If you have such a local branch,
203342
treat is just as ``master``: don't commit on it, and before starting
204343
new branches off of it, update it from upstream::
@@ -247,15 +386,15 @@ make sure to reset the correct branch::
247386
git reset --hard upstream/master
248387

249388

250-
Deleting a branch on github_
389+
Deleting a branch on GitHub_
251390
============================
252391

253392
::
254393

255394
git checkout master
256395
# delete branch locally
257396
git branch -D my-unwanted-branch
258-
# delete branch on github
397+
# delete branch on GitHub
259398
git push origin :my-unwanted-branch
260399

261400
(Note the colon ``:`` before ``test-branch``. See also:
@@ -274,7 +413,7 @@ To see a linear list of commits for this branch::
274413

275414
git log
276415

277-
You can also look at the `network graph visualizer`_ for your github_
416+
You can also look at the `network graph visualizer`_ for your GitHub_
278417
repo.
279418

280419
.. include:: links.inc

0 commit comments

Comments
 (0)