<commit_before># Copyright (C) 2008-2010, Parrot Foundation.
# $Id$

=head1 NAME

docs/project/git_workflow.pod - How to use Git to work on Parrot

=head1 DESCRIPTION

To minimize the disruption of feature development on language and tool
developers, all major changes to Parrot core take place in a branch. Ideally,
branches are short-lived, and contain the smallest set of changes possible.
It is also good practice to have "atomic" commits, in the sense that each
commit does one thing, so that it makes it easier to accept/revert some
things while keeping others. Git provides many powerful tools in the
maintainence of branches. This document aims to provide everything a Parrot
developer needs to know about Git to successfully create a branch, work on
it, keep it in sync with changes on master and finally merge the branch.

=head2 Cloning the Git Repository

To get the full version history Parrot, which is called "cloning a repository",
you will use the C<git clone> command. This will show how to clone the repo from
L<http://github.com> :

  $ git clone git://github.com/parrot/parrot.git

If you have commit access to parrot.git, then you can use the read/write SSH
protocol

  $ git clone git@github.com:parrot/parrot.git

If you are behind a firewall that will only let you do HTTP, you can use the
HTTP protocol, but it is much slower and inefficient, so only use it if you
must:

  $ git clone http://github.com/parrot/parrot.git

Cloning a git repo automatically makes the URL that you cloned from your
default "remote", which is called "origin". What this means is that
when you want to pull in new changes or push changes out in the future,
"origin" is what will be used by default.

=head2 Creating and Switching Branches

To create a branch and check it out, use the C<git checkout -b> command.
Current convention is to create branch names of the form username/foo.

  $ git checkout -b username/foo

You can also create a branch without checking it out:

  $ git branch username/foo

To checkout (or "switch to", as it is commonly referred to) the username/foo
branch:

  $ git checkout username/foo

=head2 Keeping updated

To get the latest updates:

  $ git fetch

This copies the index from your default remote (origin) and saves it to your
local index. This does not effect your working copy. To sync up your working
copy, you can use C<git rebase>

  $ git checkout master       # Switch to the master branch
  $ git rebase origin/master  # rebase latest fetched changes onto master

This is a common action, so there is also a simpler way to do it:

  $ git pull --rebase

Whenever you don't specify a remote or branch to a git command, they default
to the remote called "origin" and the master branch, so the previous command
means exactly the same as:

  $ git pull --rebase origin master

=head2 How to commit

Let's say you modified the file foo.c and added the file bar.c and you want to commit
these changes. To add these changes to the staging area (the list of stuff 
that will be included in your next commit) :

  $ git add foo.c bar.c

The command C<git add> is not only for adding new files, just keep that in mind.
It tells git "add the state of these files to my staging area."

Now for actually creating your commit! Since Git is a distributed version control
system, committing code is seperate from sending your changes to a remote server.
Keep this in mind if you are used to Subversion or similar VCS's, where committing
and sending changes are tied together.

  $ git commit -m "This is an awesome and detailed commit message"

If you do not give the -m option to C<git commit>, it will open your $EDITOR
and give you metadata which will help you write your commit message,
such as which files changed and if conflicts happened. Only lines that do
not begin with a # will be in your commit message.

TODO: Talk about how to write commit messages

=head2 Maintaining a Branch

=head2 Preparing to Merge a Branch

Post to <EMAIL> letting people know that you're about to
merge a branch.

=over

=item 1

Ask people to submit test results for their language, tool, or platform. If
you don't hear back from people, it doesn't mean they ran the tests and found
no problems, it means they didn't bother testing the branch. If you need
feedback on a particular language or platform, follow up with the person
responsible until you hear an explicit "Yes, it's working" answer.

=item 2

Let people know what tests you ran, so they can determine if you didn't run
the tests for their language or tool (or, didn't run I<all> the tests for
their language or tool if they have some unusual testing configuration).

=item 3

Mention any significant feature changes in the branch that you particularly
want tested.<commit_msg>[docs] Add paragraph about commit messages to git workflow<commit_after># Copyright (C) 2008-2010, Parrot Foundation.
# $Id$

=head1 NAME

docs/project/git_workflow.pod - How to use Git to work on Parrot

=head1 DESCRIPTION

