zdsmith
zdsmith

Reputation: 13

Staging an individual hunk using PyGit2

I'm trying to implement git add -p in pygit2, so I can make an alternative frontend to it. So I need to be able to stage individual hunks, first and foremost.

I'm able to find the hunks by using diff_to_workdir from the index, like this:

index.diff_to_workdir(0,1,1)[0].hunks

But I'm not sure exactly how to proceed from there. In fact, my intuition tells me that I don't stage things at all, but rather put together a commit myself and then hand it to the repo.

I have the sense that I ultimately need to be able to create a blob from the hunk and then use TreeBuilder to create a commit. But I just can't get there! It seems like I can only create blobs from files. Can anyone give a little guidance?

Upvotes: 1

Views: 353

Answers (1)

Carlos Martín Nieto
Carlos Martín Nieto

Reputation: 5277

In order to stage files, there is no need to get anywhere close to a commit, or even a tree. All you need is to put the new version of the file in the on-disk index.

First you get the current version of the file in the index

path = 'src/somefile.py'
repo = Repository('.')
index = Repository.index
id = index[path].id
contents = repo[id].data

Once you've applied the diff to the staged version of the file, you can write those patched contents to the object db and create tree new index entry with

new_contents = my_favourite_patch_lib.patch(contents, hunk)
new_id = repo.write(new_contents, GIT_OBJ_BLOB)
new_entry = IndexEntry(path, new_id, GIT_FILEMODE_BLOB)

and now you can update the index and write it out to disk so the rest of the system can pick it up

index.add(new_entry)
index.write()

Now you have the new contents of the file available in the repository and the index considers these new contents to be the state of the file.

Upvotes: 1

Related Questions