Bk bisect --inplace

The current bk bisect command runs on a copy of the current repository in <repo>/BitKeeper/tmp/bisect. The reason for that is so bk can rollback to an older revision and be sure it still has the data to roll forward. And it removes most problems with local work or extra files in the repository.

This causes some people problems because a fresh clone of the repository will require a full rebuild of the repository which can be very slow. Even if the following builds in the bisect directory will be incremental. So they want bisect to run in the current repository.

I propose to add a --inplace option to bisect that will skip the initial clone to the tmp directory and will instead run in place. For this to be safe the code needs to be able to restore any csets removed. It could require that the local repo be a strict subset of the default parent, or it could still do the clone to BitKeeper/tmp/bisect and use that as the source for any csets to pull back in. Or perhaps we have an extra option to point at a local repository to use as a backup.

Other sanity checks I may want to run:

  1. No locally modify files or files with pending deltas
  2. No extra files that are not ignored

These might be intentional and could be OK if the region being checked doesn’t conflict with these and we recover from a failed pull or undo well. But banning these could reduce user errors.

When using --inplace and bisect completes successfully should the local repository the repository be restored to tip or left at the oldest cset that reproduces the problem. The problem with not restoring the tip is that we have to keep the BitKeeper/tmp/bisect data and the user might not know where to find it.

@martindorey, thoughts on what semantics you guys would want?

A related request would be an interactive mode for bisect rather than requiring a script to evaluate each cset, but I will create a new topic for this idea when I get around to it.

The reason for that is so bk can rollback to an older revision and be sure it still has the data to roll forward. And it removes most problems with local work or extra files in the repository.

Ah, right, now it makes sense.

It could require that the local repo be a strict subset of the default parent

That sounds elegant to me and I imagine it’d be fine.

banning these could reduce user errors.

I agree and, further, banning them doesn’t seem like much of a hardship. Committing any half-finished work, so it could be pulled aside and undone, that’s easy. I always have a place to pull such things and cloning within a file system is cheap. It’s building that isn’t, for us.

should the local repository the repository be restored to tip or left at the oldest cset that reproduces the problem

I’d be more tempted to leave it wherever the last test was run, which might not be either. If the user wants to pay for extra rebuilds, they can choose to do so.

I did skim the git help bisect page but I have to admit that I’ve never used either it or bk bisect, so I’m not in the best place to make suggestions that would be minimally surprising to users from there. I’ve encouraged our advocate for this feature to contribute here.

I’ll propose more work than you need to do, which might make sense if the intermediate step is also something that is wanted: I’ve wanted a nested makepatch. And then a nested takepatch with a -r$REV option to apply the patch as though $REV is tip (which some of the ability is there in fastepatch to be able to ignore some of the contents of the patch). Then bisect could makepatch to BitKeeper/tmp/bisect.patch and takepatch from there to recover. More work, but with the side effect of then having a nested makepatch.

Pragmatically, what you propose sounds fine: pull from remote or clone local and pull from it.

That would be a very fast solution to the problem and have makepatch/takepatch work again would be very useful in general. At the very least the solution should be structured so the implementation can use this solution in the future.

I don’t think it would be that hard to extend makepatch to do multiple repos.

# User:     lm
# Host:     ansel.mcvoy.com
# Root:     /home/lm/bk/dev-oss/src/t

# Patch vers:       1.5
# Patch features:   BKMERGE,NESTED

== Repository ==
src/t

== ChangeSet ==

<normal patch contents>

# Patch checksum=e2a2fdd8

== Repository ==
src/gnu/patch

== ChangeSet ==
<normal patch contents>

# Patch checksum=a2e3fdd8

You could do that in a script easily enough.

Then takepatch needs to go into iterate mode when it sees the NESTED feature
in patch features.

There are the usual locking issues and rollback on failure, might be worth
it to swing through the whole patch verifying checksums and checking that
each file is there, no pending, no mods. But even so, it needs to be
atomic.

–lm

That won’t work, it needs

== Repository ==
ChangeSet rootkey

....

So Rick, what is it you want from a nested takepatch? Were you looking for performance (because parallelism is there to be had though resolve gets weird if there are conflicts)?

Or just a one file patch so you can fake branches and work on something, pop it off, work on something else?

nested patches

Mostly lightweight archive, but also simple transport (mail myself a patch, to apply on a different machine later). As well as performance to save from running makepatch N times and possibly save moving the patch over the wire. So not a single thing. And that it fit here.
Not a priority, but something that I noticed I missed because working in a nested repo made something I used to do harder or less efficient as it would be in bisect.