Git For Developers
Git is a distributed version control system. This page provides information for developers on how we manage our sources within git.
Public Repo
This page is mean for the Net-SNMP development team. If you're looking for the page on the read-only git repo available to the general public, see the Git page.
Setup
git clone ssh://USERNAME@net-snmp.git.sourceforge.net/gitroot/net-snmp/MODULE
where MODULE is either 'net-snmp' (for code) or 'htdocs' (for web documentation)
Make sure your email address and name are correct:
git config user.email "YOURSFACCOUNTNAME@users.sourceforge.net" git config user.name "YOUR NAME"
Git workflows
The first link below should be read before any code is checked in. Specifically, it describes the one important aspect: always commit to the lowest branch you want the patch to apply to!
- First and foremost, read Net-SNMP's Git Workflow
- Then, consider using the Git Branch Management macros for performing the routine tasks (branch merging, etc).
- The gitworkflows manual page is similar to ours
- A good diagram showing another similar workflow pattern.
Making changes
This is where you type vi or emacs or if you're a real developer who likes to get dirty perl -i -p -e ...
Checking out the right branch
git maintains all the code in a single directory, and lets you switch between the branches in the same directory. This is very very different than SVN and other repository systems, but most people find once they let go of the idea that they need separate directories, they're happier in the long run.
The branch may not exist yet in your local repository (run git branch -a to list all the branches known, including the remote ones). To start, simply check it out:
# git checkout V5-4-patches Branch V5-5-patches set up to track remote branch V5-5-patches from origin. Switched to a new branch 'V5-5-patches'
(and now 'git branch' without the '-a' will list it as a known local branch).
Moving changes to a different branch
If you have changes in the local repository already and want to apply them (or test them) against a different branch, the easiest way to do this is with stash and pop:
# git checkout V5-6-patches error: Your local changes to the following files would be overwritten by checkout: NEWS Please, commit your changes or stash them before you can switch branches. Aborting # git stash Saved working directory and index state WIP on V5-5-patches: 6a5e5a6 Merge branch 'V5-4-patches' into V5-5-patches HEAD is now at 6a5e5a6 Merge branch 'V5-4-patches' into V5-5-patches # git checkout V5-6-patches Branch V5-6-patches set up to track remote branch V5-6-patches from origin. Switched to a new branch 'V5-6-patches' # git stash pop Auto-merging NEWS # On branch V5-6-patches # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: NEWS # no changes added to commit (use "git add" and/or "git commit -a") Dropped refs/stash@{0} (102700302cd0a9db42b1669105291bb92fe807e9)
Committing the changes
# git commit -m "commit message" FILES
Or if you want to commit everything in a directory and down, use a directory name instead of FILES.
Or if you want to commit everything anywhere in the repo, use the -a switch.
NOTE: this only commits them to your local copy of the repository. This is different than SVN, if you're more familiar with SVN. Next you need to push them to the master repository:
Pulling the latest changes from the upstream
Whether or not you've modified files locally and checked in the changes to your local repository, you'll need to occasionally pull down any changes that others have made upstream. You do this with a pull. The --rebase option means rather than treat your development as a parallel set, try and apply your resulting patches to the end of the pulled branch instead of merging them. This tends to keep a cleaner history tree.
# git pull --rebase origin master
Assuming you followed the instructions above, and didn't cloning from somewhere else first, you should be able to shorten this to:
# git pull --rebase
This will merge any changes you've made with any that others have made. If something goes wrong, git will complain about conflicts and you'll need to resolve those either manually or using git mergetool. That's a longer subject for another lesson: Git Merging.
You may also wish to pull all the remote branches:
# git pull --all
Reviewing local commits
The most effective way to use git is to commit changes to the local tree as multiple small changes. That makes it easy to edit or revert any local changes if necessary. Once the local changes have been tested and before pushing these upstream, review the local changes and rearrange these if necessary. Try to make sure that any contributed change at least compiles such that the tree remains bisectable. One way to edit local commits is via the git rebase command. That command does not only allow to change the description of each commit, to change the order of commits, to squash multiple commits together but also to leave out some commits. Of course, if any changes have been made these have to be retested. The rebase command can be invoked as follows when working on the master branch:
# git rebase --interactive origin/master
Pushing the changes upstream
Once you're sure your commits are safe themselves and you've updated your repo with the latest upstream you can push your changes upstream to the master repository on sourceforge:
# git push origin master
Assuming you followed the instructions above, and didn't cloning from somewhere else first, you should be able to shorten this to:
# git push
And you're done!
Notes on the htdocs repository
The htdocs module, which contains the Net-SNMP website, is only synchronized from the git repository once an hour. It may take up to an hour before the changes take effect on the website.
Creating tags and branches
Tagging
Tags are simply a symbolic way of remembering "a point in time" that is easier than the sha1 hash that is more frequently seen.
git tag my-really-super-feature-works
for example will create the above tag.
XXX: discuss annotated/signed/etc tags
Pushing tags
By default, git push doesn't push tags. IE, it *only* pushes code. If you've created a tag and you want it pushed upstream, you'll need to push it manually:
git push origin TAGNAME
Or you can push all your tags:
git push --tags
Note: Please don't push personal tags... Use the individual push instead if you're creating helpful personal tags.