Re: Simulating an empty git repository without having said repository on disk
On Mon, Jan 16, 2012 at 21:41, Jeff King <peff@peff.net> wrote:
> I don't use vcsh, but I seem to recall that it works by overlaying the
> working trees of different repositories on each other, right?
> So you
> can't just say "oh, files in foo/ belong to repository 'bar'". You must
> take the union of the set of tracked files from all repos, then find the
> difference of that from the set of all files.
> Can individual repos mark things as excluded, too? Or do you have a
> master exclusion list? I.e., if I decide that I don't want "foo" tracked
> at all, how do I tell vcsh?
That's something I am still contemplating as there are several ways:
* excludes
* pre-/appends to the gitignore of every repo
* runtime magic
Feedback welcome :)
Show 5 quoted lines
> I'm not sure why you care about the empty tree if you are only looking
> at untracked files. Or perhaps the problem is that you are using "git
> status", which fundamentally cares about looking at differences between
> HEAD and the index, even though you don't care in this case. In that case,
> maybe "git ls-files -o" would be more appropriate?
--others does not work as I need to look at several repos. I tried to get the union of --others, but that creates 'argument too large' very quickly.
Initially, I tried with find, but as that is depth-first, it takes ages when compared to git's early stopping at directories.
Show 21 quoted lines
> The most straightforward way in git would be to generate a temporary
> index that mentions all of the tracked files, like this:
>
> tmp=/some/tmp/index
> rm -f $tmp
> for i in repo; do
> git --git-dir=$repo ls-files -z |
> GIT_INDEX_FILE=$tmp xargs -0 git update-index --add
> done
> GIT_INDEX_FILE=$tmp git ls-files -o
>
> but that is very close to your "create an empty git repo" (in fact, you
> might even need to in order for update-index to be happy). But it would
> give you a place to put a master exclusion list (you would use it as
> --exclude=... in the final ls-files).
>
> If you have per-repo exclusion lists, then you could take a different
> approach, and simply run "git ls-files -o" for each repository. Any
> files which appeared in _every_ output would be untracked (since tracked
> files or individually-excluded files would be omitted from at least one
> repo). Like:
See above, but I will try yours as well.
> perl -lne "/^\s*$count (.*)/ and print \$1"
I know I sound picky, but I would also like to avoid any third-party dependencies if possible. Perl is common, but not installed everywhere.
> The downside is that you are doing $count traversals of the untracked
> directories. On an OS with a reasonable lstat and a directory structure
> that fits into cache, that is probably not too big a deal, though.
With cold cache, it can take ages. Especially once you have a few git-annex repos in $HOME.
> I took a lot of guesses at exactly what you want. It might be more clear
> if you gave us an example situation along with the output you expect.
repo foo tracks .foo and .foo.d, bar .bar, etc
% vcsh list #lists repos foo bar baz % ls -aR .foo .foo.d/ .bar .baz.d/ .quux.d/ .quux.d/foo .quux.d/quux.d/quux .quux.d/quux.d/quuux .quux.d/quux.d/quuuux .quux.d/quuuux.d/quuuux pants shirts % vcsh run foo git ls-files # run command in context of repo foo .foo .foo.d .quux.d/foo % vcsh list-untracked # with the code I want in it .quux.d/quux.d/ .quux.d/quuuux.d/ pants shirts %
I hope that makes sense.
The only part that does not already work today is list-untracked.
For failed attempts look at https://github.com/RichiH/vcsh/tree/list-untracked https://github.com/RichiH/vcsh/tree/list-untracked-2
Thanks, Richard