How to rewrite change with dependents

I am having trouble finding a way to easily rewrite a change and reapply all of its dependents on top of the new change (like using git rebase -i to rewrite a non-HEAD commit in the history).

I know pijul works fundamentally differently than git, and this is not a common use case. But there are scenarios that I see myself needing to rewrite history (like removing secrets from a repo before publishing it to somewhere public).

I would like to rewrite a change that has dependent changes, while easily regenerating and applying dependent changes (I am expecting they would have new hashes). Also, flattening all the changes is not a suitable option for me.

I tried to store the changes of the dependents and then reapply them after applying the modified root change. But when I do this the dependent changes seem to reapply the original root change.

With original
A->B->C

# pijul change C > C.diff && pijul unrecord --reset C
# pijul change B > B.diff && pijul unrecord --reset B
A

# Make new changes...
# pijul record
A -> D

# pijul apply < C.diff
A -> D -> B -> C
Or probably something like
A -> D 
 \-> B -> C

Expecting
A -> D -> E
(Where E is C.diff applied on-top of D)

I really thought applying the output of C.diff would only apply the diff and not bring its dependencies along after reading

You don’t need to worry about the # Dependencies block, it just needs to be there. The dependencies themselves will be re-computed by pijul when you record the change.

From Splitting and combining changes - The Pijul manual

Also this might be related…

2 Likes

After some investigation it seems reusing a change on-top of different change then the original parent is very delicate, but possible.
Given changes
A -> B - C
When I ran something like…

pijul change C > ".stash/C.diff" && pijul unrecord --reset C
pijul change B > ".stash/B.diff" && pijul unrecord --reset B

I was able to change .stash/B.diff in only a very minor way (in my testing changing a single character) and apply it pijul apply < .stash/B.diff. If I made such a minor change and then updated C.diff with the new change ID (from applying the modified stash/B.diff) in the place of the old one, then C.diff could be applied without an issue. Of course this would me that if any other subsequent changes would also need the change IDs of there dependencies updated too (more than okay in my case).

If I changed B.diff to add a different amount of characters, it seems to lead to a (seemingly) unnecessary conflict when trying to apply C.diff.

If I leave any old change IDs in C.diffs dependencies then they will get applied with the original C.diff.

I think using pijul apply on the output of a pijul change is maybe preserving much more than I am asking for. pijul apply seems to preserve the message timestamp authors dependencies and the hunks. If there was a way to preserve only the message and apply the hunks to the local tree and record the remaining changes for a new change. Then the dependencies could be recalculated, as well the authors and timestamp.

I have been trying to write a script to automate this, but I am falling short. Maybe if there was an easy way to apply the hunks in a change to the working tree.

I feel the ability to edit changes after the fact more easily is probably an important requirement for me for r1. I get work is needed, but this is where the theory of pijul shines over other VCSs, so I reckon it’s really a selling point to have the implementation. In my case I’m wanting to split a change into smaller subchanges, and so I guess on this basis it should be possible to respect the dependencies. In fact maybe this solves the original question, as if the subchange representing the secrets can be separated from the other subchanges, then perhaps the changes that depend on it can be pulled out and then anything that depends on the secrets would need sorting before it could be dropped, or if it has no dependents then it can be safely removed.

Given changes consist of individual hunks, for a first pass would it at least be not too difficult in practice to separate out individual hunks into separate changes, which then would allow us potentially to edit one of those hunks?

Also, I guess this is slightly different, but at the minimum I think it should be possible to edit the change message, even if the change itself can’t be edited at the moment.