Hacker News new | past | comments | ask | show | jobs | submit login
Git-subtrac: all your Git submodules in one place (apenwarr.ca)
132 points by mrzool on Nov 25, 2019 | hide | past | favorite | 23 comments



I've read the README (and I've also used git-subtree in the past), but it's still a bit unclear to me how this is intended to be used. What's the typical flow?

- When should I run `subtrac update`? Only once? After every change in submodules?

- What happens if I go into a submodule folder and change a file? Should I commit inside that repository and push upstream? How is that propagated to the the parent repo?

- Does this allow me to make a change to the submodule and not push upstream, but instead "commit" it to the parent repo only?

- What is the master.trac branch? Should users checkout this branch, or is it just there for referencing data?


[author here] Hey sorry, git-subtrac is new and I didn't know what to put in the docs. To quickly answer your questions:

1. You should run it every time you make a change in a submodule.

2. You commit inside the subrepo, then run 'git subtrac update' in the parent repo. You don't need to push the subrepo anymore unless you want to (eg. because you're submitting upstream). You do need to push the new .trac branch in the parent repo somewhere - probably to the upstream parent repo.

3. Yes, exactly right.

4. It exists just to create references to all the objects in all the submodules. If you push it somewhere, then you can fetch all your submodules from there. The most common place to put it is in the parent repo, so that cloning that repo gives your users a clone of all the dependent submodules too.

Hope this helps!


What's the use case for this? The way I see it is that `git submodule` and `git subtree` (and it's much better variant git subrepo) have two different optimal use cases with a huge amount of grey area in between.

Git subtree is your better option if your repo is one logical thing, and git submodule is your better option if you repo is a sparse collection of things.

AFAICT, git subtrac is aimed more at the git subtree / git subrepo use case since it stores the submodule commits in the parent repo? If so, what are the pros & cons versus git subrepo?

https://github.com/ingydotnet/git-subrepo


My understanding is that git-subtrac is more like git-submodule, except that the submodule repository histories are copied into the parent repo (separate from the parent repo history) and tracked using an auxiliary .trac branch. I guess subtrac is short for submodule tracker.


I really don't care what the underlying technology is, just more about how the design decisions affect it's applicability to my use cases.

For example, one advantage of git submodules over git subrepo is that it allows much smaller repositories. Since subtrac copies the commits into the parent repo, it doesn't have that advantage.

That's one reason among several why I say that subtrac looks more like subrepo even though it's built on submodule tech.


> For example, one advantage of git submodules over git subrepo is that it allows much smaller repositories. Since subtrac copies the commits into the parent repo, it doesn't have that advantage.

I don't think there would be a size benefit regardless, since you would still be cloning the submodule from somewhere.

There are good reasons why you would want the contents of a submodule to remain a submodule. If you have a documentation wiki, or some sort of helper program, or a data repo, you would probably be better having it be a submodule. But submodules are awkward for a variety of reasons.


Basically, git-subtree without history mangling, by turning each commit into the child of itself plus all the submodule link commits. No more disappeared upstreams or uninitialized submodules. Seems nice.

Note that this is from the original author of git-subtree. If this turns out to be a good idea, I wonder if it will make it into git/contrib, too (is a contrib written in golang even possible?).


> (is a contrib written in golang even possible?)

    $ cd ~/src/github.com/git/git
    $ git ls-files '*.go'
    contrib/persistent-https/client.go
    contrib/persistent-https/main.go
    contrib/persistent-https/proxy.go
    contrib/persistent-https/socket.go

empirically, yes


Hah! Checked languages at https://github.com/git/git, only saw C, Make, and scripting languages. Apparently Go is buried under “Other”.


A subtool can ostensibly be written in any language. IIRC there's already bash, posix-ish shell, perl and tcl/tk.


> bash, posix-ish shell, perl and tcl/tk.

Noticed any common thread there? All scripting languages.


We have been using this since it was announced for our main repository. (The author of git-subtrac is my cofounder.) It is a definite improvement on storing submodules in separate repositories, where one of us would forget to push a commit and the other of us would have to wait for them to be online to get it.

There is still more needed to make git submodules a pleasant user experience, but this was a big missing piece of the puzzle. (Submodules mean to you need to know a ton about how git works before you can do even the most basic things.)


Cool! This is a problem I've been trying to solve.

One of my biggest annoyances was how you may have multiple submodules that are tightly related to your project, but have to be in external repos that may not logically map well.

One trick I started doing was to put the actual submodule repos physically inside my parent repos on my server, and then in my .gitmodules, using the relative directory like ./submodule1.git

So, that means:

  parent/ --> server:parent.git  
  parent/submodule1/ --> server:parent.git/submodule1.git
I have also been using orphan worktrees as well.

The reason this is such a big deal, is that for many of the data projects I work on, the different repos, while closely related, should really have completely separate history. This is because I use tools like git-annex and git-lfs to access and push large datasets within git, and it would make no sense at all to mix that in with documentation and code. I sometimes use Datalad, which handles a lot of this, but had some of its own quirks and can be overkill some times.

I'm certain to give this a try.

Such as:

  parent/  
    imaging_input/ (12G of 50G checked out w/ git-annex)  
    imaging_diffs_input/ (5G git-lfs)  
    imaging_output (git-annex)  
    logs_output/ (git-annex)  
    code/  
    wiki/
[1]: http://handbook.datalad.org/en/latest/basics/101-106-nesting...


And after I just spent several hours of headaches rebasing and wrangling git subtree and attempting to git rebase -i branch -s subtree --rebase-merges --allow-unrelated-histories (which doesn't work)...

Request: Is it possible to import only one subdirectory of another Git repository as a subtree (excluding unit tests and build scripts and such)?


Git subrepo can import a subdirectory. To oversimplify, it's a wrapper for git subtree that keeps metadata information in both your filesystem and your history so that things stay sane.

https://github.com/ingydotnet/git-subrepo


Does subrepo break when you rebase both a commit and its parent? I recall doing something like that in the past, and subrepo stopped working.


Version 0.4.0 of subrepo has been rock solid for us and has handled everything that's been thrown at it; prior versions wouldn't handle odd situations well. Whether our "odd situations" line up with yours is a different question...

Edit: to be clear; even before 0.4.0 git subrepo handled strange situations better than git subtree did mostly because git subtree requires so much more manual work that's easy to get wrong.


The 'git-subtree' tool (by the same author as this tool) can import subdirectories.


More precisely, git-subtree can extract subdirectories into their own repo, and merge repos into subdirectories.

What someone might want to try is extracting a subdirectory using git-subtree, and then importing it elsewhere using git-subtrac.


Use git-filter-branch with --subdirectory-filter to create a new repo (with history preserved) followed by git-subtree.


Nothing makes git simpler than adding another complicated command :)


That's why I went with git-subrepo [0] over submodules.

[0]: https://github.com/ingydotnet/git-subrepo


Great idea, I think I can come up with another command to help with this. https://xkcd.com/927/




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: