Как мне вернуть мои изменения в подмодуль git?

У меня есть подмодуль git (RestKit), который я добавил к своему репо.

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

Mac:app-ios user$ git submodule update RestKit

Но, как вы можете видеть здесь, это не сработало, поскольку это все еще "модифицированный контент":

Mac:app-ios user$ git status
...
#   modified:   RestKit (modified content)

Четное

Mac:app-ios user$ git submodule update -f RestKit 

не восстанавливать локально измененные файлы.
Как мне сбросить содержимое этого субмодуля?

15 ответов

Решение

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

Более надежный метод, чем все предыдущие ответы:

git submodule deinit -f .
git submodule update --init

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

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

git submodule foreach git reset --hard

Вы также можете использовать рекурсивный флаг для применения ко всем подмодулям:

git submodule foreach --recursive git reset --hard

Хорошо для меня, имея

git reset --hard

просто сбросьте подмодуль в состояние, в котором он был извлечен, а не обязательно для основного репо, на который ссылается commit/state репо. У меня все еще будет "измененное содержимое", как сказал OP. Итак, чтобы вернуть субмодуль в фиксацию исправлений, я запускаю:

git submodule update --init

Потом когда я git statusЧисто на подмодуле.

Сделать 4 шага подряд:

git submodule foreach git reset --hard HEAD
git submodule update
git submodule foreach "git checkout master; git pull"
git submodule foreach git clean -f

Если вы хотите отменить все изменения во всем репозитории вместе с подмодулями, вы можете использовать

git restore . --recurse-submodules

Это отменит все изменения, сделанные в репозитории и во вложенных модулях.

Это сработало для меня, в том числе рекурсивно в подмодули (возможно, именно поэтому ваш -f не работал, потому что вы изменили подмодуль внутри подмодуля):

git submodule update -f --recursive

Сначала попробуйте это, как говорили другие:

git submodule update --init

Если это не сработает, перейдите в каталог подмодуля и используйте следующую команду, чтобы увидеть, есть ли какие-либо изменения в подмодуле:

git status

Если в вашем подмодуле есть изменения, избавьтесь от них. Убедитесь, что вы не видите никаких изменений при запуске "git status".

Затем вернитесь в основной репозиторий и снова запустите "git submodule update --init".

Начиная с Git 2.14 (3 квартал 2017 года), вам не нужно заходить в каждый подмодуль, чтобы git reset (как в git submodule foreach git reset --hard)

Это потому, что сам git reset теперь знает, как рекурсивно войти в подмодули.

Смотрите коммит 35b96d1 (21 апреля 2017 г.) и коммит f2d4899, коммит 823bab0, коммит cd279e2 (18 апреля 2017 г.) от Stefan Beller ( stefanbeller )
(Объединено Юнио С Хамано - gitster - в коммите 5f074ca, 29 мая 2017 г.)

встроенный / сброс: добавить переключатель --recurse-submodules

git-reset это еще один рабочий манипулятор дерева, который нужно учить о подмодулях.

Когда пользователь использует git-reset и запрашивает возврат в подмодули, это сбрасывает подмодули к имени объекта, как записано в суперпроекте, отсоединяя HEAD.

Внимание: разница между:

  • git reset --hard --recurse-submodule а также
  • git submodule foreach git reset --hard

Это то, что первый также сбрасывает ваше главное рабочее дерево родительского репо, так как последний сбрасывает только рабочее дерево подмодулей.
Так что используйте с осторожностью.

Это просто:

      cd /path/to/submodule/root
git submodule update -f --init  .

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

Для git <= 2.13 эти две команды вместе должны сбросить ваши репозитории с рекурсивными подмодулями:

git submodule foreach --recursive git reset --hard
git submodule update --recursive --init

Если есть изменения в ваших подмодулях, используйте

git submodule foreach --recursive git reset --hard

Если ваши изменения представляют собой изменения удаленного подмодуля, используйте

git submodule update --init

Если эти изменения были зафиксированы, используйте

git reset --hard
git submodule update --init

Мой способ сброса всех подмодулей (БЕЗ отсоединения и сохранения их "главной" ветки):

подмодуль git foreach 'мастер проверки git && сброс git --hard $sha1'

Это работает с нашими библиотеками, работающими с GIT v1.7.1, где у нас есть репозиторий DEV и репозиторий LIVE. Сами репозитории - не что иное, как оболочка для упаковки ресурсов для проекта. все подмодули.

LIVE никогда не обновляется преднамеренно, однако файлы кэша или несчастные случаи могут произойти, оставляя грязное хранилище. Новые субмодули, добавленные в DEV, также должны быть инициализированы в LIVE.

Хранилище пакетов в DEV

Здесь мы хотим вытащить все вышестоящие изменения, о которых мы еще не знаем, затем мы обновим наш репозиторий пакетов.

# Recursively reset to the last HEAD
git submodule foreach --recursive git reset --hard

# Recursively cleanup all files and directories
git submodule foreach --recursive git clean -fd

# Recursively pull the upstream master
git submodule foreach --recursive git pull origin master

# Add / Commit / Push all updates to the package repo
git add .
git commit -m "Updates submodules"
git push   

Хранилище пакетов в LIVE

Здесь мы хотим получить изменения, которые зафиксированы в репозитории DEV, но не являются неизвестными вышестоящими изменениями.

# Pull changes
git pull

# Pull status (this is required for the submodule update to work)
git status

# Initialize / Update 
git submodule update --init --recursive

Самый популярный на данный момент ответ (deinitиupdate) избавляется от всех неотслеживаемых файлов.

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

      git submodule update --checkout --force

Команда также немного быстрее.

Другие вопросы по тегам