Statistics
| Branch: | Revision:

iof-tools / networkxMiCe / networkx-master / doc / developer / gitwash / development_workflow.rst @ 5cef0f13

History | View | Annotate | Download (13.7 KB)

1
.. highlight:: bash
2

    
3
.. _development-workflow:
4

    
5
####################
6
Development workflow
7
####################
8

    
9
You already have your own forked copy of the `networkx`_ repository, by
10
following :ref:`forking`. You have :ref:`set-up-fork`. You have configured
11
git by following :ref:`configure-git`.  Now you are ready for some real work.
12

    
13
Workflow summary
14
================
15

    
16
In what follows we'll refer to the upstream networkx ``master`` branch, as
17
"trunk".
18

    
19
* Don't use your ``master`` branch for anything.  Consider deleting it.
20
* When you are starting a new set of changes, fetch any changes from trunk,
21
  and start a new *feature branch* from that.
22
* Make a new branch for each separable set of changes |emdash| "one task, one
23
  branch" (`ipython git workflow`_).
24
* Name your branch for the purpose of the changes - e.g.
25
  ``bugfix-for-issue-14`` or ``refactor-database-code``.
26
* If you can possibly avoid it, avoid merging trunk or any other branches into
27
  your feature branch while you are working.  
28
* If you do find yourself merging from trunk, consider :ref:`rebase-on-trunk`
29
* Ask on the `networkx mailing list`_ if you get stuck.
30
* Ask for code review!
31

    
32
This way of working helps to keep work well organized, with readable history.
33
This in turn makes it easier for project maintainers (that might be you) to see
34
what you've done, and why you did it.
35

    
36
See `linux git workflow`_ and `ipython git workflow`_ for some explanation.
37

    
38
Consider deleting your master branch
39
====================================
40

    
41
It may sound strange, but deleting your own ``master`` branch can help reduce
42
confusion about which branch you are on.  See `deleting master on github`_ for
43
details.
44

    
45
.. _update-mirror-trunk:
46

    
47
Update the mirror of trunk
48
==========================
49

    
50
First make sure you have done :ref:`linking-to-upstream`.
51

    
52
From time to time you should fetch the upstream (trunk) changes from github::
53

    
54
   git fetch upstream
55

    
56
This will pull down any commits you don't have, and set the remote branches to
57
point to the right commit.  For example, 'trunk' is the branch referred to by
58
(remote/branchname) ``upstream/master`` - and if there have been commits since
59
you last checked, ``upstream/master`` will change after you do the fetch.
60

    
61
.. _make-feature-branch:
62

    
63
Make a new feature branch
64
=========================
65

    
66
When you are ready to make some changes to the code, you should start a new
67
branch.  Branches that are for a collection of related edits are often called
68
'feature branches'.
69

    
70
Making an new branch for each set of related changes will make it easier for
71
someone reviewing your branch to see what you are doing.
72

    
73
Choose an informative name for the branch to remind yourself and the rest of us
74
what the changes in the branch are for.  For example ``add-ability-to-fly``, or
75
``buxfix-for-issue-42``.
76

    
77
::
78

    
79
    # Update the mirror of trunk
80
    git fetch upstream
81
    # Make new feature branch starting at current trunk
82
    git branch my-new-feature upstream/master
83
    git checkout my-new-feature
84

    
85
Generally, you will want to keep your feature branches on your public github_
86
fork of `networkx`_.  To do this, you `git push`_ this new branch up to your
87
github repo.  Generally (if you followed the instructions in these pages, and by
88
default), git will have a link to your github repo, called ``origin``.  You push
89
up to your own repo on github with::
90

    
91
   git push origin my-new-feature
92

    
93
In git >= 1.7 you can ensure that the link is correctly set by using the
94
``--set-upstream`` option::
95

    
96
   git push --set-upstream origin my-new-feature
97

    
98
From now on git will know that ``my-new-feature`` is related to the
99
``my-new-feature`` branch in the github repo.
100

    
101
.. _edit-flow:
102

    
103
The editing workflow
104
====================
105

    
106
Overview
107
--------
108

    
109
::
110

    
111
   # hack hack
112
   git add my_new_file
113
   git commit -am 'NF - some message'
114
   git push
115

    
116
In more detail
117
--------------
118

    
119
#. Make some changes
120
#. See which files have changed with ``git status`` (see `git status`_).
121
   You'll see a listing like this one:
122

    
123
   .. code-block:: none
124

    
125
     # On branch ny-new-feature
126
     # Changed but not updated:
127
     #   (use "git add <file>..." to update what will be committed)
128
     #   (use "git checkout -- <file>..." to discard changes in working directory)
129
     #
130
     #	modified:   README
131
     #
132
     # Untracked files:
133
     #   (use "git add <file>..." to include in what will be committed)
134
     #
135
     #	INSTALL
136
     no changes added to commit (use "git add" and/or "git commit -a")
137

    
138
#. Check what the actual changes are with ``git diff`` (`git diff`_).
139
#. Add any new files to version control ``git add new_file_name`` (see
140
   `git add`_).
