Ways to contribute to Rubinius
=================================

We appreciate every contribution from the community, whether it is a clever 
patch with killing feature, bug report, documentation patch, idea for project website, 
promotion or donation.

Contributing is easy, it's like an interesting adventure:

* Get on [mailing list](http://groups.google.com/group/rubinius-dev), or join [our community](http://rubini.us/community) other ways.
* Start [investigating the code base](http://rubinius.lighthouseapp.com/projects/5089/getting-started), write a documentation patch.
* Explore and [use Rubinius](http://rubinius.lighthouseapp.com/projects/5089/common-build-problems-and-solutions), [report problems](http://rubinius.lighthouseapp.com/projects/5089/howto-write-a-ticket) you encounter.
* Start [writing specs](http://rubinius.lighthouseapp.com/projects/5089/howto-write-a-spec) for either [Rubinius VM](http://rubinius.lighthouseapp.com/projects/5089/shotgun-the-rubinius-virtual-machine) or the Ruby language. Note that there is [The Ruby Spec](http://spec.ruby-doc.org/wiki/Main_Page) project may be helpful and use your help.
* [Work on implementation](http://rubinius.lighthouseapp.com/projects/5089/coding-style-guide) to make your specs pass.
* Double check and [watch for CI](http://rubinius.lighthouseapp.com/projects/5089/specs-continuous-integration) staying green.
* We are now one step closer to next generation Ruby virtual machine making goods for the mankind.

Now let's have a closer look at each step.

Development: flowing commit bit
===================================

Rubinius has commit rights policy known as FCB (flowing commit bit) from day one. Evan given commit rights to every developer who's patch 
got into Rubinius without questions asked, etc. If you patch is applied, you get commit rights right away. That's the way we do it.

Helping out on mailing list and IRC
======================================

Main tool for communication of Rubinius developers is historically IRC. People ask questions and send patches to mailing list too, though. 
If you are just starting with Rubinius you may ask for help, help others and get some insight in group archives. If you have problems, please 
clarify what OS and architecture you use, what exactly you do and what exactly error message you get. Given this someone will definitely come 
and help you.

If they don't, maybe it is time to grab some coffee and submit a patch. This happens in open source software.

Documentation
==================

As with any documentation, there are no many guidelines you should follow. Two of them are 

* keep things well-organized
* make things clear for both novices and experienced gurus

This is it.

Writing specs
==================

Overview
--------------------------------

The Rubinius project uses [BDD](http://en.wikipedia.org/wiki/Behavior_driven_development)-style executable specifications to drive development. The specs are intended to be syntax-compatible with [RSpec](http://rspec.rubyforge.org/). However, RSpec liberally uses advanced Ruby language features that are difficult to support while a Ruby implementation is being developed. Hence, Rubinius uses a custom implementation to run the spec files.

RSpec is essentially a DSL (domain-specific language) for describing the behavior of code. The specs serve two purposes: 1) to drive development, and 2) as a verification mechanism. These goal can sometimes be at odds. During development, the code and specs evolve together. For verification, a highly stable set of specs that ideally have been audited for correctness is desirable.

Rubinius is attempting to write a standard set of Ruby specs based on the behavior of MRI (Matz's Ruby Interpreter) at roughly version 1.8.6. One of the significant challenges is the variations in the existing Ruby implementations. For example, JRuby does not have Kernel.fork. Rubinius has the Tuple class, which is not a standard part of the Ruby core library. The specs need to accommodate the compliant and non-compliant behavior of the various implementations. RSpec itself is a fairly young project. So, Rubinius defines several extensions (that are compatible with RSpec) to control execution of the specs based on the implementation that is executing them.

Organization
--------------------------------

There are many conceivable ways to organize the spec files. A graphical representation of the Rubinius directories is shown below. This structure is based on the Ruby language as well as the major components of a Ruby implementation. The goal is to maintain locality by grouping related specs.

There are two primary divisions of the specs in the spec directory: 1. specs for the Ruby language, which includes the Ruby core and standard libraries; 2. specs for the Rubinius system and its extensions to the Ruby core and standard libraries.

  spec
   |-- compiler
   |-- core
   |    +-- array
   |    +-- bignum
   |    +-- breakpoint
   |    +-- bytearray
   |    +-- ...
   |-- data
   |-- kernel
   |-- language
   |-- library
   |-- parser
   |-- ruby
   |    +-- 1.8
   |          +-- core
   |                + -- array
   |                + -- bignum
   |                + -- binding
   |                + -- class
   |                + -- ...
   |                + -- time
   |                + -- true
   |                + -- unboundmethod
   |          +-- fixtures
   |          +-- language
   |          +-- library
   |                + -- enumerator
   |                + -- ...
   |                + -- time
   |                + -- yaml
   +-- subtend
         +-- ext
The reference implementation of the Ruby language ---------------------------------------------------- The specs for the reference implementation of the Ruby language (MRI) are under spec/ruby. Presently, these are only focused on **version 1.8.x** and there is only the 1.8 subdirectory. However, as specs are written for version 1.9, those specs will be placed in a parallel tree under the 1.9 subdirectory. In the spec files under **spec/ruby**, there are also specs for other Ruby implementations where these implementations comply with or deviate from MRI (again, the reference implementation for Ruby). All the spec directories except for spec/ruby are for Rubinius specific code. Under spec/core, spec/language, and spec/libraries, there are specs for how Rubinius extends or significantly deviates from MRI. In general, there is no goal to unify spec/core, spec/language, and spec/libraries with the parallel directories under spec/ruby/. These directories serve different purposes. The language directory contains specs for the Ruby language proper. There are numerous possible way of categorizing the entities and concepts that make up a programming language. Ruby has a fairly large number of reserved words. These words significantly describe major elements of the language, including flow control constructs like "for" and "while", conditional execution like "if" and "unless", exceptional execution control like "rescue", etc. There are also literals for the basic "types" like String, Regexp, Array and Fixnum. Behavioral specifications describe the behavior of concrete entities. Rather than using concepts of computation to organize these spec files, we use entities of the Ruby language. Consider looking at any syntactic element of a Ruby program. With (almost) no ambiguity, one can identify it as a literal, reserved word, variable, etc. There is a spec file that corresponds to each literal construct and most reserved words, with the exceptions noted below. There are also several files that are more difficult to classify: all predefined variables, constants, and objects (predefined\_spec.rb), the precedence of all operators (precedence\_spec.rb), the behavior of assignment to variables (variables\_spec.rb), the behavior of subprocess execution (execution\_spec.rb), the behavior of the raise method as it impacts the execution of a Ruby program (raise\_spec.rb), and the block entities like "begin", "do", " { ... }" (block\_spec.rb). Several reserved words and other entities are combined with the primary reserved word or entity to which they are related: # predefined\_spec.rb: false, true, nil, self # for\_spec.rb: in # if\_spec.rb: then, elsif # case\_spec.rb: when # throw\_spec.rb: catch Core library -------------------- The core directory contains specs for the Ruby core library. These include classes such as Array, String, Regexp, Range, Fixnum, Float, etc. The core directory contains a subdirectory named after the classes in the core library. For example, specs for the Array class are in the array directory. Within each subdirectory of @core@, the specs for each method of that class are placed in a separate file. For example, specs for Array#compact are places in spec/core/array/compact\_spec.rb. Method names with characters like "?", "=", and "!" are in files named by stripping those characters. For example, specs for Array#compact! are in the same file as specs for Array#compact. All the spec files that are needed have already likely been created. (See bin/mkspec for details.) Standard library The library directory contains specs for the classes of the Ruby standard library. The same naming convention used in the core directory applies here, also. However, there are some legacy specs that do not yet conform to this convention. Rubinius extensions The spec/core , spec/language , and spec/library directories are for extensions to the Ruby core, language, and standard libraries respectively. Rubinius components * The compiler directory contains specs related to the compiler tool chain. * The parser directory contains specs for the parser. * The subtend directory contains specs for the Rubinius C API that is header file compatible with the MRI C API. Spec runners ---------------------- There are three runners for the the Rubinius specs: **mspec**, **ci**, and **completeness**. The completeness runner uses **mspec**. See Continuous Integration section about usage for ci. The mspec command accepts a file, directory, or shell glob to specify which spec files to execute.
$ bin/mspec -h
mspec [options] (FILE|DIRECTORY|GLOB)+

   -f, --format FORMAT      Formatter for reporting: s:specdox|d:dotted|c:ci|h:html|i:immediate
   -t, --target TARGET      Implementation that will run the specs: r:ruby|r19:ruby19|x:rbx|j:jruby
   -T, --targetopt OPT      Pass OPT as a flag to the target implementation
   -I, --include DIR        Pass DIR through as the -I option to the target
   -r, --require LIBRARY    Pass LIBRARY through as the -r option to the target
   -n, --name RUBY_NAME     Override the name used to determine the implementation
   -o, --output FILE        Formatter output will be sent to FILE
   -e STRING|FILE           Execute example(s) with descriptions matching STRING or each line of FILE
       --example
   -x STRING|FILE           Exclude example(s) with descriptions matching STRING or each line of FILE
       --exclude
   -C, --clean              Remove all compiled spec files first
   -V, --verbose            Output the name of each file processed
   -m, --marker MARKER      Outout MARKER for each file processed. Overrides -V
   -w, --warnings           Don't supress warnings
   -g, --gdb                Run under gdb
   -A, --valgrind           Run under valgrind
   -v, --version            Show version
   -h, --help               Show this message

-f, --format FORMAT

    Selects the reporter format to output specs strings and failures. The specdox report is very similar to RSpec's -f s option. The dotted reporter outputs the familiar '....F..EF..'' with exceptions listed after all specs are run. The ci reporter will only output the describe + it string for specs that fail. The immediate reporter outputs spec strings before the spec is executed so that if the VM exits due to an exception, the cause of the exception is more easily determined.

-t, --target TARGET

    Selects the Ruby implementation to be used to execute the spec files.

-T, --targetopt OPT

    Passes OPT as a flag to the target implementation, For example, bin/mspec -T "-d" -t r would pass the debug flag to ruby.

-I, --include DIR

    Passes this option directly to the selected target (see -t).

-r, --require LIBRARY

    Passes this option directly to the selected target (see -t).

-n, --name RUBY_NAME

    Overrides the name used to determine the Ruby implementation. RUBY_NAME defaults to require 'rbconfig'; Config::CONFIG["RUBY_INSTALL_NAME"] if this executes without exception.

-o, --output FILE

    Specifies the file that the reporter will write to. Defaults to STDOUT.

-e, --example STRING|FILE

    Executes only the specs whose describe + it message string matches STRING. If a file name is given, each line of the file is equivalent to -e STRING.

-x, --exclude STRING|FILE

    Does not execute any spec whose describe + it message string matches STRING. If a file name is given, each line of the file is equivalent to -x STRING.

-C, --clean

    Deletes the compiled spec files for any spec files that will be executed before running the specs.

-V, --verbose

    Outputs the name of each file processed

-m, --marker MARKER

    Outouts MARKER for each file processed. Overrides -V.

-w, --warnings

    Don't supress warnings from the target (see -t).

-g, --gdb

    Only useful with Rubinius. Passes the --gdb argument to shotgun to launch gdb.

-A, --valgrind

    Only useful with Rubinius on a platform with Valgrind installed. Passes the --valgrind option to shotgun to run under Valgrind.
Completeness Reporter
The completeness script is useful for several tasks. Using -t ruby, the script can be used to show how complete the specs are in terms of the coverage of the Ruby core library. Note that this is not anything like the rcov tool. The completeness script merely uses some naming conventions in the spec strings to run specs for class and instance methods of classes and modules whose names are accessible as constants on Object. When writing specs, you should use the completeness script to determine which class or module the specs should be written for. This is especially important for Kernel and Object. Most methods that one associates with being on an instance of Object are actually defined in the Kernel module. The specs for these need to be added to spec/core/kernel_spec.rb.
n$ bin/completeness -h
completeness [options]

   -r, --require LIBRARY    Name of library to require
   -c, --constant CONSTANT  Name of a Class or Module
   -b, --base BASE          Set base directory to BASE
   -t, --target TARGET      Implementation to test for completeness: r:ruby|r19:ruby19|x:rbx|j:jruby
   -x STRING|FILE           Exclude example(s) with descriptions matching STRING or each line of FILE
       --exclude
   -F, --report-failures    Report spec failure locations
   -o, --color              Use colors green=NoFailures yellow=WithFailures red=NoExamples
   -V, --verbose            Show mspec command being executed
   -q, --quiet              Suppress output except for final summary
   -v, --version            Show version
   -h, --help               Show this message

-r, --require LIBRARY

    Specifies the name of the library to require.

-c, --constant CONSTANT

    Specifies the name of a constant for which to run specs.

-b, --base BASE

    Set base directory to BASE. The base directory is treated as the root directory of the spec directories tree.

-t, --target TARGET

    Selects the Ruby implementation to be used to execute the spec files.

-x, --exclude STRING|FILE

    Does not execute any spec whose describe + it message string matches STRING. If a file name is given, each line of the file is equivalent to -x STRING.

-F, --report-failures

    Normally, the script does not output any failure messages or backtraces. Use this option to report spec failures.

-o, --color

    Colorize the output using green for no failures, yellow for failures, and red for no examples found.

-V, --verbose

		Print out the mspec command that is being executed for each method.

-q, --quiet

		Do not output information for each method. Only output the final summary.
Examples of spec runners -------------- For example, to determine what is the public interface of Digest::MD5, run the following:
bin/completeness -t ruby -r'digest/md5' -c Digest::MD5
Continuous integration in Rubinius ------------------------------------- As Rubinius is undergoing continual development, and since TDD/BDD is the recommended way to develop new features, Rubinius does not pass all the specs that have been written. Because of the same feature specific to virtual machine development Rubinius developers currently do not use dedicated CI server like [CruiseControl.rb](http://cruisecontrolrb.thoughtworks.com/). However, when making changes to the code, we need a way to confirm that working features are not inadvertently broken. Generally, some sort of continuous integration (CI) mechanism serves this purpose. To meet this need, Rubinius has a special runner (bin/ci) that excludes the failing specs. Every developer who writes new specs must ensure that the CI specs are updated. If all the specs pass, bin/ci -f ci will output nothing. If any specs fail, the reporter will output the spec description string for the failing spec. To be more useful for developers, the default output formatter for bin/ci is DottedFormatter (see -f option below). CI spec runner ----------------------- The rake spec task prints our the revision of the VM build and then invokes the CI spec runner bin/ci. This command is documented below.
$ bin/ci -h
ci [options] (FILE|DIRECTORY|GLOB)+

   -c, --create             Create the exclude file for failing specs
   -R, --run                Run the specs excluding the expected failures
   -i, --invert             Run the specs using only the expected failures
   -t, --target TARGET      Use TARGET to run the specs: r:ruby|r19:ruby19|x:rbx|j:jruby
   -f, --format FORMAT      Use FORMAT for reporting: s:specdox|d:dotted|c:CI|h:html|i:immediate
   -E, --excludes-dir DIR   Use DIR for the files containing spec descriptions to exclude
   -I, --include DIR        Pass DIR through as the -I option to the target
   -r, --require LIBRARY    Pass LIBRARY through as the -r option to the target
   -n, --name RUBY_NAME     Override the name used to determine the implementation
   -T, --targetopt OPT      Pass OPT as a flag to the target implementation
   -C, --clean              Remove all compiled spec files first
   -V, --verbose            Output the name of each file processed
   -m, --marker MARKER      Output MARKER for each file processed. Overrides -V
   -g, --gdb                Run under gdb
   -A, --valgrind           Run under valgrind
   -v, --version            Show version
   -h, --help               Show this message

The bin/ci command accepts a file, directory, or shell glob to specify which spec files to execute. The default set of spec files are those that have been determined to not cause the VM to raise an unhandled exception. For the purpose of simply running all CI specs, just use bin/ci.

-c, --create

    Creates the the spec exclude files for each spec file. The exclude file is spec/core/class/.spec/method_excludes.txt. Use this option to update the spec excludes when adding new specs that pass on MRI but fail on Rubinius. Also use this to update the spec excludes for any particular specs that you have made to pass on Rubinius.

-R, --run

    Executes all the specs except those listed in spec/excludes.txt and the exclude file for each spec file. This is the default action if nothing is specified. Equivalent to bin/ci.

-i, --invert

    Executes all the specs that match each line of spec/excludes.txt or each line of the exclude file for each spec file. This is the simplest way to determine if specs that were failing now pass. The default reporter is changed to DottedReporter.

-t, --target TARGET

    Selects the Ruby implementation to be used to execute the spec files.

-f, --format FORMAT

    Selects the reporter to be used for showing the output from executing the specs.

-E, --excludes-dir DIR

    Uses DIR for the files containing spec descriptions to exclude. This option overrides the CI_EXCLUDES_DIR constant. If the path is absolute (i.e. starts with '/'), the excludes directories are created in the specified directory. Otherwise, the exclude directories are created relative to the directories containing the spec files. The default exclude directory is '.spec'.

-I, --include DIR

    Passes DIR through as the -I option to the target (see -t).

-r, --require LIBRARY

    Passes LIBRARY through as the -r option to the target (see -t).

-n, --name RUBY_NAME

    Overrides the name used to determine the Ruby implementation. RUBY_NAME defaults to require 'rbconfig'; Config::CONFIG["RUBY_INSTALL_NAME"] if this executes without exception.

-T, --targetopt OPT

    Passes OPT as a flag to the target implementation (see -t).

-C, --clean

    Deletes the compiled version of any spec files that will be executed. Does not delete any compiled version for any spec files that would not be executed.

-V, --verbose

    Prints to STDERR each spec file that is being executed.

-m, --marker MARKER

    Output MARKER for each file processed. Overrides -V

-g, --gdb

    Only useful with Rubinius. Passes the --gdb argument to shotgun to launch gdb.

-A, --valgrind

    Only useful with Rubinius on a platform with Valgrind installed. Passes the --valgrind option to shotgun to run under Valgrind.
CI excludes -------------- The spec/data directory contains a tree of directories that parallels all the spec directories. In this directory, files named *\_excludes.txt list spec description strings for specs that should be excluded by the CI spec runner. Howto fix a failing spec ------------------------------ Here's the general procedure to fix a spec that is failing on Rubinius. # Run the spec with bin/mspec spec/core/class/method_spec.rb # Write the Rubinius code to make the spec pass # Run the spec again to ensure it passes # Run the CI specs with bin/ci to ensure you have not broken something else # If you get CI spec failures, run bin/ci spec/core/whatever to ensure that the failures are not resulting from interaction with other code # Update the CI excludes for the spec that you fixed with bin/ci -c spec/core/class/method_spec.rb # Format your patch with git format-patch and create a ticket (or commit if you have a bit). Development ================== Using Git distributed version control system --------------------------------------------------- The Rubinius project is using the Git SCM. Committers need to use git to commit their code directly to the main repo. Below is information on getting Git installed, getting source code with Git, and steps for working with Git. Also, see these references: * [Git crash course](http://git.or.cz/course/svn.html) for SVN users * [Git tutorial](http://www.kernel.org/pub/software/scm/git/docs/tutorial.html) * [Everyday Git](http://www.kernel.org/pub/software/scm/git/docs/everyday.html) with 20 commands or so The following manuals are more advanced but very recommended because Git is truly advanced and has a lot to offer to it's users: * [Git user manual](http://www.kernel.org/pub/software/scm/git/docs/user-manual.html) * [Branching and merging with Git](http://lwn.net/Articles/210045/) (extremely recommended) * Git local/following/remote/tracking branches [terminology confusion discussion](http://kerneltrap.org/mailarchive/git/2007/8/4/253944) * [Complete Git reference](http://www.kernel.org/pub/software/scm/git/docs/) Getting Git for Your System ---------------------------------- You can use an earlier version, but 1.5.x is definitely recommended. * MacPorts has 'git-core' port * Debian and Ubuntu has 'git-core' package * FreeBSD has 'devel/git' port (there are some issues with 1.5.3.2 version in ports so you may it easier to compile Git from source) * Get the source at http://git.or.cz/ and compile it as usual, Git dependencies are very friendly compared to ImageMagick. Development environment setup ------------------------------------ Configure Git with your proper name and email. This will display when you submit changes to the Rubinius repository.
git config  --global user.name "My Name"
git config  --global user.email "my@email"
If you prefer to use different credentials for different projects, you can also configure the above for a single repository only. See the git documentation. Formatting Git commit messages ----------------------------------- In general, use an editor to create your commit messages rather than passing them on the command line. The format should be: * A hard wrap at 72 characters * A single, short, summary of the commit * Followed by a single blank line * Followed by supporting details The supporting details could be a bulleted enumeration or an explanatory paragraph. The single summary line helps folks reviewing commits. An example commit: Fixes for Module#make\_my\_day return values. * Return nil when passed ':(' * Return true when passed ':)' * Updated specs for #make_my_day for nil argument case * Updated CI excludes. Getting the code -------------------- If you are an existing committer, see below instead. Getting the code is easy once you have git installed:
git clone git://git.rubini.us/code
(Your local directory will be called code. You can give a different name by appending it to the command above.) Commit rights and process for existing committers ------------------------------------------------------ If you are an existing committer, you can get setup to commit to the Rubinius git repository. Paste your ssh public key (~/.ssh/id_rsa.pub) into pastie.caboo.se and give Evan the URL. To get the code:
git clone git@git.rubini.us:code
(Your local directory will be called code. You can give a different name by appending it to the command above.) New committers ------------------- If you do not have commit rights yet, you can create patch files with Git. The instructions for this are after the Git workflow section. Git workflow ------------------- Working with [Git](http://git.or.cz) is significantly different that working with SVN. In particular, although similar, git pull is not svn update, git push is not svn commit, and git add is not svn add. If you are a SVN user, be sure to read the man pages for the different git commands. The following workflow is recommended by Evan and is the guideline for contributing code to Rubinius.
   1. Create a local working copy of the source code (we did this earlier.)

      git clone git://git.rubini.us:code

   2. Change to the newly created directory that contains the local working copy.

      cd code

   3. Create a branch for your work. What happens is that your working directory

      git checkout -b new_feature

   4. Edit the code and test your changes. Then commit to your local working copy

      git commit -a

   5. When you are ready to send your local changes back to the Rubinius repository, you first need to ensure that your local copy is up-to-date. First, ensure you have committed your local changes. Then switch from your topic branch to the master branch.

      git checkout master

   6. Update your local copy with changes from the Rubinius repository

      git pull

   7. Switch back to your topic branch and integrate any new changes. The git rebase command will save your changes away, update the topic branch, and then reapply them.

      git checkout new_feature
      git rebase master

      Warning! If you are sharing a branch, you must use:

      git merge master

      Rebase causes the commit layout to change and will confuse anyone you've shared this branch with.

   8. If you there are conflicts applying your changes during the git rebase command, fix them and use the following to finish applying them

      git rebase --continue

   9. Now, switch back to the master branch and merge your changes from the topic branch

      git checkout master
      git merge new_feature

  10. You might want to check that your commits ended up as you intended. To do so, you can have a look at the log

      git log

  11. Get your changes in the main repository. If you have commit rights, you can just use the git push command. Otherwise, see the section below for information on creating a set of patches to send.

      git push

  12. At this point, you can delete the branch if you like.

      git branch -d new_feature
Patches: git-format-patch ------------------------------ If you are a new committer (or want to create a patch instead of directly pushing the code for some other reason) you should create a patch file for your commits. The patch file should be then attached to a ticket on Lighthouse (see the ticket writing howto for instructions for more details on that.) You can also send the patch to the mailing list but use the ticket tracker if at all possible. Either way, the patch file(s) should be created using Git. First, make your changes as detailed below and then use the git format-patch command to create the patch files. Usually using the command is as simple as specifying the commits you want to create patches for, and that is done in one of two ways: by giving a range of commits or a starting point. As mentioned earlier, each commit is identified by a unique hash ID which you can see, for example, by looking at the git log output. You can generally shorten it -- first 8 should be plenty -- because it is unlikely to conflict (if it does, just use the full ID instead.) In my examples below I just use imaginary IDs. Let us say you created three commits, in this order my1stcom -> my2ndcom -> my3rdcom (and that the patch before those is notmycom): * Specify a range of revisions. You can use the syntax git format-patch my1stcom..my3rdcom to include the first, the last and any inbetween. Alternatively, you could use git format-patch my1stcom..HEAD and other variants instead. * Specify a single revision. This takes all patches following the one given. The only possibly unintuitive part here is that the revision you give is the last patch you do not want to include. For example, if you do git format-patch my3rdcom or git format-patch HEAD there will be no patches since there have been none since. In our case, you would want one of the following: git format-patch notmycom , git format-patch my1stcom^ , git format-patch HEAD^^^ or git format-patch HEAD~3 (or any of the other possible variations.) (In Git terminology, HEAD is the last commit in your current branch. Parent patches can be referenced either by using a caret so that HEAD^ is one before HEAD and HEAD^^ is one before one before (i.e. two before) HEAD which gets cumbersome after the second or third caret; or by tilde-number: HEAD~1 is one before HEAD, HEAD~5 is five before HEAD and much easier to use. The caret and tilde can be used for commit hashes as well. For other variants, see the git-rev-parse man page.) Whichever way you decide on, a separate patch file is produced for each, named [number]-[first line of commit message].patch. You can then attach these to a ticket (or e-mail them.) The process and Rake git tasks ------------------------------------------------ The above workflow has been wrapped up into a some rake tasks. The simplified version is: Create a branch for your work:
rake git:topic
Make your changes and commit as needed:
git commit -a
Push your changes to master branch:
rake git:push