Teach git to change to a given directory using -C option
PATCH v2 1/1 Teach git to change to a given directory using -C option
Quoted 6 lines · Eric Sunshine
Quoted 1 line · Nazri Ramliy
With this new option, the above can be done with less keystrokes:
Grammar: s/less/fewer/
More below...
Thanks for taking the time to review this patch! The fix for the above, and the following issues are in the re-roll below.
Quoted 2 lines
The synopsis at the top of git.txt mentions --git-dir and --work-tree. For consistency, -C probably ought to be mentioned there, as well.
Fixed.
Quoted 3 lines
Other options which accept a directory, such as --git-dir and --work-tree, are documented as accepting <path>, but -C is inconsistently documented as accepting <directory>.
Fixed.
Quoted 7 lines
Quoted 4 lines
+ 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 optionsThe fragment "interpreted relative" seems ambiguous when absolute paths are involved.
In this re-roll the above text is now:
-C <path>::
Run as if git were started in <path> instead of the current working directory. If multiple -C options are given, subsequent relative <path> arguments is interpreted relative to the previous effective directory:
"-C /usr -C src" is equivalent to "-C /usr/src", while "-C src -C /usr" is equivalent to "C /usr". This option ...
Quoted 6 lines
For existing options accepting an argument, the argument is formatted as <argument>. The -C option does not follow suit.
As mentioned above, all other options accepting a directory are documented as taking <path>, but -C is inconsistent and is documented as taking 'directory' instead.
Fixed as "[-C <path>]"
Quoted 4 lines
Quoted 1 line
+test_description='"-C <directory>" option and it effects on other path-related options'
s/it/its/
s/<directory>/<path>/
Fixed.
Quoted 3 lines
Quoted 1 line
+test_expect_success '"git -C <dir>" runs git from the directory <dir>' '
s/<dir>/<path>/g
Fixed.
Quoted 7 lines
Modern git tests tend to place the expected and actual outputs in files and then use
test_cmpto verify that they are identical. For instance:echo "initial in dir1" >expected &&
git -C dir1 log --format="%s" >actual &&
test_cmpexpected actual
Fixed.
Quoted 2 lines
It would make sense also to test multiple -C options with combinations of absolute and and relative paths.
Fixed - I've added one more test for testing that "-C ./here -C /there" is equivalent to "-C /there" at the end of t0056-git-C.sh.
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.
--- Documentation/git.txt | 16 +++++++++- git.c | 15 ++++++++-- t/t0056-git-C.sh | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 3 deletions(-) create mode 100755 t/t0056-git-C.sh
Documentation/git.txt +15 -1
@@ -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 were started in <path> instead of the current working + directory. If multiple -C options are given, subsequent relative <path> + arguments are interpreted relative to the previous effective directory: + "-C /usr -C src" is equivalent to "-C /usr/src", while "-C src -C /usr" + is equivalent to "C /usr". 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.
git.c +13 -2
@@ -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 );
t/t0056-git-C.sh new file +83 -0
83 lines not on this page · raw message
Signature · 1 line
1.8.4.24.g5fcd118
Quoted 5 lines · Nazri Ramliy
Documentation/git.txt +0
-0
Documentation/git.txt displayed. See linkgit:git-help[1] for more information, · line 403
Quoted 9 lines
Documentation/git.txt +6
-0@@ -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 were started in <path> instead of the current working + directory. If multiple -C options are given, subsequent relative <path> + arguments are interpreted relative to the previous effective directory: + "-C /usr -C src" is equivalent to "-C /usr/src", while "-C src -C /usr" + is equivalent to "C /usr". This option affects options that expect path
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 ...
Quoted 18 lines
t/t0056-git-C.sh new file +12
-0@@ -0,0 +1,83 @@ +#!/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 &&
t/t0056-git-C.sh line 22
Quoted 10 lines
t/t0056-git-C.sh new file +10
-0+ 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 && + expected="initial in dir1/dir2" + echo $expected >expected && + git -C dir1/dir2 commit -m "$expected" &&
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.)
t/t0056-git-C.sh line 79
Quoted 7 lines
t/t0056-git-C.sh new file +7
-0+ git -C dir1 -C dir2 log --format=%s >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 &&
It is suggested in t/README that, for Windows (MSYS bash) compatibility, you should use $(pwd) rather than $PWD.
Quoted 6 lines
t/t0056-git-C.sh new file +4
-1+ test_cmp expected actual +' + +test_done --1.8.4.24.g5fcd118