feat: implement commutable auto-commit mechanism #235
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Stack from ghstack (oldest at bottom):
We're going to tighten up our auto-commit mechanism. Currently, before we run a command, we commit ALL pending changes (including untracked files) before running the command. What I want to do now is create this commit, to be called PRE_COMMIT, but then reset the HEAD/index to the state it was before doing this commit (commit-tree might work too although we'll have to handle new untracked files correctly. They should remain untracked after the commit.) We run the command as usual. Now, we must assess the impact of the command. Easy case: no changes were made by command. Then we do nothing and can ignore the commit we made. Harder case: some changes were made. We now need to understand if the local changes and the new changes commute. First, synthetically construct the new change POST_COMMIT by creating a new commit (including all untracked files) but having its base be the PRE_COMMIT. This gives us a commit history POST_COMMIT -> PRE_COMMIT (where the arrow denotes parent). Now, we try to commute them, so we have PRE_COMMIT -> POST_COMMIT, using git cherry-pick. If the cherry-pick fails, or the new commuted patches have a different final tree than the original, we abort, and move HEAD to the un-commuted POST_COMMIT. However, if the cherry-pick succeeds, we can directly reset HEAD to be the commuted POST_COMMIT, in particular, the working tree will now have PRE_COMMIT's changes uncommitted, just like they were before hand.
codemcp-id: 250-feat-implement-commutable-auto-commit-mechanism