Git

From GnuCash
Revision as of 10:03, 6 February 2014 by Gjanssens (talk | contribs) (Branching and Merging: svn is dead - long live master (master is the preferred branch now))
Jump to: navigation, search

What is Git?

Git is a distributed version control system (VCS) originally developed by Linus Torvalds for managing Linux source code without requiring a central server. It is also the primary VCS used by the Gnome and Free Desktop projects. You can get the latest version for your system and read a rich variety of online documentation at Git's Home. In particular, Pro Git by Scott Chacon is available in several languages for free online reading at Git Book, where you can also download the English version as a PDF, ebook, or mobi.

What has that to do with Gnucash?

We have converted from Subversion to Git in order to take advantage of its branching and merging facilities, which are much richer than those provided by Subversion. Our public repositories are mirrored on Github: for code, documentation, and for the website. These are updated from the primary repository by commit hooks, so barring technical problems changes appear in these repositories within a few seconds of being committed to the primary.

Using the Github Repository

Non-Committers

Set-Up

Just clone the repository as usual:

 git clone https://github.com/Gnucash/gnucash.git

Note that the default branch in git is master. In the old svn days this was trunk. For convenience for users migrating from svn a trunk branch has been set up as an alias for the master branch but you are encouraged to switch to master as your main branch.

When you have patches, use

 git format-patch origin/master..master

(or git diff) in the root directory of your local repository to prepare them; then add the patchfile as an attachment to the appropriate bug report.

If you have a Github account, you could as well use Github's "fork" feature to set up a clone on GitHub. And then clone from that repository instead (note that this is a read-write enabled clone):

 git clone git@github.com:<YOUR-GITHUB-USERNAME>/gnucash.git

Note that this clone command takes a url in a different format. With this form you will be able to push your local changes to your GitHub account as usual:

 git push origin master
Continue with ... #Committers

Patches

If you're going to be submitting patches:

  • Create a branch to work in. We prefer that patches are to the master branch. If the patch needs to be backported, the developer who pushes it can modify the commit message, but if the code in the area you're working on has diverged significantly you can help out by providing separate patches (you'll need two working branches in that case).
 git checkout master
 git branch working-master
  • Rebase your working branch onto the target branch often so that you stay in sync:
 git rebase master working-master
  • Open a bug in Bugzilla to attach your patch to if one doesn't already exist.
  • Write good commit messages in which the bug number and summary are the first line. Skip one line, then describe the patch. For example:
 [Bug 673193] - Possible Register migration to TreeView
 
 Update the old register rewrite branch to work with the currently-released Gtk2.
  • Use git rebase -i as necessary to make a clean series of patches for complex changes.
  • Be sure to do a fresh rebase from the target branch and a make check to ensure that everything works
  • Use git format-patch to create the actual patches from your commits:
 git rebase master working-master
 git format-patch master
  • Attach the resulting patch(es) to the bug report.

Committers

Currently these GnuCash repositories are pure git repositories:

  • gnucash-htdocs

Set up

Note: this set up presumes you already have commit access to the GnuCash repositories on code.gnucash.org. If you don't but believe you should, ask for this on the gnucash-devel mailing list. You'll need to generate a key-pair and provide the public half to the GnuCash repository administrator. To generate a key pair use

 ssh-keygen -t rsa -b 1024 -f gnucash-key

You can use any name you like instead of "gnucash-key".

You will also be prompted for a passphrase, with the option to leave it blank. If you provide a passphrase, you will be prompted to provide it every time you use your key. If you don't, anyone who gains access to your key can connect to whatever servers you protect with it.

Once you have the key configured correctly and have provided it to the GnuCash repository administrator, try

 ssh -i gnucash-key git@code.gnucash.org

You'll get the usual ssh question about the fingerprint for a new host. It should be 20:23:3d:df:f3:13:34:c1:32:ca:11:77:24:21:98:01. If it is, answer "yes" to add it to your known hosts file. If you get a message followed by a list of repositories, your setup is correct and you can proceed.

Next, you'll want to to configure your local ssh client to always provide this key when connecting to code.gnucash.org. In addition, ssh should always connect as user 'git'.

On linux, you can set this up by adding the following lines in your ssh config file (~/.ssh/config):

Host code.gnucash.org
IdentityFile ~/.ssh/gnucash-key
User git

Now clone the Github repository the same way as #Non-Committers. Since changes should not be pushed to the github repository, a good way to make sure that this doesn't happen by mistake is to use the same read-only URI given above for non-committers. Alternatively, fork the Gnucash repository to your Github account and clone that (use the read-write URI in that case).

Next add the repository on code.gnucash.org as a second remote, for example as 'upstream'.

 git remote add upstream git@code.gnucash.org:gnucash-htdocs

