# Equivalent of checking out an old commit?

**URL:** <https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176>\
**Category:** Question\
**Created:** [March 16, 2018, 4:45pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176 "2018-03-16T16:45:27Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mistodon](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.pijul.org/mistodon/32/101_2.png) [@Mistodon](https://discourse.pijul.org/u/Mistodon)\
**Post date:** [March 16, 2018, 4:45pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/1 "2018-03-16T16:45:27Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![pmeunier](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.pijul.org/pmeunier/32/4_2.png) [@pmeunier](https://discourse.pijul.org/u/pmeunier)\
**Post date:** [March 16, 2018, 5:12pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/2 "2018-03-16T17:12:06Z")

</div>

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).

---

<div class="post-metadata">

**Author:** ![yory](https://avatars.discourse-cdn.com/v4/letter/y/da6949/32.png) [@yory](https://discourse.pijul.org/u/yory)\
**Post date:** [March 16, 2018, 5:40pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/3 "2018-03-16T17:40:43Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![yory](https://avatars.discourse-cdn.com/v4/letter/y/da6949/32.png) [@yory](https://discourse.pijul.org/u/yory)\
**Post date:** [March 16, 2018, 5:59pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/4 "2018-03-16T17:59:40Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Mistodon](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.pijul.org/mistodon/32/101_2.png) [@Mistodon](https://discourse.pijul.org/u/Mistodon)\
**Post date:** [March 16, 2018, 7:19pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/5 "2018-03-16T19:19:29Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![pmeunier](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.pijul.org/pmeunier/32/4_2.png) [@pmeunier](https://discourse.pijul.org/u/pmeunier)\
**Post date:** [March 16, 2018, 8:19pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/6 "2018-03-16T20:19:11Z")

</div>

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).

---

<div class="post-metadata">

**Author:** ![tae](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.pijul.org/tae/32/81_2.png) [@tae](https://discourse.pijul.org/u/tae)\
**Post date:** [February 2, 2019, 9:12pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/7 "2019-02-02T21:12:25Z")

</div>

> [@Mistodon](#):
>
> A more important requirement for me is being able to rewind to any previous state of the repo non-destructively.

Same here. Wouldn’t it be possible to temporarily “turn off” or “hide” a patch?

---

<div class="post-metadata">

**Author:** ![lthms](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.pijul.org/lthms/32/124_2.png) [@lthms](https://discourse.pijul.org/u/lthms)\
**Post date:** [February 3, 2019, 6:19pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/8 "2019-02-03T18:19:40Z")

</div>

Note that there is a way now to do it, to some extent. You can use `pijul fork` with a patch hash, and it will build a new branch with just that this patches and all of its dependencies. Combined with tags, this gives you what you want (although not as precisely and systematically as git)

---

<div class="post-metadata">

**Author:** ![tae](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.pijul.org/tae/32/81_2.png) [@tae](https://discourse.pijul.org/u/tae)\
**Post date:** [February 3, 2019, 7:08pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/9 "2019-02-03T19:08:16Z")

</div>

This is something that I think is missing in the help and the manual. At least I cannot find it or I’m misinterpreting you: after I create a tag I can recover that state, right? Which command does that?

---

<div class="post-metadata">

**Author:** ![lthms](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.pijul.org/lthms/32/124_2.png) [@lthms](https://discourse.pijul.org/u/lthms)\
**Post date:** [February 3, 2019, 8:24pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/10 "2019-02-03T20:24:46Z")

</div>

`pijul fork --patch <hash of the tag> <name of the branch>`

---

<div class="post-metadata">

**Author:** ![tae](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.pijul.org/tae/32/81_2.png) [@tae](https://discourse.pijul.org/u/tae)\
**Post date:** [February 3, 2019, 10:14pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/11 "2019-02-03T22:14:03Z")

</div>

Added to the tutorial. Thanks!

---

<div class="post-metadata">

**Author:** ![fyr](https://avatars.discourse-cdn.com/v4/letter/f/b5ac83/32.png) [@fyr](https://discourse.pijul.org/u/fyr)\
**Post date:** [March 14, 2019, 4:52am UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/12 "2019-03-14T04:52:29Z")

</div>

A piece of git porcelain missing here is the `HEAD`, as distinct from a “branch checkout”. A `detached HEAD` is a state where you’re browsing history without the intent of checkouts or even commits ending up on any particular named branch.

(Frustratingly, in `git` the most common way to end up in one is to try to checkout a remote branch, where “make a local copy” would be a more reasonable default; a remote branch of course being by definition a read-only reference you cannot locally modify. When you explicitly check out a point in history, however, detached-HEAD semantics are in fact desirable)

On a related note, does pijul have any analogue of the git `reflog`? An append-only meta-history log of what branches have pointed to(and via HEAD, which ones you have had checked out) seems only more vital in a system where branches do not encode discrete sequences of past states.

---

<div class="post-metadata">

**Author:** ![unidual](https://avatars.discourse-cdn.com/v4/letter/u/91b2a8/32.png) [@unidual](https://discourse.pijul.org/u/unidual)\
**Post date:** [February 20, 2021, 6:40pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/13 "2021-02-20T18:40:46Z")

</div>

Now (1.0.0-alpha.38) it seems to be:

`pijul fork --change <hash of the tag> <name of the branch>`

I tried that, but then after `pijul channel switch <name of the branch>` it crashed.  
It left the directory in the same state, hence `pijul diff` shows all diff between the pointed change and the current state. It wasn’t what I expected, but I guess this is due to the crash.

---

<div class="post-metadata">

**Author:** ![pmeunier](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.pijul.org/pmeunier/32/4_2.png) [@pmeunier](https://discourse.pijul.org/u/pmeunier)\
**Post date:** [February 20, 2021, 6:52pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/14 "2021-02-20T18:52:33Z")

</div>

Oops, do you think you could report the details of the crash to [nest.pijul.com/pijul/pijul/discussions](http://nest.pijul.com/pijul/pijul/discussions)?

---

<div class="post-metadata">

**Author:** ![pmeunier](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.pijul.org/pmeunier/32/4_2.png) [@pmeunier](https://discourse.pijul.org/u/pmeunier)\
**Post date:** [February 20, 2021, 7:12pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/15 "2021-02-20T19:12:56Z")

</div>

Another thing I wanted to say about this: tags aren’t working at the moment, and that’s intentional. They depend on the ongoing rewrite of the backend, because they share some of its format, and while I don’t mind breaking the repository format (it’s annoying for everybody, and about 400 times more annoying for me, because I have to convert all of [nest.pijul.com](http://nest.pijul.com) in addition to my own repos), I don’t ever want to change the patch format again.

The only reason I’d change the patch format is to introduce a new feature that cannot be foreseen yet (even code movements might be able to use the current format).

---

<div class="post-metadata">

**Author:** ![unidual](https://avatars.discourse-cdn.com/v4/letter/u/91b2a8/32.png) [@unidual](https://discourse.pijul.org/u/unidual)\
**Post date:** [February 20, 2021, 7:24pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/16 "2021-02-20T19:24:42Z")

</div>

[Here it is](https://nest.pijul.com/pijul/pijul/discussions/338)

---

<div class="post-metadata">

**Author:** ![pmeunier](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.pijul.org/pmeunier/32/4_2.png) [@pmeunier](https://discourse.pijul.org/u/pmeunier)\
**Post date:** [February 20, 2021, 8:05pm UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/17 "2021-02-20T20:05:53Z")

</div>

Yes, I saw that, thanks!

---

<div class="post-metadata">

**Author:** ![unidual](https://avatars.discourse-cdn.com/v4/letter/u/91b2a8/32.png) [@unidual](https://discourse.pijul.org/u/unidual)\
**Post date:** [February 21, 2021, 5:53am UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/18 "2021-02-21T05:53:57Z")

</div>

Ps: I still don’t know if I should do `pijul channel switch` or `pijul reset --channel` after the `fork` command!

---

<div class="post-metadata">

**Author:** ![pmeunier](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.pijul.org/pmeunier/32/4_2.png) [@pmeunier](https://discourse.pijul.org/u/pmeunier)\
**Post date:** [February 21, 2021, 7:26am UTC](https://discourse.pijul.org/t/equivalent-of-checking-out-an-old-commit/176/19 "2021-02-21T07:26:08Z")

</div>

`pijul channel switch` is an alias to `pijul reset --channel`. I find the latter more intuitive, but we decided to add the alias to make the `pijul channel` command more complete.
