Using Git-SVN for Samba Development (deprecated)

From SambaWiki

The current Samba subversion development branches are mirrored at git://git.samba.org/samba/. This document is a short Quick Start guide for using git to interact with other Samba developers.


Contents

Background

The git source code is available from http://www.kernel.org/pub/software/scm/git/. The project home page is located at http://git.or.cz/

The examples in the following sections are based off of the tools and syntax used by git v1.5.2.

The git-svn tool allows you to mirror an svn tree or complete repository as a git repository. You can then commit directly back to the svn code base after coding and checking in changes directly to your local git branch. This HOWTO is *not* about using that plugin. A short tutorial for git-svn is available online at http://utsl.gen.nz/talks/git-svn/intro.html. There's also a trifold git command cheat-sheet available.

The goal of this HOWTO is to enable developers that do not have rights necessary to check code directly into Samba's svn trees. This is not an explanation of or good introduction to the git family of commands. It tries to provide a fast track to working with the Samba trees, but it is a good idea to become familiar with some of the additional git documentation available.

Quick Start

Install git from source or some other means (e.g. apt-get install git-core). Next pull a copy of the Samba git repo:

 $ git-clone -n git://git.samba.org/samba-svnmirror.git samba4.git
 remote: Generating pack...
 remote: Done counting 205340 objects.
 remote: Deltifying 205340 objects...
 remote:  100% (205340/205340) done
 Indexing 205340 objects...
 remote: Total 205340 (delta 160646), reused 184902 (delta 140257)
  100% (205340/205340) done
 Resolving 160646 deltas...
  100% (160646/160646) done

After the local clone has been created, you should see several remote branches. Each of these correspond to one of the SAMBA_* development trees. The ones of interest are listed below

 $ cd samba4.git
 $ git branch -r
   ....
   origin/v3-0
   origin/v3-0-23
   origin/v3-0-24
   origin/v3-0-25
   origin/v3-0-26
   origin/v4-0


Now pick your remote branch of interest and create a local working branch. This example creates a local branch of the SAMBA_3_0 tree.

 $ git checkout --track -b 4-0-work origin/v4-0
 Branch 3-0-work set up to track remote branch refs/remotes/origin/v4-0.
 Switched to a new branch "4-0-work"

This will create a branch named 4-0-work based on the current HEAD of the 4.0 tree and switch your working view to the new branch.

At this point you can do your local work using the normal git commands. See the "Cheat Sheet" section for a basic primer.

Now after some time, you decide that you need to merge in the upstream Samba changes into your local tree. This is a one step call using the git-pull command.

 $ git pull

Note that git-pull is really the same as 'git-fetch && git-merge'. it ios probably a good idea to read the section on Rebasing in the Workflow section later in this document.

Since we initially setup the 4-0-work branch using the --track option, the set of changes that are pulled into the copy of the remotes/origin/v4-0 branch will be applied to your local branch as well. Git uses the notion of rebasing a branch to simply fast forward the original branching point and then reapplying all of your local changes. For more information on git-pull, refer to the Git User's guide.

Now that you have finished all of your brilliant work, simply post your local git branch on a public server somewhere and send mail to the samba-technical mailing list letting others know about it.

Working in your Local Branch

You local work can be in one of three stages:

  1. Checked into your local branch.
  2. Added to the current branch index but not checked in.
  3. Local modifications not added to the index nor checked in to the branch repository.

You can add local changes to the branch index using the git-add command. it is important to remember the way that commands like git-diff and git-commit interact with the working files, the branch index and the repository.

For example, running "git diff" will show you the changes between your working files and the index while "git diff --cached" will show you the diff between the current index and branch repo. Running "git commit" will write the changes in the index to the repo while "git commit -a" will first add all local changes to the index and then commit these (and any previous changes written to the index using "git add") to the repo.

Work Flow

Here are two basic approaches to working with multiple branches that you might find usefule for Samba development.

Case #1: A local central repository with work clones

First grab a copy of the main Samba repo using the following git-clone command. The --bare tells git that the clone will only contain branch information and not working trees (implies -n):

 $ git clone --bare git://git.samba.org/samba samba-master.git
 $ cd samba-master.git
 $ git remote add origin git://git.samba.org/samba
 $ git config remote.origin.fetch '+refs/heads/*:refs/heads/*'

You can create a crontab job to call git-fetch to update this tree periodically. Currently the samba.git tree is refreshed every 15 minutes so any more than that is inefficient and unnecessary.

Next you can create working clone trees. This example creates a local clone tree for the 3.0 code base:

 $ git clone -l -s samba-master.git samba-4-0
 $ cd samba-3-0
 $ git checkout -b 4-0 remotes/origin/v4-0

And you can do the same thing for the Samba 4.0 branch therefore having both branches checked out at one time.


Case #2: Using a single local working repo

We'll start off again by grabbing a copy of the master samba repository but without the --bare option to git-clone:

 $ git clone git://git.samba.org/samba samba-master.git

From with this tree you can only have one branch checked out at any given time, but you can always clone more repos as we did in the case #1.


Feature branches

A mental shift when moving from a centralized VCS like svn to a Distributed VCS is the use of feature branches. Too often, svn users use 'svn commit' as the save button while working on new features because svn merge is not powerful enough to really make local private branches worth the effort.

A feature branch is a local branch in your git tree that is dedicated to a single feature or work item. This make review by others and eventual merging upstream much easier as developers don't have to cherry pick from your changes but can simply look at the diff between your branch and HEAD as a complete single body of work.

Branching is cheap and easy. You can create temporary branches for testing or merging and then throw them away.

If you are working in a single repository then you can git-merge between branches. If you want to merge from another repository, then you'll have to use git-pull which is just a git-fetch followed by a git-merge. But before you get too comfortable with git-pull, read the next section on rebasing.


Using git-rebase

You should probably ready the man page for git-rebase since I'll only hit the highlight here. Think up rebasing as popping all your patches, fetching the latest upstream changes, and then pushing your changes back onto the tree (similar to using quilt). Technically, git-rebase moves the point in time that you branched from the main tree forward and then reapplies your changes (hence the term fast-forward). The advantage is that the history is linear against the main tree with your changes always being on top. And this makes other commands like git-format-patch easier to work with.

Here's a short example:

 $ git checkout -b mywork origin/v4-0     <--- Create the branch
 ...edit....git-add...git-commit....
 $ git fetch                              <--- Updates from upstream
 $ git-rebase remotes/origin/v4-0