Surprising behaviours

Hi, new(b) here! Mathematician at heart, I’m very inclined to (ab)use pijul.

Here is some feedback I have about unexpected or unintuitive behaviours (in my book).
Well, maybe I was just confused by workflows descriptions intended to the previous incarnation of pijul.

That’s the first issue: it’s hard to decipher what has become obsolete or even erroneous advice.

I love the cherry picking potential of the patch approach. E.g. to have a custom set of features, to activate or deactivate easily experimental and debugging patches, etc. But then I was a bit surprised:

  • After pijul record, the directory is still in the same state. Well, the opposite would be even more surprising! But as I understand it, that means the patch is applied. So, I expected:
    • a message about that.
    • the possibility to unapply.
      Also, I’m not sure what the log is showing. I’d like to see all patches, where the applied ones would be highlighted.

The goal was to get the directory in a previous state, yet still having the patch available to re-pick it at will. I am not sure of how to do that confidently without losing my changes!

Other surprise: at some point I did pijul add . (note the dot), but it ended including files from parent directory (according to the record message).
I removed the hunks I didn’t want from the message. But they were still included in the record.

So I tried an other approach: unrecord, and added explicitly the files I wanted in this particular record.
Then pijul diff --short shows all modified files (No way to see which one will be included in the record).
Plus, when recording again, the message was gone.


  • Could commit be made an alias for record? This would be more welcoming to long time git users. Possible mitigation:

    • Display an helpful error message (e.g. "No such command commit. Did you mean record?).
    • Give a tip to setup an alias (e.g. c) which would expand to git commit when we are in a git directory, and pijul record in a pijul directory. The link to the tip should be visible (e.g. in quickstart doc).
  • An undo command, which would exactly cancel any previous non-undo command (redo to undo the undo!).
    I’m still baffled no CVS offers that. Well, if the internal history is modified, that’s harder, unless having a meta-history (and turtles all the way down).

Hoping these remarks will be useful, I thank you for your work and the ability to have a sane git alternative or a fast darcs one!



Thanks for such a detailed list of suggestions! This is very helpful. The whole thing is a mess at the moment, because I’ve been caught in a massive invisible change, supposed to make Pijul at least five times faster, but at the cost of changing the data representation.

In particular, I love your suggestions about messages, and it would be really helpful if you could copy-paste them as separate discussions on nest.pijul.com/pijul/pijul/discussions.

You can use pijul unrecord HASH, where HASH is the hash given at the end of pijul record.

I’m afraid that could be more welcoming for Git beginners, but has a high confusion potential for advanced Git users, since they would start to believe that patches and commits are the same thing, and could get the wrong mental model. This isn’t a major problem, because you can simulate the behaviour of Git inside Pijul, but you would probably not benefit from Pijul very much if you did that (you’d just get Git + predictable merges and clean conflict resolutions).

For the same reason, we renamed “branches” to “channels” recently, to avoid the same kind of confusion (feature branches in Git are closer to “changes” in Pijul, while long-term branches in Git are closer to channels in Pijul).

Note that Darcs (a major source of inspiration for Pijul) didn’t have branches, so we’re still figuring out when branches are useful and when they aren’t.

1 Like

IMO that wouldn’t be so bad. Especially if git users could start using Pijul as a drop-in replacement for the usual git workflows, but the road to using more advanced Pijul features is still open.

Thanks for the quick and informative answer, really appreciated!

Fair enough for record vs commit. Backward pseudo-compatibility is a plague!
That being said, i think the model is similar regarding the patches: an isolated change we want to annotate/explain. And the workflow should be very similar too: make changes (ideally with respect to only one aspect), pack your changes (that is, record/commit them), repeat.
What differs is the repository state: sequence of patches vs set of (augmented) patches.
But even there, we tend to reason in term of snapshot. E.g.: I want to go back at the time of this particular patch, before the psilocybin started kicking it. I don’t really care which older patches it depends on.
That being said, that is very sweet that the a new channel doesn’t pull the entire history!
Or maybe i was just brain-washed?

I’ve seen that, but as said we lose the record message. Worse, that’s not what I need! I don’t want the patch applied at all in the working dir.
The use case here is to have some patches (e.g. old school print debugging, experimental variants) to switch on/off very easily. Like git stash or mercurial queue.
If the only way is to create a different channel, we lose the combinatorial advantage of independent patches. What am I missing here?

Will do!

Sorry, I misunderstood your suggestion. One way to do that is that pijul diff outputs the same format as pijul record, and doesn’t apply the patch, so you could pipe that into patch files somewhere (maybe a new .pijul/stash directory?), and apply/unrecord them using pijul apply/pijul unrecord. The semantics of pijul apply is a bit confusing, IIRC it expects a patch in text format on the standard input.

I don’t think you would miss that, channels are just sets of patches. If you create a debugging channel with your old school messages, this clones your patches from main. You can then record your debugging patches in the debugging channel, switch back to main, continue your work. Every time you want to switch again, you can push to debugging (pijul push . --to-channel debugging).

I’m struggling to understand the point of channels. In this example, wouldn’t it make more sense to clone the repo into a new folder and apply the change? What benefit does a channel give you? Doesn’t it clutter the repository? Or is it really more like tags, preserving a snapshot of a certain state?

Not necessarily. Darcs does that, at a great cost in terms of time and disk space. Channels can be used for many things, including indeed an efficient way to pinpoint a version (as you said, although that will be a bit redundant with tags, which are another representation of channels).

One major use case for Pijul was my use of nixpkgs, of which I’ve run a customised version for some times on a server, at the same time as contributing to their Git repository. That forced me to merge and rebase stuff often, and maintain multiple branches, but the lack of commutation + lack of identity of commits between the different branches + very long review time (Nix was a small community at the time) was annoying.

What I meant is that if I have N patches I wish to play with, I don’t want to create 2^N channels with all possible combinations!

I guess your suggestion could work:

  • record + unrecord + diff > ~/.patch/ouli + reset to create such a patch and shelve it.
  • apply < ~/.patch/ouli to unshelve it.
  • unrecord + reset to shelve it again.

I’ll quick want to wrap that into scripts, though, with some sanity checks to avoid shooting myself in the foot. Which suggests it should be available built-in!

Oh, nice. The help shows "push Pushes changes to a remote upstream" so I didn’t think it could help locally.

Haha, funny to know. Well used, frustration is a powerful motivator!

There’s a simpler variant: pijul diff > ~/.patch/ouli + reset.

pijul unrecord --reset already exists.

Note that pijul unrecord --reset commutes with other changes you have in the working copy: for example, you can unrecord and reset an old patch, while keeping your current work in the working copy (no need to record).

I was thinking about creating a patch with a message. But I forgot that unrecord discard the message anyway.


What would you think about pijul diff -m "here is my message"?

Perfect! So much simpler.