That's it.

Git and Microsoft Windows

To set up ssh with the MSYS client, proceed exactly as above.

For [TortoiseGit], you'll also need PuttyGen and Putty from [PuTTY]. Setting up Pageant to work with TortoiseGit is a bit involved, so we'll go through it step-by-step:

1. Use PuttyGen to convert your private key into Putty format. Launch puttygen, click the "load" button and select your private key file, then click the "save private key" button to save it in putty format.

2. Set up a Putty profile: Start Putty.

  • Set the Host URL to code.gnucash.org, port 22 on the Session page
  • Open Connection:SSH:Auth and at the bottom of the panel, for "Private key file for authentication" browse for the converted keyfile you made in the previous step.
  • Open Connection:Data and enter 'git' in the "Autologin username" text entry.
  • Return to the Session panel, enter a name (if you use code.gnucash.org configuring TortoiseGit will be less confusing) in the text entry named "Saved Sessions" and click the "save" button.
  • Click "open". If everything is done correctly, a command window will open and you'll see that message about terminal sessions not being allowed. If you are instead prompted for a password, you have messed up the username or key somehow and will need to contact the server admin to get your IP address unblocked.

3. Set up TortoiseGit:

  • Right-click a folder in Windows™ Explorer and select TortoiseGit:Settings. At the bottom of the Network panel of the resulting dialog box, click the "Browse" button for SSH Client and navigate to C:\Program Files\TortoiseGit\bin\TortoisePlink.exe, click "open" in the file chooser, the "OK" to dismiss the Settings box.
  • Right-click on a folder into which you want to check out (or already have checked out) Gnucash. If it's a fresh checkout, select TortoiseGit Checkout; otherwise select TortoiseGit:Relocate. Enter the URL as ssh://the-putty-session-name/gnucash. (Remember earlier where we said it would be less confusing if you use code.gnucash.org for the session name? That's because if you did the URL will be ssh://code.gnucash.org/repo/gnucash.)

You should now be able to commit changes via TortoiseGit.

Committing

Committing is simple:

 git add
 git commit

These two commands are used to record your changes locally.

 git push upstream local-branch:remote-branch

Will push your changes back to the master repository.

Branching and Merging

TBD The branching and merging strategy still has to be outlined in more detail.

The rough idea is probably:

  • Use local branches for your development. As long as you didn't publish those branches, you can locally rebase them to the most recent public branch heads (like master, 2.6.x,...)
  • When you consider the code in your local branch sufficiently mature, you can merge it into one of the public branches and push the changes upstream.

Again, we need to detail this much better. How branches are defined and managed is the core of a good git workflow. A good starting point for our own branching and merging strategy could be these two links (got these from the swig mailing list, which also recently converted to git):

Link Bugzilla Entries

Often commits are related to Bugzilla entries. In this case the first line should contain

  • Bug #<bug number>:<bug title> or
  • Bug #<bug number> - <bug title>.

