├── gitwash ├── pull_button.png ├── branch_dropdown.png ├── forking_button.png ├── this_project.inc ├── links.inc ├── git_development.rst ├── index.rst ├── git_intro.rst ├── git_install.rst ├── following_latest.rst ├── forking_hell.rst ├── known_projects.inc ├── git_resources.rst ├── set_up_fork.rst ├── git_links.inc ├── maintainer_workflow.rst ├── patching.rst ├── configure_git.rst └── development_workflow.rst ├── index.rst ├── .gitignore ├── LICENSE ├── README.rst ├── tests └── test_dump.py ├── Makefile ├── make.bat ├── conf.py └── gitwash_dumper.py /gitwash/pull_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthew-brett/gitwash/HEAD/gitwash/pull_button.png -------------------------------------------------------------------------------- /gitwash/branch_dropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthew-brett/gitwash/HEAD/gitwash/branch_dropdown.png -------------------------------------------------------------------------------- /gitwash/forking_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthew-brett/gitwash/HEAD/gitwash/forking_button.png -------------------------------------------------------------------------------- /gitwash/this_project.inc: -------------------------------------------------------------------------------- 1 | .. this file is a stub 2 | it will be overwritten by the automated installation 3 | please do not edit 4 | -------------------------------------------------------------------------------- /gitwash/links.inc: -------------------------------------------------------------------------------- 1 | .. compiling links file 2 | .. include:: known_projects.inc 3 | .. include:: this_project.inc 4 | .. include:: git_links.inc 5 | -------------------------------------------------------------------------------- /index.rst: -------------------------------------------------------------------------------- 1 | ======= 2 | Gitwash 3 | ======= 4 | 5 | Contents: 6 | 7 | .. toctree:: 8 | :maxdepth: 2 9 | 10 | gitwash/index 11 | 12 | .. toctree:: 13 | :hidden: 14 | 15 | README 16 | -------------------------------------------------------------------------------- /gitwash/git_development.rst: -------------------------------------------------------------------------------- 1 | .. _git-development: 2 | 3 | ===================== 4 | Git for development 5 | ===================== 6 | 7 | Contents: 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | 12 | forking_hell 13 | set_up_fork 14 | configure_git 15 | development_workflow 16 | maintainer_workflow 17 | -------------------------------------------------------------------------------- /gitwash/index.rst: -------------------------------------------------------------------------------- 1 | .. _using-git: 2 | 3 | Working with *PROJECTNAME* source code 4 | ================================================ 5 | 6 | Contents: 7 | 8 | .. toctree:: 9 | :maxdepth: 2 10 | 11 | git_intro 12 | git_install 13 | following_latest 14 | patching 15 | git_development 16 | git_resources 17 | -------------------------------------------------------------------------------- /gitwash/git_intro.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: bash 2 | 3 | ============== 4 | Introduction 5 | ============== 6 | 7 | These pages describe a git_ and github_ workflow for the `PROJECTNAME`_ 8 | project. 9 | 10 | There are several different workflows here, for different ways of 11 | working with *PROJECTNAME*. 12 | 13 | This is not a comprehensive git reference, it's just a workflow for our 14 | own project. It's tailored to the github hosting service. You may well 15 | find better or quicker ways of getting stuff done with git, but these 16 | should get you started. 17 | 18 | For general resources for learning git, see :ref:`git-resources`. 19 | 20 | .. include:: links.inc 21 | -------------------------------------------------------------------------------- /gitwash/git_install.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: bash 2 | 3 | .. _install-git: 4 | 5 | ============= 6 | Install git 7 | ============= 8 | 9 | Overview 10 | ======== 11 | 12 | ================ ============= 13 | Debian / Ubuntu ``sudo apt-get install git`` 14 | Fedora ``sudo dnf install git`` 15 | Windows Download and install msysGit_ 16 | OS X Use the git-osx-installer_ 17 | ================ ============= 18 | 19 | In detail 20 | ========= 21 | 22 | See the git page for the most recent information. 23 | 24 | Have a look at the github install help pages available from `github help`_ 25 | 26 | There are good instructions here: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git 27 | 28 | .. include:: links.inc 29 | -------------------------------------------------------------------------------- /gitwash/following_latest.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: bash 2 | 3 | .. _following-latest: 4 | 5 | ============================= 6 | Following the latest source 7 | ============================= 8 | 9 | These are the instructions if you just want to follow the latest 10 | *PROJECTNAME* source, but you don't need to do any development for now. 11 | 12 | The steps are: 13 | 14 | * :ref:`install-git` 15 | * get local copy of the `PROJECTNAME github`_ git repository 16 | * update local copy from time to time 17 | 18 | Get the local copy of the code 19 | ============================== 20 | 21 | From the command line:: 22 | 23 | git clone https://github.com/MAIN_GH_USER/REPONAME.git 24 | 25 | You now have a copy of the code tree in the new ``REPONAME`` directory. 26 | 27 | Updating the code 28 | ================= 29 | 30 | From time to time you may want to pull down the latest code. Do this with:: 31 | 32 | cd REPONAME 33 | git pull 34 | 35 | The tree in ``REPONAME`` will now have the latest changes from the initial 36 | repository. 37 | 38 | .. include:: links.inc 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Editor temporary/working/backup files # 2 | ######################################### 3 | .#* 4 | [#]*# 5 | *~ 6 | *$ 7 | *.bak 8 | *.diff 9 | *.org 10 | .project 11 | *.rej 12 | .settings/ 13 | .*.sw[nop] 14 | .sw[nop] 15 | *.tmp 16 | 17 | # Not sure what the next two are for 18 | *.kpf 19 | *-stamp 20 | 21 | # Compiled source # 22 | ################### 23 | *.a 24 | *.com 25 | *.class 26 | *.dll 27 | *.exe 28 | *.o 29 | *.py[oc] 30 | *.so 31 | 32 | # Packages # 33 | ############ 34 | # it's better to unpack these files and commit the raw source 35 | # git has its own built in compression methods 36 | *.7z 37 | *.bz2 38 | *.bzip2 39 | *.dmg 40 | *.gz 41 | *.iso 42 | *.jar 43 | *.rar 44 | *.tar 45 | *.tbz2 46 | *.tgz 47 | *.zip 48 | 49 | # Python files # 50 | ################ 51 | build/ 52 | _build/ 53 | ./dist 54 | ./*.egg-info 55 | ./.shelf 56 | 57 | # Logs and databases # 58 | ###################### 59 | *.log 60 | *.sql 61 | *.sqlite 62 | 63 | # OS generated files # 64 | ###################### 65 | .gdb_history 66 | .DS_Store? 67 | ehthumbs.db 68 | Icon? 69 | Thumbs.db 70 | 71 | # Things specific to this project # 72 | ################################### 73 | gitwash.egg-info/ 74 | -------------------------------------------------------------------------------- /gitwash/forking_hell.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: bash 2 | 3 | .. _forking: 4 | 5 | ====================================================== 6 | Making your own copy (fork) of PROJECTNAME 7 | ====================================================== 8 | 9 | You need to do this only once. The instructions here are very similar 10 | to the instructions at https://help.github.com/forking/ |emdash| please see 11 | that page for more detail. We're repeating some of it here just to give the 12 | specifics for the `PROJECTNAME`_ project, and to suggest some default names. 13 | 14 | Set up and configure a github account 15 | ===================================== 16 | 17 | If you don't have a github account, go to the github page, and make one. 18 | 19 | You then need to configure your account to allow write access |emdash| see 20 | the ``Generating SSH keys`` help on `github help`_. 21 | 22 | Create your own forked copy of `PROJECTNAME`_ 23 | ====================================================== 24 | 25 | #. Log into your github account. 26 | #. Go to the `PROJECTNAME`_ github home at `PROJECTNAME github`_. 27 | #. Click on the *fork* button: 28 | 29 | .. image:: forking_button.png 30 | 31 | Now, after a short pause, you should find yourself at the home page for 32 | your own forked copy of `PROJECTNAME`_. 33 | 34 | .. include:: links.inc 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ========= 2 | LICENSE 3 | ========= 4 | 5 | We release the documents under the Creative Commons attribution license: 6 | https://creativecommons.org/licenses/by/3.0/ 7 | 8 | We release the code under the simplified BSD license: 9 | 10 | Copyright (c) 2010, Matthew Brett 11 | All rights reserved. 12 | 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are 15 | met: 16 | 17 | * Redistributions of source code must retain the above copyright notice, 18 | this list of conditions and the following disclaimer. 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 26 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | -------------------------------------------------------------------------------- /gitwash/known_projects.inc: -------------------------------------------------------------------------------- 1 | .. Known projects 2 | 3 | .. PROJECTNAME placeholders 4 | .. _PROJECTNAME: https://nipy.org/ 5 | .. _`PROJECTNAME github`: https://github.com/nipy 6 | .. _`PROJECTNAME mailing list`: https://mail.python.org/mailman/listinfo/neuroimaging 7 | 8 | .. numpy 9 | .. _numpy: https://numpy.org/ 10 | .. _`numpy github`: https://github.com/numpy/numpy 11 | .. _`numpy mailing list`: https://mail.scipy.org/mailman/listinfo/numpy-discussion 12 | 13 | .. scipy 14 | .. _scipy: https://www.scipy.org 15 | .. _`scipy github`: https://github.com/scipy/scipy 16 | .. _`scipy mailing list`: https://mail.scipy.org/mailman/listinfo/scipy-dev 17 | 18 | .. nipy 19 | .. _nipy: http://nipy.org/nipy/ 20 | .. _`nipy github`: https://github.com/nipy/nipy 21 | .. _`nipy mailing list`: https://mail.python.org/mailman/listinfo/neuroimaging 22 | 23 | .. ipython 24 | .. _ipython: https://ipython.org 25 | .. _`ipython github`: https://github.com/ipython/ipython 26 | .. _`ipython mailing list`: https://mail.scipy.org/mailman/listinfo/IPython-dev 27 | 28 | .. dipy 29 | .. _dipy: https://nipy.org/dipy/ 30 | .. _`dipy github`: https://github.com/Garyfallidis/dipy 31 | .. _`dipy mailing list`: https://mail.python.org/mailman/listinfo/neuroimaging 32 | 33 | .. nibabel 34 | .. _nibabel: https://nipy.org/nibabel/ 35 | .. _`nibabel github`: https://github.com/nipy/nibabel 36 | .. _`nibabel mailing list`: https://mail.python.org/mailman/listinfo/neuroimaging 37 | 38 | .. marsbar 39 | .. _marsbar: http://marsbar.sourceforge.net 40 | .. _`marsbar github`: https://github.com/matthew-brett/marsbar 41 | .. _`MarsBaR mailing list`: https://sourceforge.net/projects/marsbar/lists/marsbar-users 42 | -------------------------------------------------------------------------------- /gitwash/git_resources.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: bash 2 | 3 | .. _git-resources: 4 | 5 | ============= 6 | git resources 7 | ============= 8 | 9 | Tutorials and summaries 10 | ======================= 11 | 12 | * `github help`_ has an excellent series of how-to guides. 13 | * The `pro git book`_ is a good in-depth book on git. 14 | * A `git cheat sheet`_ is a page giving summaries of common commands. 15 | * The `git user manual`_ 16 | * The `git tutorial`_ 17 | * `git ready`_ |emdash| a nice series of tutorials 18 | * `git magic`_ |emdash| extended introduction with intermediate detail 19 | * The `git parable`_ is an easy read explaining the concepts behind git. 20 | * `git foundation`_ expands on the `git parable`_. 21 | * Fernando Perez' git page |emdash| `Fernando's git page`_ |emdash| many 22 | links and tips 23 | * A good but technical page on `git concepts`_ 24 | * `git svn crash course`_: git for those of us used to subversion_ 25 | 26 | Advanced git workflow 27 | ===================== 28 | 29 | There are many ways of working with git; here are some posts on the 30 | rules of thumb that other projects have come up with: 31 | 32 | * Linus Torvalds on `git management`_ 33 | * Linus Torvalds on `linux git workflow`_ . Summary; use the git tools 34 | to make the history of your edits as clean as possible; merge from 35 | upstream edits as little as possible in branches where you are doing 36 | active development. 37 | 38 | Manual pages online 39 | =================== 40 | 41 | You can get these on your own machine with (e.g) ``git help push`` or 42 | (same thing) ``git push --help``, but, for convenience, here are the 43 | online manual pages for some common commands: 44 | 45 | * `git add`_ 46 | * `git branch`_ 47 | * `git checkout`_ 48 | * `git clone`_ 49 | * `git commit`_ 50 | * `git config`_ 51 | * `git diff`_ 52 | * `git log`_ 53 | * `git pull`_ 54 | * `git push`_ 55 | * `git remote`_ 56 | * `git status`_ 57 | 58 | .. include:: links.inc 59 | -------------------------------------------------------------------------------- /gitwash/set_up_fork.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: bash 2 | 3 | .. _set-up-fork: 4 | 5 | ================== 6 | Set up your fork 7 | ================== 8 | 9 | First you follow the instructions for :ref:`forking`. 10 | 11 | Overview 12 | ======== 13 | 14 | :: 15 | 16 | git clone git@github.com:your-user-name/REPONAME.git 17 | cd REPONAME 18 | git remote add upstream https://github.com/MAIN_GH_USER/REPONAME.git 19 | 20 | In detail 21 | ========= 22 | 23 | Clone your fork 24 | --------------- 25 | 26 | #. Clone your fork to the local computer with ``git clone 27 | git@github.com:your-user-name/REPONAME.git`` 28 | #. Investigate. Change directory to your new repo: ``cd REPONAME``. Then 29 | ``git branch -a`` to show you all branches. You'll get something 30 | like: 31 | 32 | .. code-block:: none 33 | 34 | * master 35 | remotes/origin/master 36 | 37 | This tells you that you are currently on the ``master`` branch, and 38 | that you also have a ``remote`` connection to ``origin/master``. 39 | What remote repository is ``remote/origin``? Try ``git remote -v`` to 40 | see the URLs for the remote. They will point to your github fork. 41 | 42 | Now you want to connect to the upstream `PROJECTNAME github`_ repository, so 43 | you can merge in changes from trunk. 44 | 45 | .. _linking-to-upstream: 46 | 47 | Linking your repository to the upstream repo 48 | -------------------------------------------- 49 | 50 | :: 51 | 52 | cd REPONAME 53 | git remote add upstream https://github.com/MAIN_GH_USER/REPONAME.git 54 | 55 | ``upstream`` here is just the arbitrary name we're using to refer to the 56 | main `PROJECTNAME`_ repository at `PROJECTNAME github`_. 57 | 58 | Note that we've used ``https://`` for the URL rather than ``git@``. The 59 | ``https://`` URL is read only. This means we that we can't accidentally 60 | (or deliberately) write to the upstream repo, and we are only going to 61 | use it to merge into our own code. 62 | 63 | Just for your own satisfaction, show yourself that you now have a new 64 | 'remote', with ``git remote -v``, giving you something like: 65 | 66 | .. code-block:: none 67 | 68 | upstream https://github.com/MAIN_GH_USER/REPONAME.git (fetch) 69 | upstream https://github.com/MAIN_GH_USER/REPONAME.git (push) 70 | origin git@github.com:your-user-name/REPONAME.git (fetch) 71 | origin git@github.com:your-user-name/REPONAME.git (push) 72 | 73 | .. include:: links.inc 74 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | .. -*- rest -*- 2 | .. vim:syntax=rst 3 | 4 | ========= 5 | Gitwash 6 | ========= 7 | 8 | A set of documents and an example repository to describe starting with 9 | github and a git workflow. 10 | 11 | Our idea is that many projects may have the same workflow, more or less. 12 | Each project needs docs that have exact project-specific command lines 13 | for use with git and github. 14 | 15 | It seems a shame to type all this out for every project, when a lot of 16 | it is the same. 17 | 18 | Gitwash is one way of solving this problem. 19 | 20 | * You can build the gitwash documents directly to review your workflow. 21 | * The documents designed for re-use in different projects are in the 22 | ``gitwash`` subdirectory. 23 | * In these documents, we've encoded the various strings you will want to 24 | replace with strings in ALL CAPS. The ``PROJECTNAME`` is the name of 25 | the project as it appears in text - for example ``IPython``. 26 | ``REPONAME`` is the name of the repository (e.g ``ipython``), and 27 | ``MAIN_GH_USER`` is the main github user (the user for the central 28 | github repository - or the name of the github "organization"). This 29 | results in links to your project repository of the form 30 | ``github.com/MAIN_GH_USER/REPONAME.git``. 31 | * The script ``gitwash_dumper.py`` will checkout the gitwash repository, 32 | do a search and replace on these strings and replace them with the 33 | ones you want, and then output these into your own docs in a place 34 | that you choose. You might want a copy of this tool somewhere in your 35 | repository. You can refresh it from time to time with:: 36 | 37 | curl -O https://raw.githubusercontent.com/matthew-brett/gitwash/main/gitwash_dumper.py 38 | 39 | For IPython, ``PROJECTNAME`` is 'IPython', ``REPONAME`` is 'ipython', and the 40 | ``MAIN_GH_USER`` is also 'ipython'. An example command for *ipython* might 41 | then be:: 42 | 43 | gitwash_dumper.py doc/devel IPython --repo-name=ipython --github-user=ipython \ 44 | --project-url=https://ipython.org \ 45 | --project-ml-url=https://mail.scipy.org/mailman/listinfo/IPython-dev 46 | 47 | to dump the search / replaced docs into the ``doc/devel/gitwash`` 48 | directory. 49 | * In the command above you'll notice that you also have to add your project main 50 | URL with the ``--project-url`` option, and the mailing list URL with the 51 | ``--project-ml-url`` option. That is the standard way to add your own links 52 | into the documentation. 53 | * You might want to have a Makefile target to update gitwash 54 | automatically from the sources. For example, in the *nipy* docs 55 | Makefile, we have:: 56 | 57 | gitwash-update: 58 | python ../tools/gitwash_dumper.py devel/guidelines nipy \ 59 | --project-url=https://nipy.org/ \ 60 | --project-ml-url=https://mail.scipy.org/mailman/listinfo/nipy-devel 61 | 62 | There's an example build of gitwash at 63 | https://matthew-brett.github.io/pydagogue/gitwash_build.html 64 | 65 | -------------------------------------------------------------------------------- /tests/test_dump.py: -------------------------------------------------------------------------------- 1 | """ Testing gitwash dumper 2 | """ 3 | 4 | from __future__ import (absolute_import, division, print_function) 5 | 6 | import os 7 | from os.path import join as pjoin, dirname, split as psplit 8 | import sys 9 | import shutil 10 | from tempfile import mkdtemp 11 | from subprocess import call 12 | 13 | from nose.tools import assert_true, assert_false, assert_equal, assert_raises 14 | 15 | _downpath, _ = psplit(dirname(__file__)) 16 | ROOT_DIR = os.path.abspath(_downpath) 17 | sys.path.append(ROOT_DIR) 18 | 19 | import gitwash_dumper as gwd 20 | 21 | EXE_PTH = pjoin(ROOT_DIR, 'gitwash_dumper.py') 22 | DOC_DIR = pjoin(_downpath, 'gitwash') 23 | TMPDIR = None 24 | 25 | def setup(): 26 | global TMPDIR 27 | TMPDIR = mkdtemp() 28 | 29 | 30 | def teardown(): 31 | shutil.rmtree(TMPDIR) 32 | 33 | 34 | def test_link_checks(): 35 | test_fname = pjoin(TMPDIR, 'test.inc') 36 | # Check case where we have links 37 | gwd.make_link_targets( 38 | 'nipy', 39 | 'nipy', 40 | 'nipy', 41 | pjoin(DOC_DIR, 'known_projects.inc'), 42 | test_fname, 43 | None, 44 | None) 45 | assert_false(os.path.isfile(test_fname)) 46 | # Add explicit links, and file gets written 47 | gwd.make_link_targets( 48 | 'nipy', 49 | 'nipy', 50 | 'nipy', 51 | pjoin(DOC_DIR, 'known_projects.inc'), 52 | test_fname, 53 | 'https://nowhere.org', 54 | None) 55 | with open(test_fname, 'rt') as test_fh: 56 | expected_text = test_fname.read() 57 | assert_equal(expected_text, 58 | """.. nipy 59 | .. _nipy: https://nowhere.org 60 | """) 61 | 62 | 63 | def test_dumper(): 64 | call([EXE_PTH, 65 | TMPDIR, 66 | 'marsbar', 67 | '--gitwash-url=%s' % ROOT_DIR]) 68 | gitwdir = pjoin(TMPDIR, 'gitwash') 69 | assert_true(os.path.isdir(gitwdir)) 70 | for dirpath, dirnames, filenames in os.walk(gitwdir): 71 | if not dirpath.endswith('gitwash'): 72 | raise RuntimeError('I only know about the gitwash directory') 73 | for filename in filenames: 74 | old_fname = pjoin(DOC_DIR, filename) 75 | new_fname = pjoin(dirpath, filename) 76 | old_contents = file(old_fname, 'rt').readlines() 77 | new_contents = file(new_fname, 'rt').readlines() 78 | for old, new in zip(old_contents, new_contents): 79 | if 'PROJECT' in old and not filename.endswith('.inc'): 80 | assert_false('PROJECT' in new) 81 | assert_true('my_project' in new) 82 | shutil.rmtree(gitwdir) 83 | 84 | 85 | def test_building(): 86 | call([EXE_PTH, 87 | TMPDIR, 88 | 'marsbar', 89 | '--gitwash-url=%s' % ROOT_DIR]) 90 | cwd = os.getcwd() 91 | shutil.copy(pjoin(ROOT_DIR, 'conf.py'), TMPDIR) 92 | try: 93 | os.chdir(TMPDIR) 94 | with open('index.rst', 'wt') as index_fh: 95 | index_fh.write('\n') 96 | call('sphinx-build -b html -d _build/doctrees . _build/html', 97 | shell=True) 98 | call('sphinx-build -b linkcheck -d _build/doctrees . _build/linkcheck', 99 | shell=True) 100 | finally: 101 | os.chdir(cwd) 102 | -------------------------------------------------------------------------------- /gitwash/git_links.inc: -------------------------------------------------------------------------------- 1 | .. This (-*- rst -*-) format file contains commonly used link targets 2 | and name substitutions. It may be included in many files, 3 | therefore it should only contain link targets and name 4 | substitutions. Try grepping for "^\.\. _" to find plausible 5 | candidates for this list. 6 | 7 | .. NOTE: reST targets are 8 | __not_case_sensitive__, so only one target definition is needed for 9 | nipy, NIPY, Nipy, etc... 10 | 11 | .. git stuff 12 | .. _git: https://git-scm.com/ 13 | .. _github: https://github.com 14 | .. _github help: https://help.github.com 15 | .. _msysgit: https://git-scm.com/download/win 16 | .. _git-osx-installer: https://git-scm.com/download/mac 17 | .. _subversion: http://subversion.tigris.org/ 18 | .. _git cheat sheet: https://help.github.com/git-cheat-sheets/ 19 | .. _pro git book: https://git-scm.com/book/en/v2 20 | .. _git svn crash course: https://git-scm.com/course/svn.html 21 | .. _network graph visualizer: https://github.com/blog/39-say-hello-to-the-network-graph-visualizer 22 | .. _git user manual: https://schacon.github.io/git/user-manual.html 23 | .. _git tutorial: https://schacon.github.io/git/gittutorial.html 24 | .. _git ready: http://gitready.com/ 25 | .. _Fernando's git page: http://www.fperez.org/py4science/git.html 26 | .. _git magic: http://www-cs-students.stanford.edu/~blynn/gitmagic/index.html 27 | .. _git concepts: https://www.sbf5.com/~cduan/technical/git/ 28 | .. _git clone: https://schacon.github.io/git/git-clone.html 29 | .. _git checkout: https://schacon.github.io/git/git-checkout.html 30 | .. _git commit: https://schacon.github.io/git/git-commit.html 31 | .. _git push: https://schacon.github.io/git/git-push.html 32 | .. _git pull: https://schacon.github.io/git/git-pull.html 33 | .. _git add: https://schacon.github.io/git/git-add.html 34 | .. _git status: https://schacon.github.io/git/git-status.html 35 | .. _git diff: https://schacon.github.io/git/git-diff.html 36 | .. _git log: https://schacon.github.io/git/git-log.html 37 | .. _git branch: https://schacon.github.io/git/git-branch.html 38 | .. _git remote: https://schacon.github.io/git/git-remote.html 39 | .. _git rebase: https://schacon.github.io/git/git-rebase.html 40 | .. _git config: https://schacon.github.io/git/git-config.html 41 | .. _why the -a flag?: http://gitready.com/beginner/2009/01/18/the-staging-area.html 42 | .. _git staging area: http://gitready.com/beginner/2009/01/18/the-staging-area.html 43 | .. _tangled working copy problem: https://2ndscale.com/rtomayko/2008/the-thing-about-git 44 | .. _git management: https://web.archive.org/web/20090224195437/http://kerneltrap.org/Linux/Git_Management 45 | .. _linux git workflow: https://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.html 46 | .. _git parable: https://tom.preston-werner.com/2009/05/19/the-git-parable.html 47 | .. _git foundation: https://matthew-brett.github.io/pydagogue/foundation.html 48 | .. _deleting master on github: https://matthew-brett.github.io/pydagogue/gh_delete_master.html 49 | .. _rebase without tears: https://matthew-brett.github.io/pydagogue/rebase_without_tears.html 50 | .. _resolving a merge: https://schacon.github.io/git/user-manual.html#resolving-a-merge 51 | .. _ipython git workflow: https://mail.scipy.org/pipermail/ipython-dev/2010-October/006746.html 52 | 53 | .. other stuff 54 | .. _python: https://www.python.org 55 | 56 | .. |emdash| unicode:: U+02014 57 | 58 | .. vim: ft=rst 59 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 14 | 15 | .PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest 16 | 17 | help: 18 | @echo "Please use \`make ' where is one of" 19 | @echo " html to make standalone HTML files" 20 | @echo " dirhtml to make HTML files named index.html in directories" 21 | @echo " pickle to make pickle files" 22 | @echo " json to make JSON files" 23 | @echo " htmlhelp to make HTML files and a HTML help project" 24 | @echo " qthelp to make HTML files and a qthelp project" 25 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 26 | @echo " changes to make an overview of all changed/added/deprecated items" 27 | @echo " linkcheck to check all external links for integrity" 28 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 29 | 30 | clean: 31 | -rm -rf $(BUILDDIR)/* 32 | 33 | html: 34 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 35 | @echo 36 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 37 | 38 | dirhtml: 39 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 40 | @echo 41 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 42 | 43 | pickle: 44 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 45 | @echo 46 | @echo "Build finished; now you can process the pickle files." 47 | 48 | json: 49 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 50 | @echo 51 | @echo "Build finished; now you can process the JSON files." 52 | 53 | htmlhelp: 54 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 55 | @echo 56 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 57 | ".hhp project file in $(BUILDDIR)/htmlhelp." 58 | 59 | qthelp: 60 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 61 | @echo 62 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 63 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 64 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/gitwash.qhcp" 65 | @echo "To view the help file:" 66 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/gitwash.qhc" 67 | 68 | latex: 69 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 70 | @echo 71 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 72 | @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ 73 | "run these through (pdf)latex." 74 | 75 | changes: 76 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 77 | @echo 78 | @echo "The overview file is in $(BUILDDIR)/changes." 79 | 80 | linkcheck: 81 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 82 | @echo 83 | @echo "Link check complete; look for any errors in the above output " \ 84 | "or in $(BUILDDIR)/linkcheck/output.txt." 85 | 86 | doctest: 87 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 88 | @echo "Testing of doctests in the sources finished, look at the " \ 89 | "results in $(BUILDDIR)/doctest/output.txt." 90 | -------------------------------------------------------------------------------- /gitwash/maintainer_workflow.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: bash 2 | 3 | .. _maintainer-workflow: 4 | 5 | ################### 6 | Maintainer workflow 7 | ################### 8 | 9 | This page is for maintainers |emdash| those of us who merge our own or other 10 | peoples' changes into the upstream repository. 11 | 12 | Being as how you're a maintainer, you are completely on top of the basic stuff 13 | in :ref:`development-workflow`. 14 | 15 | The instructions in :ref:`linking-to-upstream` add a remote that has read-only 16 | access to the upstream repo. Being a maintainer, you've got read-write access. 17 | 18 | It's good to have your upstream remote have a scary name, to remind you that 19 | it's a read-write remote:: 20 | 21 | git remote add upstream-rw git@github.com:MAIN_GH_USER/REPONAME.git 22 | git fetch upstream-rw 23 | 24 | ******************* 25 | Integrating changes 26 | ******************* 27 | 28 | Let's say you have some changes that need to go into trunk 29 | (``upstream-rw/master``). 30 | 31 | The changes are in some branch that you are currently on. For example, you are 32 | looking at someone's changes like this:: 33 | 34 | git remote add someone https://github.com/someone/REPONAME.git 35 | git fetch someone 36 | git branch cool-feature --track someone/cool-feature 37 | git checkout cool-feature 38 | 39 | So now you are on the branch with the changes to be incorporated upstream. The 40 | rest of this section assumes you are on this branch. 41 | 42 | A few commits 43 | ============= 44 | 45 | If there are only a few commits, consider rebasing to upstream:: 46 | 47 | # Fetch upstream changes 48 | git fetch upstream-rw 49 | # rebase 50 | git rebase upstream-rw/master 51 | 52 | Remember that, if you do a rebase, and push that, you'll have to close any 53 | github pull requests manually, because github will not be able to detect the 54 | changes have already been merged. 55 | 56 | A long series of commits 57 | ======================== 58 | 59 | If there are a longer series of related commits, consider a merge instead:: 60 | 61 | git fetch upstream-rw 62 | git merge --no-ff upstream-rw/master 63 | 64 | The merge will be detected by github, and should close any related pull requests 65 | automatically. 66 | 67 | Note the ``--no-ff`` above. This forces git to make a merge commit, rather than 68 | doing a fast-forward, so that these set of commits branch off trunk then rejoin 69 | the main history with a merge, rather than appearing to have been made directly 70 | on top of trunk. 71 | 72 | Check the history 73 | ================= 74 | 75 | Now, in either case, you should check that the history is sensible and you have 76 | the right commits:: 77 | 78 | git log --oneline --graph 79 | git log -p upstream-rw/master.. 80 | 81 | The first line above just shows the history in a compact way, with a text 82 | representation of the history graph. The second line shows the log of commits 83 | excluding those that can be reached from trunk (``upstream-rw/master``), and 84 | including those that can be reached from current HEAD (implied with the ``..`` 85 | at the end). So, it shows the commits unique to this branch compared to trunk. 86 | The ``-p`` option shows the diff for these commits in patch form. 87 | 88 | Push to trunk 89 | ============= 90 | 91 | :: 92 | 93 | git push upstream-rw my-new-feature:master 94 | 95 | This pushes the ``my-new-feature`` branch in this repository to the ``master`` 96 | branch in the ``upstream-rw`` repository. 97 | 98 | .. include:: links.inc 99 | -------------------------------------------------------------------------------- /make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | set SPHINXBUILD=sphinx-build 6 | set BUILDDIR=_build 7 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . 8 | if NOT "%PAPER%" == "" ( 9 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 10 | ) 11 | 12 | if "%1" == "" goto help 13 | 14 | if "%1" == "help" ( 15 | :help 16 | echo.Please use `make ^` where ^ is one of 17 | echo. html to make standalone HTML files 18 | echo. dirhtml to make HTML files named index.html in directories 19 | echo. pickle to make pickle files 20 | echo. json to make JSON files 21 | echo. htmlhelp to make HTML files and a HTML help project 22 | echo. qthelp to make HTML files and a qthelp project 23 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 24 | echo. changes to make an overview over all changed/added/deprecated items 25 | echo. linkcheck to check all external links for integrity 26 | echo. doctest to run all doctests embedded in the documentation if enabled 27 | goto end 28 | ) 29 | 30 | if "%1" == "clean" ( 31 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 32 | del /q /s %BUILDDIR%\* 33 | goto end 34 | ) 35 | 36 | if "%1" == "html" ( 37 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 38 | echo. 39 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 40 | goto end 41 | ) 42 | 43 | if "%1" == "dirhtml" ( 44 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 45 | echo. 46 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 47 | goto end 48 | ) 49 | 50 | if "%1" == "pickle" ( 51 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 52 | echo. 53 | echo.Build finished; now you can process the pickle files. 54 | goto end 55 | ) 56 | 57 | if "%1" == "json" ( 58 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 59 | echo. 60 | echo.Build finished; now you can process the JSON files. 61 | goto end 62 | ) 63 | 64 | if "%1" == "htmlhelp" ( 65 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 66 | echo. 67 | echo.Build finished; now you can run HTML Help Workshop with the ^ 68 | .hhp project file in %BUILDDIR%/htmlhelp. 69 | goto end 70 | ) 71 | 72 | if "%1" == "qthelp" ( 73 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 74 | echo. 75 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 76 | .qhcp project file in %BUILDDIR%/qthelp, like this: 77 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\gitwash.qhcp 78 | echo.To view the help file: 79 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\gitwash.ghc 80 | goto end 81 | ) 82 | 83 | if "%1" == "latex" ( 84 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 85 | echo. 86 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 87 | goto end 88 | ) 89 | 90 | if "%1" == "changes" ( 91 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 92 | echo. 93 | echo.The overview file is in %BUILDDIR%/changes. 94 | goto end 95 | ) 96 | 97 | if "%1" == "linkcheck" ( 98 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 99 | echo. 100 | echo.Link check complete; look for any errors in the above output ^ 101 | or in %BUILDDIR%/linkcheck/output.txt. 102 | goto end 103 | ) 104 | 105 | if "%1" == "doctest" ( 106 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 107 | echo. 108 | echo.Testing of doctests in the sources finished, look at the ^ 109 | results in %BUILDDIR%/doctest/output.txt. 110 | goto end 111 | ) 112 | 113 | :end 114 | -------------------------------------------------------------------------------- /gitwash/patching.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: bash 2 | 3 | ================ 4 | Making a patch 5 | ================ 6 | 7 | You've discovered a bug or something else you want to change 8 | in `PROJECTNAME`_ .. |emdash| excellent! 9 | 10 | You've worked out a way to fix it |emdash| even better! 11 | 12 | You want to tell us about it |emdash| best of all! 13 | 14 | The easiest way is to make a *patch* or set of patches. Here 15 | we explain how. Making a patch is the simplest and quickest, 16 | but if you're going to be doing anything more than simple 17 | quick things, please consider following the 18 | :ref:`git-development` model instead. 19 | 20 | .. _making-patches: 21 | 22 | Making patches 23 | ============== 24 | 25 | Overview 26 | -------- 27 | 28 | :: 29 | 30 | # tell git who you are 31 | git config --global user.email you@yourdomain.example.com 32 | git config --global user.name "Your Name Comes Here" 33 | # get the repository if you don't have it 34 | git clone https://github.com/MAIN_GH_USER/REPONAME.git 35 | # make a branch for your patching 36 | cd REPONAME 37 | git branch the-fix-im-thinking-of 38 | git checkout the-fix-im-thinking-of 39 | # hack, hack, hack 40 | # Tell git about any new files you've made 41 | git add somewhere/tests/test_my_bug.py 42 | # commit work in progress as you go 43 | git commit -am 'BF - added tests for Funny bug' 44 | # hack hack, hack 45 | git commit -am 'BF - added fix for Funny bug' 46 | # make the patch files 47 | git format-patch -M -C master 48 | 49 | Then, send the generated patch files to the `PROJECTNAME 50 | mailing list`_ |emdash| where we will thank you warmly. 51 | 52 | In detail 53 | --------- 54 | 55 | #. Tell git who you are so it can label the commits you've 56 | made:: 57 | 58 | git config --global user.email you@yourdomain.example.com 59 | git config --global user.name "Your Name Comes Here" 60 | 61 | #. If you don't already have one, clone a copy of the 62 | `PROJECTNAME`_ repository:: 63 | 64 | git clone https://github.com/MAIN_GH_USER/REPONAME.git 65 | cd REPONAME 66 | 67 | #. Make a 'feature branch'. This will be where you work on 68 | your bug fix. It's nice and safe and leaves you with 69 | access to an unmodified copy of the code in the main 70 | branch:: 71 | 72 | git branch the-fix-im-thinking-of 73 | git checkout the-fix-im-thinking-of 74 | 75 | #. Do some edits, and commit them as you go:: 76 | 77 | # hack, hack, hack 78 | # Tell git about any new files you've made 79 | git add somewhere/tests/test_my_bug.py 80 | # commit work in progress as you go 81 | git commit -am 'BF - added tests for Funny bug' 82 | # hack hack, hack 83 | git commit -am 'BF - added fix for Funny bug' 84 | 85 | Note the ``-am`` options to ``commit``. The ``m`` flag just 86 | signals that you're going to type a message on the command 87 | line. The ``a`` flag |emdash| you can just take on faith |emdash| 88 | or see `why the -a flag?`_. 89 | 90 | #. When you have finished, check you have committed all your 91 | changes:: 92 | 93 | git status 94 | 95 | #. Finally, make your commits into patches. You want all the 96 | commits since you branched from the ``master`` branch:: 97 | 98 | git format-patch -M -C master 99 | 100 | You will now have several files named for the commits: 101 | 102 | .. code-block:: none 103 | 104 | 0001-BF-added-tests-for-Funny-bug.patch 105 | 0002-BF-added-fix-for-Funny-bug.patch 106 | 107 | Send these files to the `PROJECTNAME mailing list`_. 108 | 109 | When you are done, to switch back to the main copy of the 110 | code, just return to the ``master`` branch:: 111 | 112 | git checkout master 113 | 114 | Moving from patching to development 115 | =================================== 116 | 117 | If you find you have done some patches, and you have one or 118 | more feature branches, you will probably want to switch to 119 | development mode. You can do this with the repository you 120 | have. 121 | 122 | Fork the `PROJECTNAME`_ repository on github |emdash| :ref:`forking`. 123 | Then:: 124 | 125 | # checkout and refresh master branch from main repo 126 | git checkout master 127 | git pull origin master 128 | # rename pointer to main repository to 'upstream' 129 | git remote rename origin upstream 130 | # point your repo to default read / write to your fork on github 131 | git remote add origin git@github.com:your-user-name/REPONAME.git 132 | # push up any branches you've made and want to keep 133 | git push origin the-fix-im-thinking-of 134 | 135 | Then you can, if you want, follow the 136 | :ref:`development-workflow`. 137 | 138 | .. include:: links.inc 139 | -------------------------------------------------------------------------------- /gitwash/configure_git.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: bash 2 | 3 | .. _configure-git: 4 | 5 | =============== 6 | Configure git 7 | =============== 8 | 9 | .. _git-config-basic: 10 | 11 | Overview 12 | ======== 13 | 14 | Your personal git configurations are saved in the ``.gitconfig`` file in 15 | your home directory. 16 | 17 | Here is an example ``.gitconfig`` file: 18 | 19 | .. code-block:: none 20 | 21 | [user] 22 | name = Your Name 23 | email = you@yourdomain.example.com 24 | 25 | [alias] 26 | ci = commit -a 27 | co = checkout 28 | st = status 29 | stat = status 30 | br = branch 31 | wdiff = diff --color-words 32 | 33 | [core] 34 | editor = vim 35 | 36 | [merge] 37 | summary = true 38 | 39 | You can edit this file directly or you can use the ``git config --global`` 40 | command:: 41 | 42 | git config --global user.name "Your Name" 43 | git config --global user.email you@yourdomain.example.com 44 | git config --global alias.ci "commit -a" 45 | git config --global alias.co checkout 46 | git config --global alias.st "status -a" 47 | git config --global alias.stat "status -a" 48 | git config --global alias.br branch 49 | git config --global alias.wdiff "diff --color-words" 50 | git config --global core.editor vim 51 | git config --global merge.summary true 52 | 53 | To set up on another computer, you can copy your ``~/.gitconfig`` file, 54 | or run the commands above. 55 | 56 | In detail 57 | ========= 58 | 59 | user.name and user.email 60 | ------------------------ 61 | 62 | It is good practice to tell git_ who you are, for labeling any changes 63 | you make to the code. The simplest way to do this is from the command 64 | line:: 65 | 66 | git config --global user.name "Your Name" 67 | git config --global user.email you@yourdomain.example.com 68 | 69 | This will write the settings into your git configuration file, which 70 | should now contain a user section with your name and email: 71 | 72 | .. code-block:: none 73 | 74 | [user] 75 | name = Your Name 76 | email = you@yourdomain.example.com 77 | 78 | Of course you'll need to replace ``Your Name`` and ``you@yourdomain.example.com`` 79 | with your actual name and email address. 80 | 81 | Aliases 82 | ------- 83 | 84 | You might well benefit from some aliases to common commands. 85 | 86 | For example, you might well want to be able to shorten ``git checkout`` 87 | to ``git co``. Or you may want to alias ``git diff --color-words`` 88 | (which gives a nicely formatted output of the diff) to ``git wdiff`` 89 | 90 | The following ``git config --global`` commands:: 91 | 92 | git config --global alias.ci "commit -a" 93 | git config --global alias.co checkout 94 | git config --global alias.st "status -a" 95 | git config --global alias.stat "status -a" 96 | git config --global alias.br branch 97 | git config --global alias.wdiff "diff --color-words" 98 | 99 | will create an ``alias`` section in your ``.gitconfig`` file with contents 100 | like this: 101 | 102 | .. code-block:: none 103 | 104 | [alias] 105 | ci = commit -a 106 | co = checkout 107 | st = status -a 108 | stat = status -a 109 | br = branch 110 | wdiff = diff --color-words 111 | 112 | Editor 113 | ------ 114 | 115 | You may also want to make sure that your editor of choice is used :: 116 | 117 | git config --global core.editor vim 118 | 119 | Merging 120 | ------- 121 | 122 | To enforce summaries when doing merges (``~/.gitconfig`` file again): 123 | 124 | .. code-block:: none 125 | 126 | [merge] 127 | log = true 128 | 129 | Or from the command line:: 130 | 131 | git config --global merge.log true 132 | 133 | .. _fancy-log: 134 | 135 | Fancy log output 136 | ---------------- 137 | 138 | This is a very nice alias to get a fancy log output; it should go in the 139 | ``alias`` section of your ``.gitconfig`` file: 140 | 141 | .. code-block:: none 142 | 143 | lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)[%an]%Creset' --abbrev-commit --date=relative 144 | 145 | You use the alias with:: 146 | 147 | git lg 148 | 149 | and it gives graph / text output something like this (but with color!): 150 | 151 | .. code-block:: none 152 | 153 | * 6d8e1ee - (HEAD, origin/my-fancy-feature, my-fancy-feature) NF - a fancy file (45 minutes ago) [Matthew Brett] 154 | * d304a73 - (origin/placeholder, placeholder) Merge pull request #48 from hhuuggoo/master (2 weeks ago) [Jonathan Terhorst] 155 | |\ 156 | | * 4aff2a8 - fixed bug 35, and added a test in test_bugfixes (2 weeks ago) [Hugo] 157 | |/ 158 | * a7ff2e5 - Added notes on discussion/proposal made during Data Array Summit. (2 weeks ago) [Corran Webster] 159 | * 68f6752 - Initial implimentation of AxisIndexer - uses 'index_by' which needs to be changed to a call on an Axes object - this is all very sketchy right now. (2 weeks ago) [Corr 160 | * 376adbd - Merge pull request #46 from terhorst/master (2 weeks ago) [Jonathan Terhorst] 161 | |\ 162 | | * b605216 - updated joshu example to current api (3 weeks ago) [Jonathan Terhorst] 163 | | * 2e991e8 - add testing for outer ufunc (3 weeks ago) [Jonathan Terhorst] 164 | | * 7beda5a - prevent axis from throwing an exception if testing equality with non-axis object (3 weeks ago) [Jonathan Terhorst] 165 | | * 65af65e - convert unit testing code to assertions (3 weeks ago) [Jonathan Terhorst] 166 | | * 956fbab - Merge remote-tracking branch 'upstream/master' (3 weeks ago) [Jonathan Terhorst] 167 | | |\ 168 | | |/ 169 | 170 | Thanks to Yury V. Zaytsev for posting it. 171 | 172 | .. include:: links.inc 173 | -------------------------------------------------------------------------------- /conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # gitwash documentation build configuration file, created by 4 | # sphinx-quickstart on Sat Apr 24 10:54:48 2010. 5 | # 6 | # This file is execfile()d with the current directory set to its containing dir. 7 | # 8 | # Note that not all possible configuration values are present in this 9 | # autogenerated file. 10 | # 11 | # All configuration values have a default; values that are commented out 12 | # serve to show the default. 13 | 14 | from __future__ import (absolute_import, division, print_function) 15 | 16 | import sys, os 17 | 18 | # If extensions (or modules to document with autodoc) are in another directory, 19 | # add these directories to sys.path here. If the directory is relative to the 20 | # documentation root, use os.path.abspath to make it absolute, like shown here. 21 | #sys.path.append(os.path.abspath('.')) 22 | 23 | # -- General configuration ----------------------------------------------------- 24 | 25 | # Add any Sphinx extension module names here, as strings. They can be extensions 26 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 27 | extensions = [] 28 | 29 | # Add any paths that contain templates here, relative to this directory. 30 | templates_path = ['_templates'] 31 | 32 | # The suffix of source filenames. 33 | source_suffix = '.rst' 34 | 35 | # The encoding of source files. 36 | #source_encoding = 'utf-8' 37 | 38 | # The master toctree document. 39 | master_doc = 'index' 40 | 41 | # General information about the project. 42 | project = u'gitwash' 43 | copyright = u'2010, Matthew Brett, Fernando Perez' 44 | 45 | # The version info for the project you're documenting, acts as replacement for 46 | # |version| and |release|, also used in various other places throughout the 47 | # built documents. 48 | # 49 | # The short X.Y version. 50 | version = '0.1a' 51 | # The full version, including alpha/beta/rc tags. 52 | release = '0.1a' 53 | 54 | # The language for content autogenerated by Sphinx. Refer to documentation 55 | # for a list of supported languages. 56 | #language = None 57 | 58 | # There are two options for replacing |today|: either, you set today to some 59 | # non-false value, then it is used: 60 | #today = '' 61 | # Else, today_fmt is used as the format for a strftime call. 62 | #today_fmt = '%B %d, %Y' 63 | 64 | # List of documents that shouldn't be included in the build. 65 | #unused_docs = [] 66 | 67 | # List of directories, relative to source directory, that shouldn't be searched 68 | # for source files. 69 | exclude_trees = ['_build'] 70 | 71 | # The reST default role (used for this markup: `text`) to use for all documents. 72 | #default_role = None 73 | 74 | # If true, '()' will be appended to :func: etc. cross-reference text. 75 | #add_function_parentheses = True 76 | 77 | # If true, the current module name will be prepended to all description 78 | # unit titles (such as .. function::). 79 | #add_module_names = True 80 | 81 | # If true, sectionauthor and moduleauthor directives will be shown in the 82 | # output. They are ignored by default. 83 | #show_authors = False 84 | 85 | # The name of the Pygments (syntax highlighting) style to use. 86 | pygments_style = 'sphinx' 87 | 88 | # A list of ignored prefixes for module index sorting. 89 | #modindex_common_prefix = [] 90 | 91 | 92 | # -- Options for HTML output --------------------------------------------------- 93 | 94 | # The theme to use for HTML and HTML Help pages. Major themes that come with 95 | # Sphinx are currently 'default' and 'sphinxdoc'. 96 | html_theme = 'default' 97 | 98 | # Theme options are theme-specific and customize the look and feel of a theme 99 | # further. For a list of options available for each theme, see the 100 | # documentation. 101 | #html_theme_options = {} 102 | 103 | # Add any paths that contain custom themes here, relative to this directory. 104 | #html_theme_path = [] 105 | 106 | # The name for this set of Sphinx documents. If None, it defaults to 107 | # " v documentation". 108 | #html_title = None 109 | 110 | # A shorter title for the navigation bar. Default is the same as html_title. 111 | #html_short_title = None 112 | 113 | # The name of an image file (relative to this directory) to place at the top 114 | # of the sidebar. 115 | #html_logo = None 116 | 117 | # The name of an image file (within the static path) to use as favicon of the 118 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 119 | # pixels large. 120 | #html_favicon = None 121 | 122 | # Add any paths that contain custom static files (such as style sheets) here, 123 | # relative to this directory. They are copied after the builtin static files, 124 | # so a file named "default.css" will overwrite the builtin "default.css". 125 | html_static_path = ['_static'] 126 | 127 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 128 | # using the given strftime format. 129 | #html_last_updated_fmt = '%b %d, %Y' 130 | 131 | # If true, SmartyPants will be used to convert quotes and dashes to 132 | # typographically correct entities. 133 | #html_use_smartypants = True 134 | 135 | # Custom sidebar templates, maps document names to template names. 136 | #html_sidebars = {} 137 | 138 | # Additional templates that should be rendered to pages, maps page names to 139 | # template names. 140 | #html_additional_pages = {} 141 | 142 | # If false, no module index is generated. 143 | #html_use_modindex = True 144 | 145 | # If false, no index is generated. 146 | #html_use_index = True 147 | 148 | # If true, the index is split into individual pages for each letter. 149 | #html_split_index = False 150 | 151 | # If true, links to the reST sources are added to the pages. 152 | #html_show_sourcelink = True 153 | 154 | # If true, an OpenSearch description file will be output, and all pages will 155 | # contain a tag referring to it. The value of this option must be the 156 | # base URL from which the finished HTML is served. 157 | #html_use_opensearch = '' 158 | 159 | # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). 160 | #html_file_suffix = '' 161 | 162 | # Output file base name for HTML help builder. 163 | htmlhelp_basename = 'gitwashdoc' 164 | 165 | 166 | # -- Options for LaTeX output -------------------------------------------------- 167 | 168 | # The paper size ('letter' or 'a4'). 169 | #latex_paper_size = 'letter' 170 | 171 | # The font size ('10pt', '11pt' or '12pt'). 172 | #latex_font_size = '10pt' 173 | 174 | # Grouping the document tree into LaTeX files. List of tuples 175 | # (source start file, target name, title, author, documentclass [howto/manual]). 176 | latex_documents = [ 177 | ('index', 'gitwash.tex', u'gitwash Documentation', 178 | u'Matthew Brett, Fernando Perez', 'manual'), 179 | ] 180 | 181 | # The name of an image file (relative to this directory) to place at the top of 182 | # the title page. 183 | #latex_logo = None 184 | 185 | # For "manual" documents, if this is true, then toplevel headings are parts, 186 | # not chapters. 187 | #latex_use_parts = False 188 | 189 | # Additional stuff for the LaTeX preamble. 190 | #latex_preamble = '' 191 | 192 | # Documents to append as an appendix to all manuals. 193 | #latex_appendices = [] 194 | 195 | # If false, no module index is generated. 196 | #latex_use_modindex = True 197 | -------------------------------------------------------------------------------- /gitwash_dumper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' Checkout gitwash repo into directory and do search replace on name ''' 3 | 4 | from __future__ import (absolute_import, division, print_function) 5 | 6 | import os 7 | from os.path import join as pjoin 8 | import shutil 9 | import sys 10 | import re 11 | import glob 12 | import fnmatch 13 | import tempfile 14 | from subprocess import call 15 | from optparse import OptionParser 16 | 17 | verbose = False 18 | 19 | 20 | def clone_repo(url, branch): 21 | cwd = os.getcwd() 22 | tmpdir = tempfile.mkdtemp() 23 | try: 24 | cmd = 'git clone %s %s' % (url, tmpdir) 25 | call(cmd, shell=True) 26 | os.chdir(tmpdir) 27 | cmd = 'git checkout %s' % branch 28 | call(cmd, shell=True) 29 | except: 30 | shutil.rmtree(tmpdir) 31 | raise 32 | finally: 33 | os.chdir(cwd) 34 | return tmpdir 35 | 36 | 37 | def cp_files(in_path, globs, out_path): 38 | try: 39 | os.makedirs(out_path) 40 | except OSError: 41 | pass 42 | out_fnames = [] 43 | for in_glob in globs: 44 | in_glob_path = pjoin(in_path, in_glob) 45 | for in_fname in glob.glob(in_glob_path): 46 | out_fname = in_fname.replace(in_path, out_path) 47 | pth, _ = os.path.split(out_fname) 48 | if not os.path.isdir(pth): 49 | os.makedirs(pth) 50 | shutil.copyfile(in_fname, out_fname) 51 | out_fnames.append(out_fname) 52 | return out_fnames 53 | 54 | 55 | def filename_search_replace(sr_pairs, filename, backup=False): 56 | ''' Search and replace for expressions in files 57 | 58 | ''' 59 | with open(filename, 'rt') as in_fh: 60 | in_txt = in_fh.read(-1) 61 | out_txt = in_txt[:] 62 | for in_exp, out_exp in sr_pairs: 63 | in_exp = re.compile(in_exp) 64 | out_txt = in_exp.sub(out_exp, out_txt) 65 | if in_txt == out_txt: 66 | return False 67 | with open(filename, 'wt') as out_fh: 68 | out_fh.write(out_txt) 69 | if backup: 70 | with open(filename + '.bak', 'wt') as bak_fh: 71 | bak_fh.write(in_txt) 72 | return True 73 | 74 | 75 | def copy_replace(replace_pairs, 76 | repo_path, 77 | out_path, 78 | cp_globs=('*',), 79 | rep_globs=('*',), 80 | renames = ()): 81 | out_fnames = cp_files(repo_path, cp_globs, out_path) 82 | renames = [(re.compile(in_exp), out_exp) for in_exp, out_exp in renames] 83 | fnames = [] 84 | for rep_glob in rep_globs: 85 | fnames += fnmatch.filter(out_fnames, rep_glob) 86 | if verbose: 87 | print('\n'.join(fnames)) 88 | for fname in fnames: 89 | filename_search_replace(replace_pairs, fname, False) 90 | for in_exp, out_exp in renames: 91 | new_fname, n = in_exp.subn(out_exp, fname) 92 | if n: 93 | os.rename(fname, new_fname) 94 | break 95 | 96 | 97 | def make_link_targets(proj_name, 98 | user_name, 99 | repo_name, 100 | known_link_fname, 101 | out_link_fname, 102 | url=None, 103 | ml_url=None): 104 | """ Check and make link targets 105 | 106 | If url is None or ml_url is None, check if there are links present for these 107 | in `known_link_fname`. If not, raise error. The check is: 108 | 109 | Look for a target `proj_name`. 110 | Look for a target `proj_name` + ' mailing list' 111 | 112 | Also, look for a target `proj_name` + 'github'. If this exists, don't write 113 | this target into the new file below. 114 | 115 | If we are writing any of the url, ml_url, or github address, then write new 116 | file with these links, of form: 117 | 118 | .. _`proj_name` 119 | .. _`proj_name`: url 120 | .. _`proj_name` mailing list: url 121 | """ 122 | with open(known_link_fname, 'rt') as link_fh: 123 | link_contents = link_fh.readlines() 124 | have_url = not url is None 125 | have_ml_url = not ml_url is None 126 | have_gh_url = None 127 | for line in link_contents: 128 | if not have_url: 129 | match = re.match(r'..\s+_`%s`:\s+' % proj_name, line) 130 | if match: 131 | have_url = True 132 | if not have_ml_url: 133 | match = re.match(r'..\s+_`%s mailing list`:\s+' % proj_name, line) 134 | if match: 135 | have_ml_url = True 136 | if not have_gh_url: 137 | match = re.match(r'..\s+_`%s github`:\s+' % proj_name, line) 138 | if match: 139 | have_gh_url = True 140 | if not have_url or not have_ml_url: 141 | raise RuntimeError('Need command line or known project ' 142 | 'and / or mailing list URLs') 143 | lines = [] 144 | if not url is None: 145 | lines.append('.. _`%s`: %s\n' % (proj_name, url)) 146 | if not have_gh_url: 147 | gh_url = 'https://github.com/%s/%s\n' % (user_name, repo_name) 148 | lines.append('.. _`%s github`: %s\n' % (proj_name, gh_url)) 149 | if not ml_url is None: 150 | lines.append('.. _`%s mailing list`: %s\n' % (proj_name, ml_url)) 151 | if len(lines) == 0: 152 | # Nothing to do 153 | return 154 | # A neat little header line 155 | lines = ['.. %s\n' % proj_name] + lines 156 | with open(out_link_fname, 'wt') as out_links: 157 | out_links.writelines(lines) 158 | 159 | 160 | USAGE = ''' 161 | 162 | If not set with options, the repository name is the same as the 164 | 165 | If not set with options, the main github user is the same as the 166 | repository name.''' 167 | 168 | 169 | GITWASH_CENTRAL = 'https://github.com/matthew-brett/gitwash.git' 170 | GITWASH_BRANCH = 'main' 171 | 172 | 173 | def main(): 174 | parser = OptionParser() 175 | parser.set_usage(parser.get_usage().strip() + USAGE) 176 | parser.add_option("--repo-name", dest="repo_name", 177 | help="repository name - e.g. nitime", 178 | metavar="REPO_NAME") 179 | parser.add_option("--github-user", dest="main_gh_user", 180 | help="github username for main repo - e.g fperez", 181 | metavar="MAIN_GH_USER") 182 | parser.add_option("--gitwash-url", dest="gitwash_url", 183 | help="URL to gitwash repository - default %s" 184 | % GITWASH_CENTRAL, 185 | default=GITWASH_CENTRAL, 186 | metavar="GITWASH_URL") 187 | parser.add_option("--gitwash-branch", dest="gitwash_branch", 188 | help="branch in gitwash repository - default %s" 189 | % GITWASH_BRANCH, 190 | default=GITWASH_BRANCH, 191 | metavar="GITWASH_BRANCH") 192 | parser.add_option("--source-suffix", dest="source_suffix", 193 | help="suffix of ReST source files - default '.rst'", 194 | default='.rst', 195 | metavar="SOURCE_SUFFIX") 196 | parser.add_option("--project-url", dest="project_url", 197 | help="URL for project web pages", 198 | default=None, 199 | metavar="PROJECT_URL") 200 | parser.add_option("--project-ml-url", dest="project_ml_url", 201 | help="URL for project mailing list", 202 | default=None, 203 | metavar="PROJECT_ML_URL") 204 | (options, args) = parser.parse_args() 205 | if len(args) < 2: 206 | parser.print_help() 207 | sys.exit() 208 | out_path, project_name = args 209 | if options.repo_name is None: 210 | options.repo_name = project_name 211 | if options.main_gh_user is None: 212 | options.main_gh_user = options.repo_name 213 | repo_path = clone_repo(options.gitwash_url, options.gitwash_branch) 214 | try: 215 | copy_replace((('PROJECTNAME', project_name), 216 | ('REPONAME', options.repo_name), 217 | ('MAIN_GH_USER', options.main_gh_user)), 218 | repo_path, 219 | out_path, 220 | cp_globs=(pjoin('gitwash', '*'),), 221 | rep_globs=('*.rst',), 222 | renames=(('\.rst$', options.source_suffix),)) 223 | make_link_targets(project_name, 224 | options.main_gh_user, 225 | options.repo_name, 226 | pjoin(out_path, 'gitwash', 'known_projects.inc'), 227 | pjoin(out_path, 'gitwash', 'this_project.inc'), 228 | options.project_url, 229 | options.project_ml_url) 230 | finally: 231 | shutil.rmtree(repo_path) 232 | 233 | 234 | if __name__ == '__main__': 235 | main() 236 | -------------------------------------------------------------------------------- /gitwash/development_workflow.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: bash 2 | 3 | .. _development-workflow: 4 | 5 | #################### 6 | Development workflow 7 | #################### 8 | 9 | You already have your own forked copy of the `PROJECTNAME`_ 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 PROJECTNAME ``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 `PROJECTNAME 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 `PROJECTNAME`_. 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 ..." to update what will be committed) 128 | # (use "git checkout -- ..." to discard changes in working directory) 129 | # 130 | # modified: README 131 | # 132 | # Untracked files: 133 | # (use "git add ..." 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/REPONAME``. 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 PROJECTNAME 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/REPONAME`` 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@github.com:your-user-name/REPONAME.git 212 | 213 | Your collaborators can then commit directly into that repo with the 214 | usual:: 215 | 216 | git commit -am 'ENH - much better code' 217 | git push origin master # pushes directly into your repo 218 | 219 | Explore your repository 220 | ----------------------- 221 | 222 | To see a graphical representation of the repository branches and 223 | commits:: 224 | 225 | gitk --all 226 | 227 | To see a linear list of commits for this branch:: 228 | 229 | git log 230 | 231 | You can also look at the `network graph visualizer`_ for your github 232 | repo. 233 | 234 | Finally the :ref:`fancy-log` ``lg`` alias will give you a reasonable text-based 235 | graph of the repository. 236 | 237 | .. _rebase-on-trunk: 238 | 239 | Rebasing on trunk 240 | ----------------- 241 | 242 | Let's say you thought of some work you'd like to do. You 243 | :ref:`update-mirror-trunk` and :ref:`make-feature-branch` called 244 | ``cool-feature``. At this stage trunk is at some commit, let's call it E. Now 245 | you make some new commits on your ``cool-feature`` branch, let's call them A, B, 246 | C. Maybe your changes take a while, or you come back to them after a while. In 247 | the meantime, trunk has progressed from commit E to commit (say) G: 248 | 249 | .. code-block:: none 250 | 251 | A---B---C cool-feature 252 | / 253 | D---E---F---G trunk 254 | 255 | At this stage you consider merging trunk into your feature branch, and you 256 | remember that this here page sternly advises you not to do that, because the 257 | history will get messy. Most of the time you can just ask for a review, and not 258 | worry that trunk has got a little ahead. But sometimes, the changes in trunk 259 | might affect your changes, and you need to harmonize them. In this situation 260 | you may prefer to do a rebase. 261 | 262 | rebase takes your changes (A, B, C) and replays them as if they had been made to 263 | the current state of ``trunk``. In other words, in this case, it takes the 264 | changes represented by A, B, C and replays them on top of G. After the rebase, 265 | your history will look like this: 266 | 267 | .. code-block:: none 268 | 269 | A'--B'--C' cool-feature 270 | / 271 | D---E---F---G trunk 272 | 273 | See `rebase without tears`_ for more detail. 274 | 275 | To do a rebase on trunk:: 276 | 277 | # Update the mirror of trunk 278 | git fetch upstream 279 | # go to the feature branch 280 | git checkout cool-feature 281 | # make a backup in case you mess up 282 | git branch tmp cool-feature 283 | # rebase cool-feature onto trunk 284 | git rebase --onto upstream/master upstream/master cool-feature 285 | 286 | In this situation, where you are already on branch ``cool-feature``, the last 287 | command can be written more succinctly as:: 288 | 289 | git rebase upstream/master 290 | 291 | When all looks good you can delete your backup branch:: 292 | 293 | git branch -D tmp 294 | 295 | If it doesn't look good you may need to have a look at 296 | :ref:`recovering-from-mess-up`. 297 | 298 | If you have made changes to files that have also changed in trunk, this may 299 | generate merge conflicts that you need to resolve - see the `git rebase`_ man 300 | page for some instructions at the end of the "Description" section. There is 301 | some related help on merging in the git user manual - see `resolving a merge`_. 302 | 303 | .. _recovering-from-mess-up: 304 | 305 | Recovering from mess-ups 306 | ------------------------ 307 | 308 | Sometimes, you mess up merges or rebases. Luckily, in git it is 309 | relatively straightforward to recover from such mistakes. 310 | 311 | If you mess up during a rebase:: 312 | 313 | git rebase --abort 314 | 315 | If you notice you messed up after the rebase:: 316 | 317 | # reset branch back to the saved point 318 | git reset --hard tmp 319 | 320 | If you forgot to make a backup branch:: 321 | 322 | # look at the reflog of the branch 323 | git reflog show cool-feature 324 | 325 | 8630830 cool-feature@{0}: commit: BUG: io: close file handles immediately 326 | 278dd2a cool-feature@{1}: rebase finished: refs/heads/my-feature-branch onto 11ee694744f2552d 327 | 26aa21a cool-feature@{2}: commit: BUG: lib: make seek_gzip_factory not leak gzip obj 328 | ... 329 | 330 | # reset the branch to where it was before the botched rebase 331 | git reset --hard cool-feature@{2} 332 | 333 | .. _rewriting-commit-history: 334 | 335 | Rewriting commit history 336 | ------------------------ 337 | 338 | .. note:: 339 | 340 | Do this only for your own feature branches. 341 | 342 | There's an embarrassing typo in a commit you made? Or perhaps the you 343 | made several false starts you would like the posterity not to see. 344 | 345 | This can be done via *interactive rebasing*. 346 | 347 | Suppose that the commit history looks like this:: 348 | 349 | git log --oneline 350 | eadc391 Fix some remaining bugs 351 | a815645 Modify it so that it works 352 | 2dec1ac Fix a few bugs + disable 353 | 13d7934 First implementation 354 | 6ad92e5 * masked is now an instance of a new object, MaskedConstant 355 | 29001ed Add pre-nep for a copule of structured_array_extensions. 356 | ... 357 | 358 | and ``6ad92e5`` is the last commit in the ``cool-feature`` branch. Suppose we 359 | want to make the following changes: 360 | 361 | * Rewrite the commit message for ``13d7934`` to something more sensible. 362 | * Combine the commits ``2dec1ac``, ``a815645``, ``eadc391`` into a single one. 363 | 364 | We do as follows:: 365 | 366 | # make a backup of the current state 367 | git branch tmp HEAD 368 | # interactive rebase 369 | git rebase -i 6ad92e5 370 | 371 | This will open an editor with the following text in it:: 372 | 373 | pick 13d7934 First implementation 374 | pick 2dec1ac Fix a few bugs + disable 375 | pick a815645 Modify it so that it works 376 | pick eadc391 Fix some remaining bugs 377 | 378 | # Rebase 6ad92e5..eadc391 onto 6ad92e5 379 | # 380 | # Commands: 381 | # p, pick = use commit 382 | # r, reword = use commit, but edit the commit message 383 | # e, edit = use commit, but stop for amending 384 | # s, squash = use commit, but meld into previous commit 385 | # f, fixup = like "squash", but discard this commit's log message 386 | # 387 | # If you remove a line here THAT COMMIT WILL BE LOST. 388 | # However, if you remove everything, the rebase will be aborted. 389 | # 390 | 391 | To achieve what we want, we will make the following changes to it:: 392 | 393 | r 13d7934 First implementation 394 | pick 2dec1ac Fix a few bugs + disable 395 | f a815645 Modify it so that it works 396 | f eadc391 Fix some remaining bugs 397 | 398 | This means that (i) we want to edit the commit message for 399 | ``13d7934``, and (ii) collapse the last three commits into one. Now we 400 | save and quit the editor. 401 | 402 | Git will then immediately bring up an editor for editing the commit 403 | message. After revising it, we get the output:: 404 | 405 | [detached HEAD 721fc64] FOO: First implementation 406 | 2 files changed, 199 insertions(+), 66 deletions(-) 407 | [detached HEAD 0f22701] Fix a few bugs + disable 408 | 1 files changed, 79 insertions(+), 61 deletions(-) 409 | Successfully rebased and updated refs/heads/my-feature-branch. 410 | 411 | and the history looks now like this:: 412 | 413 | 0f22701 Fix a few bugs + disable 414 | 721fc64 ENH: Sophisticated feature 415 | 6ad92e5 * masked is now an instance of a new object, MaskedConstant 416 | 417 | If it went wrong, recovery is again possible as explained :ref:`above 418 | `. 419 | 420 | .. include:: links.inc 421 | --------------------------------------------------------------------------------