Skip to content

Instantly share code, notes, and snippets.

@nicktoumpelis
Created April 23, 2014 13:00
Show Gist options
  • Save nicktoumpelis/11214362 to your computer and use it in GitHub Desktop.
Save nicktoumpelis/11214362 to your computer and use it in GitHub Desktop.
Cleans and resets a git repo and its submodules
git clean -xfd
git submodule foreach --recursive git clean -xfd
git reset --hard
git submodule foreach --recursive git reset --hard
git submodule update --init --recursive
@siimsoni
Copy link

siimsoni commented Apr 20, 2017

    If the Git configuration variable clean.requireForce is not set to false, git clean will refuse to delete files or directories unless given -f, -n or -i. Git will refuse to delete directories with .git sub directory or file unless a second -f is given.

Use force twice to clean directorise with .git subdirectories: git clean -xfdf. I had some tangling submodules that would not get deleted with just git clean -xfd.

@zippo227
Copy link

this is nice. thanks!

@syntholly
Copy link

Now this is a handy, awesome set of commands!
Not especially destructive, just does a little house-keeping post-commit.

Excellent, thank you.

@larsbrinkhoff
Copy link

Maybe git submodule sync?

@Davidius86
Copy link

Davidius86 commented May 21, 2019

If you do have a script that checks out a git repo or you have removed submodules this script fails. I also would reorder the cleanup to the end in case of submodule changes. That's what I have now:

#! /bin/sh

git reset --hard
git submodule foreach --recursive 'git checkout -- . || :'
git submodule update --init --recursive
git clean -d -f -f -x
git submodule foreach --recursive git clean -d -f -f -x

@Davidius86
Copy link

I today faced the issue that I had staged files in submodules. To get this solved the full script is:

#! /bin/sh

git reset --hard
git submodule foreach --recursive 'git reset HEAD . || :'
git submodule foreach --recursive 'git checkout -- . || :'
git submodule update --init --recursive
git clean -d -f -f -x
git submodule foreach --recursive git clean -d -f -f -x

@StevenACoffman
Copy link

StevenACoffman commented Dec 12, 2019

@Davidius86 In git reset HEAD . || : I think the || : is meant to be "or true"?
I'm curious why you use this instead of git reset --hard?

@nicktoumpelis
Copy link
Author

I've written/found this a long time ago. I think it's time for an update.

@lucascoelhof
Copy link

Thanks a lot for sharing it!

@ShineSmile
Copy link

Nice work!
Thanks for sharing!

@Danysan1
Copy link

Thanks for sharing!

@ohenley
Copy link

ohenley commented Sep 30, 2020

Finally, something that works. Thx!

@lucasrangit
Copy link

Git 2.14+ supports reset of the repo and submodules in one line: git reset --hard --recurse-submodule

@nicktoumpelis
Copy link
Author

Thank you everybody for your comments!

@NaClYen
Copy link

NaClYen commented May 3, 2021

Git 2.14+ supports reset of the repo and submodules in one line: git reset --hard --recurse-submodule

Awesome information!! Quite simple solution.

@yuzhichang
Copy link

I revised the script:

#!/bin/bash
#Cleans and resets a git repo and its submodules
#https://gist.github.com/nicktoumpelis/11214362
git reset --hard
git submodule sync --recursive
git submodule update --init --force --recursive
git clean -ffdx
git submodule foreach --recursive git clean -ffdx

@sambacha
Copy link

sambacha commented Jul 6, 2022

I revised the script:

#!/bin/bash
#Cleans and resets a git repo and its submodules
#https://gist.github.com/nicktoumpelis/11214362
git reset --hard
git submodule sync --recursive
git submodule update --init --force --recursive
git clean -ffdx
git submodule foreach --recursive git clean -ffdx
git config --global alias.rinse '!git submodule foreach --recursive git clean -xfd && git submodule sync --recursive && git restore . --recurse-submodules'

@lkwg82
Copy link

lkwg82 commented Sep 12, 2022

git reset --hard --recurse-submodule

use this (see above)

@yuzhichang
Copy link

git config --global alias.rinse '!git reset --hard --recurse-submodule && git submodule sync --recursive && git submodule update --init --force --recursive && git clean -ffdx && git submodule foreach --recursive git clean -ffdx'

@lucasrangit
Copy link

git restore

@sambacha can you elaborate on why you added git restore? What's the use-case?

@sambacha
Copy link

```shell
git restore

@sambacha can you elaborate on why you added git restore? What's the use-case?

It resets the submodules back

@lucasrangit
Copy link

lucasrangit commented Sep 19, 2022

git restore . --recurse-submodules

It resets the submodules back

Does it also take care of the git reset --hard --recurse-submodules to discard any changes in the working trees? If so, why do the git restore last and not first?

@hhe
Copy link

hhe commented Dec 2, 2022

The key for me was git submodule sync. Thank you @larsbrinkhoff @yuzhichang!

It's a sneaky issue whenever the URLs specified in .gitmodules get updated, but the old URLs continue to silently be used (as shown by git submodule foreach --recursive git remote get-url origin). Git should honestly warn us whenever the two are different.

@mikebeaton
Copy link

mikebeaton commented Sep 16, 2024

Maybe git submodule sync?

For anyone coming new to all these commands, I believe this suggestion is 'as well', not 'instead' (see later comments for what this adds).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment