Development Guidelines
======================

It is recommended that PyTao is updated and maintained in the following
way. This workflow was not invented by this project, there are many
helpful tutorials online like
[this](https://guides.github.com/introduction/flow) if you want more
information.

Creating a Local Checkout
-------------------------

If you want to make changes to a repository the first step is to create
your own fork. This allows you to create feature branches without
cluttering the main repository. It also assures that the main repository
is only added to by Pull Request and review. Repositories can be forked
from the GitHub site like presented at [this
example](https://help.github.com/articles/fork-a-repo). Once this
repository is created, you can clone into your own workspace.

```shell
$ git clone https://YOUR-USERNAME@github.com/YOUR-USERNAME/REPOSITORY.git
```

Now, that we have a copy of the repository create a branch for the
feature or bug you would like to work on.

```shell
$ git checkout -b my-feature

$ git status
On branch my-feature
nothing to commit, working tree clean
```

Commit Guidelines
-----------------

Now you are ready to start working! Make changes to files and commit
them to your new branch. We like to preface our commit messages with a
descriptor code. This makes it easier for someone reviewing your commit
history to see what you have done. These are borrowed from the
[NumPy](https://docs.scipy.org/doc/numpy/dev/gitwash/development_workflow.html#writing-the-commit-message)
development documentation.

  Code   Description
  ------ ----------------------------------------------------
  API    an (incompatible) API change
  BLD    change related to building
  BUG    bug fix
  DEP    deprecate something, or remove a deprecated object
  DEV    development tool or utility
  DOC    documentation
  ENH    enhancement
  MNT    maintenance commit (refactoring, typos, etc.)
  REV    revert an earlier commit
  STY    style fix (whitespace, PEP8)
  TST    addition or modification of tests
  REL    related to releasing numpy
  WIP    Commit that is a work in progress

It is also helpful underneath classes and functions to write docstrings.
These are later converted by Sphinx into HTML documentation. They also
are a valuable tool for exploration of a codebase within an IPython
terminal. Docstrings should follow the form described in the [NumPy
documentation](http://www.sphinx-doc.org/en/stable/ext/example_numpy.html)

Merging Changes
---------------

Once you are happy with your code, `push` it back to your fork on
GitHub.

```shell
$ git push origin my-feature
```

You should now be able to create a Pull Request back to the original
repository. **You should never commit directly back to the original
repository**. In fact, if you are creating a new repository it is
possible to strictly disallow this by explicitly protecting certain
branches from direct commits.The reason we feel strongly that Pull
Requests are necessary because they:

1)  Allows other collaborators to view the changes you made, and give
    feedback.
2)  Leave an easily understood explanation to why these changes are
    necessary.

Once these changes are deemed acceptable to enter the main repository,
they Pull Request can be merged.

Syncing your Local Checkout
---------------------------

Inevitably, changes to the upstream repository will occur and you will
need to update your local checkout to reflect those. The first step is
to make your local checkout aware of the upstream repository. If this is
done correctly, you should see something like this:

```shell
$ git remote add upstream https://github.com/UPSTREAM-ORG/REPOSITORY.git
$ git remote -v
origin   https://github.com/YOUR-USERNAME/REPOSITORY.git (fetch)
origin   https://github.com/YOUR-USERNAME/REPOSITORY.git (push)
upstream https://github.com/UPSTREAM-ORG/REPOSITORY.git (fetch)
upstream https://github.com/UPSTREAM-ORG/REPOSITORY.git (push)
```

Now, we need to fetch any changes from the upstream repository.
`git fetch` will grab the latest commits that were merged since we made
our own fork

```shell
$ git fetch upstream
```

Ideally you haven\'t made any changes to your `master` branch. So you
should be able to merge the latest `master` branch from the upstream
repository without concern. All you need to do is to switch to your
`master` branch, and pull in the changes from the upstream remote. It is
usually a good idea to push any changes back to your fork as well.

```shell
$ git checkout master
$ git pull upstream master
$ git push origin master
```

Finally, we need to update our feature-branch to have the new changes.
Here we use a `git rebase` to take our local changes, remove them
temporarily, pull the upstream changes into our branch, and then re-add
our local changes on the tip of the commit history. This avoids
extraneous merge commits that clog the commit history of the branch. A
more in-depth discussion can be found
[here](https://www.atlassian.com/git/tutorials/merging-vs-rebasing).
This process should look like this:

```shell
$ git checkout my-feature
$ git rebase upstream/master
```


## Note


This process should not be done if you think that anyone else is also
working on that branch. The rebasing process re-writes the commit
history so any other checkout of the same branch referring to the old
history will create duplicates of all the commits.

