Skip to main content

Resetting a Git submodule

·3 mins

This site’s Hugo theme is a Git submodule, but it somehow broke. Updating it with git submodule update --remote --merge did nothing neither locally or remotely on Gitlab.

I have no clue what caused it. Perhaps I had too many themes, or did something that I can no longer recall. And it has been a while since the last update.

All I need to do is remove the submodule, and re-initialized it. But removing a submodule is not straightforward. Git doesn’t have a built-in way to do this.

Before proceeding with what I’m working on, ensure you create a copy of your repo and work on that copy instead.

As of this writing, my git version is 2.39.2 on macOS 13.7.5:

❯ git --version
git version 2.39.2 (Apple Git-143)

and the submodule was committed for the first time in:

❯ git --no-pager log --diff-filter=A -- .gitmodules

commit 48ae2fda77a91b84b49732d8154557bc857c9dcd
Author: Kavish Gour <kavishgr@protonmail.com>
Date:   Mon Jul 29 15:55:55 2024 +0400

    congo theme

What’s left to do, is to remove the submodule and add it back.

Reinitialized the submodule #

I found a working solution on stackoverflow. First you’ll need to unregister or remove the entire submodule from .git/config:

❯ git submodule deinit -f themes/congo

Cleared directory 'themes/congo'
Submodule 'themes/congo' (https://github.com/jpanther/congo.git) unregistered for path 'themes/congo'

Remove the submodule directory from .git/modules:

❯ rm -rf .git/modules/themes/congo

I’ll keep the submodule entry in .gitmodules since I will reinitialize it. If you deleted it, restore it back with:

git restore .gitmodule

Now just remove the directory with git rm:

❯ git rm -f themes/congo
rm 'themes/congo'
From man git-rm: git rm remove files matching pathspec from the index, or from the working tree and the index. git rm will not remove a file from just your working directory. (There is no option to remove a file only from the working tree and yet keep it in the index; use /bin/rm if you want to do that.)

The submodule status should not point to any commit since the submodule is not present:

❯ git submodule status

Add the theme back as a submodule:

❯ git submodule add -b stable https://github.com/jpanther/congo.git themes/congo

Cloning into '/Users/kavish/Documents/GitHub/kavishgr.gitlab.io/themes/congo'...
remote: Enumerating objects: 26970, done.
remote: Counting objects: 100% (14/14), done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 26970 (delta 5), reused 5 (delta 2), pack-reused 26956 (from 3)
Receiving objects: 100% (26970/26970), 44.44 MiB | 3.41 MiB/s, done.
Resolving deltas: 100% (15640/15640), done.

Now its status point to latest stable commit:

❯ git submodule status
 b4b6bf644b87326b5dfa2239c2751436890e06ea themes/congo (v2.11.0-88-gb4b6bf64)

Gitlab CI/CD Runner #

This is my old runner:

image: registry.gitlab.com/pages/hugo/hugo_extended:0.132.2
before_script:
  - git submodule init
  - git submodule update --force
pages:
  script:
  - hugo
  artifacts:
    paths:
    - public
  only:
  - master

Updating it with this one, switching from manual git submodule init/update to GitLab’s built-in submodule handling for automatic updates:

default:
  image: "${CI_TEMPLATE_REGISTRY_HOST}/pages/hugo/hugo_extended:0.140.2"

variables:
  GIT_SUBMODULE_STRATEGY: recursive
  GIT_SUBMODULE_UPDATE_FLAGS: --remote

test:
  script:
    - hugo
  rules:
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH

deploy-pages:  
  script:
    - hugo
  pages: true
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  environment: production

Refs #

Because free will, though it makes evil possible, is also the only thing that makes possible any love or goodness or joy worth having.
C.S. LEWIS.