How do I revert my changes to a git submodule?

I have a git submodule (RestKit) which I have added to my repo.

I accidentally changed some files in there and I’d like to go back to the source version. In order to do that, I tried to run

  • Can I ignore the global .gitignore?
  • Git log stats with regular expressions
  • “Connection refused - connect(2) (Errno::ECONNREFUSED)” when pushing to the remote git server from gitlab
  • git - Same file added by both branches causes weird merge conflict
  • Guidelines for hosting VisualStudio projects on github
  • How can I make Gitolite post-receive hook to show full path to modified file?
  • Mac:app-ios user$ git submodule update RestKit

    But as you can see here, this did not work as it is still “modified content”:

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


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

    doesn’t revert locally modified files.
    How do I reset the content of that submodule?

  • Can I share my private GitHub repository by link?
  • Git thinks I'm a different user, won't give me access to github repo
  • Git - Pushing code to two remotes
  • Git commit with no commit message
  • How to mirror a git repository safely?
  • git find fat commit
  • 10 Solutions collect form web for “How do I revert my changes to a git submodule?”

    Move into the submodule’s directory, then do a git reset --hard to reset all modified files to their last committed state. Be aware that this will discard all non-committed changes.

    If you want to do this for all submodules, without having to change directories, you can perform

    git submodule foreach git reset --hard

    You can also use the recursive flag to apply to all submodules:

    git submodule foreach --recursive git reset --hard

    A more fail-safe method than all previous answers:

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

    The first command completely “unbinds” all submodules, the second then makes a fresh checkout of them.
    It takes longer than the other methods, but will work whatever the state of your submodules.

    Well for me, having

    git reset --hard

    just reset the submodule to the state where it checked out, not necessary to the main’s repo referenced commit/state. I’ll still have “modified contents” like OP said. So, in order to get the submodule back to the corrects commit, I run:

    git submodule update --init

    Then when I do git status, it’s clean on the submodule.

    do 4 steps sequential:

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

    This works with our libraries running GIT v1.7.1, where we have a DEV package repo and LIVE package repo. The repositories themselves are nothing but a shell to package the assets for a project. all submodules.

    The LIVE is never updated intentionally, however cache files or accidents can occur, leaving the repo dirty. New submodules added to the DEV must be initialized within LIVE as well.

    Package Repository in DEV

    Here we want to pull all upstream changes that we are not yet aware of, then we will update our package repository.

    # 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   

    Package Repository in LIVE

    Here we want to pull the changes that are committed to the DEV repository, but not unknown upstream changes.

    # Pull changes
    git pull
    # Pull status (this is required for the submodule update to work)
    git status
    # Initialize / Update 
    git submodule update --init --recursive

    Since Git 2.14 (Q3 2017), you don’t have to go into each submodule to do a git reset (as in git submodule foreach git reset --hard)

    That is because git reset itself knows now how to recursively go into submodules.

    See commit 35b96d1 (21 Apr 2017), and commit f2d4899, commit 823bab0, commit cd279e2 (18 Apr 2017) by Stefan Beller (stefanbeller).
    (Merged by Junio C Hamano — gitster — in commit 5f074ca, 29 May 2017)

    builtin/reset: add –recurse-submodules switch

    git-reset is yet another working tree manipulator, which should be taught about submodules.

    When a user uses git-reset and requests to recurse into submodules,
    this will reset the submodules to the object name as recorded in the
    superproject, detaching the HEADs.

    Warning: the difference between:

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

    is that the former will also reset your main parent repo working tree, as the latter would only reset the submodules working tree.
    So use with caution.

    This worked for me, including recursively into submodules (perhaps that’s why your -f didn’t work, cause you changed a submodule inside the submodule):

    git submodule update -f --recursive

    For git <= 2.13 these two commands combined should reset your repos with recursive submodules:

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

    my way to reset all submodules (WITHOUT detaching & keeping their “master” branch):

    git submodule foreach ‘git checkout master && git reset –hard $sha1’

    Git Baby is a git and github fan, let's start git clone.