From: Nazri Ramliy <ayiehere@gmail.com>
To: peff@peff.net, git@vger.kernel.org
Cc: Nazri Ramliy <ayiehere@gmail.com>
Subject: [PATCH] Teach git to change to a given directory using -C option
Date: Sun, 21 Apr 2013 21:48:46 +0800 [thread overview]
Message-ID: <1366552126-6090-1-git-send-email-ayiehere@gmail.com> (raw)
In-Reply-To: <20130419161250.GC14263@sigill.intra.peff.net>
This is similar in spirit to to "make -C dir ..." and "tar -C dir ...".
Currently finding out the status of a git repository that is located
away from the current working directory without going to that directory
can be done in the following ways:
1. (cd ~/foo && git status)
2. git --git-dir=~/foo/.git --work-dir=~/foo status
3. GIT_DIR=~/foo/.git GIT_WORK_TREE=~/foo git status
While doable the methods shown above are arguably more suitable for
scripting than quick command line invocations.
With this new option, the above can be done a bit more tersely:
$ git -C ~/foo status
A new test script is added to verify the behavior of this option with
other path-related options like --git-dir and --work-tree.
Signed-off-by: Nazri Ramliy <ayiehere@gmail.com>
---
Jeff: Thanks for pointing out the mistakes.
But I did not address your concern:
> I know you are copying this from the other options in the same function,
> but I wonder if they should all be calling "error()" (and dropping the
> terminating ".") to better match our usual error messages.
because I'd rather have that fix be done in a separate topic.
The other points raised are all valid and fixed in this new patch.
Documentation/git.txt | 13 +++++++++
git.c | 15 ++++++++--
t/t0056-git-C.sh | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 102 insertions(+), 2 deletions(-)
create mode 100755 t/t0056-git-C.sh
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 6a875f2..6064b3d 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -379,6 +379,19 @@ displayed. See linkgit:git-help[1] for more information,
because `git --help ...` is converted internally into `git
help ...`.
+-C <directory>::
+ Run as if git were started in <directory> instead of the current
+ working directory. If multiple -C options are given, subsequent
+ directory arguments are interpreted relative to the previous one: -C
+ /usr -C src is equivalent to -C /usr/src. This option affects options
+ that expect path name like --git-dir and --work-tree in that their
+ interpretations of the path names would be made relative to the
+ effective working directory caused by the -C option. For example the
+ following invocations are equivalent:
+
+ git --git-dir=a.git --work-tree=b -C c status
+ git --git-dir=c/a.git --work-tree=c/b status
+
-c <name>=<value>::
Pass a configuration parameter to the command. The value
given will override values from configuration files.
diff --git a/git.c b/git.c
index 1ada169..a8731e9 100644
--- a/git.c
+++ b/git.c
@@ -6,7 +6,7 @@
#include "run-command.h"
const char git_usage_string[] =
- "git [--version] [--help] [-c name=value]\n"
+ "git [--version] [--help] [-C directory] [-c name=value]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
" [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]\n"
" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
@@ -53,7 +53,18 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
/*
* Check remaining flags.
*/
- if (!prefixcmp(cmd, "--exec-path")) {
+ if (!strcmp(cmd, "-C")) {
+ if (*argc < 2) {
+ fprintf(stderr, "No directory given for -C.\n" );
+ usage(git_usage_string);
+ }
+ if (chdir((*argv)[1]))
+ die_errno("Cannot change to '%s'", (*argv)[1]);
+ if (envchanged)
+ *envchanged = 1;
+ (*argv)++;
+ (*argc)--;
+ } else if (!prefixcmp(cmd, "--exec-path")) {
cmd += 11;
if (*cmd == '=')
git_set_argv_exec_path(cmd + 1);
diff --git a/t/t0056-git-C.sh b/t/t0056-git-C.sh
new file mode 100755
index 0000000..370eae6
--- /dev/null
+++ b/t/t0056-git-C.sh
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+test_description='"-C <directory>" option and it effects on other path-related options'
+
+. ./test-lib.sh
+
+test_expect_success '"git -C <dir>" runs git from the directory <dir>' '
+ test_create_repo dir1 &&
+ echo 1 >dir1/a.txt &&
+ (cd dir1 && git add a.txt && git commit -m "initial in dir1") &&
+ expected="initial in dir1" &&
+ actual=$(git -C dir1 log --format=%s) &&
+ test "$expected" = "$actual"
+'
+
+test_expect_success 'Multiple -C options: "-C dir1 -C dir2" is equivalent to "-C dir1/dir2"' '
+ test_create_repo dir1/dir2 &&
+ echo 1 >dir1/dir2/a.txt &&
+ git -C dir1/dir2 add a.txt &&
+ expected="initial in dir1/dir2" &&
+ git -C dir1/dir2 commit -m "$expected" &&
+ actual=$(git -C dir1 -C dir2 log --format=%s) &&
+ test "$expected" = "$actual"
+'
+
+test_expect_success 'Effect on --git-dir option: "-C c --git-dir=a.git" is equivalent to "--git-dir c/a.git"' '
+ mkdir c &&
+ mkdir c/a &&
+ mkdir c/a.git &&
+ (cd c/a.git && git init --bare) &&
+ echo 1 >c/a/a.txt &&
+ git --git-dir c/a.git --work-tree=c/a add a.txt &&
+ git --git-dir c/a.git --work-tree=c/a commit -m "initial" &&
+ expected="$(git --git-dir=c/a.git log -1 --format=%s)" &&
+ actual=$(git -C c --git-dir=a.git log -1 --format=%s) &&
+ test "$expected" = "$actual"
+'
+
+test_expect_success 'Order should not matter: "--git-dir=a.git -C c" is equivalent to "-C c --git-dir=a.git"' '
+ expected="$(git -C c --git-dir=a.git log -1 --format=%s)" &&
+ actual=$(git --git-dir=a.git -C c log -1 --format=%s) &&
+ test "$expected" = "$actual"
+'
+
+test_expect_success 'Effect on --work-tree option: "-C c/a.git --work-tree=../a" is equivalent to "--work-tree=c/a --git-dir=c/a.git"' '
+ rm c/a/a.txt &&
+ expected="$(git --git-dir=c/a.git --work-tree=c/a status)" &&
+ actual="$(git -C c/a.git --work-tree=../a status)" &&
+ test "$expected" = "$actual"
+'
+
+test_expect_success 'Order should not matter: "--work-tree=../a -C c/a.git" is equivalent to "-C c/a.git --work-tree=../a"' '
+ expected="$(git -C c/a.git --work-tree=../a status)" &&
+ actual="$(git --work-tree=../a -C c/a.git status)" &&
+ test "$expected" = "$actual"
+'
+
+test_expect_success 'Effect on --git-dir and --work-tree options - "-C c --git-dir=a.git --work-tree=a" is equivalent to "--git-dir=c/a.git --work-tree=c/a"' '
+ expected="$(git --git-dir=c/a.git --work-tree=c/a status)" &&
+ actual="$(git -C c --git-dir=a.git --work-tree=a status)" &&
+ test "$expected" = "$actual"
+'
+
+test_expect_success 'Order should not matter: "-C c --git-dir=a.git --work-tree=a" is equivalent to "--git-dir=a.git -C c --work-tree=a"' '
+ expected="$(git -C c --git-dir=a.git --work-tree=a status)" &&
+ actual="$(git --git-dir=a.git -C c --work-tree=a status)" &&
+ test "$expected" = "$actual"
+'
+
+test_expect_success 'Order should not matter: "-C c --git-dir=a.git --work-tree=a" is equivalent to "--git-dir=a.git --work-tree=a -C c"' '
+ expected="$(git -C c --git-dir=a.git --work-tree=a status)" &&
+ actual="$(git --git-dir=a.git --work-tree=a -C c status)" &&
+ test "$expected" = "$actual"
+'
+
+test_done
--
1.8.2.1.339.g52a3e01
next prev parent reply other threads:[~2013-04-21 13:49 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-19 12:21 [PATCH] Teach git to change to a given directory using -C option Nazri Ramliy
2013-04-19 16:12 ` Jeff King
2013-04-20 22:18 ` Jonathan Nieder
2013-04-21 3:58 ` Jeff King
2013-04-21 13:48 ` Nazri Ramliy [this message]
-- strict thread matches above, loose matches on Subject: below --
2013-08-30 13:35 Nazri Ramliy
2013-09-01 4:48 ` Eric Sunshine
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1366552126-6090-1-git-send-email-ayiehere@gmail.com \
--to=ayiehere@gmail.com \
--cc=git@vger.kernel.org \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).