141
#. To commit all modified files into the local copy of your repo,, do
142
   ``git commit -am 'A commit message'``.  Note the ``-am`` options to
143
   ``commit``. The ``m`` flag just signals that you're going to type a
144
   message on the command line.  The ``a`` flag |emdash| you can just take on
145
   faith |emdash| or see `why the -a flag?`_ |emdash| and the helpful use-case
146
   description in the `tangled working copy problem`_. The `git commit`_ manual
147
   page might also be useful.
148
#. To push the changes up to your forked repo on github, do a ``git
149
   push`` (see `git push`_).
150

    
151
Ask for your changes to be reviewed or merged
152
=============================================
153

    
154
When you are ready to ask for someone to review your code and consider a merge:
155

    
156
#. Go to the URL of your forked repo, say
157
   ``https://github.com/your-user-name/networkx``.
158
#. Use the 'Switch Branches' dropdown menu near the top left of the page to
159
   select the branch with your changes:
160

    
161
   .. image:: branch_dropdown.png
162

    
163
#. Click on the 'Pull request' button:
164

    
165
   .. image:: pull_button.png
166

    
167
   Enter a title for the set of changes, and some explanation of what you've
168
   done.  Say if there is anything you'd like particular attention for - like a
169
   complicated change or some code you are not happy with.
170

    
171
   If you don't think your request is ready to be merged, just say so in your
172
   pull request message.  This is still a good way of getting some preliminary
173
   code review.
174

    
175
Some other things you might want to do
176
======================================
177

    
178
Delete a branch on github
179
-------------------------
180

    
181
::
182

    
183
   git checkout master
184
   # delete branch locally
185
   git branch -D my-unwanted-branch
186
   # delete branch on github
187
   git push origin :my-unwanted-branch
188

    
189
Note the colon ``:`` before ``my-unwanted-branch``.  See also:
190
https://help.github.com/articles/pushing-to-a-remote/#deleting-a-remote-branch-or-tag
191

    
192
Several people sharing a single repository
193
------------------------------------------
194

    
195
If you want to work on some stuff with other people, where you are all
196
committing into the same repository, or even the same branch, then just
197
share it via github.
198

    
199
First fork networkx into your account, as from :ref:`forking`.
200

    
201
Then, go to your forked repository github page, say
202
``https://github.com/your-user-name/networkx``
203

    
204
Click on the 'Admin' button, and add anyone else to the repo as a
205
collaborator:
206

    
207
   .. image:: pull_button.png
208

    
209
Now all those people can do::
210

    
211
    git clone git@githhub.com:your-user-name/networkx.git
212

    
213
Remember that links starting with ``git@`` use the ssh protocol and are
214
read-write; links starting with ``git://`` are read-only.
215

    
216
Your collaborators can then commit directly into that repo with the
217
usual::
218

    
219
     git commit -am 'ENH - much better code'
220
     git push origin master # pushes directly into your repo
221

    
222
Explore your repository
223
-----------------------
224

    
225
To see a graphical representation of the repository branches and
226
commits::
227

    
228
   gitk --all
229

    
230
To see a linear list of commits for this branch::
231

    
232
   git log
233

    
234
You can also look at the `network graph visualizer`_ for your github
235
repo.
236

    
237
Finally the :ref:`fancy-log` ``lg`` alias will give you a reasonable text-based
238
graph of the repository.
239

    
240
.. _rebase-on-trunk:
241

    
242
Rebasing on trunk
243
-----------------
244

    
245
Let's say you thought of some work you'd like to do. You
246
:ref:`update-mirror-trunk` and :ref:`make-feature-branch` called
247
``cool-feature``. At this stage trunk is at some commit, let's call it E. Now
248
you make some new commits on your ``cool-feature`` branch, let's call them A, B,
249
C.  Maybe your changes take a while, or you come back to them after a while.  In
250
the meantime, trunk has progressed from commit E to commit (say) G:
251

    
252
.. code-block:: none
253

    
254
          A---B---C cool-feature
255
         /
256
    D---E---F---G trunk
257

    
258
At this stage you consider merging trunk into your feature branch, and you
259
remember that this here page sternly advises you not to do that, because the
260
history will get messy. Most of the time you can just ask for a review, and not
261
worry that trunk has got a little ahead.  But sometimes, the changes in trunk
262
might affect your changes, and you need to harmonize them.  In this situation
263
you may prefer to do a rebase.
264

    
265
rebase takes your changes (A, B, C) and replays them as if they had been made to
266
the current state of ``trunk``.  In other words, in this case, it takes the
267
changes represented by A, B, C and replays them on top of G. After the rebase,
268
your history will look like this:
269

    
270
.. code-block:: none
271

    
272
                  A'--B'--C' cool-feature
273
                 /
274
    D---E---F---G trunk
275

    
276
See `rebase without tears`_ for more detail.
277

    
278
To do a rebase on trunk::
279

    
280
    # Update the mirror of trunk
281
    git fetch upstream
282
    # go to the feature branch
283
    git checkout cool-feature
284
    # make a backup in case you mess up
285
    git branch tmp cool-feature
286
    # rebase cool-feature onto trunk
