<chapter id="dev.contrib">
	<title>Contributing to MantisBT</title>

	<para>
		MantisBT uses the source control tool <ulink url="http://git.or.cz">Git</ulink>
		for tracking development of the project.  If you are new to Git, you can
		find some good resources for learning and installing Git in the
		<link linkend="dev.appendix.git">Appendix</link>.
	</para>

	<sect1 id="dev.contrib.setup">
		<title>Initial Setup</title>

		<para>
			There are a few steps the MantisBT team requires of contributers and
			developers when accepting code submissions.  The user needs to configure
			Git to know their full name (not a screen name) and an email address they
			can be contacted at (not a throwaway address).
		</para>

		<para>
			To set up your name and email address with Git, run the following
			commands, substituting your own real name and email address:
		</para>

		<programlisting>
$ git config --global user.name "John Smith"
$ git config --global user.email "jsmith@mantisbt.org"
		</programlisting>

		<para>
			Optionally, you may want to also configure Git to use terminal colors
			when displaying file diffs and other information, and you may want to
			alias certain Git actions to shorter phrases for less typing:
		</para>

		<programlisting>
$ git config --global color.diff "auto"
$ git config --global color.status "auto"
$ git config --global color.branch "auto"

$ git config --global alias.st "status"
$ git config --global alias.di "diff"
$ git config --global alias.co "checkout"
$ git config --global alias.ci "commit"
		</programlisting>

	</sect1>

	<sect1 id="dev.contrib.clone">
		<title>Cloning the Repository</title>

		<para>
			The primary repository for MantisBT is hosted and available in multiple
			methods depending on user status and intentions.  For most contributers,
			the public clone URL is
			<ulink url="git://mantisbt.org/mantisbt.git">git://mantisbt.org/mantisbt.git</ulink>.
			To clone the repository, perform the following from your target workspace:
		</para>

		<programlisting>
$ git clone git://mantisbt.org/mantisbt.git
		</programlisting>

		<para>
			If you are a member of the MantisBT development team with write access to
			the repository, there is a special clone URL that uses your SSH key to
			handle access permissions and allow you read and write access.  Note: This
			action <emphasis>will fail</emphasis> if you do not have developer access
			or do not have your public SSH key set up correctly.
		</para>

		<programlisting>
$ git clone git@mantisbt.org:mantisbt.git
		</programlisting>

		<para>
			After performing the cloning operation, you should end up with a new
			directory in your workspace, <filename>mantisbt/</filename>.  By default,
			it will only track code from the primary remote branch, <literal>master</literal>,
			which is the latest development version of MantisBT.  For contributers
			planning to work with stable release branches, or other development
			branches, you will need to set up local tracking branches in your
			repository.  The following commands will set up a tracking branch for the
			current stable branch, <literal>master-1.2.x</literal>.
		</para>

		<programlisting>
$ git checkout -b master-1.2.x origin/master-1.2.x
		</programlisting>

	</sect1>

	<sect1 id="dev.contrib.branch">
		<title>Maintaining Tracking Branches</title>

		<para>
			In order to keep your local repository up to date with the official,
			there are a few simple commands needed for any tracking branches that you
			may have, including <literal>master</literal> and
			<literal>master-1.2.x</literal>.
		</para>

		<para>
			First, you'll need to got the latest information from the remote repo:
		</para>

		<programlisting>
$ git fetch origin
		</programlisting>

		<para>
			Then for each tracking branch you have, enter the following commands:
		</para>

		<programlisting>
$ git checkout master
$ git rebase origin/master
		</programlisting>

		<para>
			Alternatively, you may combine the above steps into a single command
			for each remote tracking branch:
		</para>

		<programlisting>
