[Home]Git

LinuxCNCKnowledgeBase | RecentChanges | PageIndex | Preferences | LinuxCNC.org

Showing revision 40
On June 20, 2009, the LinuxCNC project began using [git] as its revision control system, replacing CVS. [Read the announcement]

This page collects instructions and guidelines for using git with LinuxCNC. There is also a wealth of documentation for git, including

and full manpages for every git command (man git-clone or git --help clone)

The below tips can feel very daunting; don't panic. Your day-to-day life with git is going to be very simple:

 git pull
 git commit -a
 git format-patch OR git push

1. Prepare your system for development with git
1.1. Install git on your system
1.2. Configure your identity
2. Create an initial check-out
2.1. Anonymous checkouts
2.2. Registered user checkouts
2.3. About your cloned local repo
3. View history
4. Commit changes
4.1. Commit message style
5. Get changes from others
5.1. ... from the central repository
5.2. ... from other repositories
5.3. ... from patches
6. Work with branches
6.1. If you prefer to use different directories for different branches
7. Share your changes with others
7.1. Choose an appropriate starting point
7.2. Use multiple commits to organize changes
7.3. Follow the style of the surrounding code
7.4. Prepare commits to share with fellow developers
7.5. Making sure every commit builds
7.6. Send patches through e-mail or the web
7.7. Push changes to the central repository
7.8. Push changes to your own public repository
8. Policy
8.1. Renaming files
8.2. Prefer "rebase"
9. Tips and tricks
9.1. Use a global ignore file for editor backups
9.2. Pull Script
9.3. Copying to a USB stick
9.4. Stash before pull

1. Prepare your system for development with git

1.1. Install git on your system

