test-lib.sh: Add new function, test_expect_code
[gitweb.git] / Documentation / howto / using-topic-branches.txt
index de28cf7ce791a2de81f3887176360014d91ea3e5..4698abe46bff0b878dcfcd05771f5760483b4278 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.9f
+
 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"
+ $ git checkout test && git merge "Auto-update from upstream" test linus
+ $ git checkout release && git merge "Auto-update from upstream" release linus
 
-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
@@ -104,7 +128,7 @@ commit to this branch.
 When you are happy with the state of this change, you can pull it into the
 "test" branch in preparation to make it public:
 
- $ git checkout test && git resolve test speed-up-spinlocks "Pull speed-up-spinlock changes"
+ $ git checkout test && git merge "Pull speed-up-spinlock changes" test speed-up-spinlocks
 
 It is unlikely that you would have any conflicts here ... but you might if you
 spent a while on this step and had also pulled new versions from upstream.
@@ -114,7 +138,7 @@ same branch into the "release" tree ready to go upstream.  This is where you
 see the value of keeping each patch (or patch series) in its own branch.  It
 means that the patches can be moved into the "release" tree in any order.
 
- $ git checkout release && git resolve release speed-up-spinlocks "Pull speed-up-spinlock changes"
+ $ git checkout release && git merge "Pull speed-up-spinlock changes" release speed-up-spinlocks
 
 After a while, you will have a number of branches, and despite the
 well chosen names you picked for each of them, you may forget what
@@ -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 merge "Auto-update from upstream" $1 linus
+       ;;
+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 merge "Pull $1 into $2 branch" $2 $1
+       ;;
+*)
+       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