Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
403 views
in Technique[技术] by (71.8m points)

git submodule tracking a tag

I know how to add a submodule that tracks a branch (-b branchname) but I want to know if there is a similar functionality to track a tag.

Let say I have a tag for a specific project in a submodule repo. I add new features in the submodule repo and pull up the tag to a certain commit. I want the project that is using the submodule to track the tag without having to have an extra commit in the project repo.

Is this possible ?

Regards

question from:https://stackoverflow.com/questions/65852532/git-submodule-tracking-a-tag

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Actually, even with the -b option, Git submodules always specify a specific commit by raw hash ID. The -b option is notable for how Git doesn't really use it, in other words.1 ?? But it's not what you want anyway: you want a specific tag.

Now, the thing about a Git tag is this: it's never supposed to move. What that means, once it's stripped down to bare-bones ideas, is that a tag name is just a human-readable name for some specific raw hash ID, and it should always mean that hash ID. This distinguishes tag names from branch names: branch names are names for a specific hash ID, but the hash ID for the name br1, with br1 being a branch name, is supposed to change over time.

Another way to phrase this is:

  • A branch name always means the latest commit, rather than one particular commit regardless of what's happened recently.

  • A tag name always means that one particular commit we picked out on that particular day. In essence, this is the opposite of a branch name.

But, given the above, and given the way submodules work—the superproject specifies the submodule commit by raw hash ID—there's no point in using a tag name. If tag name tag1 means commit a123456 forever, then the only reason to use the name tag1 instead of the raw hash ID is for human consumption ... and a submodule reference isn't for human consumption, it's for Git. So you just want to pick a commit and stick with it, which is what a submodule already does.

In other words, don't bother. The only time this would make any difference is if you move tags, and you're not supposed to move tags. If you are moving tags—picking a different commit now and then—you're misusing them: the things that are supposed to move are branch names, not tag names. Stop doing that.2


1Obviously, Git does record the branch name somewhere. You can then get Git to use it. The method is not obvious, though, and git submodule update is a little weird with it. The real key here is that the superproject Git repository keeps the submodule repository on a detached HEAD at all times. Even if you specify a branch name, the submodule is still using detached-HEAD mode. So it's not actually using the branch name—not directly, anyway. The idea, not necessarily terribly well implemented, is that the superproject Git can command the submodule Git to git fetch from some third Git repository, then use git rev-parse to translate some remote-tracking name related to the branch name into a hash ID, and thereby somehow arrive at the right hash ID to use for the detached HEAD checkout in the submodule.

This is all rather cumbersome and complicated. Submodule support is being improved as an ongoing project, and it might someday become simpler and saner, but for now my personal recommendation is that if you want branch-like behavior from "submodules", don't use git submodule itself directly here. Just enter the submodule, treat it as a regular Git repository, run git checkout or git switch as usual, and then do your work there to bring it up to date and have the right commit checked out. Then, exit the submodule back to the superproject, and use git add to update the superproject repository's index so as to record the new correct hash ID.

If you do all this my way, you don't need the -b option at all. You can use it as a reminder-to-self, if you like.

If you have a sufficiently modern Git, git submodule update --remote can simplify this somewhat. I know this didn't work well in Git 1.5/1.6; it might be OK as far back as 1.7 or 1.8, which would make it work fairly well today, since even the older Linux distributions now come with 1.7 or 1.8 versions. It's probably fine since about 2.5, about the time git worktree appeared.

2Of course, with Git, you are in control. If you have a really damn good reason to move tags around, and are aware of how it can break the heads of other people who are using your repository, you can in fact move tags around. But then you'll need to move the submodule commits around by making new commits. See also footnote 1.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...