Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | |
| 2 | Doing the BK Thing, Penguin-Style |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | This set of notes is intended mainly for kernel developers, occasional |
| 8 | or full-time, but sysadmins and power users may find parts of it useful |
| 9 | as well. It assumes at least a basic familiarity with CVS, both at a |
| 10 | user level (use on the cmd line) and at a higher level (client-server model). |
| 11 | Due to the author's background, an operation may be described in terms |
| 12 | of CVS, or in terms of how that operation differs from CVS. |
| 13 | |
| 14 | This is -not- intended to be BitKeeper documentation. Always run |
| 15 | "bk help <command>" or in X "bk helptool <command>" for reference |
| 16 | documentation. |
| 17 | |
| 18 | |
| 19 | BitKeeper Concepts |
| 20 | ------------------ |
| 21 | |
| 22 | In the true nature of the Internet itself, BitKeeper is a distributed |
| 23 | system. When applied to revision control, this means doing away with |
| 24 | client-server, and changing to a parent-child model... essentially |
| 25 | peer-to-peer. On the developer's end, this also represents a |
| 26 | fundamental disruption in the standard workflow of changes, commits, |
| 27 | and merges. You will need to take a few minutes to think about |
| 28 | how to best work under BitKeeper, and re-optimize things a bit. |
| 29 | In some sense it is a bit radical, because it might described as |
| 30 | tossing changes out into a maelstrom and having them magically |
| 31 | land at the right destination... but I'm getting ahead of myself. |
| 32 | |
| 33 | Let's start with this progression: |
| 34 | Each BitKeeper source tree on disk is a repository unto itself. |
| 35 | Each repository has a parent (except the root/original, of course). |
| 36 | Each repository contains a set of a changesets ("csets"). |
| 37 | Each cset is one or more changed files, bundled together. |
| 38 | |
| 39 | Each tree is a repository, so all changes are checked into the local |
| 40 | tree. When a change is checked in, all modified files are grouped |
| 41 | into a logical unit, the changeset. Internally, BK links these |
| 42 | changesets in a tree, representing various converging and diverging |
| 43 | lines of development. These changesets are the bread and butter of |
| 44 | the BK system. |
| 45 | |
| 46 | After the concept of changesets, the next thing you need to get used |
| 47 | to is having multiple copies of source trees lying around. This -really- |
| 48 | takes some getting used to, for some people. Separate source trees |
| 49 | are the means in BitKeeper by which you delineate parallel lines |
| 50 | of development, both minor and major. What would be branches in |
| 51 | CVS become separate source trees, or "clones" in BitKeeper [heh, |
| 52 | or Star Wars] terminology. |
| 53 | |
| 54 | Clones and changesets are the tools from which most of the power of |
| 55 | BitKeeper is derived. As mentioned earlier, each clone has a parent, |
| 56 | the tree used as the source when the new clone was created. In a |
| 57 | CVS-like setup, the parent would be a remote server on the Internet, |
| 58 | and the child is your local clone of that tree. |
| 59 | |
| 60 | Once you have established a common baseline between two source trees -- |
| 61 | a common parent -- then you can merge changesets between those two |
| 62 | trees with ease. Merging changes into a tree is called a "pull", and |
| 63 | is analagous to 'cvs update'. A pull downloads all the changesets in |
| 64 | the remote tree you do not have, and merges them. Sending changes in |
| 65 | one tree to another tree is called a "push". Push sends all changes |
| 66 | in the local tree the remote does not yet have, and merges them. |
| 67 | |
| 68 | From these concepts come some initial command examples: |
| 69 | |
| 70 | 1) bk clone -q http://linux.bkbits.net/linux-2.5 linus-2.5 |
| 71 | Download a 2.5 stock kernel tree, naming it "linus-2.5" in the local dir. |
| 72 | The "-q" disables listing every single file as it is downloaded. |
| 73 | |
| 74 | 2) bk clone -ql linus-2.5 alpha-2.5 |
| 75 | Create a separate source tree for the Alpha AXP architecture. |
| 76 | The "-l" uses hard links instead of copying data, since both trees are |
| 77 | on the local disk. You can also replace the above with "bk lclone -q ..." |
| 78 | |
| 79 | You only clone a tree -once-. After cloning the tree lives a long time |
| 80 | on disk, being updating by pushes and pulls. |
| 81 | |
| 82 | 3) cd alpha-2.5 ; bk pull http://gkernel.bkbits.net/alpha-2.5 |
| 83 | Download changes in "alpha-2.5" repository which are not present |
| 84 | in the local repository, and merge them into the source tree. |
| 85 | |
| 86 | 4) bk -r co -q |
| 87 | Because every tree is a repository, files must be checked out before |
| 88 | they will be in their standard places in the source tree. |
| 89 | |
| 90 | 5) bk vi fs/inode.c # example change... |
| 91 | bk citool # checkin, using X tool |
| 92 | bk push bk://gkernel@bkbits.net/alpha-2.5 # upload change |
| 93 | Typical example of a BK sequence that would replace the analagous CVS |
| 94 | situation, |
| 95 | vi fs/inode.c |
| 96 | cvs commit |
| 97 | |
| 98 | As this is just supposed to be a quick BK intro, for more in-depth |
| 99 | tutorials, live working demos, and docs, see http://www.bitkeeper.com/ |
| 100 | |
| 101 | |
| 102 | |
| 103 | BK and Kernel Development Workflow |
| 104 | ---------------------------------- |
| 105 | Currently the latest 2.5 tree is available via "bk clone $URL" |
| 106 | and "bk pull $URL" at http://linux.bkbits.net/linux-2.5 |
| 107 | This should change in a few weeks to a kernel.org URL. |
| 108 | |
| 109 | |
| 110 | A big part of using BitKeeper is organizing the various trees you have |
| 111 | on your local disk, and organizing the flow of changes among those |
| 112 | trees, and remote trees. If one were to graph the relationships between |
| 113 | a desired BK setup, you are likely to see a few-many-few graph, like |
| 114 | this: |
| 115 | |
| 116 | linux-2.5 |
| 117 | | |
| 118 | merge-to-linus-2.5 |
| 119 | / | | |
| 120 | / | | |
| 121 | vm-hacks bugfixes filesys personal-hacks |
| 122 | \ | | / |
| 123 | \ | | / |
| 124 | \ | | / |
| 125 | testing-and-validation |
| 126 | |
| 127 | Since a "bk push" sends all changes not in the target tree, and |
| 128 | since a "bk pull" receives all changes not in the source tree, you want |
| 129 | to make sure you are only pushing specific changes to the desired tree, |
| 130 | not all changes from "peer parent" trees. For example, pushing a change |
| 131 | from the testing-and-validation tree would probably be a bad idea, |
| 132 | because it will push all changes from vm-hacks, bugfixes, filesys, and |
| 133 | personal-hacks trees into the target tree. |
| 134 | |
| 135 | One would typically work on only one "theme" at a time, either |
| 136 | vm-hacks or bugfixes or filesys, keeping those changes isolated in |
| 137 | their own tree during development, and only merge the isolated with |
| 138 | other changes when going upstream (to Linus or other maintainers) or |
| 139 | downstream (to your "union" trees, like testing-and-validation above). |
| 140 | |
| 141 | It should be noted that some of this separation is not just recommended |
| 142 | practice, it's actually [for now] -enforced- by BitKeeper. BitKeeper |
| 143 | requires that changesets maintain a certain order, which is the reason |
| 144 | that "bk push" sends all local changesets the remote doesn't have. This |
| 145 | separation may look like a lot of wasted disk space at first, but it |
| 146 | helps when two unrelated changes may "pollute" the same area of code, or |
| 147 | don't follow the same pace of development, or any other of the standard |
| 148 | reasons why one creates a development branch. |
| 149 | |
| 150 | Small development branches (clones) will appear and disappear: |
| 151 | |
| 152 | -------- A --------- B --------- C --------- D ------- |
| 153 | \ / |
| 154 | -----short-term devel branch----- |
| 155 | |
| 156 | While long-term branches will parallel a tree (or trees), with period |
| 157 | merge points. In this first example, we pull from a tree (pulls, |
| 158 | "\") periodically, such as what occurs when tracking changes in a |
| 159 | vendor tree, never pushing changes back up the line: |
| 160 | |
| 161 | -------- A --------- B --------- C --------- D ------- |
| 162 | \ \ \ |
| 163 | ----long-term devel branch----------------- |
| 164 | |
| 165 | And then a more common case in Linux kernel development, a long term |
| 166 | branch with periodic merges back into the tree (pushes, "/"): |
| 167 | |
| 168 | -------- A --------- B --------- C --------- D ------- |
| 169 | \ \ / \ |
| 170 | ----long-term devel branch----------------- |
| 171 | |
| 172 | |
| 173 | |
| 174 | |
| 175 | |
| 176 | Submitting Changes to Linus |
| 177 | --------------------------- |
| 178 | There's a bit of an art, or style, of submitting changes to Linus. |
| 179 | Since Linus's tree is now (you might say) fully integrated into the |
| 180 | distributed BitKeeper system, there are several prerequisites to |
| 181 | properly submitting a BitKeeper change. All these prereq's are just |
| 182 | general cleanliness of BK usage, so as people become experts at BK, feel |
| 183 | free to optimize this process further (assuming Linus agrees, of |
| 184 | course). |
| 185 | |
| 186 | |
| 187 | |
| 188 | 0) Make sure your tree was originally cloned from the linux-2.5 tree |
| 189 | created by Linus. If your tree does not have this as its ancestor, it |
| 190 | is impossible to reliably exchange changesets. |
| 191 | |
| 192 | |
| 193 | |
| 194 | 1) Pay attention to your commit text. The commit message that |
| 195 | accompanies each changeset you submit will live on forever in history, |
| 196 | and is used by Linus to accurately summarize the changes in each |
| 197 | pre-patch. Remember that there is no context, so |
| 198 | "fix for new scheduler changes" |
| 199 | would be too vague, but |
| 200 | "fix mips64 arch for new scheduler switch_to(), TIF_xxx semantics" |
| 201 | would be much better. |
| 202 | |
| 203 | You can and should use the command "bk comment -C<rev>" to update the |
| 204 | commit text, and improve it after the fact. This is very useful for |
| 205 | development: poor, quick descriptions during development, which get |
| 206 | cleaned up using "bk comment" before issuing the "bk push" to submit the |
| 207 | changes. |
| 208 | |
| 209 | |
| 210 | |
| 211 | 2) Include an Internet-available URL for Linus to pull from, such as |
| 212 | |
| 213 | Pull from: http://gkernel.bkbits.net/net-drivers-2.5 |
| 214 | |
| 215 | |
| 216 | |
| 217 | 3) Include a summary and "diffstat -p1" of each changeset that will be |
| 218 | downloaded, when Linus issues a "bk pull". The author auto-generates |
| 219 | these summaries using "bk changes -L <parent>", to obtain a listing |
| 220 | of all the pending-to-send changesets, and their commit messages. |
| 221 | |
| 222 | It is important to show Linus what he will be downloading when he issues |
| 223 | a "bk pull", to reduce the time required to sift the changes once they |
| 224 | are downloaded to Linus's local machine. |
| 225 | |
| 226 | IMPORTANT NOTE: One of the features of BK is that your repository does |
| 227 | not have to be up to date, in order for Linus to receive your changes. |
| 228 | It is considered a courtesy to keep your repository fairly recent, to |
| 229 | lessen any potential merge work Linus may need to do. |
| 230 | |
| 231 | |
| 232 | 4) Split up your changes. Each maintainer<->Linus situation is likely |
| 233 | to be slightly different here, so take this just as general advice. The |
| 234 | author splits up changes according to "themes" when merging with Linus. |
| 235 | Simultaneous pushes from local development go to special trees which |
| 236 | exist solely to house changes "queued" for Linus. Example of the trees: |
| 237 | |
| 238 | net-drivers-2.5 -- on-going net driver maintenance |
| 239 | vm-2.5 -- VM-related changes |
| 240 | fs-2.5 -- filesystem-related changes |
| 241 | |
| 242 | Linus then has much more freedom for pulling changes. He could (for |
| 243 | example) issue a "bk pull" on vm-2.5 and fs-2.5 trees, to merge their |
| 244 | changes, but hold off net-drivers-2.5 because of a change that needs |
| 245 | more discussion. |
| 246 | |
| 247 | Other maintainers may find that a single linus-pull-from tree is |
| 248 | adequate for passing BK changesets to him. |
| 249 | |
| 250 | |
| 251 | |
| 252 | Frequently Answered Questions |
| 253 | ----------------------------- |
| 254 | 1) How do I change the e-mail address shown in the changelog? |
| 255 | A. When you run "bk citool" or "bk commit", set environment |
| 256 | variables BK_USER and BK_HOST to the desired username |
| 257 | and host/domain name. |
| 258 | |
| 259 | |
| 260 | 2) How do I use tags / get a diff between two kernel versions? |
| 261 | A. Pass the tags Linus uses to 'bk export'. |
| 262 | |
| 263 | ChangeSets are in a forward-progressing order, so it's pretty easy |
| 264 | to get a snapshot starting and ending at any two points in time. |
| 265 | Linus puts tags on each release and pre-release, so you could use |
| 266 | these two examples: |
| 267 | |
| 268 | bk export -tpatch -hdu -rv2.5.4,v2.5.5 | less |
| 269 | # creates patch-2.5.5 essentially |
| 270 | bk export -tpatch -du -rv2.5.5-pre1,v2.5.5 | less |
| 271 | # changes from pre1 to final |
| 272 | |
| 273 | A tag is just an alias for a specific changeset... and since changesets |
| 274 | are ordered, a tag is thus a marker for a specific point in time (or |
| 275 | specific state of the tree). |
| 276 | |
| 277 | |
| 278 | 3) Is there an easy way to generate One Big Patch versus mainline, |
| 279 | for my long-lived kernel branch? |
| 280 | A. Yes. This requires BK 3.x, though. |
| 281 | |
| 282 | bk export -tpatch -r`bk repogca bk://linux.bkbits.net/linux-2.5`,+ |
| 283 | |