$ git checkout master
$ git pull --rebase
		</programlisting>
	</sect1>

	<sect1 id="dev.contrib.prepare">
		<title>Preparing Feature Branches</title>

		<para>
			For each local or shared feature branch that you are working on, you will
			need to keep it up to date with the appropriate master branch.  There are
			multiple methods for doing this, each better suited to a different type of
			feature branch.  <emphasis>Both methods assume that you have already
			performed the previous step, to <link linkend="dev.contrib.branch">update
			your local tracking branches</link>.</emphasis>
		</para>

		<sect2 id="dev.contrib.prepare.local">
			<title>Private Branches</title>

			<para>
				If the topic branch in question is a local, private branch, that you are not
				sharing with other developers, the simplest and easiest method to stay up to
				date with <literal>master</literal> is to use the <command>rebase</command>
				command.  This will append all of your feature branch commits into a linear
				history after the last commit on the <literal>master</literal> branch.
			</para>

			<programlisting>
$ git checkout feature
$ git rebase master
			</programlisting>

			<para>
				Do note that this changes the commit ID for each commit in your feature
				branch, which will cause trouble for anyone sharing and/or following your
				branch.  In this case, if you have rebased a branch that other users are
				watching or working on, they can fix the resulting conflict by rebasing
				their copy of your branch onto your branch:
			</para>

			<programlisting>
$ git checkout feature
$ git fetch remote/feature
$ git rebase remote/feature
			</programlisting>
		</sect2>

		<sect2 id="dev.contrib.prepare.public">
			<title>Public Branches</title>

			<para>
				For any publicly-shared branches, where other users may be watching your
				feature branches, or cloning them locally for development work, you'll need
				to take a different approach to keeping it up to date with
				<literal>master</literal>.
			</para>

			<para>
				To bring public branch up to date, you'll need to <command>merge</command>
				the current <literal>master</literal> branch, which will create a special
				"merge commit" in the branch history, causing a logical "split" in commit
				history where your branch started and joining at the merge.  These merge
				commits are generally disliked, because they can crowd commit history, and
				because the history is no longer linear.  They will be dealt with during
				the <link linkend="dev.contrib.submit.repo">submission process</link>.
			</para>

			<programlisting>
$ git checkout feature
$ git merge master
			</programlisting>

			<para>
				At this point, you can push the branch to your public repository, and
				anyone following the branch can then pull the changes directly into their
				local branch, either with another merge, or with a rebase, as necessitated
				by the public or private status of their own changes.
			</para>
		</sect2>

	</sect1>

	<sect1 id="dev.contrib.test">
		<title>Running PHPUnit tests</title>

		<para>
			MantisBT has a suite of PHPUnit tests found in the <literal>tests</literal>
			directory. You are encouraged to add your own tests for the patches you
			are submitting, but please remember that your changes must not break
			existing tests.
		</para>

		<para>
			In order to run the tests, you will need to have the PHP Soap extension
			and <ulink url="http://www.phpunit.de">PHPUnit</ulink> installed. The tests
			are configured using a <literal>bootstrap.php</literal> file. The 
			<literal>boostrap.php.sample</literal> file contains the settings you will
			need to adjust to run all the tests. 
		</para>

		<para>
			Running the unit tests is done from the <literal>tests</literal> directory
			using the following command:
		</para>

		<programlisting>
$ phpunit --bootstrap bootstrap.php AllTests.php
		</programlisting>

	</sect1>

	<sect1 id="dev.contrib.submit">
		<title>Submitting Changes</title>

		<para>
			When you have a set of changes to MantisBT that you would like to contribute
			to the project, there are two preferred methods of making those changes
			available for project developers to find, retrieve, test, and commit.  The
			simplest method uses Git to generate a specially-formatted patch, and the
			other uses a public repository to host changes that developers can pull from.
		</para>

		<para>
			Formatted patches are very similar to file diffs generated by other tools or
			source control systems, but contain far more information, including your name
			and email address, and for every commit in the set, the commit's timestamp,
			message, author, and more.  This formatted patch allows anyone to import the
			enclosed changesets directly into Git, where all of the commit information is
			preserved.
		</para>

		<para>
			Using a public repository to host your changes is marginally more complicated
			than submitting a formatted patch, but is more versatile.  It allows you to
			keep your changesets up to date with the offiicial development repository,
			and it lets anyone stay up to date with your repository, without needing to
			constantly upload and download new formatted patches whenever you change
			anything.  There is no need for a special server, as free hosting for public
			repositories can be found on many sites, such as
			<ulink url="http://git.mantisforge.org">MantisForge.org</ulink>,
			<ulink url="http://github.com">GitHub</ulink>, or
			<ulink url="http://gitorious.com">Gitorious</ulink>.
		</para>

		<sect2 id="dev.contrib.submit.patch">
			<title>Via Formatted Patches</title>

			<para>
				Assuming that you have an existing local branch that you've kept up to date
				with <literal>master</literal> as described in
				<link linkend="dev.contrib.prepare">Preparing Feature Branches</link>,
				generating a formatted patch set should be relatively straightforward,
				using an appropriate filename as the target of the patch set:
			</para>

			<programlisting>
