Як повернути вказівник підмодуля Git на комісію, що зберігається у сховищі, що містить?


128

У мене в основному git repo є підмодуль git. Як я розумію, головний репо зберігає значення SHA (десь ...), вказуючи на специфічну комісію підмодуля, з якою воно "пов'язане".

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

Я хотів би повернути цей покажчик так, щоб головне репо і підмодуль знову синхронізувалися.

Першим моїм (напевно, наївним) інстинктом було сказати git reset --hard- це, здається, працює на все інше. На мій подив, це не спрацювало за цим сценарієм.

Тож я зрозумів, що я можу набрати git diff, відзначити ідентифікатор SHA, який раніше мав вказівник підмодуля, а потім перейти до підмодуля і git checkout [SHA ID]... але, безумовно, повинен бути простіший спосіб?

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

Відповіді:


167

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

На сторінці субмодуля:

Оновити зареєстровані підмодулі, тобто клонувати відсутні підмодулі та
оформити комісію, вказану в індексі, що містить
сховище. Це зробить підмодулі HEAD від'єднаними, якщо тільки
- вказано rebase або --merge або ключовий підмодуль. $ name.update
встановлюється для відновлення або злиття.

Виконайте це, і все повинно бути добре:

git submodule update

4
Якось для мене потрібно було додати --init. Без нього субмодулі залишалися б у стані (new commits). Хоча мої підмодулі вже були ініціалізовані.
Ambidex

@Ambidex так, --initвибір є вирішальним у всьому цьому. Мені було запропоновано ім'я користувача та пароль, оскільки мої підмодулі були клоновані через https. Я зайшов в обидві папки і встановив пульти для використання sshпротоколу для оформлення замовлення.
A-Dubb

1
не працює, якщо модифікація хешу підмодуля модифікована та не встановлена
tribbloid

можна додати --рекурсивний, щоб вам не потрібно було переходити до всіх підмодулів
Gaspa79,

21

Щоб змінити команду, на яку вказує підмодуль, вам потрібно перевірити цю версію в підмодулі, а потім повернутися до вмісту репо, що додається, додати та здійснити цю зміну.

Або, якщо ви хочете, щоб підмодуль знаходився у версії, на яку вказує верхнє репо, зробіть це git submodule update --recursive. Додайте, --initякщо ви щойно клонували.

Крім того, git submoduleбез команди підмодуля буде показана команда, на яку ви вказуєте. Перед коміттом буде - або +, якщо воно не синхронізоване.

Якщо ви подивитеся на дерево з підмодулем в ньому, то можна побачити, що підмодуль позначений commitяк протилежний решті, що є краплинами або деревами.

щоб побачити, що конкретна фіксація пунктів wrt до підмодулів ви можете:

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

Ви можете побачити фіксацію чи будь-що інше, якщо вам це подобається, перейшовши в журнал тощо ( git-dirопція на рівні команд git дозволяє пропустити необхідність переходу CD до підмодуля):

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

Наведена нижче команда допомогла мені (я хотів ігнорувати будь-які зміни в підмодулі та в моєму модулі також): оновлення підмодуля git
Rajesh Goel

6

Ще один випадок, з яким я щойно зіткнувся, - це якщо в підмодулі змінилися нестандартні зміни, які ви хочете відкинути. Оновлення підмодулю git не видалить цю зміну, а також не скине git --hard у батьківському каталозі. Вам потрібно зайти в каталог підмодулів і зробити скидання git --hard. Тож якщо я хочу повністю відмовитись від нестандартних змін і в моєму батьківському, і в підмодулі, я виконую наступне:

У батьків:

git reset --hard

git submodule update

У підмодулі:

git reset --hard

5

Використовуйте git ls-tree HEADв папці "суперпроект", щоб побачити, на що виконується ваш підмодуль. Потім перейдіть у каталог підмодулів і скористайтеся, 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має три гілки на ньому, які можуть бути використані для оформлення замовлення в каталозі субмодулів.


ДЯКУЄМО ДАНУ, ПЕРФЕКТИ!
Алек


1

Я хотів ігнорувати будь-які зміни в підмодулі та в своєму модулі також

Наведена нижче команда допомогла мені:

git submodule update --init --recursive
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.