Как вернуть указатель 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