Merge branch 'master'
[git.git] / Documentation / howto / using-topic-branches.txt
index de28cf7..c6c635a 100644 (file)
@@ -1,16 +1,16 @@
 Date: Mon, 15 Aug 2005 12:17:41 -0700
 From: tony.luck@intel.com
 Subject: Some tutorial text (was git/cogito workshop/bof at linuxconf au?)
+Abstract: In this article, Tony Luck discusses how he uses GIT
+ as a Linux subsystem maintainer.
 
 Here's something that I've been putting together on how I'm using
 GIT as a Linux subsystem maintainer.
 
-I suspect that I'm a bit slap-happy with the "git checkout" commands in
-the examples below, and perhaps missing some of the _true-git_ ways of
-doing things.
-
 -Tony
 
+Last updated w.r.t. GIT 0.99.5
+
 Linux subsystem maintenance using GIT
 -------------------------------------
 
@@ -48,45 +48,69 @@ Change directory into the cloned tree you just created
 
  $ cd work
 
-Make a GIT branch named "linus", and rename the "origin" branch as linus too:
+Set up a remotes file so that you can fetch the latest from Linus' master
+branch into a local branch named "linus":
+
+ $ cat > .git/remotes/linus
+ URL: rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
+ Pull: master:linus
+ ^D
 
- $ git checkout -b linus
- $ mv .git/branches/origin .git/branches/linus
+and create the linus branch:
+
+ $ git branch linus
 
 The "linus" branch will be used to track the upstream kernel.  To update it,
 you simply run:
 
- $ git checkout linus && git pull linus
+ $ git fetch linus
+
+you can do this frequently (and it should be safe to do so with pending
+work in your tree, but perhaps not if you are in mid-merge).
+
+If you need to keep track of other public trees, you can add remote branches
+for them too:
 
-you can do this frequently (as long as you don't have any uncommited work
-in your tree).
+ $ git branch another
+ $ cat > .git/remotes/another
+ URL: ... insert URL here ...
+ Pull: name-of-branch-in-this-remote-tree:another
+ ^D
 
-If you need to keep track of other public trees, you can add branches for
-them too:
+and run:
 
- $ git checkout -b another linus
- $ echo URL-for-another-public-tree > .git/branches/another
+ $ git fetch another
 
 Now create the branches in which you are going to work, these start
 out at the current tip of the linus branch.
 
- $ git checkout -b test linus
- $ git checkout -b release linus
+ $ git branch test linus
+ $ git branch release linus
 
 These can be easily kept up to date by merging from the "linus" branch:
 
  $ git checkout test && git resolve test linus "Auto-update from upstream"
  $ git checkout release && git resolve release linus "Auto-update from upstream"
 
-Set up so that you can push upstream to your public tree:
+Set up so that you can push upstream to your public tree (you need to
+log-in to the remote system and create an empty tree there before the
+first push).
 
- $ echo master.kernel.org:/ftp/pub/scm/linux/kernel/git/aegl/linux-2.6.git > .git/branches/origin
+ $ cat > .git/remotes/mytree
+ URL: master.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
+ Push: release
+ Push: test
+ ^D
 
-and then push each of the test and release branches using:
+and the push both the test and release trees using:
 
- $ git push origin test
-and
- $ git push origin release
+ $ git push mytree
+
+or push just one of the test and release branches using:
+
+ $ git push mytree test
+or
+ $ git push mytree release
 
 Now to apply some patches from the community.  Think of a short
 snappy name for a branch to hold this patch (or related group of
@@ -142,7 +166,12 @@ output from:
 
 is empty.  At this point the branch can be deleted:
 
- $ rm .git/refs/heads/branchname
+ $ git branch -d branchname
+
+Some changes are so trivial that it is not necessary to create a separate
+branch and then merge into each of the test and release branches.  For
+these changes, just apply directly to the "release" branch, and then
+merge that into the "test" branch.
 
 To create diffstat and shortlog summaries of changes to include in a "please
 pull" request to Linus you can use:
@@ -151,3 +180,109 @@ pull" request to Linus you can use:
 and
  $ git-whatchanged release ^linus | git-shortlog
 
+
+Here are some of the scripts that I use to simplify all this even further.
+
+==== update script ====
+# Update a branch in my GIT tree.  If the branch to be updated
+# is "linus", then pull from kernel.org.  Otherwise merge local
+# linus branch into test|release branch
+
+case "$1" in
+test|release)
+       git checkout $1 && git resolve $1 linus "Auto-update from upstream"
+       ;;
+linus)
+       before=$(cat .git/refs/heads/linus)
+       git fetch linus
+       after=$(cat .git/refs/heads/linus)
+       if [ $before != $after ]
+       then
+               git-whatchanged $after ^$before | git-shortlog
+       fi
+       ;;
+*)
+       echo "Usage: $0 linus|test|release" 1>&2
+       exit 1
+       ;;
+esac
+
+==== merge script ====
+# Merge a branch into either the test or release branch
+
+pname=$0
+
+usage()
+{
+       echo "Usage: $pname branch test|release" 1>&2
+       exit 1
+}
+
+if [ ! -f .git/refs/heads/"$1" ]
+then
+       echo "Can't see branch <$1>" 1>&2
+       usage
+fi
+
+case "$2" in
+test|release)
+       if [ $(git-rev-list $1 ^$2 | wc -c) -eq 0 ]
+       then
+               echo $1 already merged into $2 1>&2
+               exit 1
+       fi
+       git checkout $2 && git resolve $2 $1 "Pull $1 into $2 branch"
+       ;;
+*)
+       usage
+       ;;
+esac
+
+==== status script ====
+# report on status of my ia64 GIT tree
+
+gb=$(tput setab 2)
+rb=$(tput setab 1)
+restore=$(tput setab 9)
+
+if [ `git-rev-list release ^test | wc -c` -gt 0 ]
+then
+       echo $rb Warning: commits in release that are not in test $restore
+       git-whatchanged release ^test
+fi
+
+for branch in `ls .git/refs/heads`
+do
+       if [ $branch = linus -o $branch = test -o $branch = release ]
+       then
+               continue
+       fi
+
+       echo -n $gb ======= $branch ====== $restore " "
+       status=
+       for ref in test release linus
+       do
+               if [ `git-rev-list $branch ^$ref | wc -c` -gt 0 ]
+               then
+                       status=$status${ref:0:1}
+               fi
+       done
+       case $status in
+       trl)
+               echo $rb Need to pull into test $restore
+               ;;
+       rl)
+               echo "In test"
+               ;;
+       l)
+               echo "Waiting for linus"
+               ;;
+       "")
+               echo $rb All done $restore
+               ;;
+       *)
+               echo $rb "<$status>" $restore
+               ;;
+       esac
+       git-whatchanged $branch ^linus | git-shortlog
+done