Remix.run Logo
schacon 14 minutes ago

Well, there are a couple of problems here, if you are interested in an actual answer.

The first is that update-index only works on worktree files, so you need to be actually modifying file contents on disk and then essentially running `hash-object` on them, then `commit-tree`, etc. For an agent, each of these are tool calls and ones that they're not very good at (because nobody really does this manually).

Quick example for clarification. Let's say you want to move half of the changes of a file from one commit to another.

The ideal way would be to run something like:

`git squash <commit-a>:<hunk-id> <commit-b>`

Which could load the tree of commit-a into memory, virtually apply the hunk change to it, calculate the new tree, write it out and rebase the commits - thus moving the hunk. This is what tools like GitButler do with `but squash` etc. One command, pretty simple, all in memory and extremely fast.

The "plumbing" path you suggest would be something like:

- (record patch changes you want) - git reset HEAD~3 - (apply patches you want in commit 1) - git update-index - git commit - (apply patches you want in commit 2) - git update-index - git commit - (recreate the commits above that)

You talk about not interacting with the work tree, but `update-index` directly deals with the working directory. It's just not built for operations like this. It's built for Linus interactively building trees from contents on a filesystem.

skydhash 4 minutes ago | parent [-]

I'm saying this because, git store whole files for each commit, not hunks or patches. Scripting it out without doing any interactions would be to have discrete steps which can be rollback. So it's better to have the changes (the patch) separate from what needs to be changed (the file). So the agents need only to edit the patch in three separate version (c1, c2, c3), then loop with the apply->update-index->commit action, each easily verifiable and revertable.