How to Use BitKeeper
Contents |
← Back to MySQL University main page
[edit] How to Use BitKeeper
- Date: 2007-11-15
- Presenter: Sergei Golubchik
- Scribe: Paul DuBois
- Attendees (please register by filling in your name below, and read the Instructions for Attendees):
- Philip Stoev
- Davi Arnaut
- Rayson Ho
- Peter Lavin
- Timour
- Shawn Green
- Morgan Tocker
- ...
[edit] Presentation
[edit] basic concepts
- terms
- package, e.g. "MySQL"
- repository
- sfile, gfile, see bk help filetypes
- delta: one file change. A difference between two consecutive file versions. delta number is NOT persistent
- changeset: a group of deltas, quantum of data exchange between repositories, you don't push or pull deltas - only changesets as a whole. changeset number is NOT persistent
- key (package, repo, file, delta, cset). a key IS persistent. bk commit mails include changeset key
- see bk help terms
- distributed system
- no central repository, no client-server. peer-to-peer instead
- every clone is complete, everything is stored locally
- that means: you commit locally, there're no remove commits.
- you can examine the history locally, no need to access the network for it
- the only "remote" operation - changeset exchange with another repository
- local clones as branches
- no cherry-picking
- every changeset implicitly depends on all previous changesets in the tree
- changeset cannot be added to a tree if dependencies are missing
[edit] our setup
- main tree
- peer-to-peer, but some trees are more equal than others
- a trees on bk-internal
- branches
- mysql-5.1 is a clone of mysql-5.0, mysql-5.0 is a clone of mysql-4.1, etc
- team trees
- every team has its own tree, a clone of main
- public trees: http://mysql.bkbits.net
- triggers
- commit email
- pushbuild
- bugdb 'pushed into'
[edit] workflow
- clone a tree (main, team, your local: [bk clone]) or
- update your local clone [bk pull]
- edit files [bk edit], fix a bug, test it
- group the changes in a changeset [bk citool]
- wait for review, correct the patch if necessary [bk fix -c]
- send your changes to the parent [bk push]
- it may require merging if the parent is ahead of your tree [bk pull and bk resolve]
[edit] bk commands overview
- help
- https://inside.mysql.com/wiki/BitKeeper
- bk helptool - graphical front-end to the BitKeeper help system
- workflow
- bk clone - create a new copy of a package
- bk pull - update a repository from its parent[s]
- bk resolve - merge and/or apply new work after a pull
- bk citool - BitKeeper graphical check-in tool
- bk collapse - combine recent changesets into a single unit of work
- bk push - send local changes to parent repository
- bk send and bk receive - push/pull analogs over email
- bk fix -c - "uncommit" a committed patch to apply post-review changes
- bk unedit - destroy any unchecked in changes to specified files
- bk stripdel - strip deltas out of an sfile
- bk undo - Undo a changeset or set of changesets
- bk unpull - remove changesets added by bk pull
- examining history
- bk changes - show changeset history
- bk changes -/.../ (-/#12345/)
- bk changes -u... (-userg)
- bk changes -c... (-c-10d)
- bk changes -r... (-rmysql-5.0.44..mysql-5.0.46)
- bk changes -vvv
- bk csettool - BitKeeper graphical changeset browser
- bk csets - run changes or csettool on last set of incoming changes
- bk difftool - BitKeeper graphical differences viewer
- bk revtool - BitKeeper graphical history browser
- to diff two revisions of a file in bk revtool: left mouseclick on one revision, right mouseclick on the other
- bk treediff - compare two directory trees
- bk grep - search some/all revisions of one or more files for a pattern
- bk changes - show changeset history
- file ops: simply add 'bk'
- bk chmod - change the mode of a file and save it
- bk cp - create a copy of a file preserving its revision history
- bk mv - rename file[s]
- bk rm - remove BitKeeper file[s]
- bk rmdir - remove a BitKeeper directory
- bk unrm - resurrect a removed BitKeeper file
- admin
- bk setuptool - create a new BitKeeper package
- bk admin - administer BitKeeper files
- bk check - check repository for consistency
- bk help config-etc - configuring BitKeeper
- bk help config-gui - configuration for BitKeeper graphical tools
- bk ignore - ignore shell glob patterns
- bk gone - mark a file (key) as gone
- bk rmgone - remove files having keys in the gone file
- scripting
- bk gnupatch - generate traditional patches
- bk repogca - show greatest common ancestor across a set of repositories
- bk root - print the path name to the root of the repository
- bk log - print file revision history and/or metadata
- a.k.a. bk prs
- example from post-commit trigger
% bk -R log -r+ -h -d':P:::I:' ChangeSet serg:1.2598
- bk rset - generate a "release set"
- from post-commit trigger:
- bk rset - generate a "release set"
bk rset -r+ -ah | bk gnupatch -h -dup -T
- bk parent - manage repository parent pointer[s]
- bk sfiles - generate lists of BitKeeper controlled files
- example: all changed files
- bk -r sfiles -c
- example: all changed files
- bk lock - lock a repository or show lockers
- bk unlock - remove BitKeeper file or repository locks
- bk upgrade - upgrade to, or check for, new versions of BitKeeper
- how to use w/o GUI
- bk help - get help for BitKeeper commands
- bk setup - create a new BitKeeper package
- bk co - check out BitKeeper files
- also bk edit
- bk ci - check in modified files
- also bk new
- bk comments - change checkin comments
- bk commit - commit deltas to a changeset
- bk annotate - provide annotated listings of one or more source files
- bk diffs - show differences in revision controlled files
- bk pending - list deltas which need to be in a changeset
[edit] FAQ, bk tips and tricks
- how to install
- see https://inside.mysql.com/wiki/BitKeeper
- download the installer from bk site, run it
- set REAL_EMAIL
- install the license
- BK_CONFIG or /etc/BitKeeper/etc/config
- how to merge
- you may need to merge manually, resolve merge conflicts after a pull (or bk receive)
- bk resolve
- '?' for help
- 'p' command
- 'e' command
- I personally find 'f' (three-way graphical merge) useless
- merge helper scripts
- how to undo a merge
- bk unpull
- bk undo -aREV
- who wrote that ? (interactive)
- you have 5.1 tree, I assume ?
- dark secrets of bk gone
- the first rule of using bk gone: you don't use bk gone
- by far the easiest way to corrupt a tree
- cannot be undone (BitKeeper/etc/gone is append-only)
- takes a KEY, not a filename !!!
- mostly harmless until bk rmgone (or manual rm)
- but also useless
- after bk rmgone you cannot pull a changeset that contains a delta for a file that you've marked gone
- the repository is basically corrupted
- unless a file is gone in 4.0 - it's unsafe to mark a file gone in any upper version
- if a file is gone in 4.0, you don't need to mark a file gone in any upper version
- so - don't
- local mirrors
- use bk clone -l
- bk repogca
- explained here: https://inside.mysql.com/wiki/HowToPush
- good: you don't need to merge others' changes
- bad: somebody still have to merge, you're pushing your work onto others
- bad: trees start diverging, merge changesets never get merged upwards
- copying bk trees (e.g. with cp or tar)
- the problem: "cannot connect to same repo ID"
- backup
- full
- everything
- reasonably small
- only SCCS directories
- BitKeeper/log
- bk sfiles -gcx
- minimal
- BitKeeper/log
- bk sfiles -gcx
- bk send -u`bk parent -l` -
- beware multiple restores!
- full
- how to fix a broken tree
- ERROR-can't connect to same repo_id
- solution - clone one of the copies
- ERROR-Lock fail: possible permission problem
- ERROR-Unable to lock repository for update
- ERROR-cannot cd to /home/bk/mysql-5.1
- problems on bk-internal
- but most often: you're not in bk group
- File is marked as gone in this repository and therefor cannot accept updates.
- bk gone gone bad
- solution: bk clone -rrepogca a remote repository
- copy sfile of a file in question into your tree
- Missing delta (bk help chk2) in extra/yassl/taocrypt/src/coding.cpp
- latest bk corruption because of rsync migration
- solution - copy s.coding.cpp from a good tree
- ERROR-can't connect to same repo_id
[edit] bk tuning
- BitKeeper/etc/config: per-user/host/path settings
[serg:]checkout:get checkout:edit
- templates: BitKeeper/templates/*
- triggers: BitKeeper/triggers/*
- shell scripts (name, _name)
% cat ~/bin/_grepw #!/bin/sh bk grep -Hn "\<$1\>"
- merge helpers
- use as !bk-eb at the bk resolve prompt
% cat ~/bin/bk-e
#!/bin/sh
# was bk_manual_resolve by Monty
file=/tmp/resolve.$$
diff -u $BK_GCA $BK_REMOTE > $file
cp $BK_LOCAL $BK_MERGE
patch $BK_MERGE $file
if test -f ${BK_MERGE}.rej
then
echo Patch failed. You need to do this manually.
gvim -o -f $BK_MERGE ${BK_MERGE}.rej
fi
rm $file
% cat ~/bin/bk-eb
#!/bin/sh
file=/tmp/resolve.$$
diff -ub $BK_GCA $BK_REMOTE > $file
cp $BK_LOCAL $BK_MERGE
patch -l $BK_MERGE $file
if test -f ${BK_MERGE}.rej
then
echo Patch failed. You need to do this manually.
gvim -o -f $BK_MERGE ${BK_MERGE}.rej
fi
rm $file
% cat ~/bin/bk-dl #!/bin/sh diff -up $BK_GCA $BK_LOCAL
% cat ~/bin/bk-dlm #!/bin/sh diff -up $BK_LOCAL $BK_MERGE
% cat ~/bin/bk-dr #!/bin/sh diff -up $BK_GCA $BK_REMOTE
% cat ~/bin/bk-drm #!/bin/sh diff -up $BK_REMOTE $BK_MERGE
- ~/.bk/config-gui: gui config with the full power of tcl/tk
- documented example: different colors depending on the screen size
if {[winfo screenwidth .] <= 1024} {
# These show up better on LCD displays.
set gc(oldColor) lightseagreen
set gc(newColor) gray
set gc(fm3.handColor) yellow
}
- extension examples:
- ignore whitespace in difftool
- prev/next cset in csettool
- you'll need old bk release with plain-text gui to know variable names
proc csettool_mod {} {
proc nextCset {} {
global fileCount lastFile Files
set line $Files($lastFile)
if {$lastFile == $fileCount} { return }
while {$lastFile < $fileCount} {
incr lastFile
incr line
if {$Files($lastFile) > $line} { break }
}
dotFile
}
proc prevCset {} {
global fileCount lastFile Files
set line $Files($lastFile)
if {$lastFile == 1} { return }
while {$lastFile > 1} {
incr lastFile -1
incr line -1
if {$Files($lastFile) < $line} { break }
}
dotFile
}
bind all <Alt-n> nextCset
bind all <Alt-p> prevCset
pack .menu.nextCset -after .menu.help -side left -fill y
pack .menu.prevCset -after .menu.help -side left -fill y
}
switch [file tail $::argv0] {
csettool {
after 2000 csettool_mod
}
difftool {
while {$::argc >= 0} {
set a [lindex $::argv 0]
if {[regexp -- {^-[-A-Za-qs-z].*} $a]} {
set ::sdiffw [concat $::sdiffw $a]
incr ::argc -1
set ::argv [lreplace $::argv 0 0]
} else {
break
}
}
}
}
[edit] vim tricks
let bkroot=system('echo -n `bk root`')
let &tags=bkroot . "/tags"
let &path=".," . bkroot . "/include,/usr/include,,"
menu 90.400 B&K.&Edit :!bk edit %<CR><CR><CR>:e!<CR>
menu 90.500 B&K.&Unedit :!bk unedit %<CR><CR><CR>:e!<CR>
menu 90.600 B&K.&Difftool :!sh -c 'bk difftool -b % >/dev/null 2>/dev/null' &<CR><CR>
menu 90.700 B&K.&Revtool :!sh -c 'bk revtool % >/dev/null 2>/dev/null'&<CR><CR>
[edit] Questions
[edit] Questions asked during the session
- bk collapse - in order to have multiple changesets to collapse, you have to have pushed several changesets already, right? If you haven't pushed any changesets then the next changeset you push is already a collapsed set of your changes, right?
- No. If you haven't pushed any changesets, you push a set of changesets. If you want a set of changesets to be pushed as one changeset, you collapse them.
- so pushing is not how to create changesets?
- No. You can create any number of changesets locally. push is how you exchange changesets.
- about repogca: You said it leaves unmerged changesets - but I feel you can still merge them up and so avoid them, at the cost of having empty merge changesets in the tree. Any negative side of that ?
- [listen to voice stream for example]
- If I pull the main tree from 5.1 will I also get all changesets back to 4.0? or will the history of 5.1 start only at the point it was cloned from 5.0 ?
- If you pull from 5.1, you get the history all the way back to 3.23, the original repository.
- Why not create a "clean" clone as we branch new versions? (with no history before the clone ?)
- A repository w/o history is not very useful. Also, you cannot pull changesets from earlier releases (e.g., cannot pull 5.0 changes into 5.1)
- Is there an alternative to "repogca" to avoid unmerged changesets ?
- Not that I know of.
- is it better to try to merge locally before pushing a changeset or to push and merge into the destination tree?
- You cannot merge remotely.
[edit] Voice recording and other links
- Voice Recording: Ogg Audio (13MB)
- IRC log: IRC Text (5KB)