In the package manager, select the package "git-core" (the package "git" is an unrelated program; don't choose it). Optionally, select "gitk" or "qgit" (not on Dapper) to graphically view project history, and "git-gui" to graphically select files to commit.

If you're using Ubuntu Dapper, git 1.6 packages are available on the linuxcnc.org package server in the linuxcnc2.3 directory. If you already have this repository enabled, simply update your package lists, and the new git packages will be available for installation. (The git 1.1 packages that shipped with dapper, and the git 1.5 packages in dapper-backports, are both not recommended for various reasons)

1.2. Configure your identity

 git config --global user.name "Your full name"
 git config --global user.email "you@example.com"
Use your real name (not a handle), and use an unobfuscated e-mail address.

2. Create an initial check-out

"clone" is the git command that gets a copy of a project's history. It is roughly like "cvs co", except that the whole project history (not just the current working files) are available after a clone.

2.1. Anonymous checkouts

 git clone git://git.linuxcnc.org/git/linuxcnc.git linuxcnc-dev
this will create a new local directory 'linuxcnc-dev' and fetch the full history of the project. On a system with a 3 megabit connection, this took about 3 minutes and the created directory is about 80 megs. The repo created by this clone command is a full repo: it has all of the history, and you can make local commits (for your own use, or for sending to developers with commit access to the central repo). You can not push back to the central repo from this repo.

2.2. Registered user checkouts

If you are a registered developer with "push" access, use
 git clone ssh://developername@git.linuxcnc.org/git/linuxcnc.git linuxcnc-dev
This creates a repo that can push back to the central repo.

2.3. About your cloned local repo

Both of the clone commands above create a directory in your working directory called "linuxcnc-dev", containing a full clone of the linuxcnc.org git repo. All the commands below assume that you are in the linuxcnc-dev directory unless noted otherwise.

3. View history

Take a look at the history:
 git log -C --stat
(git log has a bunch of options; this set detects renames and copies, and shows a summary of what files are changed in each commit)

Get a closer look at a particular change by commit:

 git log -C -p -1 57c609
(-p shows a patch, -1 restricts to a single change, and 57c609 is the start of a commit shown by the first 'git log' command)

Get a list of commits to a particular file since v2.1.7 branch:

 git log --oneline v2.1.7..origin/v2_3_branch -- src/hal/components/stepgen.c

View history graphically, if you installed the necessary program:

 gitk --all
 qgit --all

You can also [view the history online in gitweb], but viewing the history locally is often more powerful.

4. Commit changes

Edit some files and then commit the changes locally:
 git commit -s -a -m"my well-intentioned changes"

Use 'git add' to select specific files to commit, or 'git add --interactive' to specify specific edits in specific files to commit. 'git add' also functions like 'cvs add' for new files:

 git add README
 git commit -s -m"my well-intentioned changes"

Use a GUI to select individual changes to commit, and to compose the commit message:

 git gui
 qgit

In git, "commit" is a purely local operation. See "Share your changes with others" below.

4.1. Commit message style

Keep commit messages around 72 columns wide (so that in a default-size terminal window, they don't wrap when shown by 'git log')

Use the first line as a summary of the intent of the change (almost like the subject line of an e-mail). Follow it with a blank line, then a longer message explaining the change. Example:

    Get rid of RTAPI_SUCCESS, use 0 instead

    The test "retval < 0" should feel familiar; it's the same kind of test you use
    in userspace (returns -1 for error) and in kernel space (returns -ERRNO for
    error)

5. Get changes from others

5.1. ... from the central repository

To get changes that have been committed to the location you originally cloned from:
 git pull

5.2. ... from other repositories

Pull changes made by another developer in his public repository but not yet committed to the central repository:
 git pull git://git.unpythonic.net/linuxcnc-ignores.git master
(this pulls two commits that change old .cvsignore files to new .gitignore files and add some missing items to .gitignore)

'git remote' can be used to manage short names for repositories that you frequently pull from.

5.3. ... from patches

Apply a patch from another developer, preserving the other developer's identity as the patch author:
 git am --signoff patch.mbox

6. Work with branches

To list just the branches in your local repository:

 git branch

To list all the branches in the remote repository:

 git branch -r

To check out a branch, for example, the 2.5 branch:

 git checkout -b v2.5_branch origin/v2.5_branch

To work on the 2.5 branch instead of 'master' ('master' is the git equivalent of cvs 'TRUNK'):

 git branch --track v2.5_branch origin/v2.5_branch
 git checkout v2.5_branch
After you branch, you can switch freely between master and branch:
 git checkout master
 git checkout v2.5_branch

You can create your own branch based off another branch:

 git branch my-topic master
git often uses "topic" as a placeholder for a branch name, because everything in a branch should be on one "topic"--a topic might be to add feature X, refactor subsystem Y, only fix bugs from version Z, and so on.

6.1. If you prefer to use different directories for different branches

The following sequence creates "linuxcnc2.5-dev" alongside "linuxcnc-dev", then uses 'git relink' to save disk space, then switches to the v2_5_branch in the linuxcnc2.5-dev directory:
 cp -r linuxcnc-dev/ linuxcnc2.5-dev
 git relink linuxcnc2.5-dev/ linuxcnc-dev/
 cd linuxcnc2.5-dev
 git branch v2_5_branch origin/v2_5_branch 
 git checkout v2_5_branch 

7. Share your changes with others

7.1. Choose an appropriate starting point

For new features, use the git 'origin/master' branch as the starting point.

For v2.5_branch bugfixes, use the merge-base of master and v2.5_branch. You can make a bugfix and merge it into both branches like so:

 git checkout $(git merge-base origin/v2.5_branch origin/master)
 git checkout -b descriptive-bugfix-branch-name
 edit/compile/test/commit
 git checkout master
 git merge descriptive-bugfix-branch-name
 compile/test
 git checkout v2.5_branch
 git merge descriptive-bugfix-branch-name
 compile/test

Check with cradek before pushing changes to v2.5_branch. If your bugfix is approved for v2.5_branch, then it will also be fixed on master when changes in the branch are merged up.

For v2.4_branch bugfixes, use the merge-base of master and v2.4_branch. You can make a bugfix and merge it into both branches like so:

 git checkout $(git merge-base origin/v2.4_branch origin/master)
 git checkout -b descriptive-bugfix-branch-name
 edit/compile/test/commit
 git checkout master
 git merge descriptive-bugfix-branch-name
 compile/test
 git checkout v2.4_branch
 git merge descriptive-bugfix-branch-name
 compile/test

Check with jepler before pushing changes to v2.4_branch. If your bugfix is approved for v2.4_branch, then it will also be fixed on master when changes in the branch are merged up.

For more information about why to structure bugfixes like this, see [gitworkflows: Merging Upwards].

7.2. Use multiple commits to organize changes

When appropriate, organize your changes into a series of commits where each commit is a logical step towards your ultimate goal. For example, first factor out some complex code into a new function. Then, in a second commit, fix an underlying bug. Then, in the third commit, add a new feature which is made easier by the refactoring and which would not have worked without fixing that bug.

This is helpful to reviewers, because it is easier to see that the "factor out code into new function" step was right when there aren't other edits mixed in; it's easier to see that the bug is fixed when the change that fixes it is separate from the new feature; and so on.

7.3. Follow the style of the surrounding code

Make an effort to follow the prevailing indentation style of surrounding code. In particular, changes to whitespace make it harder for other developers to track changes over time. When reformatting code must be done, do it as a commit separate from any semantic changes.

7.4. Prepare commits to share with fellow developers

With git, it's possible to record every edit and false start as a separate commit. This is very convenient as a way to create checkpoints during development, but often you don't want to share these false starts with others.

Git provides two main ways to do this, both of which can be done freely before you share the change:

7.5. Making sure every commit builds

If your change consists of several patches, 'git rebase -i' may be used to reorder these patches into a sequence of commits which more clearly lays out the steps of your work. A potential consequence of reordering patches is that one might get dependencies wrong - for instance, introducing a use of a variable, and the declaration of that variable only follows in a later patch.

While the branch HEAD will build, not every commit might build in such a case, and that breaks git-bisect (find by binary search the change that introduced a bug) - something somebody else might use later on to find the commit which introduced a bug. So beyond making sure your branch builds, it is important to assure every single commit builds as well.

There's an automatic way to check a branch for each commit being buildable - see http://dustin.github.com/2010/03/28/git-test-sequence.html , and the code at https://github.com/dustin/bindir/blob/master/git-test-sequence. Use as follows (in this case testing every commit from origin/master to HEAD, including running regression tests):

 $ cd linuxcnc-dev
 $ git-test-sequence origin/master.. '(cd src;make;runtests)'

This will either report 'All's well' or 'Broke on <commit>'

7.6. Send patches through e-mail or the web

When you think your changes are ready to be used by others, you can share it in the form of a patch. Make a series of patches for each commit in your local branch but not in 'origin':
 git format-patch -M origin
This creates a number of files with names like
 0001-my-well-intentioned-change.patch
These patch files are suitable for putting on a webserver or for sending as e-mail with your favorite mail client or git-send-email (some configuration required).

To submit a patch, there are several different options:

By posting your patch in a public forum rather than in private to a single developer, you create more opportunities for review and comment.

These are some of the questions developers are likely to have about your patch:

It is not uncommon for a patch to go through several revisions before it is accepted.

7.7. Push changes to the central repository

If you've been approved to directly push your changes to the central repository, then after some initial setup of ssh keys it's a fairly simple process:
 git pull
 # resolve any conflicts, but generally there won't be any
 git push
If another developer pushed between your pull and your push, you will have to pull and then push again. This isn't expected to happen very frequently, but it will happen more frequently than with cvs since it's required when any file changed, not just when a specific file being committed changed. It is also best to use "git pull --rebase" in this case, this will cause the changes from the central repository to be positioned before your own changes (thus skipping a merge).

With git we will want to reevaluate how readily little-tested changes are pushed to 'master', since git provides so many more ways for developers to exchange patches and collaborate on new features.

7.8. Push changes to your own public repository

You can host a public repository to which you "push" and from which others can "pull". If you don't have a server of your own to do this, services like [1] and [2] are free for open source projects. After you push to your own public repository, other developers can browse your changes or "pull" them.

8. Policy

Just because a thing can be done with git doesn't mean it should be done.

8.1. Renaming files

Please use the ability to rename files very cautiously. Like running indent on single files, renames still make it more difficult to follow changes over time. At a minimum, you should seek consensus on irc or the mailing list that the rename is an improvement.

8.2. Prefer "rebase"

Use "git pull --rebase" instead of bare "git pull" in order to keep a nice linear history. When you "--rebase", you always retain your work as revisions that are ahead of origin/master, so you can do things like git format-patch them to share with others without pushing to the central repository.

9. Tips and tricks

9.1. Use a global ignore file for editor backups

Different developers' editors use different backup file names. Rather than put every possible editor backup file name in every project .gitignore, use a personal gitignore file to ignore your own editor backup files:
 git config --global core.excludesfile ~/.gitignore
 echo '*~' >> ~/.gitignore
Now, the exclusion pattern '*~' will be applied in every directory of every git project you use.

9.2. Pull Script

I made a little script that pulls and then loads the GUI. Speeds the process up for me. BJT

 #!/bin/bash
 clear
 cd linuxcnc-dev
 git pull
 git gui
 echo Git-R-Done!

9.3. Copying to a USB stick

If you get errors trying to copy your linuxcnc-dev directory to a usb stick then tar it up first. From the directory above linuxcnc-dev
 tar cvf linuxcnc-dev.tar linuxcnc-dev
 then copy linuxcnc-dev.tar to the stick
 then 
 tar xvf /path/to/linuxcnc-dev.tar 
 on the other system
If your usb stick is memory challenged you can compress the the files by adding a z. Like cvzf and xvzf.

9.4. Stash before pull

To pull, you must have no uncommitted changes in your working tree. If your local work is done, just commit it and then pull.

If you have work in progress that isn't ready to commit, "stash" it:

 git stash save
 git pull --rebase
 git stash apply

LinuxCNCKnowledgeBase | RecentChanges | PageIndex | Preferences | LinuxCNC.org
This page is read-only. Follow the BasicSteps to edit pages. | View other revisions | View current revision
Edited April 1, 2012 5:29 pm by KimK (diff)
Search:
Published under a Creative Commons License