From: Nazri Ramliy <ayiehere@gmail.com>
To: Eric Sunshine <sunshine@sunshineco.com>
Cc: Git List <git@vger.kernel.org>, Jeff King <peff@peff.net>,
Jonathan Nieder <jrnieder@gmail.com>
Subject: [PATCH v3] Teach git to change to a given directory using -C option
Date: Tue, 3 Sep 2013 19:59:47 +0800 [thread overview]
Message-ID: <20130903115944.GA29542@gmail.com> (raw)
On Tue, Sep 3, 2013 at 3:42 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:
> No wish to bike-shed, however, I find "effective directory" somewhat
> difficult to digest due to its jargony feel. It also seems ambiguous
> (to me) since "previous effective directory" may mean "directory when
> git was run" or "directory set by most recent -C". My earlier
> suggestion
>
> When multiple -C options are given, each subsequent non-absolute
> -C <path> is interpreted relative to the preceding -C <path>.
>
> avoided jargon and left no room for ambiguity.
>
> However, perhaps the examples are clear enough to make excessive prose
> explanation unnecessary, thus:
>
> Run as if git was started in <path> instead of the current
> working directory. Multiple -C options are allowed and acted upon
> in the order given, thus "-C /usr -C src" is equivalent to "-C
> /usr/src", and "-C src -C /usr" is equivalent to "C /usr". This
> option affects ...
I did feel that the explanation is becoming wordy. I'll take the former
as it is terser. I've split the part that explain the effects on other
options that take path argument into a separate paragraph.
> It's curious that this test uses a variable ($expected) to avoid
> repeating literal "initial in dir1/dir2", however, the previous test
> repeats its literal "initial in dir1". (IMHO, the repeated literal
> actually makes the test a bit easier to read, and it's not likely to
> be a maintenance burden.)
Fixed.
> It is suggested in t/README that, for Windows (MSYS bash)
> compatibility, you should use $(pwd) rather than $PWD.
Fixed.
Thanks for another round of review!
nazri
-- >8 --
Subject: [PATCH] Teach git to change to a given directory using -C option
This is similar in spirit to to "make -C dir ..." and "tar -C dir ...".
Currently it takes more effort (keypresses) to invoke git command in a
different directory than the current one without leaving the current
directory:
1. (cd ~/foo && git status)
git --git-dir=~/foo/.git --work-dir=~/foo status
GIT_DIR=~/foo/.git GIT_WORK_TREE=~/foo git status
2. (cd ../..; git grep foo)
3. for d in d1 d2 d3; do (cd $d && git svn rebase); done
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 with fewer keystrokes:
1. git -C ~/foo status
2. git -C ../.. grep foo
3. for d in d1 d2 d3; do git -C $d svn rebase; done
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>
---
Documentation/git.txt | 16 +++++++++-
git.c | 15 ++++++++--
t/t0056-git-C.sh | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 110 insertions(+), 3 deletions(-)
create mode 100755 t/t0056-git-C.sh
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 83edf30..6105cb0 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -9,7 +9,7 @@ git - the stupid content tracker
SYNOPSIS
--------
[verse]
-'git' [--version] [--help] [-c <name>=<value>]
+'git' [--version] [--help] [-C <path>] [-c <name>=<value>]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
@@ -395,6 +395,20 @@ displayed. See linkgit:git-help[1] for more information,
because `git --help ...` is converted internally into `git
help ...`.
+-C <path>::
+ Run as if git was started in <path> instead of the current working
+ directory. When multiple -C options are given, each subsequent
+ non-absolute "-C <path>" is interpreted relative to the preceding "-C
+ <path>".
+
+ 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 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 2025f77..52bce74 100644
--- a/git.c
+++ b/git.c
@@ -7,7 +7,7 @@
#include "commit.h"
const char git_usage_string[] =
- "git [--version] [--help] [-c name=value]\n"
+ "git [--version] [--help] [-C <path>] [-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"
@@ -54,7 +54,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..c0006da
--- /dev/null
+++ b/t/t0056-git-C.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+test_description='"-C <path>" option and its effects on other path-related options'
+
+. ./test-lib.sh
+
+test_expect_success '"git -C <path>" runs git from the directory <path>' '
+ test_create_repo dir1 &&
+ echo 1 >dir1/a.txt &&
+ (cd dir1 && git add a.txt && git commit -m "initial in dir1") &&
+ echo "initial in dir1" >expected &&
+ git -C dir1 log --format=%s >actual &&
+ test_cmp 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 &&
+ echo "initial in dir1/dir2" >expected &&
+ git -C dir1/dir2 commit -m "initial in dir1/dir2" &&
+ git -C dir1 -C dir2 log --format=%s >actual &&
+ test_cmp 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" &&
+ git --git-dir=c/a.git log -1 --format=%s >expected &&
+ git -C c --git-dir=a.git log -1 --format=%s >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'Order should not matter: "--git-dir=a.git -C c" is equivalent to "-C c --git-dir=a.git"' '
+ git -C c --git-dir=a.git log -1 --format=%s >expected &&
+ git --git-dir=a.git -C c log -1 --format=%s >actual &&
+ test_cmp 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 &&
+ git --git-dir=c/a.git --work-tree=c/a status >expected &&
+ git -C c/a.git --work-tree=../a status >actual &&
+ test_cmp 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"' '
+ git -C c/a.git --work-tree=../a status >expected &&
+ git --work-tree=../a -C c/a.git status >actual &&
+ test_cmp 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"' '
+ git --git-dir=c/a.git --work-tree=c/a status >expected &&
+ git -C c --git-dir=a.git --work-tree=a status >actual &&
+ test_cmp 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"' '
+ git -C c --git-dir=a.git --work-tree=a status >expected &&
+ git --git-dir=a.git -C c --work-tree=a status >actual &&
+ test_cmp 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"' '
+ git -C c --git-dir=a.git --work-tree=a status >expected &&
+ git --git-dir=a.git --work-tree=a -C c status >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'Relative followed by fullpath: "-C ./here -C /there" is equivalent to "-C /there"' '
+ echo "initial in dir1/dir2" >expected &&
+ git -C dir1 -C "$(pwd)/dir1/dir2" log --format=%s >actual &&
+ test_cmp expected actual
+'
+
+test_done
--
1.8.4.22.g38647a4
next reply other threads:[~2013-09-03 11:59 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-09-03 11:59 Nazri Ramliy [this message]
2013-09-03 22:46 ` [PATCH v3] Teach git to change to a given directory using -C option Junio C Hamano
2013-09-03 23:37 ` Eric Sunshine
2013-09-04 6:36 ` Nazri Ramliy
2013-09-04 6:45 ` Eric Sunshine
2013-09-04 12:20 ` Nazri Ramliy
2013-09-08 10:32 ` Eric Sunshine
2013-09-09 1:49 ` Nazri Ramliy
2013-09-09 5:01 ` Eric Sunshine
2013-09-09 13:47 ` Nazri Ramliy
2013-09-09 16:32 ` Junio C Hamano
2013-09-09 17:42 ` Eric Sunshine
2013-09-09 17:59 ` Junio C Hamano
2013-09-09 18:43 ` 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=20130903115944.GA29542@gmail.com \
--to=ayiehere@gmail.com \
--cc=git@vger.kernel.org \
--cc=jrnieder@gmail.com \
--cc=peff@peff.net \
--cc=sunshine@sunshineco.com \
/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).