If trac sees the hash sign (#), it should create a link to that bugzilla entry.

Backport Rules

While usually commits will be applied to master, sometimes it is desired to backport them on the stable branch, currently 2.4. There are a few rules to decide, if a commit should be backported:

  • If the commit fixes a bug(1) that was reported in bugzilla against the stable branch, the changeset should be backported, but:
  • The backporting effort should be trivial. If complicated manual intervention is required, backporting should be skipped to maintain stability.
  • Backports should not require new or stronger dependencies.
  • If the changeset modifies the data model, it should be split in 2 parts:
    • The part to read the modified data model should be backported.
    • The part to write the modified data model should only be applied on trunk.
This would allow a user to test a new main release on one computer while still using the older version on another computer or later on the same computer again without data loss.

If you wish to backport your commit on trunk should contain the mark BP in a separate line of the comment. That would trigger the prefix AUDIT to the mails sent to the gnucash-patches and gnucash-changes lists.

Note

  • Backporting only applies for true bugs, meaning errors in the existing functionality or intended use. New features, additions to current functionality, enhancement requests etc. are not considered for backporting, even if the enhancement request was registered in bugzilla against the stable branch.

Current Backport Policy

Backports should be cherry-picked and thoroughly tested as soon as possible after committing to trunk/master.

Backport comment format

This section is adapted from Geert Janssens' email [1] to the gnucash-devel list.

The commit message for trunk should contain, somewhere within the body of the message, a line with only “BP” on it to indicate this commit is meant to be backported. That helps to check later if all the relevant commits are really backported. It also alters the commit messages that are sent to gnucash-patches and gnucash-changes to begin with “AUDIT”. The AUDIT/BP marks don’t trigger any automatic backporting tasks within the source code management system, but they’re still useful for other developers to follow what gets backported and what not.

The commit message on the commit that goes into the stable branch essentially uses the same text with two small changes: the line containing the “BP” mark is removed, and the revision number of the trunk commit is prepended to the message, surrounded with square brackets.

An example will probably make it much clearer. The commit to trunk would have this message:

My latest changes
BP

Let’s assume this got committed in r22445 and now has to be backported. The message to use on the stable branch will now be:

[22445] My latest changes

That’s it.


Other options exists as well; feel free to edit this wiki page.

Back to Development Process

Collaboration

With rare exceptions we don't want to clutter the master repository with feature branches, so how can two developers collaborate on one? There are several ways to go about it: You can pass patches between you over email, chat, or carrier pigeon; Git is designed to handle that easily (except for carrier pigeon transport, as that requires retyping the patch, which is a pain). You can arrange for all of your repositories to be available on the net, and git pull amongst yourselves. Or you can use one of the public repositories like Github or Gitorious to manage your changes.


Accessing GnuCash BugZilla from Git

There is a plugin, called git-bz, written for Git that allows it to talk to BugZilla and do things with bugs like attach patches, add comments, mark as fixed, etc.–all from the command line. See the git-bz page for details.

Conversion Notice

For some time now the gnucash-htdocs repository has been used to store both the website and a compiled version of our documentation in html, pdf, ebup and mobi formats. The problem with this is that the compiled documentation is pretty large. The repository is currently over 800Mb in size and increasing with each release. That means that over time a simple clone of the repository will cost increasingly more bandwidth and diskspace.

People that wish to work on the website don't need this compiled documentation so the large download is an unnecessary burden. We have decided to fix this by splitting off the compiled documentation into a separate repository. It's only relevant for a release manager. After the split, the gnucash-htdocs repository will be regenerated without the docs history.

As we are doing maintenance on this repository we will remove the "trunk" branch as well in favour of the more git-typical "master" branch.

If you have your own clone of the gnucash-htdocs git repository you will have to reclone the new repository if you want to enjoy the smaller footprint. If you have local changes you'll want to preserve them. So instead of deleting the directory rename it. For the examples we'll call it gnucash-htdocs-old, and we'll clone into gnucash-htdocs-new. That's just to make sure we don't forget which is which. After the import process is complete, you can remove gnucash-htdocs-old and rename gnucash-htdocs-new.

You've been assiduous about always using git pull --rebase, right? No? You've got changes mixed into master? No matter. rebase to the rescue: (I'm using master as an example here, but it could be any tracking branch.)

 cd gnucash-htdocs-old
 git pull --rebase
 git branch -m master foo #This is your new feature branch. You can call it anything you like
 git branch -t master origin/master
 git rebase master foo

There. Now all of your changes are in a nice feature branch. You might have to reconcile some conflicts, but better sooner than later, eh? If you already have feature branches -- we'll use foo for our example -- just make sure that it's up to date with its tracking branch:

 git checkout master
 git pull --rebase
 git rebase master foo

Now you're ready to export your changes. Do this one feature branch at the time. Create a set of patches for your feature branch:

 cd ../gnucash-htdocs-old
 git checkout foo
 git format-patch --stdout master > ../foo.mbox

And import your branch foo into the new repo:

 cd ../gnucash-htdocs-new
 git checkout master
 git checkout -b foo
 git am ../foo.mbox

That's it. Repeat for each feature branch and tracking branch. When you're done and really, really sure that everything is properly set up, you can delete gnucash-htdocs-old and any foo.mbox you created.

Note: When you run git checkout master in gnucash-htdocs-new, git should respond with

 Checking out files: 100% (1247/1247), done.
 Branch master set up to track remote branch master from origin.
 Switched to a new branch 'master'

If it doesn't, then it may have gotten confused. If

 git log --oneline -n 10

doesn't produce the expected results,

 git branch -D master
 git branch -t master origin/master

To get the proper master branch.

Github Forks: If you have made a Github fork you will need to make sure that your local repo is current and then delete the fork and re-fork the regenerated repository, then proceed according to the instructions above, finally pushing any new branches back to your Github fork.

Related Topics

  • Git Migration tracks the required changes to our infrastructure and support code before we can switch to a pure git based workflow.
  • Git vs Svn has some background on conceptual differences between svn and git. This may help people with a strong svn background to make the switch to git.
  • Purely for historical interest: GnuCash has been maintaining its source code in a hybrid svn-git system for a while. In has now moved on to a pure git environment. We had some documentation for this hybrid setup as well. The current page's history will reveal how a user was to configure her local setup, Git_Svn_Mirror explains what was needed on the server side.