Equivalent of checking out an old commit?


Hi there! I’m looking into Pijul, mostly out of curiousity, and wondering how to accomplish the equivalent of checking out an old Git commit.

Say, for example, I notice compile times have drastically increased at some point, and I want to find out which patch caused it (possibly by bisecting). How would I accomplish that in Pijul?


Hi! thanks for your interest. We don’t have bisecting yet, but the way Pijul works is quite different from Git, you would have to unrecord individual patches in order to get back to a previous state.

The current way to do this is by (1) branching, in order to keep your current state, and (2) on the new branch, unrecording the patch you think might be causing the problem, then reverting to get the working copy back to that state.

This is all kind of tedious as of now, because only primitive operations are implemented, but we’d be delighted to hear feedback about how to make it easier. In particular, maybe there are easier workflows than bisect (Git does it because history in Git is sequential, we don’t have that restriction here).


I’ve been thinking about this too. Bisect is nice because often I don’t actually know what caused problems, so I say, let’s try to go completely back in time at X and see if it worked correctly back then. While this is would be possible in pijul too with the implementation I suggest, pijul’s model might lend itself to some interesting applications: say that now I found an untested bug; I don’t know what commit caused it yet, but I know how to test for it; so I commit a patch with the new test, then roll back each previous commit (leaving the new test applied), each time testing the repo against the new test (and it should be simple to make it automatic, say pijul bisect --exec "./my_testsuite"). This would be very cool and impossible with snapshot-based vcs, because those are roll-all-or-nothing.

Maybe the bisect command would be something like: pick the patches I want to unapply from a date-sorted list (for convenience + preserving git’s functionality); I can pick both item-by-item and by range (1, 3, 6-15). Interactive selection by default, but also scriptable. Optionally declare one or more commands to execute at each unapply event.


My main point is that if the testing is automatic we get rid of all the annoying manual fiddling (git start then git bisect than again than remember to clean up, etc).
This would also mean getting rid of the gradual halving algorithm; we can actually test all the patches we want, as it comes to little cost (unless the test takes a lot to run), than return a list of all failing patches, sorted meaningfully to help us catch the bug.


Thanks for that solution, even if it is currently a little manual.

Plus the alternative to bisecting there is a really cool idea.

Perhaps I distracted a little from my point though by bringing up bisecting. A more important requirement for me is being able to rewind to any previous state of the repo non-destructively. I realize that’s a very linear way of looking it at things, but it’s also important for reproducing the exact environment of a bug/degradation/etc.

So say every patch triggers a build on CI. Would it be best to create branches on every deploy to permit resetting to there?


Good question, it all depends on what you’re doing. Branches in Pijul are not meant to be used like in Git, in fact Git branches are more like patches in Pijul.

A branch in Pijul is a set of patch hashes, plus a representation of the repository state. That internal representation can be a little expensive in terms of space, but different branches share the parts of that they have in common.

So, if you have a branch, outputting its state to the working copy (using pijul revert) can be done in time linear in the size of the working copy. If you want to unrecord a patch, it’s more expensive: unrecording a single patch is linear in the size of the patch, and in the number of lines deleted by other patches around hunks deleted by this patch (this can be large).