user3606175
user3606175

Reputation: 2203

Updating files from one repository to tag in another repository

I have multiple repos that I work with. I have a requirement to create tag in one of them, update revisions of files and use the same tag to update files from another repository. Is this possible? (Assuming that tag is pushed to remote server).

Or is there a way I can have a parent remote tag (I don't know how) and use it in all the repositories to update files from their repos.

All files in repos are exclusive of each other. There are no common files. These are all different folders structures and files.

Thanks for looking

EDIT: AS I assumed, it looks like this is not a good practice in the context of git and tags. But I am going to try rewording the files to see if my question can make sense.

Basically, I have a commit A of everything in Repo A. I create a tag TagA and push it to the remote Server. Now, I am in Repo B. and I have commited everything in RepoB, say CommitB. Now, Can I add the CommitB to TagA?

Hope this helps. Thanks again for looking.

Upvotes: 0

Views: 720

Answers (2)

torek
torek

Reputation: 489083

Based on your edit, I think maybe what you're saying comes down to this:

  • You have some collection of N (N > 1) repositories.
  • At some point in time it becomes useful to build a system / whatever out of all N repositories.
  • Let's assume this is written to a DVD or whatever (let's just call this a "Release"), and handed off to someone (let's call this person "Customer").
  • Now work continues, and the N repositories get further modified (each one independently).
  • Later, Customer comes back and says "hey, when I frob the bizzle, the framistan dumps core."
  • Now you/your group must reproduce precisely what you gave Customer, so that you can try frobbing the bizzle while observing the framistan.

Your question is: "Can I use tags to reproduce precisely what I gave Customer?"

The answer to that question is "Yes, but git will neither help nor hinder you in this process." To achieve your goal, you simply tag each repository, then use the tagged versions of the files to build the release:

release=...
tag=...
for (each repository) do
    git clone -n $repository $release/$repository
    (cd $release/$repository; git checkout $tag; rm -rf .git)
done

You then remember what tag(s) you used when you made the Release. You help yourself (rather than git helping you) if you use a single tag-name, such as a version-and-date or customer-name or whatever, on all the repositories, in the process of making the Release.

Of course, when it comes to fixing Customer's problem, you'll need a way to make changes to some files in some repositories, committing those changes, and probably tagging and building a new release based on those fixes. You'll want to keep the old tag around so that if Customer (or some second CustomerB) is still using the old Release, rather than the patched one, you can reproduce that at will. So this implies that you should also have a branch for each release-group. Again, git will neither help nor hinder you in terms of creating a branch-name in all repositories.


If you're making test (non-release) versions for QA, usually you'd start by making the branch anyway—this branch is where the release will "come from", as it were—and then tag everything and make the QA version just like making a real release, which they test. Then you make fixes on the branch and make a new tag. Essentially, each of these is an "internal release" to QA only. Old tags can be discarded pretty quickly (unlike releases to customers). Depending on whether QA wants/needs to test two or more release candidates, you might get away with not bothering with a tag at all, and just using the branch-tips as the commit-IDs for each repository.


One other alternative (to tagging and/or branching in all the various repositories) is to make a "super-project" that consists mainly or even solely of git "submodules". The way this works is relatively simple in concept. The last time I touched submodules (back in the days of git 1.5.x), though, they were quite painful to use. Presumably they are at least somewhat improved now.

The way submodules work, at a fundamental level, is that in your "super-project", you record the paths to the various "sub-project" repositories, and then you make a commit in the super-project that simply records the exact commit-ID of each sub-project, simultaneously.

Tagging a repository merely gives you a symbolic name (such as "v1.2") that maps to a raw commit-ID (SHA-1). So you gather up all the commit-IDs of all the sub-projects and make a commit that, in essence, merely has a list like this:

sub-project A: commit ID A234567
sub-project B: commit ID B345678
...
sub-project F: commit ID F098765

This commit in the super-project, which records all those sub-project IDs has its own ID, of course (perhaps 5544321, say). You can then give the super-project ID a symbolic (tag) name (such as "v1.2"). Now you can go from tag ("v1.2") to super-project ID (5544321) and from there to sub-project name-and-ID (A, id A234567)—which is just what you need to re-create the Release. As Carl noted in his answer, this avoids cluttering-up the sub-projects with tags. (However, if you need to fix a bug, you may generally still have to clutter up the sub-projects with branches anyway, so that you have a place to add commits.)

Upvotes: 1

Carl
Carl

Reputation: 44478

No, you can't. Because a tag is tied to a specific commit.

The best you can do is:

  1. Delete the tag on the remote and on every repository that has pulled from the remote (if you know who has), including A.
  2. Create the tag on B with the updated files. Push it.

However, as you can see, you are in effect destroying the constant nature of a tag by doing it. This is bad practice, because you're not using a tag for its intended purpose and so what you're probably after is something else.

If you think about it, what you're really after is git's concept of a branch.

  1. You create a branch in repo A.
  2. You push it to the remote server.
  3. You pull it down to repo B.
  4. You make whatever changes you need to make and commit.
  5. You push the updated branch to the remote server.
  6. Now, when repo A pulls the branch, it receives the updates.

UPDATE:

If the code in each repository is completely different, you still need a way to know what makes up a "release". Why?

Consider the following scenario

You have 3 repositories:
Repo A : currently at version 1.7.32
Repo B : currently at version 3.1.41
Repo C : currently at version 2.18.28

You need to make a release at this point in time. So you could tell everyone working on every repository to tag their current release with the same label, or, you could version control what makes up a release itself:

Root (this is a repository)
  |- A at 1.7.32
  |- B at 3.1.41
  |- C at 2.18.28

So, now, you just tag the root repository and this means that when you need to reproduce the code for the release, you checkout root using the tag you gave it and you get all the other repositories at the versions they are supposed to be.

One consequence of this is A,B or C aren't tagged directly. Why should they be? They could be libraries that are used in many products. You don't want a tag in each repository for every product they're used in.

We haven't been using the correct terminology yet, but it seems to me that what you're looking for is a way to manage a hierarchy of repositories.

Given that you're starting from a place where you have code in separate repositories to begin with, you probably want to read up on git subtree.

Upvotes: 1

Related Questions