Как вернуть указатель Git Submodule на фиксацию, хранящуюся в содержащем репозитории?

У меня есть подмодуль git в моем основном репозитории git. Насколько я понимаю, основное репо хранит значение SHA (где-то...), указывая на конкретную фиксацию подмодуля, что он "связан с".

Я вошел в свой подмодуль и набрал git checkout some_other_branch. Я понятия не имею, от кого я пришел.

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

Мой первый (возможно, наивный) инстинкт должен был сказать git reset --hard, который, похоже, работает на все остальное. К моему удивлению, это не сработало для этого сценария.

Итак, я понял, что могу набрать git diff, отметить идентификатор SHA, который использовался указателем подмодуля, а затем перейти в подмодуль и git checkout [SHA ID]... но, безусловно, должен быть более простой способ

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

Ответ 1

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

Из справочной страницы подмодуля:

Update the registered submodules, i.e. clone missing submodules and
checkout the commit specified in the index of the containing
repository. This will make the submodules HEAD be detached unless
--rebase or --merge is specified or the key submodule.$name.update
is set to rebase or merge.

Запустите это, и все должно быть хорошо:

git submodule update

Ответ 2

Чтобы изменить фиксацию, на которую указывает подмодуль, вам нужно проверить эту версию в подмодуле, затем вернуться к содержанию repo, добавить и зафиксировать это изменение.

Или, если вы хотите, чтобы подмодуль находился в версии, на которую указывает верхняя точка репо, сделайте git submodule update --recursive. Добавьте --init, если вы только что клонировали.

Кроме того, git submodule без команды subodule покажет вам фиксацию, на которую вы указываете. Перед фиксацией будет - или + +, если он не синхронизирован.

Если вы посмотрите на дерево с подмодулем в нем, вы увидите, что подмодуль отмечен как commit, а не остальные, которые являются блобами или деревьями.

чтобы узнать, какое конкретное значение указывает на подмодули, вы можете:

git ls-tree <some sha1, or branch, etc> Submodule/path

вы можете увидеть коммит или что-нибудь еще, если хотите, передав его в журнал и т.д. (параметр git-dir на уровне git позволяет пропустить cd до подмодуля):

git --git-dir=Submodule/path log -1 $(<the above statement>)

Ответ 3

Используйте git ls-tree HEAD в папке "superproject", чтобы узнать, что изначально было связано с вашим подмодулем. Затем перейдите в каталог подмодулей и используйте git log --oneline --decorate, чтобы увидеть, в какой ветке включена исходная фиксация. Наконец, git checkout original-commit-branch.

Используя некоторые тестовые каталоги, которые я установил, вот как выглядят команды:

$ git --version
git version 1.7.4.1
$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   sm2 (new commits)
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git ls-tree HEAD
100644 blob 76813a07ae558db274cefc6d903ec24323fdeb0d    .gitmodules
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    main
160000 commit 7c5889497938cd5699a9234a98ee93947e52b1ed  sm1
160000 commit f68bed61cba6f94cef57554f2cf46a45a4a0d337  sm2
$ cd sm2
$ git log --oneline --decorate
5b8d48f (HEAD, foo1) foo1.1
f68bed6 (origin/master, origin/HEAD, master) Initial commit.
$ git checkout master
Switched to branch 'master'
$ cd ..
$ git status
# On branch master
nothing to commit (working directory clean)

"Суперпроект" показывает субмодуль sm2 при фиксации f68bed6, но sm2 имеет HEAD в 5b8d48f. Подтверждение подмодуля f68bed6 имеет три ветки на нем, которые могут использоваться для проверки в каталоге подмодуля.

Ответ 4

Другой случай, с которым я столкнулся, заключается в том, что в подмодуле, который вы хотите отменить, есть неустановленное изменение. git обновление подмодуля не удалит это изменение и не будет git reset --hard в родительском каталоге. Вам нужно перейти в каталог подмодулей и сделать git reset - hard. Поэтому, если я хочу полностью отказаться от неустановленных изменений в моем родительском и подмодуле, я делаю следующее:

В роли:

git reset --hard

git submodule update

В подмодуле:

git reset --hard

Ответ 5

Ответ здесь каким-то образом не решил мою конкретную проблему с подмодулем, поэтому, если это случится и с вами, попробуйте следующее...

 git submodule foreach git reset --hard

https://kalyanchakravarthy.net/blog/git-discard-submodule-changes/

Ответ 6

Я хотел не обращать внимания на любые изменения в подмодуле, а также в моем модуле

Следующая команда помогла мне:

обновление подмодуля git --init --recursive