Как вернуть указатель подмодуля Git на коммит, хранящийся в репозитории? - PullRequest
107 голосов
/ 25 октября 2011

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

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

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

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

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

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

Ответы [ 5 ]

145 голосов
/ 25 октября 2011

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

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

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
19 голосов
/ 25 октября 2011

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

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

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

Если вы посмотрите на дерево с подмодулем в нем, вы увидите, что подмодуль помечен как 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>)
5 голосов
/ 09 апреля 2017

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

В родительском:

git reset --hard

git submodule update

В подмодуле:

git reset --hard
5 голосов
/ 25 октября 2011

Используйте 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 ГОЛОВА в 5b8d48f.Коммит подмодуля f68bed6 имеет три ветви, которые можно использовать для извлечения в каталоге подмодуля.

3 голосов
/ 22 мая 2018

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

 git submodule foreach git reset --hard

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

...