Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GitPython: how to commit updated submodule

I have been at this for hours now, and although I have a feeling I'm close I can't seem to figure this out.

I'm trying to make a script that takes a git repository, updates a submodule in that repository to a specified version, and commits that change.

What works:

I can find the repository, get the submodule and check out the commit I want.

What doesn't work:

I can't seem to add the updated submodule hash so I can commit it.

My Code:

repos = Repo('path/to/repos')
submodule = repos.submodule('submodule-name')
submodule.module().git.checkout('wanted commit')

diff = repos.index.diff(None)

At this point I can see the submodule-change. If I check sourcetree, I can see the changed submodule in the 'unstaged files'. The thing is, I have no clue how to stage the change so I can commit it.

What I have tried:

  • If I commit using repos.index.commit(''), it creates an empty commit.
  • If I try to add the path of the submodule using repos.index.add([submodule.path]), all files in the submodule are added to the repository, which is definately not what I want.
  • If I try to add the submodule itself (which should be possible according to the docs) using repos.index.add([submodule]), nothing seems to happen.
like image 643
Bob Vork Avatar asked Aug 05 '15 14:08

Bob Vork


1 Answers

There are two ways to add new submodule commits to the parent repository. One will use the git command directly, the other one will be implemented in pure-python.

All examples are based on the code presented in the question.

Simple

repos.git.add(submodule.path)
repos.index.commit("updated submodule to 'wanted commit'")

The code above will invoke the git command, which is similar to doing a git add <submodule.path> in a shell.

Pythonic

submodule.binsha = submodule.module().head.commit.binsha
repos.index.add([submodule])
repos.index.commit("updated submodule to 'wanted commit'")

The IndexFile.add(...) implementation adds whichever binsha it finds in the submodule object. This one would be the one in the parent repository's current commit, and not the commit that was checked out in the submodule. One can see the Submodule object as a singular snapshot of the submodule, which does not change, nor does not it know about changes to the submodule's repository.

In this case it seems easiest to just overwrite the binsha field of the submodule object to the one that is actually checked out in its repository, so adding it to the index will have the desired effect.

like image 129
Byron Avatar answered Sep 20 '22 17:09

Byron