I don’t know how adverse this is to Pijul’s philosophy, but it would be very nice to have a staging area for changes. This may just be me longing for
git functionality, but too many times now have I forgotten to remove some unrelated changes from the
pijul rec window, only to notice after I’ve pushed. While
pijul add already exists, a
pijul restore (or similarly named command) would be a good companion.
I agree the staging area in Git is nice, but I wonder whether we could do that with just
pijul rec --amend. Have you tried that command?
I have indeed used
pijul rec --amend to drop unrelated changes in the past, but when those changes are in
Cargo.lock and multiple other files, it quickly becomes a hassle to track down which files I actually wanted in that record. I probably just need to use
pijul more and stop comparing everything to how
git does things.
Some thing to try first maybe is to make
pijul rec a bit more friendly to recording partial changes. E.g. some interactive version like what
git add -p does, where you can pick changes one-by-one or by file.
Or allowing to record multiple changes from one
pijul rec editing session, by grouping them under different change header sections.
Or instead of staging changes, there could be some support for marking certain changes as “irrelevant”? Along the lines of
pijul rec --ignore Cargo.lock which creates a change that is somehow tagged as “ignored”, and thus wouldn’t be pushed by default. Maybe along with something like
pijul unrecord --ignored which would drop all these irrelevant changes.
I agree with all those comments. First, a general note (not an answer): any line starting with
# is ignored in the change format.
I can think of multiple options:
Editor modes. I started to work at some on a VSCode mode for Pijul to try and think about what would be needed to do that. Even though I don’t use it myself, VSCode is by far the most popular text editor nowadays. See my attempt there: https://nest.pijul.com/pmeunier/vscode-pijul. I believe this sort of stuff could make editing changes easier.
Extra commands in
record, for example
pijul record --amend HASH --drop-files Cargo.lock. Can we think of a complete set of useful commands?
@robx: I was thinking of a more convoluted thing where “parked” changes would be kept on a separate channel, but this is super Git-like, your idea is way better. I guess these could be kept in the
.pijul/config and editable both manually and with the commands, what do you think?
When using amend to drop changes from a patch we can’t really drop the dependencies from the changes (since we as a user don’t know them). So as it stands now it’s pretty easy to remove changes from a patch, but the patch will still depend on things that it shouldn’t.
There are plenty of good things to be said for Git stage. I am just going to bring up one pit fall with it as implemented in Git. To be clear, I do use stage changes when working with Git despite the potential issues I am going to describe. If there is a demand for staging changes, implementing such a feature would still be worth while even if these problems cannot be avoided. Plenty of developers likely never use hooks, which the issue I am bringing up revolve around.
When a file is staged in Git, it is copied to a staging area. This copy is the version that will be committed if only staged changes are committed. The problem comes when you are using hooks to check files for correctness before committing.
Say you have a hook apply some formatting rules (Pijul uses rust-fmt to do this). What if the staged file is not correctly formatted, but the working copy is correctly formatted for some reason? The hook would need to know to run the formatting program on the staged copy.
Also problematic for a naive formatting hook that runs against the working copy would be if the working copy is incorrectly formatted. And the working copy has additional changes not in the staged copy. If the formatting hook is actually fixing the files before the commit / record, if it then stages the properly formatted version overwriting the intended changes.
Finally, hooks that work on individual files can be made to run on the staged versions. But what if a hook does some action that involves additional dependencies? Such as running a code linter. If a staged file depends on another that has no staged changes, but the working copy has been altered how would this be resolved?
Never mind if there is something going of with files that are non-versioned in the the repository (say the contents of the
node_modules folder in a NodeJS project that impacts the hook.
I cannot really see a good way to implement staging of changes that meets all the following:
There is maybe one way to do it all, but it would only be “convenient to use for the user” when working through a graphical interface, which would put it more of a feature for a plugin for a code editor / IDE than something to add to the main CLI tool.
Basically, it would be less staging changes and then recording them and more stash the changes, reset the working directory, and then reapplying parts of the change set at a time and recording the partial changes. It is reapplying parts of a larger change set that would be hard to make convenient to use for a CLI program.
I moved a bit on this:
One of the things in Git that allows staging to work is that there are no files in Git, just blobs and trees. The index can therefore be just an extra tree. In Pijul, because we want filesystem changes to commute with other changes, we can’t do that.
Another thing is, since there is no patch editing in Git, Git can delete the entire contents of the index, whereas we might want more flexibility.
In order to move forward anyway, I implemented something to allow implementing a staging area independently from Pijul itself, by adding two options to
pijul record: one is
--working-copy, which allows one to specify a different working copy (such as
.pijul/index), and the other one is
--ignore-missing, which doesn’t record file deletions.