$ git format-patch --binary --stdout origin/master..HEAD > feature_branch.patch
			</programlisting>

			<para>
				Once you've generated the formatted patch file, you can easily attach it
				to a bug report, or even use the patch file as an email to send to the
				developer mailing list.  Developers, or other users, can then import this
				patch set into their local repositories using the following command, again
				substituting the appropriate filename:
			</para>

			<programlisting>
$ git am --signoff feature_branch.patch
			</programlisting>

		</sect2>

		<sect2 id="dev.contrib.submit.repo">
			<title>Via Public Repository</title>

			<para>
				We'll assume that you've already set up a public repository, either on a
				free repository hosting site, or using <command>git-daemon</command> on your own
				machine, and that you know both the public clone URL and the private push
				URL for your public repository.
			</para>

			<para>
				For the purpose of this demonstration, we'll use a public clone URL of
				<literal>git://mantisbt.org/contrib.git</literal>, a private push URL of
				<literal>git@mantisbt.org:contrib.git</literal>, and a hypothetical
				topic branch named <literal>feature</literal>.
			</para>

			<para>
				You'll need to start by registering your public repository as a 'remote' for
				your working repository, and then push your topic branch to the public
				repository.  We'll call the remote <literal>public</literal> for this; remember to
				replace the URL's and branch name as appropriate:
			</para>

			<programlisting>
$ git remote add public git@mantisbt.org:contrib.git
$ git push public feature
			</programlisting>

			<para>
				Next, you'll need to generate a 'pull request', which will list information
				about your changes and how to access them.  This process will attempt to
				verify that you've pushed the correct data to the public repository, and
				will generate a summary of changes that you should paste into a bug report
				or into an email to the developer mailing list:
			</para>

			<programlisting>
$ git request-pull origin/master git://mantisbt.org/contrib.git feature
			</programlisting>

			<para>
				Once your pull request has been posted, developers and other users can add
				your public repository as a remote, and track your feature branch in their
				own working repository using the following commands, replacing the remote
				name and local branch name as appropriate:
			</para>

			<programlisting>
$ git remote add feature git://mantisbt.org/contrib.git
$ git checkout -b feature feature/feature
			</programlisting>

			<para>
				If a remote branch is approved for entry into <literal>master</literal>,
				then it should first be rebased onto the latest commits, so that Git can
				remove any unnecessary merge commits, and create a single linear history
				for the branch.  Once that's completed, the branch can be fast-forwarded
				onto <literal>master</literal>:
			</para>

			<programlisting>
$ git checkout feature
$ git rebase master
$ git checkout master
$ git merge --ff feature
			</programlisting>

			<para><emphasis>
				If a feature branch contains commits by non-developers, the branch should
				be signed off by the developer handling the merge, as a replacement for the
				above process:
			</emphasis></para>

			<programlisting>
$ git checkout feature
$ git rebase master
$ git format-patch --binary --stdout master..HEAD > feature_branch.patch
$ git am --signoff feature_branch.patch
			</programlisting>

		</sect2>

	</sect1>

</chapter>

