Como reverto minhas alterações para um submódulo git?


271

Eu tenho um submódulo git (RestKit) que eu adicionei ao meu repositório.

Alterei acidentalmente alguns arquivos e gostaria de voltar à versão original. Para fazer isso, tentei executar

Mac:app-ios user$ git submodule update RestKit

Mas como você pode ver aqui, isso não funcionou, pois ainda é "conteúdo modificado":

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

Até

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

não reverte arquivos modificados localmente.
Como redefinir o conteúdo desse submódulo?


Se git reset --hardnão funcionar, tente primeiro especificar a ramificação remota com git reset --hard origin/<branch_name>.
Jerry K.

Respostas:


209

Mova para o diretório do submódulo e faça um git reset --hardpara redefinir todos os arquivos modificados para o último estado confirmado. Esteja ciente de que isso descartará todas as alterações não confirmadas.


6
A atualização do submódulo git (mesmo sem o --init) funcionou para eu abandonar as "alterações" do submódulo quando eu realmente não havia mudado nada. Se você for para o diretório do submódulo e o status do git aparecer vazio, tente isso em vez da redefinição.
DNA eclético

16
git submodule update --inittrabalhou para mim; sem --initisso não funcionou.
Per Lundberg

Soberbo !! Fiz alterações no submódulo em um repositório meu onde o importei. E isso voltou ao que deveria ser.
Noitidart 17/06/16

2
redefinir - não funcionou para mim, meu submódulo ainda não pôde ser iniciado por causa de alterações locais.
malhal

33
além de @markshiz, git submodule update -f --initno meu caso.
precisa saber é o seguinte

280

Se você quiser fazer isso para todos os submódulos, sem precisar alterar os diretórios, poderá executar

git submodule foreach git reset --hard

Você também pode usar o sinalizador recursivo para aplicar a todos os submódulos:

git submodule foreach --recursive git reset --hard


7
isso funciona muito melhor para automação do que tentar cd em cada diretório de submodulo.
Travis Castillo

4
Note que você também pode querergit submodule foreach --recursive git clean -x -f -d
yoyo

1
na minha máquina (Windows usando Git 2.22.0) Preciso de aspas simples em torno do segundo comando git ao usar o sinalizador --recursive ou ele não funcionará: submodule git foreach --recursive 'git clean -x -f -d'
aatwo 17/01

196

Um método mais à prova de falhas do que todas as respostas anteriores:

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

O primeiro comando "desata" completamente todos os submódulos, o segundo faz uma nova verificação deles.
Leva mais tempo que os outros métodos, mas funcionará independentemente do estado dos seus submódulos.


1
Infelizmente isso não funcionou no meu caso (com arquivos locais modificados em um submódulo git), o "update --init" vomita comandoerror: Your local changes to the following files would be overwritten by checkout
rogerdpack

Para atualizar um sub-módulo específico, faça: $ git sub-módulo deinit -f - <submodule_path> e, em seguida, $ git atualização do sub-módulo --init - <submodule_path>
Priyank

Eu tentei todos os métodos acima até chegar a este. Para mim, este é o único que tem o meu git procurando "limpa" (sem o *em meu PS1que git status -unofoi incapaz de explicar).
Guy Rapaport

60

Bem para mim, tendo

git reset --hard

basta redefinir o submódulo para o estado em que efetuou o check-out, desnecessário ao commit / state referenciado pelo repositório principal. Ainda terei "conteúdo modificado", como disse o OP. Portanto, para obter o submódulo de volta ao commit correto, execute:

git submodule update --init

Então, quando eu faço git status, fica limpo no submódulo.


lamentavelmente submodule update --initnão parece reverter modificações locais no meu caso de qualquer maneira: |
Rogerdpack # 21/16

48

faça 4 etapas sequenciais:

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

2
O único que me ajudou também.
21414 Victor Victorienien

pergunta, se o submódulo for novo, não haverá um arquivo .git dentro desse diretório, correto? o comando git borbulha para o repositório pai?
Santiago arizti 28/11/16

1
@jiahut Mesmo depois de fazer isso, ainda tenho "(novos commits") ao lado do meu submódulo ao fazer o 'status git' dos pais?
David Doria

1
@DavidDoria git submodule updatefoi o que corrigiu o problema (new commits)para mim.
Ubershmekel

31

Isso funcionou para mim, incluindo recursivamente em submódulos (talvez seja por isso que seu -f não funcionou, porque você alterou um submódulo dentro do submódulo):

git submodule update -f --recursive

12

Primeiro tente isso, como outros já disseram:

git submodule update --init

Se isso não funcionar, mude para o diretório do submódulo e use o seguinte comando para verificar se há alguma alteração no submódulo:

git status

Se houver alterações no seu submódulo, livre-se delas. Verifique se você não vê nenhuma alteração ao executar o "status git".

Em seguida, volte ao repositório principal e execute "git submodule update --init" novamente.


9

Desde o Git 2.14 (terceiro trimestre de 2017), você não precisa entrar em cada submódulo para fazer um git reset(como em git submodule foreach git reset --hard)

Isso ocorre porque o próprio git reset agora sabe como recursivamente entrar nos submódulos.

Consulte commit 35b96d1 (21 de abril de 2017) e commit f2d4899 , commit 823bab0 , commit cd279e2 (18 de abril de 2017) por Stefan Beller ( stefanbeller) .
(Mesclado por Junio ​​C Hamano - gitster- na commit 5f074ca , 29 de maio de 2017)

builtin / reset: adicionar opção --recurse-submodules

git-reset é mais um manipulador de árvore de trabalho, que deve ser ensinado sobre submódulos.

Quando um usuário usa git-reset e solicita a recursão em submódulos, isso redefine o submódulo para o nome do objeto, conforme registrado no superprojeto, desconectando os HEADs.

Atenção : a diferença entre:

  • git reset --hard --recurse-submodule e
  • git submodule foreach git reset --hard

é que o primeiro também redefinirá sua árvore de trabalho principal do repositório pai, pois o último redefiniria apenas a árvore de trabalho dos submódulos.
Portanto, use com cuidado.


7

Para git <= 2.13, esses dois comandos combinados devem redefinir seus repositórios com submódulos recursivos:

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

3

Isso funciona com nossas bibliotecas executando o GIT v1.7.1, onde temos um repositório de pacotes DEV e um repositório de pacotes LIVE. Os próprios repositórios nada mais são que um shell para empacotar os ativos de um projeto. todos os submódulos.

O LIVE nunca é atualizado intencionalmente, no entanto, arquivos em cache ou acidentes podem ocorrer, deixando o repositório sujo. Novos submódulos adicionados ao DEV também devem ser inicializados no LIVE.

Repositório de Pacotes no DEV

Aqui queremos extrair todas as alterações que ainda não estamos cientes, e atualizaremos nosso repositório de pacotes.

# 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   

Repositório de Pacotes no LIVE

Aqui, queremos extrair as alterações confirmadas no repositório DEV, mas não as alterações iniciais desconhecidas.

# Pull changes
git pull

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

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

2

Se você deseja descartar todas as alterações em todo o repositório, juntamente com os submódulos, você pode usar

git restore . --recurse-submodules

Isso desfará todas as alterações feitas no repositório e nos submódulos.


0

minha maneira de redefinir todos os submódulos (SEM desanexar e manter sua ramificação "principal"):

submodule git foreach 'mestre do checkout do git && git reset --hard $ sha1'

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.