This page has moved to: http://linuxcnc.org/docs/2.5/html/code/Contributing-to-LinuxCNC.html |
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
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
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)
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.
git clone git://git.linuxcnc.org/git/linuxcnc.git linuxcnc-devthis 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.
git clone ssh://developername@git.linuxcnc.org/git/linuxcnc.git linuxcnc-devThis creates a repo that can push back to the central repo.
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.
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.
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)
git pull
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.
git am --signoff patch.mbox
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_branchAfter 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 mastergit 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.
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
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].
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.
Git provides two main ways to do this, both of which can be done freely before you share the change:
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>'
git format-patch -M originThis creates a number of files with names like
0001-my-well-intentioned-change.patchThese 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:
These are some of the questions developers are likely to have about your patch:
git pull # resolve any conflicts, but generally there won't be any git pushIf 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.
git config --global core.excludesfile ~/.gitignore echo '*~' >> ~/.gitignoreNow, the exclusion pattern '*~' will be applied in every directory of every git project you use.
#!/bin/bash clear cd linuxcnc-dev git pull git gui echo Git-R-Done!
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 systemIf your usb stick is memory challenged you can compress the the files by adding a z. Like cvzf and xvzf.
If you have work in progress that isn't ready to commit, "stash" it:
git stash save git pull --rebase git stash apply