= How to Contribute to OpenSCAP

This document is meant for new OpenSCAP contributors and it describes how to
contribute to the OpenSCAP project. Let's suppose that you already have an
active Github's account with a user name _adam_ and you want to fix one of the
issue from the link:https://github.com/OpenSCAP/openscap/issues[tracker]. Let's
say that we want to fix the isuues with number _455_ and the fix will go into
the _maint-1.0_ branch.

== Fork the OpenSCAP repository
Before you start working on a fix it's a good practice to leave a
comment in the issue that you work on the fix so other contributors know that
the fix is in progress.  Next thing you have to do is to fork the OpenSCAP
repository. You can do that by pressing the **Fork** button in the top-right
corner on the Github's link:https://github.com/OpenSCAP/openscap[OpenSCAP page].
It will create a copy of the original repository which you can use for
proposing changes.

== Choose the right branch
Before you start working of the fix it's necessary to determine which branch the
fix will go into. If you are not familiar with the OpenSCAP's branches or
versions yet please have a look at the link:versioning.adoc[versioning]
document. Be aware that the fact that an issue description says that the fix
should go to a _maint-1.2_ branch doesn't have to be true. It's a good practice
to investigate the correct branch first or ask experienced developers on our
FreeNode IRC channel called `#openscap` or
link:https://www.redhat.com/mailman/listinfo/open-scap-list[mailing list].

Once you have forked the repository and decided what branch the fix will go into
you can clone your forked repository.
[[app-listing]]
[source,bash]
----
$ git clone git@github.com:adam/openscap.git
----


Now you can create a new branch, which we will call _fix_455_, where you can work on the fix. Remember that
the name of the new branch will appear in the commit message when your fix is
merged so choose the name wisely.

[[app-listing]]
[source,bash]
----
# checkout to the maint-1.0 branch
$ git checkout maint-1.0
# create a new branch
$ git checkout -b fix_455
----

NOTE: The default branch of the openscap repository is set to the `maint-1.2`.
Our fix will go into the `maint-1.0` so we have to switch to this branch before
creating a new one.

== Fix the issue
NOTE: OpenSCAP is licensed under LGPLv2. Any fixes or improvements must be licensed
under the same license to be included. Check the COPYING file in the repository
for more details.

Now you can work on the fix. Try to create small commits which can be easily
reviewed and make self-explaining commit messages. The
link:http://chris.beams.io/posts/git-commit/[How to Write a Git Commit
Message] article could help you with that. Nobody will review a pull request
which contains a four thousand new lines of code.

NOTE: Since we're fixing an issue number 455 make sure that your commit message
contain a
link:https://help.github.com/articles/closing-issues-via-commit-messages/[keyword]
which will close the issue automatically when your pull request is merged.


Let's say that you've fixed the issue, made a few commits to your local fix_455
branch and you think it's ready to be review by other contributors. Before you
push your local changes to your remote forked repository it's necessary to check
if your changes will be applicable and won't be in a conflict with some work that
  other contributors could publish while you were working on the fix.


== Rebase before pull request
If some other contributor pushed some code to the maint-1.0 branch while you was
working of the fix then it's necessary to pull those changes and rebase our fix
on top of them. First we need to make sure that our local maint-1.0 branch is
up-to date.

[[app-listing]]
[source,bash]
----
# add remote name 'upstream' to refer to the upstream's repository
$ git remote add upstream git@github.com:OpenSCAP/openscap.git
# checkout to branch 'maint-1.0' in your local forked repository
$ git checkout maint-1.0
# download and apply any upstream changes to your local maint-1.0 branch
$ git pull --ff-only upstream maint-1.0
----

Now you can go back to your local branch with the fix and try to rebase your
changes on top of your local updated maint-1.0 branch. If there are no conflicts
then you can push your branch with the fix to your remote forked repository.

[[app-listing]]
[source,bash]
----
# checkout back to your branch with the fix
$ git checkout fix_455
# rebase your changes on the top of the updated maint-1.0 branch
$ git rebase maint-1.0
# push your changes to your remote forked repository
$ git push origin fix_455
# note about --force
----

NOTE: If you've already push the branch to your remote repository then made some
changes and know you want to rewrite the fix_455 branch then the `--force`
option may come in handy but be aware that it will rewrite your fix_455 branch
so please use wisely.

== Create a new pull request
Once you have pushed your local fix_455 branch to your remote forked repository
you can link:https://help.github.com/articles/creating-a-pull-request/[create] a
new pull request. You can create the pull request on the OpenSCAP's
link:https://github.com/OpenSCAP/openscap/pulls[github page] when you click on
the `Pull requests` in the right menu then you see the green *New pull request*
button. In the branch menu choose the branch that contains your fix. That is the
fix_455 branch and also don't forget to set maint-1.0 as the base branch. The
base branch is the one that your fix_455 will be compared to. If there are no
conflicts add some description and hit the *Create pull request* button.

Developers and contributor that watch the repository should now
receive an email about a new pull request. They will review your code and
probably leave you some comments. If there are any you should get back to your
code and make the changes.

=== Make changes in the submitted pull request
After the review is done and one or more experienced developers is complaining
about your code you have to do some changes. There are two ways to change your
code in a submitted pull request:

 . Add a new commit or,
 . edit existing commits.

==== Add a new commit
Adding a new commit is easy and I would choose this option if I would have to
add something new like a function or a new module.

==== Edit existing commits
If you just need to fix a typo or add a condition I would choose to go back to
the commit, where the change is needed, and use commit's `--ammed` option to
change the commit. You can use following steps to do that.

[[app-listing]]
[source,bash]
----
# show all the commits in your fix_455 branch
$ git rebase -i maint-1.0
# replace 'pick' with 'e' at a line with commit you'd like to change
# make your changes
# vim my_source_file.c
# commit your new changes
$ git commit --amend
# get back to your last commit
$ git rebase --continue
----

=== Closing the pull request
Once the pull request has been merged to upstream's branch the pull request will
be closed automatically. The issue will be also closed if you used the right
keyword in the commit message. Now you can delete your `fix_455` branch.

[[app-listing]]
[source,bash]
----
# detele the fix_455 branch
$ git branch -d fix_455
----
