Lars Hjemli <hje...@gmail.com> writes:

> diff --git a/Documentation/git-for-each-repo.txt 
> b/Documentation/git-for-each-repo.txt
> new file mode 100644
> index 0000000..be49e96
> --- /dev/null
> +++ b/Documentation/git-for-each-repo.txt
> @@ -0,0 +1,62 @@
> +git-for-each-repo(1)
> +====================
> +
> +NAME
> +----
> +git-for-each-repo - Execute a git command in multiple repositories

"multiple non-bare repositories", I think.

> +
> +SYNOPSIS
> +--------
> +[verse]
> +'git for-each-repo' [--all|--clean|--dirty] [command]
> +
> +DESCRIPTION
> +-----------
> +The git-for-each-repo command is used to locate all git repositoris

Likewise; "all non-bare Git repositories".

> diff --git a/t/t6400-for-each-repo.sh b/t/t6400-for-each-repo.sh
> new file mode 100755
> index 0000000..4797629
> --- /dev/null
> +++ b/t/t6400-for-each-repo.sh
> @@ -0,0 +1,48 @@
> +#!/bin/sh
> +#
> +# Copyright (c) 2013 Lars Hjemli
> +#
> +
> +test_description='Test the git-for-each-repo command'
> +
> +. ./test-lib.sh
> +
> +test_expect_success "setup" '
> +     test_create_repo clean &&
> +     (cd clean && test_commit foo) &&
> +     git init --separate-git-dir=.cleansub clean/gitfile &&
> +     (cd clean/gitfile && test_commit foo && echo bar >>foo.t) &&
> +     test_create_repo dirty-wt &&
> +     (cd dirty-wt && mv .git .linkedgit && ln -s .linkedgit .git &&
> +       test_commit foo && rm foo.t) &&
> +     test_create_repo dirty-idx &&
> +     (cd dirty-idx && test_commit foo && git rm foo.t) &&
> +     mkdir fakedir && mkdir fakedir/.git
> +'
> +
> +test_expect_success "without flags, all repos are included" '
> +     echo "." >expect &&
> +     echo "clean" >>expect &&
> +     echo "clean/gitfile" >>expect &&
> +     echo "dirty-idx" >>expect &&
> +     echo "dirty-wt" >>expect &&
> +     git for-each-repo | sort >actual &&
> +     test_cmp expect actual
> +'
> +
> +test_expect_success "--dirty only includes dirty repos" '
> +     echo "clean/gitfile" >expect &&
> +     echo "dirty-idx" >>expect &&
> +     echo "dirty-wt" >>expect &&
> +     git for-each-repo --dirty | sort >actual &&
> +     test_cmp expect actual
> +'
> +
> +test_expect_success "--clean only includes clean repos" '
> +     echo "." >expect &&
> +     echo "clean" >>expect &&
> +     git for-each-repo --clean | sort >actual &&
> +     test_cmp expect actual
> +'

Please add tests to show some command executions (e.g. test output
from "git ls-files", or something).

> +static void handle_repo(char *path, const char **argv)
> +{
> +     if (path[0] == '.' && path[1] == '/')
> +             path += 2;
> +     if (match != ALL && match != get_repo_state())
> +             return;
> +     if (*argv) {
> +             color_fprintf_ln(stdout, GIT_COLOR_YELLOW, "[%s]", path);
> +             run_command_v_opt(argv, RUN_GIT_CMD);

This seems to allow people to run only a single Git subcommand,
which is probably not what most people want to see.  Don't we want
to support something as simple as this?

        git for-each-repository sh -c "ls *.c"

> +     } else
> +             printf("%s\n", path);

Assuming that the non *argv case is for consumption by programs and
scripts (similar to the way "ls-files" output is piped to downstream),
we prefer to (1) support "-z" so that "xargs -0" can read paths with
funny characters, and (2) use quote_c_style() from quote.c when "-z"
is not in effect.

> +}
> + ...
> +                     setenv(GIT_DIR_ENVIRONMENT, gitdir, 1);
> +                     strbuf_setlen(path, len - 1);
> +                     setenv(GIT_WORK_TREE_ENVIRONMENT, path->buf, 1);
> +                     handle_repo(path->buf, argv);

When you are only showing the path to a repository, I do not think
you want setenv() or chdir() at all. Shouldn't these be done inside
handle_repo() function?  As you are only dealing with non-bare
repositories (and that is what you print in "listing only" mode
anyway), handle_repo() can borrow path (not path->buf) and append
and strip "/.git" as needed.

Also, while it is a good idea to protect this program from stray
GIT_DIR/GIT_WORK_TREE the user may have in the environment when this
program is started, I think this is not enough, if you allow the
*argv commands to run worktree related operations in each repository
you discover.  You would need to chdir() to the top of the working
tree.

The run-command API lets you specify custom environment only for the
child process without affecting yourself by setting .env member of
the child_process structure, so we may want to use that instead of
doing setenv() on ourselves (and letting it inherited by the child).

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to