GitPython: как обновить подмодуль

Я был здесь уже несколько часов, и хотя у меня такое чувство, что я близко, я не могу понять этого.

Я пытаюсь создать script, который принимает репозиторий git, обновляет подмодуль в этом репозитории до указанной версии и фиксирует это изменение.

Что работает:

Я могу найти репозиторий, получить подмодуль и проверить коммит, который я хочу.

Что не работает:

Я не могу добавить обновленный хеш-подмодуль, чтобы я мог его зафиксировать.

Мой код:

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

diff = repos.index.diff(None)

В этот момент я вижу изменение подмодуля. Если я проверю sourcetree, я могу увидеть измененный подмодуль в "неустановленных файлах". Дело в том, что я понятия не имею, как внести изменения, чтобы я мог его совершить.

То, что я пробовал:

  • Если я использую repos.index.commit(''), он создает пустую фиксацию.
  • Если я попытаюсь добавить путь к подмодулю с помощью repos.index.add([submodule.path]), все файлы в подмодуле добавляются в репозиторий, что определенно не то, что я хочу.
  • Если я попытаюсь добавить сам подмодуль (что должно быть возможно в соответствии с документами) с помощью repos.index.add([submodule]), ничего не происходит.

Ответ 1

Существует два способа добавления новых подмодулей в родительский репозиторий. Один будет использовать команду git напрямую, а другой будет реализован в чистом питоне.

Все примеры основаны на коде, представленном в вопросе.

Простой

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

В приведенном выше коде будет вызвана команда git, которая аналогична выполнению git add <submodule.path> в оболочке.

Pythonic

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

IndexFile.add(...) добавляет в зависимости от того, что binsha находит в объекте подмодуля. Это будет тот, который в текущем фиксаторе родительского репозитория, а не фиксация, которая была проверена в подмодуле. Объект Submodule можно увидеть как особый снимок подмодуля, который не изменяется и не знает об изменениях в репозитории подмодулей.

В этом случае проще всего просто перезаписать поле binsha объекта подмодуля тем, которое фактически вывешено в его репозитории, поэтому добавление его в индекс будет иметь желаемый эффект.