Как мне вернуть мои изменения в подмодуль 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
Команда также немного быстрее.