0

Every time I push a commit to the submodule I need to update the parent repo to the latest commit in the submodule. Is there any automatic way to do that in the remote?

I understood that there is no way directly I can achieve this, but cCan someone suggest an alternate for git submodules? I just saw git-tree, google repo tools but not sure how to change my current setup to use those?

James Z
  • 12,209
  • 10
  • 24
  • 44
Bala krishna
  • 519
  • 1
  • 10
  • 24
  • Submodule Git repositories are generally not even aware that some superproject is using them. That makes it literally impossible: if my repo X on GitHub is your submodule, and I make new commits in my repo X, I'm not going to be alerting you to them. – torek Aug 27 '21 at 10:36
  • @torek , that is correct but what alternate we can do on this one, my scenario I want to put infra related code in a separate repository and application code should be in another repository, but my application code should use my infra code (which is in different repo ) – Bala krishna Aug 27 '21 at 11:03
  • If you control both repos, there's no problem here: whenever you make a new commit in repo S (the submodule), make a new commit in repo R (the superproject). Write yourself a little script (or even a large one, whatever size it takes). – torek Aug 27 '21 at 11:05
  • @torek , but there are nearly 15-20 applications code repositories that need to be updated every time if there is a change in my infra repository. even if we write a script , where that script should execute????, how can we invoke the script????? Currently I am manually updating all repo's whenever there is a change in infra repo. – Bala krishna Aug 27 '21 at 11:15
  • OK, so you have a list of "repos that depend on S". Your script will read: `for R in ` or similar, depending on what language you use to write the script. Given that there are many s, the script probably should maintain a mini-database or log file of which s have been successfully updated, and which have yet to be updated. – torek Aug 27 '21 at 11:17
  • Where should you put this script? Probably, the same place that you make updates to S and run `git push`. How should you run it? That's up to you. Git does not come with such a script, so you must write your own, and then you choose how it is to be used. – torek Aug 27 '21 at 11:19

2 Answers2

0

You mention google repo tools. Here's a solution by repo.

Say you have two repositories, parent.git and sub.git, hosted in https://hostingservice. The expected folder structure is

parent/
├── .git
└── sub/
    └── .git

As sub is not a submodule of parent, you need to add it to parent's .gitignore.

Create a repository to track repo manifests. Suppose it's https://hostingservice/manifest.git. Make a manifest foo.xml that organizes parent.git and sub.git.

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
    <remote fetch=".." name="origin"/>
    <default remote="origin"/>
    <project name="parent" path="parent" revision="release_v1.2" />
    <project name="sub" path="parent/sub" revision="release_v0.3" />
</manifest>

Add and commit foo.xml in manifest.git and suppose it's on branch default.

Now you can use repo to download parent.git and sub.git,

# initialize the current folder as a repo environment
repo init -u https://hostingservice/manifest.git -b default -m foo.xml

# clone the repositories and check out their revisions
repo sync -c -d

repo init clones manifest.git and checks out default into .repo/manifests.

foo.xml instructs repo to clone parent.git and checks out its branch release_v1.2 into the folder parent under the current directory, and clone sub.git and checks out its branch release_v0.3 into parent/sub.

revision="release_v0.3" means to always use the current head of release_v0.3 whenever you re-run repo init and repo sync commands. Sometimes you may want a specific commit 8b6228f4e0f5b059a6d5d93ba9aed15089c4b324 reachable from release_v0.3, then use revision="8b6228f4e0f5b059a6d5d93ba9aed15089c4b324" upstream="release_v0.3" instead to get a fixed revision.

When needed you can add more repositories to foo.xml.

ElpieKay
  • 27,194
  • 6
  • 32
  • 53
  • My repo's are hosted on bitbucket .gitmodules structure is : [submodule "infra/charts"] path = arch/chart url = https://bitbucket.xxxx.xxxxx/scmgmt/archdev/chart.git branch = develop. – Bala krishna Aug 29 '21 at 04:47
0

Every time I push a commit to the submodule I need to update the parent repo to the latest commit in the submodule. Is there any automatic way to do that in the remote?

Automatic way to do that? Yes. "In the remote" depends on what's hosting the remote.

To do it locally, you can have a pre-push hook that checks whether the repo's being used as a vanilla-ish submodule (with the work tree nested directly inside the using project's work tree) and auto-updates that containing project, here's a sketch of that logic:

set -x
IFS=$'\n'  # just sidestep wordsplitting
toplevel=`git rev-parse --show-toplevel` || exit
if up=`git -C $toplevel/.. rev-parse --show-toplevel 2>&-`; then
        # we're checked out and nested inside another checkout
        sm_path=${toplevel#$up/}
        if uplink=`git -C $up rev-parse -q --verify :$sm_path`; then
                # and it's got an index entry for this checkout:
                # it's using us as a submodule. update its gitlink entry.
                git -C $up update-index --cacheinfo 160000,$(git rev-parse @),$sm_path
        fi
fi

And that's the hard part, auto-updating the containing project's checkout.

The problem here is, just exactly how sure are you that containing checkout is really the right one to update with the new submodule stuff, or that the new submodule stuff isn't an exploratory thing not intended for production use? I'm not saying this can't be done, I'm saying that any choices you make here are going to either sharply constrain the workflows you can safely use or dramatically complicate the code. To the point that it's probably easier to just pop a message in the pre-push reminding you that you might want to to add, commit and push the containing project too.

jthill
  • 55,082
  • 5
  • 77
  • 137
  • My repo's are hosted on bitbucket .gitmodules structure is : [submodule "infra/charts"] path = arch/chart url = https://bitbucket.xxxx.xxxxx/scmgmt/archdev/chart.git branch = develop – Bala krishna Aug 29 '21 at 04:46
  • Then learn how to run hooks and discover submodule structure and so fortth on bitbucket-hosted repos or do it on your local ones and push the results as suggested. – jthill Aug 29 '21 at 05:20