Open jwhitley opened 9 years ago
I like the idea of syncing with bundler/npm etc as I'd imagine it'd reduce the friction for taking up this tool. Can I just confirm though that the actual code will be included in the parent repo? That's the whole point of this tool I believe but just to be sure...
Also one downside is that we'd no longer be able to work on the child repositories in place like we could via unfreeze
before.
To answer your questions:
Can I just confirm though that the actual code will be included in the parent repo?
No, the implementation in this fork does not keep any child repo commits or code in the parent repository. The parent repo only contains "pointers" to the child repos, e.g. stored in a .giternal.lock
file.
Also one downside is that we'd no longer be able to work on the child repositories in place like we could via unfreeze before.
The child repos' are stored under the parent repo, just like with the old unfreeze
. Child repo working trees are in the locations specified in the giternal config, just like always. The difference is that (with the changes needed for this PR) that the "freeze" operation only writes a file in the parent repo marking the current git ref for each child repo.
Does that make sense?
For me the whole point of giternal is that the child repo code is included in the parent repo (though not necessarily the entire git history), so if a vendor lib decided to go offline, you wouldn't be stuffed. How is new paradigm any different than git submodules?
@Club15CC Thanks for the feedback. For this fork, I'm likely to stay with this approach, but I definitely appreciate your desire to keep snapshots of the child repo's trees. For my part, I've almost always used full clones of dependencies' repos for that need.
To your question about git submodules, I find that they work poorly with collaboration on child repos. This fork is intended to help out with a workflow as follows:
Vagrantfile
, Chef or Puppet provisioning code, and often a Ruby-based top-level tool that wraps up the day-to-day uses of giternal/vagrant/etc. into a simple workflow.Particularly with number 3 above, submodules are not a good fit because they're a constant source of merge conflicts. With this giternal fork, child repos are easy to manage and there's no worry about conflicts. If/when I do add a lockfile, I expect it would be mostly updated and used on release branch(es) to record the specific versions of child repos used in that release.
Definitely sympathise on the inadequacy of submodules: http://stackoverflow.com/questions/7702638/git-sub-repos-external-libs-for-web-development-best-strategy-once-and-for
It's interesting though as I'm doing more iOS dev at the moment where two things are drastically different than web:
Anyway, interesting to see your requirements. I do think a more bundler style approach would win giternal some traction.
I completely agree re: freezing external dependencies in-repo. I've managed that very problem in various ways over the years. This fork of giternal was very specifically conceived around a "we own all the repos" model. E.g. development shops with big SoA codebases, but where they own all of those services.
In your case of iOS development, vendoring libs directly into the repo is sensible. I've used git's subtree merge for that as well. Subtree merge is also similar to a setup I used to manage in Perforce years ago. In P4, we kept a whole //depot/3p tree for third-party dependencies. If we ever took a new drop, it would be updated and built under /3p, then the rebuilt libs were merged over to the relevant product branch. That kept the source code and its history well documented, and provided a nice paper trail if we ever hit an issue with a dependency.
Cheers!
This fork removed the old
freeze
(and unfreeze) commands as they flattened the child repositories' content into the parent (or "meta") git repository. This proved highly undesirable for some projects that I've applied giternal to, so it was removed.The proposed replacement is to follow the pattern of package managers such as Ruby's bundler, npm, and others by creating a version lockfile. The rough workflow would be:
If a specific config setting exists, e.g.:
Then
giternal update
willgit pull
in each child repo, and create/update a .giternal.lock file which specifies the specific refs in each of the child repos.A new command
giternal install
will update each child repo to the ref in the lockfile. If thelockfile
config is enabled and no lockfile is present,giternal install
fails with an error. Iflockfile
is not enabled, it is a synonym forgiternal update
unless the--strict
command line flag is present, in which case it fails. The--strict
flag is to enforce a workflow where automated tooling expects to receive a blessed version set via a lockfile, and should be notified via error if this is not the case.giternal update
will likely also need extra options, e.g. to allow a specific named repository to be updated versus all repos in the config.