fboender/multi-git-status

targeting git repos with a nonstandard name/path?

Opened this issue · 4 comments

It would be nice to be able to point mgitstatus at nonstandard git repos.

My personal use-case is the yadm dotfile manager https://github.com/TheLocehiliosan/yadm, which is uses a distinct path. Typically we'd just interact with that repo via yadm <git-sub-command>..., but we can also do something like GIT_DIR=~/.yadm/git.repo git status to run plain git commands against it.

I'm not sure what's best in terms of syntax/implementation (I can imagine a few different ways...) but a fairly simple idea is a flag to specify one -name to the find command. For example, I can use something like this to match all of the git repositories mgitstatus finds, plus the yadm repo I mentioned: find -L . -maxdepth 3 -type d -name "*.git" (I had to adjust the maxdepth up 1, though, since that's matching deeper in the tree).

Another (more flexible, but maybe overkill?) option would just be, whether through accepting paths last with a flag to change the meaning, or a git-style -- path separator, support passing an explicit list of paths directly to the git repositories themselves, and let the user do whatever makes sense in their case.

If I understand you correctly, you mean support for work trees that are different than the location of the .git dir? I think they're called "detached working dirs" or something. Like this:

# Create a separate "checkout" in ~/Temp/mgs/
$ git --git-dir ~/Projects/fboender/multi-git-status/.git --work-tree ~/Temp/mgs reset --hard

I suspect that this is what yadm does under the hood, much like other dotfile managers.

Multi-git-status needs to know both the working dir and the .git dir locations. Otherwise, it cannot give meaningful information on much of the state of a repository. However, there is no link between the two (unless the .git dir is in the working dir), and no way for multi-git-status to figure out their locations.

For example, I can use something like this to match all of the git repositories mgitstatus finds, plus the yadm repo I mentioned: find -L . -maxdepth 3 -type d -name "*.git"

This is already what mgitstatus does at the moment. See line 128. But mgitstatus needs both the .git dir and the working tree.

I currently don't see a very user-friendly way on the commandline for the user to provide a mapping between where the .git files are located and where the working tree is for multiple repositories. Unless I add something like a configuration / mapping file. Perhaps something like this:

# <work tree> [.git path]
/home/fboender/Temp/mgs /home/fboender/Projects/fboender/multi-git-status/.git
/home/fboender/foo /home/fboender/Projects/fboender/foo/.git

That's a bit of a departure from the way mgitstatus works now. I'm not sure it's worth it to support such a (I assume) fringe use-case.

Good point. I agree that it's probably an edge-case that doesn't justify significantly complicating anything.

I'll try to find some time to think on/poke at the source.

Had a little time to pick at implementing this directly in command syntax. The basic functionality is pretty simple, but finding logical/syntactical space for it is a little trickier...

Here are the main ways I've thought about it:

  1. Accept additional positional args and treat each pair as a work_tree and git_dir.
    • This keeps the conceptual code change pretty small.
    • But it would block you from adding more positional args, which you might justifiably object to :)
    • I don't recall having seen paired positional args as a pattern before. May be some confusion around communicating it.
  2. Do the same as 1 above, but require a lone -- arg to separate them.
    • This would preserve space for more positional args.
    • -- is already a git syntax idiom, and this does use it in a similar-but-not-identical way.
  3. Make a separate version of the command/script to handle this use-case.
    • Could be an advanced/explicit version that supports all behavior, or just laser-focused on this edge case.
    • Doesn't burden existing syntax or take up space in the potential syntax space.
    • But, keeping it DRY would mean separating parts and generating the existing executable script and a new one.
  4. Use a flag (whatever short/long flag you prefer; I used -x for explicit when I tried this)
    • to indicate a different syntax mode that interprets all positional arguments differently
      • doesn't really fit in with existing arg/syntax patterns, so documenting/communicating/understanding may all be harder
    • supply once per target repo (as many times as desired), and consume the next 2 arguments,
      • the current arg parsing model doesn't square well with this; implementation/diff likely more complex/involved
      • consuming 2 args per flag is a little surprising

Curious how these strike you.