An Introduction to Git
Contents
- 1 Introduction
- 2 What is Git?
- 3 What has that to do with Gnucash?
- 4 Using the Github Repository
- 5 Patches
- 6 Pull Requests
- 6.1 Set-Up Your Personal GitHub Repository
- 6.2 Set-Up a Local Repository on your PC
- 6.3 Create a working-branch (Pull Requests)
- 6.4 Commit
- 6.5 Sync your local master/maint from origin (Pull Requests)
- 6.6 Push Back To Your Personal Repository
- 6.7 Create a Pull Request
- 6.8 Cleanup
- 6.9 Prepare for your next working branch
Introduction
This page is for explaining the use of git in the development process to programmers, documenters or translators who are not familiar with git. Those already familiar with git may find the Git page more suitable.
Developers who have write (commit) access to the official (canonical) GnuCash git repositories are often termed Committers. This page is for Non-Committers.
These instructions are only an unofficial suggested methodology. Git is a very powerful tool and there are often many different ways to do something. If you know of a better way, please feel free to update this page.
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.
If you know nothing about version control, that doesn't matter. Just read Getting Started - About Version Control. There in the left column you can select your language.
Another good place to start is Good Resources for Learning Git and GitHub - not only if you want to use GitHub for #Pull Requests.
git help
will give you a list of usual commands and
git help <command>
will show you the manual page of that command.
There are several GUIs available for git, e.g.:
- git gui
- gitk (shows the history)
- SourceTree for Windows or Mac
and most IDEs have plugins for it.
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.
svn.gnucash.org is just another name for code.gnucash.org, the server that hosts the canonical git repository, wiki, Mailing Lists, automated win32 builds, and the nightly builds of the documentation and API docs (via Doxygen) for both branchs. The old SVN repository is there too and it is possible to check out from it but since it doesn't take commits there's no reason to do so.
Using the Github Repository
Branches
There are 2 important branches in most of our repositories:
- master
- is the default branch in git. New features and their documentation should be based on this branch. 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.
- maint
- Bugfixes, translations, improvements of the documentation should usually be applied on this branch.
Non-Committers should always work in a branch specific to the bug or feature being worked on, not the master or maint branch. Name the feature or working branch after the bug or feature - e.g. bug-12345 or invoice-new-button.
Patches or Pull Requests?
There are 2 main ways to submit bug fixes, modifications or enhancements for review:
- GitHub pull requests
- These are preferred by the developers due to rich GitHub code review functionality, but are more complicated to create than patches.
- Proceed to #Pull Requests.
- Patches
- A patch is essentially a specially formatted file containing a list of the files that have been changed, and for each file, before and after listings of the changed lines.
Patches
Set-Up
Create the directory you wish to hold your repository or repositories in and make it current. Assuming you wish it to be called github in your home directory:
mkdir ~/github cd ~/github
Create a copy of the required repository on your PC by cloning:
git clone https://github.com/Gnucash/gnucash.git
- other URLs
- https://github.com/Gnucash/gnucash-docs.git (documentation)
- https://github.com/Gnucash/gnucash-htdocs.git (website)
- See https://github.com/Gnucash for further repos e.g. with OS/distro specific build scripts.
The clone example above will create the local repository
~/github/gnucash
and also defines a remote named origin pointing to the cloned from repository which you can use in future as a shortcut instead of the full URL.
Change into the repository directory:
cd gnucash
Only the default branch master will have been cloned. If you wish to work on a modification to the maint branch, create local branch maint to track your remote branch:
git branch --track maint origin/maint
Create a working-branch (Patches)
- Open a bug in Bugzilla to attach your patch to if one doesn't already exist.
- Use a particular working branch for only one bug or feature. This will make it much easier to make changes and generate new patches should that prove necessary.
- Create a local (on your PC) branch to work in:
- Bug fixes should branch from maint unless the bug applies only to the unstable version.
- New features must branch from master.
The following example is for a new feature; substitute maint for master if you're doing a bug-fix.
Checkout the branch (master or maint) on which your working-branch will be based, e.g.:
git checkout master
Note: checkout prepares your local repository ready for work on a particular branch by resetting all files back to how they were at the time they were last committed. It is much easier if you only checkout a branch after committing all changes you have made to the current branch. You will get a warning if you try to change branches and there are uncommitted changes. It is not wise to leave a file open in an editor while checking out a branch as you may accidentally save a version from another branch.
git branch working-branch # Creates branch working-branch from the current branch git checkout working-branch # make working-branch current
You are now ready to make and test your changes in your local working branch.
Commit
See http://wiki.gnucash.org/wiki/Documentation_Update_Instructions#Step_11_Commit_your_Changes
Sync your local master/maint from origin (Patches)
After you have completed your changes, to minimize the chances of your future patch conflicting with any changes that may have been committed to the official GnuCash repositories while you were working:
- Update the local master or maint branch (depending on which your working branch was created from) in your local repository from origin:
git pull origin master
- Rebase your working branch commits based on the updated master or maint:
git rebase master working-branch
You can update both master and maint if you wish but you only need to update the branch on which your working branch was based.
- Test again to make sure everthing works with the rebased code
Create Patch(es)
A patch file is created for each commit.
- Use git rebase -i as necessary to make a clean series of patches for complex changes.
- Use git format-patch to create the actual patches from your commits:
cd ~/github/gncucash git format-patch origin/master..master
(or git diff) to prepare them.
- Attach the resulting patch(es) to the bug report. It is not necessary to email anyone as the relevant people are automatically emailed when you attach a patch to a bug.
- If a committer asks you to make changes, revise your original commit and make a new patch. Don't submit a patch to be applied on top of an old one. git-rebase -i can be very helpful if you have a series of patches.
Cleanup
Once the patch has been either merged or rejected, you can delete the local working branch:
git checkout master git branch -D working-branch E.g. git branch -D bug-99999 # delete local branch bug-99999
If you no longer require your local repository, you can just delete the folder on your PC and it's sub-folders.
Prepare for your next patch
Follow the instructions in Sync your local master/maint from origin (Patches), then Create a working-branch (Patches).
Pull Requests
If you prefer, you can use a GitHub Pull Request instead of attaching a patch to a bug. You'll need to create a GitHub account if you haven't got one already and set it up for ssh access.
Suggested remote repository names for Non-Committers Using Pull Requests
Use the following names in your local PC repository for remote repositories:
- upstream: The official repository to which only authorized developers can write. E.g.
- github.com/Gnucash/gnucash
- or
- github.com/Gnucash/gnucash-docs
- These are actually public mirrors for the real GnuCash official repositories.
- origin: This is your personal writable GitHub repository. E.g.
- github.com/[YOUR-GITHUB-USERNAME]/gnucash
- or
- github.com/[YOUR-GITHUB-USERNAME]/gnucash-docs
- Pull requests are made from here to the upstream repository.
Set-Up Your Personal GitHub Repository
Use Github's fork feature to set up a your own personal read-write enabled clone on GitHub:
In a web browser, go to https://www.github.com, login and search for Gnucash. Click on the link for the required repository, E.g.
Gnucash/gnucash or Gnucash/gnucash-docs
Click on the Fork button at top right. This will create
www.github.com/[YOUR-GITHUB-USERNAME]/gnucash-docs
Set-Up a Local Repository on your PC
As you will eventually push your modified local repository branch back to your personal GitHub repository, it is useful to create your local PC repository by cloning from your personal GitHub repository, rather than the official GnuCash repository. The remote name origin in your local repository, is automatically set up to point to where you clone from (I.e. your personal GitHub repository).
Create the directory you wish to hold your repository or repositories in and make it current. Assuming you wish it to be called github in your home directory:
mkdir ~/github cd ~/github
Clone from your remote personal repository origin:
git clone git@github.com:<YOUR-GITHUB-USERNAME>/gnucash.git</tt>
The clone example above will create the local repository
~/github/gnucash
and also defines a remote named origin pointing to the cloned from repository which you can use in future as a shortcut instead of the full URL.
Change into the repository directory:
cd gnucash
Only the default branch master will have been cloned. If you wish to work on a modification which should be applied to the maint branch, create local branch maint to track your remote branch:
git branch --track maint origin/maint
Create a working-branch (Pull Requests)
- Create a branch to work in:
- Bug fixes should branch from maint unless the bug applies only to the unstable version.
- New features must branch from master.
- Open a bug in Bugzilla to enable your work to be tracked if one doesn't already exist.
The following example is for a new feature and therefore uses master; substitute maint for master if you're doing a bug-fix.
- Use a particular working branch for only one bug or feature. This will make it much easier to make changes should that prove necessary.
git checkout master git branch working-branch # Create branch working-branch from the current branch git checkout working-branch
Note: checkout prepares your local repository for work on a particular branch by resetting all files back to how they were at the time that branch was last committed. It is much easier if you only checkout a branch after committing all changes you have made to the current branch. It is not wise to leave a file open in an editor while checking out a branch as you may accidentally save a version from another branch.
You are now ready to make and test your changes in your local working branch.
Commit
See http://wiki.gnucash.org/wiki/Documentation_Update_Instructions#Step_11_Commit_your_Changes
Sync your local master/maint from origin (Pull Requests)
After you have completed and tested your changes, to minimize the chances of your future pull request conflicting with any changes that may have been committed to the official GnuCash repositories while you were working:
- Update the local master or maint branch (depending on which your working branch is based) in your local repository from origin:
git pull origin master
- Rebase your working branch commits based on the updated master or maint:
git rebase master working-branch
- Test again to make sure everything works with the rebased code.
You can update both master and maint if you wish but you only need to update the branch on which your working branch was based.
Push Back To Your Personal Repository
If you followed these instructions and cloned to your local working-branch from your personal github repository, then the remote name origin already points to your personal remote github repository. Check your defined remotes by:
git remote -v
The output of the above should include:
origin git@github.com:<YOUR-GITHUB-USERNAME>/gnucash-docs.git (fetch) origin git@github.com:<YOUR-GITHUB-USERNAME>/gnucash-docs.git (push)
so you can push your working-branch to your remote personal github repository by:
git push origin working-branch E.g. git push origin bug-99999
If your remote named origin does not point to your personal github repository but you have another remote which does, then substitute your remote name for origin in the above command.
If you don't have a remote name that points to your personal github repository, then add a remote name that does, E.g. to add remote named mygithub:
git remote add mygithub ssh://git@github.com/<YOUR-GITHUB-USERNAME>/gnucash
then git push mygithub working-branch
Create a Pull Request
- Now log in to your GitHub account, go to your forked gnucash repository, select working-branch from the branch pick list, and click pull request. It's above the "last commit" line on the right in the directory view.
- In the resulting form, give your pull request a title and describe its motivation. If it's associated with a bug, use the bug number and title for your title and paste the bug URL into the description. Note that GitHub descriptions use Markdown and that there's a preview tab to help you make sure that everything looks the way you want it.
- Click the Send Pull Request button to the right of the description block.
- If a developer requires changes to your pull request, amend your commits as necessary and force-push your branch. Don't make any changes to that working branch that aren't associated with the pull request!
Cleanup
- Once the pull request has been reviewed and either merged or rejected, you can delete the branch.
To delete the local branch:
git branch -D working-branch E.g. git branch -D bug-99999 # delete local branch bug-99999
To delete the working branch from your personal remote github repository:
git push <remote-name> :working-branch # note space before :working-branch E.g. git push origin :bug-99999
If you no longer require your local repository, you can just delete the folder on your PC and it's sub-folders.
Prepare for your next working branch
Follow the instructions in Sync your local master/maint from origin (Pull Requests), then Create a working-branch (Pull Requests).