2

The problem: Can I pin git modules to specific commits?

I am writing a build script to produce an artifact which is a Zip archive of multiple submodules with a few requirements.

  • the artifact generated must be tagged / versioned
  • the tag of the repo with the build script must be used to version the artifact

Here is the rub:

If I checkout:

git clone git@whatever:thing/mybuildscipt

and then do

git submodule update --init

I need the exact commit number of each submodule to be recorded in the build script's repo (ideally in .gitmodules) so that in the future, if I should do

git checkout 1.2.3
git submodule update

I am going to the same submodules as they were at when the build script repo was tagged with "1.2.3".

Long ago, this is exactly how git submodules worked: They were pinned to a specific commit and that commit hash was actually in the .gitmodule - I need that behavior and it's not at all clear to me, based on my research, if it's still possible.

Here is a summary of the commands being run the in build script, so that you can get the idea what is to be accomplished. Ultimately if I checkout a specific version of the git repo that contains the build script, it should produce an identical zip archive as before.

export NEXT_VERSION=$(
    git tag --sort=committerdate \
       | tail -1 \
       | awk -F '.' '{print $1"."$2"." $3 +1}')
git submodule update --init

# remove the .git dir to save space
git submodule | awk '{print $2}' | xargs -I {} -n 1 rm -fR {}/.git
git submodule | awk '{print $2}' | xargs zip -qr ${FILE_NAME}

# push to object storage
mc cp ${FILE_NAME} ${ALIAS}/${bucket}/${FILE_NAME}

# tag
git tag ${NEXT_VERSION}
# update tags
git push --tags origin
Christian Bongiorno
  • 5,150
  • 3
  • 38
  • 76
  • 1
    "*Long ago, this is exactly how git submodules worked…*" They still work the same way, nothing changed. What is your problem with submodules? Commit hashes were never stored in `.gitmodules` — they were stored (and still are stored) in every commit. – phd Jan 09 '23 at 04:38
  • Where is the commit hash for the submodules stored then? When I do a `git submodule update` absolutely nothing in the repo shows are changed. If I'm misunderstanding, then ok, I just need to know how to be SURE it's recording the commit ids – Christian Bongiorno Jan 09 '23 at 04:46
  • "*Where is the commit hash for the submodules stored then?*" In commits of the superproject. You can get the commit for a submodule with `git rev-parse commit:path/to/subm` where `commit` can be any pointer to a commit (`HEAD`, branch, tag, SHA1). – phd Jan 09 '23 at 04:52

1 Answers1

1

Where is the commit hash for the submodules stored then?

In a gitlink, a SHA1 recorded as a special entry in the index.

git ls-files --stage|grep 160000

The all purpose of a submodule is to record/restore a specific SHA1 of its associated repository.

One possible scenario where the same SHA1 is not restore is if your submodule is configured to follow a branch, and you are using a git submodule update --remote option.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Well, it should only be following a branch when the script runs - basically, pull the head of branch `develop`, but the pin it. So, `this:1.2.3 -> other:2.3.4, something:4.5.6` Classic transitive dependency management. I will read up on what you've sent. Thanks – Christian Bongiorno Jan 09 '23 at 17:55
  • So, you're basically saying that, if I simply remove the `branch = develop` from my gitmodule, then this just works and I can tag this script repo and be done? I guess I can test that theory – Christian Bongiorno Jan 09 '23 at 18:00
  • @ChristianBongiorno That is the idea, yes. By default (no branch), a submodule is made to restore one specific commit. – VonC Jan 09 '23 at 18:05