287
    git rebase --onto upstream/master upstream/master cool-feature
288

    
289
In this situation, where you are already on branch ``cool-feature``, the last
290
command can be written more succinctly as::
291

    
292
    git rebase upstream/master
293

    
294
When all looks good you can delete your backup branch::
295

    
296
   git branch -D tmp
297

    
298
If it doesn't look good you may need to have a look at
299
:ref:`recovering-from-mess-up`.
300

    
301
If you have made changes to files that have also changed in trunk, this may
302
generate merge conflicts that you need to resolve - see the `git rebase`_ man
303
page for some instructions at the end of the "Description" section. There is
304
some related help on merging in the git user manual - see `resolving a merge`_.
305

    
306
.. _recovering-from-mess-up:
307

    
308
Recovering from mess-ups
309
------------------------
310

    
311
Sometimes, you mess up merges or rebases. Luckily, in git it is
312
relatively straightforward to recover from such mistakes.
313

    
314
If you mess up during a rebase::
315

    
316
   git rebase --abort
317

    
318
If you notice you messed up after the rebase::
319

    
320
   # reset branch back to the saved point
321
   git reset --hard tmp
322

    
323
If you forgot to make a backup branch::
324

    
325
   # look at the reflog of the branch
326
   git reflog show cool-feature
327

    
328
   8630830 cool-feature@{0}: commit: BUG: io: close file handles immediately
329
   278dd2a cool-feature@{1}: rebase finished: refs/heads/my-feature-branch onto 11ee694744f2552d
330
   26aa21a cool-feature@{2}: commit: BUG: lib: make seek_gzip_factory not leak gzip obj
331
   ...
332

    
333
   # reset the branch to where it was before the botched rebase
334
   git reset --hard cool-feature@{2}
335

    
336
.. _rewriting-commit-history:
337

    
338
Rewriting commit history
339
------------------------
340

    
341
.. note::
342

    
343
   Do this only for your own feature branches.
344

    
345
There's an embarrassing typo in a commit you made? Or perhaps the you
346
made several false starts you would like the posterity not to see.
347

    
348
This can be done via *interactive rebasing*.
349

    
350
Suppose that the commit history looks like this::
351

    
352
    git log --oneline
353
    eadc391 Fix some remaining bugs
354
    a815645 Modify it so that it works
355
    2dec1ac Fix a few bugs + disable
356
    13d7934 First implementation
357
    6ad92e5 * masked is now an instance of a new object, MaskedConstant
358
    29001ed Add pre-nep for a copule of structured_array_extensions.
359
    ...
360

    
361
and ``6ad92e5`` is the last commit in the ``cool-feature`` branch. Suppose we
362
want to make the following changes:
363

    
364
* Rewrite the commit message for ``13d7934`` to something more sensible.
365
* Combine the commits ``2dec1ac``, ``a815645``, ``eadc391`` into a single one.
366

    
367
We do as follows::
368

    
369
    # make a backup of the current state
370
    git branch tmp HEAD
371
    # interactive rebase
372
    git rebase -i 6ad92e5
373

    
374
This will open an editor with the following text in it::
375

    
376
    pick 13d7934 First implementation
377
    pick 2dec1ac Fix a few bugs + disable
378
    pick a815645 Modify it so that it works
379
    pick eadc391 Fix some remaining bugs
380

    
381
    # Rebase 6ad92e5..eadc391 onto 6ad92e5
382
    #
383
    # Commands:
384
    #  p, pick = use commit
385
    #  r, reword = use commit, but edit the commit message
386
    #  e, edit = use commit, but stop for amending
387
    #  s, squash = use commit, but meld into previous commit
388
    #  f, fixup = like "squash", but discard this commit's log message
389
    #
390
    # If you remove a line here THAT COMMIT WILL BE LOST.
391
    # However, if you remove everything, the rebase will be aborted.
392
    #
393

    
394
To achieve what we want, we will make the following changes to it::
395

    
396
    r 13d7934 First implementation
397
    pick 2dec1ac Fix a few bugs + disable
398
    f a815645 Modify it so that it works
399
    f eadc391 Fix some remaining bugs
400

    
401
This means that (i) we want to edit the commit message for
402
``13d7934``, and (ii) collapse the last three commits into one. Now we
403
save and quit the editor.
404

    
405
Git will then immediately bring up an editor for editing the commit
406
message. After revising it, we get the output::
407

    
408
    [detached HEAD 721fc64] FOO: First implementation
409
     2 files changed, 199 insertions(+), 66 deletions(-)
410
    [detached HEAD 0f22701] Fix a few bugs + disable
411
     1 files changed, 79 insertions(+), 61 deletions(-)
412
    Successfully rebased and updated refs/heads/my-feature-branch.
413

    
414
and the history looks now like this::
415

    
416
     0f22701 Fix a few bugs + disable
417
     721fc64 ENH: Sophisticated feature
418
     6ad92e5 * masked is now an instance of a new object, MaskedConstant
419

    
420
If it went wrong, recovery is again possible as explained :ref:`above
421
<recovering-from-mess-up>`.
422

    
423
.. include:: links.inc