An Introduction to Git

From GnuCash
Revision as of 15:10, 24 March 2017 by Gjanssens (talk | contribs) (Branches: Remove svn distractions)
Jump to: navigation, search

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 manage our code and documentation sources in Git.

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.

code.gnucash.org is 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.

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.
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

OR

 git checkout -b working-branch   # create working-branch from the current branch and check it out in one step

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 or 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 checkout master
 git pull origin master
 or
 git checkout maint
 git pull origin maint
  • 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 or 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

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              # Checkout the branch (master or maint) on which your new working-branch will be based
 git branch working-branch        # Create branch working-branch from the current branch
 git checkout working-branch
 OR
 git checkout -b working-branch   # create working-branch from the current branch and check it out in one step

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 or maint from upstream (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:

  • Check if remote upstream is already defined
 git remote -v
  • If upstream is not already defined, create it. For example
 git remote add upstream ssh://git@github.com/Gnucash/gnucash
  • Update the local master or maint branch (depending on which your working branch is based) in your local repository from upstream:
 git checkout master
 git pull upstream master
 or
 git checkout maint
 git pull upstream maint
  • Update master or maint in your personal GitHub repository (origin) from your local repository:
 git push 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:

 # Note: no need to checkout your working-branch first
 git push origin working-branch
 E.g.
 git push origin bug-99999

If you have amended a local commit that has already been previously pushed to your remote repo, override the remote commit by:

 git push --force origin working-branch

If you already made a pull request before the amendment, github might have difficulties to display your recent changes correctly on the PR page.

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.

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 or maint from upstream (Pull Requests), then #Create a working-branch (Pull Requests).