From a2f15a812c16cc0fa56a74af0e52d30ff4e615db Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 15 Aug 2005 15:36:52 -0700 Subject: Keep excellent tutorial for using topic branches by Tony Luck I would eventually like to move this to become a part of the tutorial, but anyway, this was an excellent post that describes how topic branches can be used to keep track of local changes. diff --git a/Documentation/howto/using-topic-branches.txt b/Documentation/howto/using-topic-branches.txt new file mode 100644 index 0000000..de28cf7 --- /dev/null +++ b/Documentation/howto/using-topic-branches.txt @@ -0,0 +1,153 @@ +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?) + +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 + +Linux subsystem maintenance using GIT +------------------------------------- + +My requirements here are to be able to create two public trees: + +1) A "test" tree into which patches are initially placed so that they +can get some exposure when integrated with other ongoing development. +This tree is available to Andrew for pulling into -mm whenever he wants. + +2) A "release" tree into which tested patches are moved for final +sanity checking, and as a vehicle to send them upstream to Linus +(by sending him a "please pull" request.) + +Note that the period of time that each patch spends in the "test" tree +is dependent on the complexity of the change. Since GIT does not support +cherry picking, it is not practical to simply apply all patches to the +test tree and then pull to the release tree as that would leave trivial +patches blocked in the test tree waiting for complex changes to accumulate +enough test time to graduate. + +Back in the BitKeeper days I achieved this my creating small forests of +temporary trees, one tree for each logical grouping of patches, and then +pulling changes from these trees first to the test tree, and then to the +release tree. At first I replicated this in GIT, but then I realised +that I could so this far more efficiently using branches inside a single +GIT repository. + +So here is the step-by-step guide how this all works for me. + +First create your work tree by cloning Linus's public tree: + + $ git clone rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git work + +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: + + $ git checkout -b linus + $ mv .git/branches/origin .git/branches/linus + +The "linus" branch will be used to track the upstream kernel. To update it, +you simply run: + + $ git checkout linus && git pull linus + +you can do this frequently (as long as you don't have any uncommited work +in your tree). + +If you need to keep track of other public trees, you can add branches for +them too: + + $ git checkout -b another linus + $ echo URL-for-another-public-tree > .git/branches/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 + +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: + + $ echo master.kernel.org:/ftp/pub/scm/linux/kernel/git/aegl/linux-2.6.git > .git/branches/origin + +and then push each of the test and release branches using: + + $ git push origin test +and + $ git push origin 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 +patches), and create a new branch from the current tip of the +linus branch: + + $ git checkout -b speed-up-spinlocks linus + +Now you apply the patch(es), run some tests, and commit the change(s). If +the patch is a multi-part series, then you should apply each as a separate +commit to this branch. + + $ ... patch ... test ... commit [ ... patch ... test ... commit ]* + +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" + +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. + +Some time later when enough time has passed and testing done, you can pull the +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" + +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 +they are for, or what status they are in. To get a reminder of what +changes are in a specific branch, use: + + $ git-whatchanged branchname ^linus | git-shortlog + +To see whether it has already been merged into the test or release branches +use: + + $ git-rev-list branchname ^test +or + $ git-rev-list branchname ^release + +[If this branch has not yet been merged you will see a set of SHA1 values +for the commits, if it has been merged, then there will be no output] + +Once a patch completes the great cycle (moving from test to release, then +pulled by Linus, and finally coming back into your local "linus" branch) +the branch for this change is no longer needed. You detect this when the +output from: + + $ git-rev-list branchname ^linus + +is empty. At this point the branch can be deleted: + + $ rm .git/refs/heads/branchname + +To create diffstat and shortlog summaries of changes to include in a "please +pull" request to Linus you can use: + + $ git-whatchanged -p release ^linus | diffstat -p1 +and + $ git-whatchanged release ^linus | git-shortlog + -- cgit v0.10.2-6-g49f6