To minimize the disruption of feature development on language and tool
developers, all major changes to Parrot core take place in a branch. Ideally,
branches are short-lived, and contain the smallest set of changes possible.
It is also good practice to have "atomic" commits, in the sense that each
commit does one thing, so that it makes it easier to accept/revert some
things while keeping others. Git provides many powerful tools in the
maintainence of branches. This document aims to provide everything a Parrot
developer needs to know about Git to successfully create a branch, work on
it, keep it in sync with changes on master and finally merge the branch.

=head2 Cloning the Git Repository

To get the full version history Parrot, which is called "cloning a repository",
you will use the C<git clone> command. This will show how to clone the repo from
L<http://github.com> :

  $ git clone git://github.com/parrot/parrot.git

If you have commit access to parrot.git, then you can use the read/write SSH
protocol

  $ git clone <EMAIL>:parrot/parrot.git

If you are behind a firewall that will only let you do HTTP, you can use the
HTTP protocol, but it is much slower and inefficient, so only use it if you
must:

  $ git clone http://github.com/parrot/parrot.git

Cloning a git repo automatically makes the URL that you cloned from your
default "remote", which is called "origin". What this means is that
when you want to pull in new changes or push changes out in the future,
"origin" is what will be used by default.

=head2 Creating and Switching Branches

To create a branch and check it out, use the C<git checkout -b> command.
Current convention is to create branch names of the form username/foo.

  $ git checkout -b username/foo

You can also create a branch without checking it out:

  $ git branch username/foo

To checkout (or "switch to", as it is commonly referred to) the username/foo
branch:

  $ git checkout username/foo

=head2 Keeping updated

To get the latest updates:

  $ git fetch

This copies the index from your default remote (origin) and saves it to your
local index. This does not effect your working copy. To sync up your working
copy, you can use C<git rebase>

  $ git checkout master       # Switch to the master branch
  $ git rebase origin/master  # rebase latest fetched changes onto master

This is a common action, so there is also a simpler way to do it:

  $ git pull --rebase

Whenever you don't specify a remote or branch to a git command, they default
to the remote called "origin" and the master branch, so the previous command
means exactly the same as:

  $ git pull --rebase origin master

=head2 How to commit

Let's say you modified the file foo.c and added the file bar.c and you want to commit
these changes. To add these changes to the staging area (the list of stuff 
that will be included in your next commit) :

  $ git add foo.c bar.c

The command C<git add> is not only for adding new files, just keep that in mind.
It tells git "add the state of these files to my staging area."

Now for actually creating your commit! Since Git is a distributed version control
system, committing code is seperate from sending your changes to a remote server.
Keep this in mind if you are used to Subversion or similar VCS's, where committing
and sending changes are tied together.

  $ git commit -m "This is an awesome and detailed commit message"

If you do not give the -m option to C<git commit>, it will open your $EDITOR
and give you metadata which will help you write your commit message,
such as which files changed and if conflicts happened. Only lines that do
not begin with a # will be in your commit message.

Commit messages consist of a one line "short message" and an optional long
message that can be as long as you like. There must be an empty line between
the short message and the long message. It is often a good practice to keep the
first line of a commit message relatively short, around 50 characters. This
allows for tools to succinctly display one-line commit messages with metadata.
It is good practice to describe *why* something was done in the long message,
in addition to what was done.

=head2 Maintaining a Branch

=head2 Preparing to Merge a Branch

Post to <EMAIL> letting people know that you're about to
merge a branch.

=over

=item 1

Ask people to submit test results for their language, tool, or platform. If
you don't hear back from people, it doesn't mean they ran the tests and found
no problems, it means they didn't bother testing the branch. If you need
feedback on a particular language or platform, follow up with the person
responsible until you hear an explicit "Yes, it's working" answer.

=item 2

Let people know what tests you ran, so they can determine if you didn't run
the tests for their language or tool (or, didn't run I<all> the tests for
their language or tool if they have some unusual testing configuration).

=item 3

Mention any significant feature changes in the branch that you particularly
want tested.
{'fraction_non_alphanumeric': 0.04384300409467692, 'fraction_numerical': 0.00399480675122341, 'mean_word_length': 3.9771371769383697, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7460559', 'n_tokens_mistral': 2687, 'n_tokens_neox': 2550, 'n_words': 1665}