"git read-tree -m" and the like require worktree
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/9 "git read-tree -m" and the like require worktree
--- builtin-read-tree.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
builtin-read-tree.c +3 -0
@@ -219,6 +219,9 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)if ((opts.dir && !opts.update))die ("--exclude-per-directory is meaningless unless -u" ); +if (opts.merge) +setup_work_tree (); +if (opts.prefix) {int pfxlen =strlen (opts.prefix);int pos;
Signature · 1 line
1.5.4.2.281.g28d0e
Quoted 10 lines · Nguyễn Thái Ngọc Duy
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>--- builtin-read-tree.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)builtin-read-tree.c +0
-0
builtin-read-tree.c int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) · line 227
Quoted 9 lines
builtin-read-tree.c +3
-0@@ -219,6 +219,9 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)if ((opts.dir && !opts.update))die ("--exclude-per-directory is meaningless unless -u" ); +if (opts.merge) +setup_work_tree (); +if (opts.prefix) {int pfxlen =strlen (opts.prefix);int pos;
How would this interact with "read-tree -m -i"?
Quoted 16 lines · Junio C Hamano
Quoted 13 lines · Nguyễn Thái Ngọc Duy
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>--- builtin-read-tree.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)builtin-read-tree.c +0
-0@@ -219,6 +219,9 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)if ((opts.dir && !opts.update))die ("--exclude-per-directory is meaningless unless -u" );
Quoted 9 lines
builtin-read-tree.c int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) · line 227
Quoted 6 lines
builtin-read-tree.c +3
-0+if (opts.merge) +setup_work_tree (); +if (opts.prefix) {int pfxlen =strlen (opts.prefix);int pos;How would this interact with "read-tree -m -i"?
It setups worktree anyway. Bad. The following would be better
+ if (opts.merge && !opts.index_only)
+ setup_work_tree();
+
Signature · 1 line
Duy
PATCH 2/9 Make sure setup_git_directory is called before accessing repository
In reply to a message not in the archiveRight now setup_git_env is called automatically when needed and will not die out if $GIT_DIR is invalid. The next patch no longer guarantee that, so make sure all commands have environment properly setup before using.
--- fast-import.c | 1 + hash-object.c | 10 +++++----- index-pack.c | 2 ++ 3 files changed, 8 insertions(+), 5 deletions(-)
fast-import.c +1 -0
@@ -2377,6 +2377,7 @@ int main(int argc, const char **argv) {unsigned int i, show_stats =1 ; +setup_git_directory ();git_config (git_pack_config);if (!pack_compression_seen && core_compression_seen) pack_compression_level = core_compression_level;
hash-object.c +5 -5
@@ -42,7 +42,10 @@ int main(int argc, char **argv)int prefix_length =-1 ;int no_more_flags =0 ;int hashstdin =0 ; +int nongit =0 ; + prefix =setup_git_directory_gently (&nongit); + prefix_length = prefix ?strlen (prefix) :0 ;git_config (git_default_config);for (i =1 ; i < argc; i++) {
@@ -53,11 +56,8 @@ int main(int argc, char **argv) type = argv[i]; }else if (!strcmp (argv[i],"-w" )) { -if (prefix_length <0 ) { - prefix =setup_git_directory (); - prefix_length = - prefix ?strlen (prefix) :0 ; - } +if (nongit) +die ("Not a git repository" ); write_object =1 ; }else if (!strcmp (argv[i],"--" )) {
index-pack.c +2 -0
@@ -703,7 +703,9 @@ int main(int argc, char **argv)char *index_name_buf =NULL , *keep_name_buf =NULL ;struct pack_idx_entry **idx_objects;unsigned char sha1[20 ]; +int nongit =0 ; +setup_git_directory_gently (&nongit);git_config (git_index_pack_config);for (i =1 ; i < argc; i++) {
Signature · 1 line
1.5.4.2.281.g28d0e
PATCH 3/9 Make get_git_dir() and 'git rev-parse --git-dir' absolute path
In reply to a message not in the archive--- builtin-rev-parse.c | 14 +------------- environment.c | 1 + t/t1300-repo-config.sh | 2 +- t/t1400-update-ref.sh | 4 ++-- t/t9300-fast-import.sh | 2 +- 5 files changed, 6 insertions(+), 17 deletions(-)
builtin-rev-parse.c +1 -13
@@ -496,19 +496,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)continue ; }if (!strcmp (arg,"--git-dir" )) { -const char *gitdir =getenv (GIT_DIR_ENVIRONMENT ); -static char cwd[PATH_MAX ]; -if (gitdir) { -puts (gitdir); -continue ; - } -if (!prefix) { -puts (".git" ); -continue ; - } -if (!getcwd (cwd,PATH_MAX )) -die ("unable to get current working directory" ); -printf ("%s/.git\n" , cwd); +puts (get_git_dir ());continue ; }if (!strcmp (arg,"--is-inside-git-dir" )) {
environment.c +1 -0
@@ -51,6 +51,7 @@ static void setup_git_env(void) git_dir =getenv (GIT_DIR_ENVIRONMENT );if (!git_dir) git_dir =DEFAULT_GIT_DIR_ENVIRONMENT ; + git_dir =xstrdup (make_absolute_path (git_dir)); git_object_dir =getenv (DB_ENVIRONMENT );if (!git_object_dir) { git_object_dir =xmalloc (strlen (git_dir) +9 );
t/t1300-repo-config.sh +1 -1
@@ -497,7 +497,7 @@ test_expect_success numbers ' ' cat > expect <<EOF -fatal: bad config value for 'aninvalid.unit' in .git/config +fatal: bad config value for 'aninvalid.unit' in $(pwd)/.git/config EOF test_expect_success 'invalid unit' '
t/t1400-update-ref.sh +2 -2
@@ -169,7 +169,7 @@ test_expect_success \ 'rm -f o e git rev-parse --verify "master@{2005-05-26 23:33:01}" >o 2>e && test '"$B"' = $(cat o) && - test "warning: Log .git/logs/'"$m has gap after $gd"'." = "$(cat e)"' + test "warning: Log '"$(pwd)"'/.git/logs/'"$m has gap after $gd"'." = "$(cat e)"' test_expect_success \ 'Query "master@{2005-05-26 23:38:00}" (middle of history)' \ 'rm -f o e
@@ -187,7 +187,7 @@ test_expect_success \ 'rm -f o e git rev-parse --verify "master@{2005-05-28}" >o 2>e && test '"$D"' = $(cat o) && - test "warning: Log .git/logs/'"$m unexpectedly ended on $ld"'." = "$(cat e)"' + test "warning: Log '"$(pwd)"'/.git/logs/'"$m unexpectedly ended on $ld"'." = "$(cat e)"' rm -f .git/$m .git/logs/$m expect
t/t9300-fast-import.sh +1 -1
@@ -510,7 +510,7 @@ test_expect_success \ 'git-fast-import --export-pack-edges=edges.list <input' cat >expect <<EOF -.git/objects/pack/pack-.pack: `git rev-parse --verify export-boundary` +$(pwd)/.git/objects/pack/pack-.pack: `git rev-parse --verify export-boundary` EOF test_expect_success \ 'I: verify edge list' \
Signature · 1 line
1.5.4.2.281.g28d0e
PATCH 4/9 Make setup_work_tree() return new prefix
In reply to a message not in the archiveworktree setup inside setup_git_directory*() is not perfect. It does not take core.worktree into account. So when you do setup_work_tree(), the real work tree may be not the one setup_git_directory*() gives you. You need a new prefix in that case.
This also effectively reverts dd5c8af (Fix setup_git_directory_gently() with relative GIT_DIR & GIT_WORK_TREE). The problem is IMHO that git-diff does not setup worktree when it needs it, so setting up worktree from setup_git_directory_gently() is a fix in a wrong place.
--- builtin-blame.c | 4 +- builtin-diff-files.c | 4 ++- builtin-diff.c | 4 ++- builtin-ls-files.c | 8 ++-- builtin-read-tree.c | 2 +- builtin-rev-parse.c | 2 + builtin-rm.c | 2 +- cache.h | 2 +- git.c | 2 +- setup.c | 84 ++++++++++++++++---------------------------------- 10 files changed, 45 insertions(+), 69 deletions(-)
builtin-blame.c +2 -2
@@ -2291,6 +2291,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)/* (3) */ if (argc <= i)usage (blame_usage); + prefix =setup_work_tree (prefix); path =add_prefix (prefix, argv[i]);if (i +1 == argc -1 ) { final_commit_name = argv[i +1 ];
@@ -2306,7 +2307,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)else if (i != argc -1 )usage (blame_usage);/* garbage at end */ -setup_work_tree ();if (!has_path_in_work_tree (path))die ("cannot stat path %s: %s" , path,strerror (errno));
@@ -2354,7 +2354,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)* do not default to HEAD, but use the working tree * or "--contents". */ -setup_work_tree (); +setup_work_tree (prefix); sb.final =fake_working_tree_commit (path, contents_from);add_pending_object (&revs, &(sb.final->object),":" ); }
builtin-diff-files.c +3 -1
@@ -26,8 +26,10 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)if (!setup_diff_no_index (&rev, argc, argv, nongit, prefix)) argc =0 ; -else +else { + rev.prefix =setup_work_tree (prefix); argc =setup_revisions (argc, argv, &rev,NULL ); + }if (!rev.diffopt.output_format) rev.diffopt.output_format =DIFF_FORMAT_RAW ; result =run_diff_files_cmd (&rev, argc, argv);
builtin-diff.c +3 -1
@@ -244,8 +244,10 @@ int cmd_diff(int argc, const char **argv, const char *prefix)if (!setup_diff_no_index (&rev, argc, argv, nongit, prefix)) argc =0 ; -else +else { + rev.prefix =setup_work_tree (prefix); argc =setup_revisions (argc, argv, &rev,NULL ); + }if (!rev.diffopt.output_format) { rev.diffopt.output_format =DIFF_FORMAT_PATCH ;if (diff_setup_done (&rev.diffopt) <0 )
builtin-ls-files.c +4 -4
@@ -23,7 +23,7 @@ static int show_valid_bit;static int line_terminator ='\n' ;static int prefix_len; -static int prefix_offset; +static int prefix_offset =-1 ;static const char **pathspec;static int error_unmatch;static char *ps_matched;
@@ -435,8 +435,6 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)struct dir_struct dir;memset (&dir,0 ,sizeof (dir)); -if (prefix) - prefix_offset =strlen (prefix);git_config (git_default_config);for (i =1 ; i < argc; i++) {
@@ -569,7 +567,9 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix) }if (require_work_tree && !is_inside_work_tree ()) -setup_work_tree (); + prefix =setup_work_tree (prefix); +if (prefix_offset ==-1 ) + prefix_offset = prefix ?strlen (prefix) :0 ; pathspec =get_pathspec (prefix, argv + i);
builtin-read-tree.c +1 -1
@@ -220,7 +220,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)die ("--exclude-per-directory is meaningless unless -u" );if (opts.merge) -setup_work_tree (); +setup_work_tree (NULL );if (opts.prefix) {int pfxlen =strlen (opts.prefix);
builtin-rev-parse.c +2 -0
@@ -472,6 +472,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)continue ; }if (!strcmp (arg,"--show-prefix" )) { +if (is_inside_work_tree ()) + prefix =setup_work_tree (prefix);if (prefix)puts (prefix);continue ;
builtin-rm.c +1 -1
@@ -156,7 +156,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)usage_with_options (builtin_rm_usage, builtin_rm_options);if (!index_only) -setup_work_tree (); + prefix =setup_work_tree (prefix); pathspec =get_pathspec (prefix, argv); seen =NULL ;
cache.h +1 -1
@@ -282,7 +282,7 @@ extern const char *get_git_work_tree(void);#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"extern const char **get_pathspec (const char *prefix,const char **pathspec); -extern void setup_work_tree (void ); +extern const char *setup_work_tree (const char *prefix);extern const char *setup_git_directory_gently (int *);extern const char *setup_git_directory (void );extern const char *prefix_path (const char *prefix,int len,const char *path);
git.c +1 -1
@@ -252,7 +252,7 @@ static int run_command(struct cmd_struct *p, int argc, const char **argv)if (p->option &USE_PAGER )setup_pager ();if (p->option &NEED_WORK_TREE ) -setup_work_tree (); + prefix =setup_work_tree (prefix);trace_argv_printf (argv,"trace: built-in: git" );
setup.c +27 -57
106 lines not on this page · raw message
Signature · 1 line
1.5.4.2.281.g28d0e
Re: [PATCH 4/9] Make setup_work_tree() return new prefix
Hi,
Quoted 25 lines · Nguyễn Thái Ngọc Duy
setup.c +11
-8@@ -336,24 +321,21 @@ const char *setup_git_directory_gently(int *nongit_ok)static char buffer[1024 +1 ];const char *retval; +/* +* The old behaviour (which we retain here) is to set +* the work tree root to the cwd, unless overridden by +* the config, the command line, or GIT_WORK_TREE. +*/ if (!work_tree_env) { - retval =set_work_tree (gitdirenv); -/* config may override worktree */ -if (check_repository_format_gently (nongit_ok)) -return NULL ; -return retval; +char buffer[PATH_MAX +1 ]; + +if (!getcwd (buffer,sizeof (buffer))) +die ("Could not get the current working directory" ); + git_work_tree_cfg =xstrdup (buffer); + inside_work_tree =1 ; } -if (check_repository_format_gently (nongit_ok)) -return NULL ; - retval = get_relative_cwd(buffer, sizeof(buffer) - 1,
setup.c const char *setup_git_directory_gently(int *nongit_ok) · line 338
Quoted 10 lines
setup.c +2
-8- get_git_work_tree()); -if (!retval || !*retval) -return NULL ; -set_git_dir (make_absolute_path (gitdirenv)); -if (chdir (work_tree_env) <0 ) -die ("Could not chdir to %s" , work_tree_env); -strcat (buffer,"/" ); -return retval; +check_repository_format_gently (nongit_ok); +return NULL ;
What about the situation where you are in a subdirectory of core.worktree? You return prefix NULL? That's wrong.
I am sorry, but with all these intrusive changes, I get a very uneasy feeling. As uneasy as with the original series, which I tried to fix up, not really succeeding.
Ciao,
Dscho
Re: [PATCH 4/9] Make setup_work_tree() return new prefix
Quoted 36 lines · Johannes Schindelin
Hi,
Quoted 30 lines · Nguyễn Thái Ngọc Duy
setup.c +11
-13@@ -336,24 +321,21 @@ const char *setup_git_directory_gently(int *nongit_ok)static char buffer[1024 +1 ];const char *retval; +/* +* The old behaviour (which we retain here) is to set +* the work tree root to the cwd, unless overridden by +* the config, the command line, or GIT_WORK_TREE. +*/ if (!work_tree_env) { - retval =set_work_tree (gitdirenv); -/* config may override worktree */ -if (check_repository_format_gently (nongit_ok)) -return NULL ; -return retval; +char buffer[PATH_MAX +1 ]; + +if (!getcwd (buffer,sizeof (buffer))) +die ("Could not get the current working directory" ); + git_work_tree_cfg =xstrdup (buffer); + inside_work_tree =1 ; } -if (check_repository_format_gently (nongit_ok)) -return NULL ; - retval =get_relative_cwd (buffer,sizeof (buffer) -1 , -get_git_work_tree ()); -if (!retval || !*retval) -return NULL ; -set_git_dir (make_absolute_path (gitdirenv)); -if (chdir (work_tree_env) <0 )
Quoted 8 lines
setup.c const char *setup_git_directory_gently(int *nongit_ok) · line 338
Quoted 5 lines
setup.c +2
-3-die ("Could not chdir to %s" , work_tree_env); -strcat (buffer,"/" ); -return retval; +check_repository_format_gently (nongit_ok); +return NULL ;What about the situation where you are in a subdirectory of core.worktree? You return prefix NULL? That's wrong.
This is an intermediate patch. At the end of the series, you will see that _gently() does not return prefix. I split it for easier review.
Quoted 3 lines
I am sorry, but with all these intrusive changes, I get a very uneasy feeling. As uneasy as with the original series, which I tried to fix up, not really succeeding.
In constrast I feel good :) To me setup_git_directory*() at the end look really nice. No chdir() all over the place
(temporary chdir() for detecting .git does not count). It also gives a chance to get rid of worktree to commands that do not care about worktree at all.
Quoted 3 lines
Ciao,
Dscho
Signature · 1 line
Duy
Re: [PATCH 4/9] Make setup_work_tree() return new prefix
Hi,
Quoted 11 lines · Nguyen Thai Ngoc Duy
Quoted 3 lines · Johannes Schindelin
I am sorry, but with all these intrusive changes, I get a very uneasy feeling. As uneasy as with the original series, which I tried to fix up, not really succeeding.
In constrast I feel good :) To me setup_git_directory*() at the end look really nice. No
chdir()all over the place (temporarychdir()for detecting .git does not count). It also gives a chance to get rid of worktree to commands that do not care about worktree at all.
Well, I'll have to review your patches in depth, then. Which will take some days, because I wanted to submit builtin-remote first.
Ciao,
Dscho
PATCH 5/9 http-push: Avoid calling setup_git_directory() twice
In reply to a message not in the archive--- http-push.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
http-push.c +2 -2
@@ -2173,7 +2173,7 @@ int main(int argc, char **argv)struct ref *ref;char *rewritten_url =NULL ; -setup_git_directory (); +const char *prefix =setup_git_directory (); remote =xcalloc (sizeof (*remote),1 );
@@ -2375,7 +2375,7 @@ int main(int argc, char **argv) commit_argv[3 ] = old_sha1_hex; commit_argc++; } -init_revisions (&revs,setup_git_directory ()); +init_revisions (&revs, prefix);setup_revisions (commit_argc, commit_argv, &revs,NULL );free (new_sha1_hex);if (old_sha1_hex) {
Signature · 1 line
1.5.4.2.281.g28d0e
Re: [PATCH 5/9] http-push: Avoid calling setup_git_directory() twice
Quoted 4 lines · Nguyễn Thái Ngọc Duy
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>--- http-push.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
Calling setup more than once is now an error? I do not mind the new restriction but is it documented clearly somewhere?
Re: [PATCH 5/9] http-push: Avoid calling setup_git_directory() twice
Quoted 10 lines · Junio C Hamano
Quoted 4 lines · Nguyễn Thái Ngọc Duy
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>--- http-push.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)Calling setup more than once is now an error? I do not mind the new restriction but is it documented clearly somewhere?
This part was left from my attempt to make setup_git_directory() return no prefix. The attempt failed but I thought it was a still good cleanup. Now think it again. I agree calling setup_git_directory() twice is an error as it may call setup_work_tree(NULL) twice. Yes it needs to be documented. Will amend the documentation patch.
Signature · 1 line
Duy
PATCH 6/9 Completely move out worktree setup from setup_git_directory_gently()
In reply to a message not in the archiveThis was impossible earlier because git_dir can be relative. Now that git_dir is absolute, I see no reason for worktree setup inside setup_git_directory_gently(). The semantic is now clearer: if you need worktree, call setup_work_tree yourself (well, I will clean up setup_git_directory() part later)
This patch will free some commands from prefix handling if they don't ever need worktree.
--- builtin-apply.c | 7 +++++-- builtin-bundle.c | 9 ++------- builtin-config.c | 15 +++++---------- builtin-diff-files.c | 10 +++++----- builtin-diff.c | 11 ++++++----- builtin-upload-archive.c | 4 ++-- cache.h | 2 +- git.c | 6 +----- hash-object.c | 8 +------- setup.c | 34 +++++++++++++++++----------------- 10 files changed, 45 insertions(+), 61 deletions(-)
builtin-apply.c +5 -2
@@ -3103,8 +3103,11 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)const char *whitespace_option =NULL ; - prefix =setup_git_directory_gently (&is_not_gitdir); - prefix_length = prefix ?strlen (prefix) :0 ; +setup_git_directory_gently (&is_not_gitdir); +if (!is_not_gitdir &&is_inside_work_tree ()) { + prefix =setup_work_tree (NULL ); + prefix_length = prefix ?strlen (prefix) :0 ; + }git_config (git_apply_config);if (apply_default_whitespace)parse_whitespace_option (apply_default_whitespace);
builtin-bundle.c +2 -7
@@ -11,7 +11,7 @@static const char *bundle_usage="git-bundle (create <bundle> <git-rev-list args> | verify <bundle> | list-heads <bundle> [refname]... | unbundle <bundle> [refname]... )" ; -int cmd_bundle (int argc,const char **argv,const char *prefix) +int cmd_bundle (int argc,const char **argv,const char *unused_prefix) {struct bundle_header header;int nongit =0 ;
@@ -27,12 +27,7 @@ int cmd_bundle(int argc, const char **argv, const char *prefix) argc -=2 ; argv +=2 ; - prefix =setup_git_directory_gently (&nongit); -if (prefix && bundle_file[0 ] !='/' ) { -snprintf (buffer,sizeof (buffer),"%s/%s" , prefix, bundle_file); - bundle_file = buffer; - } - +setup_git_directory_gently (&nongit);memset (&header,0 ,sizeof (header));if (strcmp (cmd,"create" ) && (bundle_fd =read_bundle_header (bundle_file, &header)) <0 )
builtin-config.c +5 -10
@@ -262,11 +262,11 @@ static int get_colorbool(int argc, const char **argv) } } -int cmd_config (int argc,const char **argv,const char *prefix) +int cmd_config (int argc,const char **argv,const char *unused_prefix) {int nongit =0 ;char * value; -const char *file =setup_git_directory_gently (&nongit); +setup_git_directory_gently (&nongit);while (1 < argc) {if (!strcmp (argv[1 ],"--int" ))
@@ -276,8 +276,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)else if (!strcmp (argv[1 ],"--list" ) || !strcmp (argv[1 ],"-l" )) {if (argc !=2 )usage (git_config_set_usage); -if (git_config (show_all_config) <0 && file && errno) -die ("unable to read config file %s: %s" , file, +if (git_config (show_all_config) <0 && errno) +die ("unable to read config file: %s" ,strerror (errno));return 0 ; }
@@ -296,12 +296,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)else if (!strcmp (argv[1 ],"--file" ) || !strcmp (argv[1 ],"-f" )) {if (argc <3 )usage (git_config_set_usage); -if (!is_absolute_path (argv[2 ]) && file) - file =prefix_filename (file,strlen (file), - argv[2 ]); -else - file = argv[2 ]; -setenv (CONFIG_ENVIRONMENT , file,1 ); +setenv (CONFIG_ENVIRONMENT , argv[2 ],1 ); argc--; argv++; }
builtin-diff-files.c +5 -5
@@ -13,21 +13,21 @@ static const char diff_files_usage[] ="git-diff-files [-q] [-0/-1/2/3 |-c|--cc|--no-index] [<common diff options>] [<path>...]" COMMON_DIFF_OPTIONS_HELP ; -int cmd_diff_files (int argc,const char **argv,const char *prefix) +int cmd_diff_files (int argc,const char **argv,const char *unused_prefix) {struct rev_info rev;int nongit =0 ;int result; - prefix =setup_git_directory_gently (&nongit); -init_revisions (&rev, prefix); +setup_git_directory_gently (&nongit); +init_revisions (&rev,NULL );git_config (git_diff_basic_config);/* no "diff" UI options */ rev.abbrev =0 ; -if (!setup_diff_no_index (&rev, argc, argv, nongit, prefix)) +if (!setup_diff_no_index (&rev, argc, argv, nongit,NULL )) argc =0 ;else { - rev.prefix =setup_work_tree (prefix); + rev.prefix =setup_work_tree (NULL ); argc =setup_revisions (argc, argv, &rev,NULL ); }if (!rev.diffopt.output_format)
builtin-diff.c +6 -5
@@ -202,7 +202,7 @@ static void refresh_index_quietly(void)rollback_lock_file (lock_file); } -int cmd_diff (int argc,const char **argv,const char *prefix) +int cmd_diff (int argc,const char **argv,const char *unused_prefix) {int i;struct rev_info rev;
@@ -233,19 +233,20 @@ int cmd_diff(int argc, const char **argv, const char *prefix)* Other cases are errors. */ - prefix =setup_git_directory_gently (&nongit); +setup_git_directory_gently (&nongit);git_config (git_diff_ui_config);if (diff_use_color_default ==-1 ) diff_use_color_default = git_use_color_default; -init_revisions (&rev, prefix); +init_revisions (&rev,NULL ); rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; -if (!setup_diff_no_index (&rev, argc, argv, nongit, prefix)) +if (!setup_diff_no_index (&rev, argc, argv, nongit,NULL )) argc =0 ;else { - rev.prefix =setup_work_tree (prefix); + rev.prefix =setup_work_tree (NULL ); + rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; argc =setup_revisions (argc, argv, &rev,NULL ); }if (!rev.diffopt.output_format) {
builtin-upload-archive.c +2 -2
@@ -17,7 +17,7 @@ static const char lostchild[] ="git-upload-archive: archiver process was lost" ; -static int run_upload_archive (int argc,const char **argv,const char *prefix) +static int run_upload_archive (int argc,const char **argv,const char *unused_prefix) {struct archiver ar;const char *sent_argv[MAX_ARGS ];
@@ -67,7 +67,7 @@ static int run_upload_archive(int argc, const char **argv, const char *prefix)/* parse all options sent by the client */ treeish_idx =parse_archive_args (sent_argc, sent_argv, &ar); -parse_treeish_arg (sent_argv + treeish_idx, &ar.args, prefix); +parse_treeish_arg (sent_argv + treeish_idx, &ar.args,NULL );parse_pathspec_arg (sent_argv + treeish_idx +1 , &ar.args);return ar.write_archive (&ar.args);
cache.h +1 -1
@@ -283,7 +283,7 @@ extern const char *get_git_work_tree(void);extern const char **get_pathspec (const char *prefix,const char **pathspec);extern const char *setup_work_tree (const char *prefix); -extern const char *setup_git_directory_gently (int *); +extern void setup_git_directory_gently (int *);extern const char *setup_git_directory (void );extern const char *prefix_path (const char *prefix,int len,const char *path);extern const char *prefix_filename (const char *prefix,int len,const char *path);
git.c +1 -5
@@ -156,11 +156,10 @@ static int split_cmdline(char *cmdline, const char ***argv)static int handle_alias (int *argcp,const char ***argv) {int nongit =0 , envchanged =0 , ret =0 , saved_errno = errno; -const char *subdir;int count, option_count;const char ** new_argv; - subdir =setup_git_directory_gently (&nongit); +setup_git_directory_gently (&nongit); alias_command = (*argv)[0 ];git_config (git_alias_config);
@@ -216,9 +215,6 @@ static int handle_alias(int *argcp, const char ***argv) ret =1 ; } -if (subdir) -chdir (subdir); - errno = saved_errno;return ret;
hash-object.c +1 -7
@@ -38,14 +38,11 @@ int main(int argc, char **argv)int i;const char *type = blob_type;int write_object =0 ; -const char *prefix =NULL ; -int prefix_length =-1 ;int no_more_flags =0 ;int hashstdin =0 ;int nongit =0 ; - prefix =setup_git_directory_gently (&nongit); - prefix_length = prefix ?strlen (prefix) :0 ; +setup_git_directory_gently (&nongit);git_config (git_default_config);for (i =1 ; i < argc; i++) {
@@ -80,9 +77,6 @@ int main(int argc, char **argv)hash_stdin (type, write_object); hashstdin =0 ; } -if (0 <= prefix_length) - arg =prefix_filename (prefix, prefix_length, - arg);hash_object (arg,type_from_string (type), write_object); no_more_flags =1 ; }
setup.c +17 -17
@@ -301,7 +301,7 @@ static int check_repository_format_gently(int *nongit_ok)* We cannot decide in this function whether we are in the work tree or * not, since the config can only be read _after_ this function was called. */ -const char *setup_git_directory_gently (int *nongit_ok) +void setup_git_directory_gently (int *nongit_ok) {const char *work_tree_env =getenv (GIT_WORK_TREE_ENVIRONMENT );static char cwd[PATH_MAX +1 ];
@@ -335,11 +335,11 @@ const char *setup_git_directory_gently(int *nongit_ok) inside_work_tree =1 ; }check_repository_format_gently (nongit_ok); -return NULL ; +return ; }if (nongit_ok) { *nongit_ok =1 ; -return NULL ; +return ; }die ("Not a git repository: '%s'" , gitdirenv); }
@@ -364,9 +364,12 @@ const char *setup_git_directory_gently(int *nongit_ok) inside_git_dir =1 ;if (!work_tree_env) inside_work_tree =0 ; -setenv (GIT_DIR_ENVIRONMENT ,"." ,1 ); +if (chdir (cwd)) +die ("Cannot come back to cwd" ); + cwd[offset] ='\0' ; +setenv (GIT_DIR_ENVIRONMENT , cwd,1 );check_repository_format_gently (nongit_ok); -return NULL ; +return ; }chdir (".." ); do {
@@ -375,27 +378,23 @@ const char *setup_git_directory_gently(int *nongit_ok)if (chdir (cwd))die ("Cannot come back to cwd" ); *nongit_ok =1 ; -return NULL ; +return ; }die ("Not a git repository" ); } }while (cwd[--offset] !='/' ); } +if (chdir (cwd)) +die ("Cannot come back to cwd" ); inside_git_dir =0 ;if (!work_tree_env) inside_work_tree =1 ; git_work_tree_cfg =xstrndup (cwd, offset); -if (check_repository_format_gently (nongit_ok)) -return NULL ; -if (offset == len) -return NULL ; - -/* Make "offset" point to past the '/', and add a '/' at the end */ - offset++; - cwd[len++] ='/' ; - cwd[len] =0 ; -return cwd + offset; + cwd[offset] ='/' ; +strcpy (cwd+offset+1 ,DEFAULT_GIT_DIR_ENVIRONMENT ); +setenv (GIT_DIR_ENVIRONMENT , cwd,1 ); +check_repository_format_gently (nongit_ok); }int git_config_perm (const char *var,const char *value)
@@ -444,5 +443,6 @@ int check_repository_format(void)const char *setup_git_directory (void ) { -return setup_git_directory_gently (NULL ); +setup_git_directory_gently (NULL ); +return is_inside_work_tree () ?setup_work_tree (NULL ) :NULL ; }
Signature · 1 line
1.5.4.2.281.g28d0e
Re: [PATCH 6/9] Completely move out worktree setup from setup_git_directory_gently()
builtin-diff-files.c int cmd_diff(int argc, const char **argv, const char *prefix)
Quoted 10 lines · Nguyễn Thái Ngọc Duy
builtin-diff-files.c +3
-3- prefix =setup_git_directory_gently (&nongit); -init_revisions (&rev, prefix); +setup_git_directory_gently (&nongit); +init_revisions (&rev,NULL );@@ -233,19 +233,20 @@ int cmd_diff(int argc, const char **argv, const char *prefix) -init_revisions (&rev, prefix); +init_revisions (&rev,NULL );
Hmm. How is the effect of this change compensated later to give proper prefix value to rev.diffopt.prefix?
Re: [PATCH 6/9] Completely move out worktree setup from setup_git_directory_gently()
Quoted 9 lines · Junio C Hamano
Quoted 4 lines · Nguyễn Thái Ngọc Duy
builtin-diff-files.c +2
-2- prefix =setup_git_directory_gently (&nongit); -init_revisions (&rev, prefix); +setup_git_directory_gently (&nongit); +init_revisions (&rev,NULL );
Quoted 9 lines
builtin-diff-files.c int cmd_diff(int argc, const char **argv, const char *prefix) · line 23
Quoted 5 lines
builtin-diff-files.c +1
-1@@ -233,19 +233,20 @@ int cmd_diff(int argc, const char **argv, const char *prefix) -init_revisions (&rev, prefix); +init_revisions (&rev,NULL );Hmm. How is the effect of this change compensated later to give proper prefix value to rev.diffopt.prefix?
I assume you meant rev.prefix? rev.prefix is set right before setup_revisions(). (grr.. I think I left an redundant rev.diffopt.skip_stat_unmatch assignment)
Signature · 1 line
Duy
Re: [PATCH 6/9] Completely move out worktree setup from setup_git_directory_gently()
Quoted 16 lines · Nguyen Thai Ngoc Duy
Quoted 15 lines · Junio C Hamano
Quoted 12 lines · Nguyễn Thái Ngọc Duy
builtin-diff-files.c +3
-3- prefix =setup_git_directory_gently (&nongit); -init_revisions (&rev, prefix); +setup_git_directory_gently (&nongit); +init_revisions (&rev,NULL );@@ -233,19 +233,20 @@ int cmd_diff(int argc, const char **argv, const char *prefix) -init_revisions (&rev, prefix); +init_revisions (&rev,NULL );
Quoted 7 lines
Quoted 3 lines
Hmm. How is the effect of this change compensated later to give proper prefix value to rev.diffopt.prefix?
I assume you meant rev.prefix? rev.prefix is set right before
setup_revisions(). (grr.. I think I left an redundant rev.diffopt.skip_stat_unmatch assignment)
I did mean rev.diffopt.prefix that is initialized by the last four lines in init_revisions() from the value of prefix you pass.
Re: [PATCH 6/9] Completely move out worktree setup from setup_git_directory_gently()
Quoted 23 lines · Junio C Hamano
Quoted 20 lines · Nguyen Thai Ngoc Duy
Quoted 18 lines · Junio C Hamano
builtin-diff-files.c int cmd_diff(int argc, const char **argv, const char *prefix) · line 23
Quoted 12 lines · Nguyễn Thái Ngọc Duy
builtin-diff-files.c +3
-3- prefix =setup_git_directory_gently (&nongit); -init_revisions (&rev, prefix); +setup_git_directory_gently (&nongit); +init_revisions (&rev,NULL );@@ -233,19 +233,20 @@ int cmd_diff(int argc, const char **argv, const char *prefix) -init_revisions (&rev, prefix); +init_revisions (&rev,NULL );Hmm. How is the effect of this change compensated later to give proper prefix value to rev.diffopt.prefix?
Quoted 7 lines
Quoted 3 lines
I assume you meant rev.prefix? rev.prefix is set right before
setup_revisions(). (grr.. I think I left an redundant rev.diffopt.skip_stat_unmatch assignment)I did mean rev.diffopt.prefix that is initialized by the last four lines in
init_revisions()from the value of prefix you pass.
Um.. I missed commit "diff --relative". Thanks for noticing.
Signature · 1 line
Duy
Re: [PATCH 6/9] Completely move out worktree setup from setup_git_directory_gently()
In reply to Nguyễn Thái Ngọc DuyHi,
Quoted 3 lines · Nguyễn Thái Ngọc Duy
This was impossible earlier because
git_dircan be relative. Now thatgit_diris absolute, I see no reason for worktree setup insidesetup_git_directory_gently().
I do see it, though. Why make the users work harder? If you want to get the git directory, chances are that you want to work with a worktree, too.
And you really cannot properly separate worktree detection from git directory detection: in most of the cases, you will find them at the _same_ time (if .git/ is the git directory, the working directory is .).
So I am mildly negative on the thrust of your patch series.
Ciao,
Dscho
Re: [PATCH 6/9] Completely move out worktree setup from setup_git_directory_gently()
Quoted 10 lines · Johannes Schindelin
Hi,
Quoted 3 lines · Nguyễn Thái Ngọc Duy
This was impossible earlier because
git_dircan be relative. Now thatgit_diris absolute, I see no reason for worktree setup insidesetup_git_directory_gently().I do see it, though. Why make the users work harder?
To make clear separation of worktree usage? I think it's good to add setup_work_tree() where you really need it. Right now in commands that use setup_git_directory_gently(), it is (to me) really hard to tell whether an option require worktree.
Another point of removing worktree setup from _gently(): worktree setup can die() while _gently()'s purpose is, well, do it gently. If it's not safe, let the caller decide.
Also having to deal with prefix while you don't need worktree at all is a bit of work that can be eliminated with this series.
Quoted 2 lines
If you want to get
the git directory, chances are that you want to work with a worktree, too.
Yes. That's why I keep worktree setup in setup_git_directory().
Quoted 3 lines
And you really cannot properly separate worktree detection from git directory detection: in most of the cases, you will find them at the _same_ time (if .git/ is the git directory, the working directory is .).
No I don't separate worktree detection. I only avoid moving to worktree unless necessary. Right after _gently() you can tell if you have a worktree and where it is.
Quoted 5 lines
So I am mildly negative on the thrust of your patch series.
Ciao,
Dscho
Signature · 1 line
Duy
PATCH 7/9 builtin-archive: mark unused prefix "unused_prefix"
In reply to a message not in the archivecmd_archive() is registered without RUN_SETUP so its prefix will be NULL forever. Let's make that clear.
--- builtin-archive.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
builtin-archive.c +3 -3
@@ -236,11 +236,12 @@ static const char *extract_remote_arg(int *ac, const char **av)return remote; } -int cmd_archive (int argc,const char **argv,const char *prefix) +int cmd_archive (int argc,const char **argv,const char *unused_prefix) {struct archiver ar;int tree_idx;const char *remote =NULL ; +const char *prefix; remote =extract_remote_arg (&argc, argv);if (remote)
@@ -250,9 +251,8 @@ int cmd_archive(int argc, const char **argv, const char *prefix)memset (&ar,0 ,sizeof (ar)); tree_idx =parse_archive_args (argc, argv, &ar); -if (prefix ==NULL ) - prefix =setup_git_directory (); + prefix =setup_git_directory (); argv += tree_idx;parse_treeish_arg (argv, &ar.args, prefix);parse_pathspec_arg (argv +1 , &ar.args);
Signature · 1 line
1.5.4.2.281.g28d0e
PATCH 8/9 Make setup_git_directory() auto-setup worktree if found
In reply to a message not in the archiveThe semantic is simpler: if worktree is found, use it or die.
--- builtin-ls-files.c | 4 ++-- builtin-rev-parse.c | 7 +++++-- builtin-rm.c | 5 ++--- setup.c | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-)
builtin-ls-files.c +2 -2
@@ -566,8 +566,8 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)break ; } -if (require_work_tree && !is_inside_work_tree ()) - prefix =setup_work_tree (prefix); +if (require_work_tree && !get_git_work_tree ()) +die ("This operation must be run in a work tree" );if (prefix_offset ==-1 ) prefix_offset = prefix ?strlen (prefix) :0 ;
builtin-rev-parse.c +5 -2
@@ -359,15 +359,16 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)return 0 ; } -int cmd_rev_parse (int argc,const char **argv,const char *prefix) +int cmd_rev_parse (int argc,const char **argv,const char *unused_prefix) {int i, as_is =0 , verify =0 ;unsigned char sha1[20 ]; +const char *prefix =NULL ;if (argc >1 && !strcmp ("--parseopt" , argv[1 ]))return cmd_parseopt (argc -1 , argv +1 , prefix); - prefix =setup_git_directory (); +setup_git_directory_gently (NULL );git_config (git_default_config);for (i =1 ; i < argc; i++) {const char *arg = argv[i];
@@ -487,6 +488,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)printf ("%s\n" , work_tree);continue ; } +else + pfx = prefix =setup_work_tree (prefix);while (pfx) { pfx =strchr (pfx,'/' );if (pfx) {
builtin-rm.c +2 -3
@@ -155,10 +155,9 @@ int cmd_rm(int argc, const char **argv, const char *prefix)if (!argc)usage_with_options (builtin_rm_usage, builtin_rm_options); -if (!index_only) - prefix =setup_work_tree (prefix); - pathspec =get_pathspec (prefix, argv); +if (!pathspec) +die ("No valid pathspec" ); seen =NULL ;for (i =0 ; pathspec[i] ; i++)/* nothing */ ;
setup.c +1 -1
@@ -444,5 +444,5 @@ int check_repository_format(void)const char *setup_git_directory (void ) {setup_git_directory_gently (NULL ); -return is_inside_work_tree () ?setup_work_tree (NULL ) :NULL ; +return get_git_work_tree () ?setup_work_tree (NULL ) :NULL ; }
Signature · 1 line
1.5.4.2.281.g28d0e
PATCH 9/9 Documentation: update api-builtin and api-setup
In reply to a message not in the archive--- Documentation/technical/api-builtin.txt | 10 ++++ Documentation/technical/api-setup.txt | 70 +++++++++++++++++++++++++++---- 2 files changed, 72 insertions(+), 8 deletions(-)
Documentation/technical/api-builtin.txt +10 -0
@@ -33,6 +33,10 @@ git: If the standard output is connected to a tty, spawn a pager and feed our output to it. +`NEED_WORK_TREE`:: + + Make sure there is a work tree to work on. + . Add `builtin-foo.o` to `BUILTIN_OBJS` in `Makefile`. Additionally, if `foo` is a new command, there are 3 more things to do:
@@ -59,5 +63,11 @@ to the subdirectory the command started from. This allows you to convert a user-supplied pathname (typically relative to that directory) to a pathname relative to the top of the work tree. +`NEED_WORK_TREE` also set `prefix` like `RUN_SETUP`. But it will `die()` +if there is no work tree. + +If neither `NEED_WORK_TREE` nor `RUN_SETUP` is set, `prefix` is always `NULL`. +No chdir(2) will be done. + The return value from `cmd_foo()` becomes the exit status of the command.
Documentation/technical/api-setup.txt +62 -8
75 lines not on this page · raw message
Signature · 1 line
1.5.4.2.281.g28d0e
Re: [PATCH 9/9] Documentation: update api-builtin and api-setup
Hi,
Quoted 3 lines · Nguyễn Thái Ngọc Duy
Documentation/technical/api-builtin.txt | 10 ++++ Documentation/technical/api-setup.txt | 70 +++++++++++++++++++++++++++---- 2 files changed, 72 insertions(+), 8 deletions(-)
I'm curious --- did anything ever come of this patch?
Documentation/technical/api-setup.txt line 5
Quoted 8 lines
Documentation/technical/api-setup.txt +2
-0@@ -1,13 +1,67 @@ setup API ========= +End-user point-of-view how the setup works +------------------------------------------
I suppose this is scattered through git(1) and git-config(1) now. Maybe it would make sense to centralized in git-repository-layout(5) or gitcli(7) and put cross-references elsewhere.
Quoted 4 lines
Documentation/technical/api-setup.txt +4
-0+. If you have `GIT_DIR` exported, then no discovery is attempted. + We use the `GIT_DIR` you set it, and the repository lives + there. `$GIT_DIR/config` is the repository config. +
Documentation/technical/api-setup.txt line 20
Quoted 10 lines
Documentation/technical/api-setup.txt +10
-0+. Otherwise we do the usual discovery going up to find the + repository. + +. If you have `GIT_WORK_TREE` exported, or otherwise if the + config has `core.worktree`, that's where your worktree is. + If these variables point to an invalid place, you have no worktree. + +. Otherwise, if you have `GIT_DIR` exported, you do not have a + worktree. Else one level above your `$GIT_DIR` is the toplevel + of your worktree.
E.g., like this (but simpler somehow):
Locating the repository
-----------------------
Typically git is run from within a work tree with a .git subdirectory at its top level or within a <project>.git directory associated to a bare repository. To find the toplevel directory, git will repeatedly chdir("..") and at each level check for (in order of preference):
a) a subdirectory named ".git" with readable "objects" and "refs" subdirectories and a readable "HEAD" file;
b) a file named ".git";
c) readable "objects" and "refs" subdirectories and a readable "HEAD" file.
Each is interpreted differently:
a) a .git subdirectory is the repository and the directory containing it is the top of the work tree.
b) a .git file is used to locate the repository (see "Platform-independent .git symlink" below) and the directory containing a .git file is the top of the work tree.
c) an ancestory of the starting cwd containing objects/, refs/, and HEAD is treated as a bare repository. There is no work tree in that case.
Limiting the repository search
------------------------------
Git will not chdir("..") into a directory named in the GIT_CEILING_DIRECTORIES environment variable, nor will it chdir("..") into a directory on a different filesystem unless the GIT_DISCOVERY_ACROSS_FILESYSTEM variable is set.
Unusual repository layouts
--------------------------
If the GIT_DIR environment variable is set, it will be used and no repository search performed. The work tree defaults to ".".
The GIT_WORK_TREE environment variable can be used to specify the top level of the work tree. It can even be used from within a bare repository, to set up a temporary work tree.
The "core.worktree" configuration variable in a repository can be used to specify the top level of the work tree, relative to the repository root. This can be useful in situations in which the work tree must be completely pristine (so that it is not possible to put a .git symlink or .git file in the top level).
Some files usually found in the repository can be placed elsewhere if requested through the environment.
* GIT_CONFIG - .git/config
* GIT_OBJECT_DIRECTORY - .git/objects
* GIT_INDEX_FILE - .git/index
* GIT_GRAFT_FILE - .git/info/grafts
Quoted 9 lines
Documentation/technical/api-setup.txt +9
-0+ +Repository setup +---------------- + +At startup: + +. If the command always need a repository, call + `setup_git_directory()`. It will ensure you have a valid + repository. It will `die()` otherwise. If a worktree is detected,
Documentation/technical/api-setup.txt line 39
Quoted 10 lines
Documentation/technical/api-setup.txt +10
-0+ it will be setup automatically. + +. If the command can optionally run in a repository, use + `setup_git_directory_gently(&nongit_ok)`,which is similar + to `setup_git_directory()` except it won't `die()` + but sets `nongit_ok` to true if run outside a repository. + No chdir(2) is done. + +. If you don't want worktree setup at all, but always need a git repository, + you can use `setup_git_directory_gently(NULL)`.
Simpler advice might be:
. If the command is builtin and always needs a repository,
use the RUN_SETUP flag in the builtin table.
. If the command is builtin and can benefit from a repository,
use RUN_SETUP_GENTLY.
. If you have to run a repository search later, call
"setup_git_directory_gently" or the shortcut "setup_git_directory" (which means "setup_git_directory_gently(NULL)").
Documentation/technical/api-setup.txt line 43
Quoted 4 lines
Documentation/technical/api-setup.txt +4
-0+ +Do not access git repository (even indirectly like `git_config()`) before +calling one of these functions. Otherwise you may encounter `die()` if git +fails to automatically find/setup a repository.
. If you try to access the git repository (even indirectly like
git_config()) before calling setup_git_directory_gently then git will look in the wrong place.
. When changing the value of the GIT_DIR environment variable, call
set_git_dir. setup_git_directory_gently does this already.
Documentation/technical/api-setup.txt line 54
Quoted 11 lines
Documentation/technical/api-setup.txt +11
-0+ +Working directory setup +----------------------- + +If `setup_git_directory()` is used, worktree can be optionally setup already. +To check if work tree has been setup, use `get_git_work_tree()`. The return +value is `NULL` if no work tree is setup or work tree directory otherwise. + +If you need a working directory, use `setup_work_tree()`. It will +move current directory to top-level working directory and return +a prefix. It will `die()` if unable to setup working directory.
Did we ever figure out what happens/should happen when the requested worktree is not an ancestor of cwd?
Documentation/technical/api-setup.txt line 67
Quoted 13 lines
Documentation/technical/api-setup.txt +13
-0+ +Miscellanous functions +---------------------- + +To know where `$GIT_DIR` is, use `get_git_dir()`. It will always return +an absolute path. To know where `$GIT_WORK_TREE` is, use +`get_git_work_tree()`. To check if you are inside a worktree or a git +repository, use `is_inside_work_tree()` or `is_inside_git_dir()` respectively. +There functions may be not valid until `setup_git_directory*()` is called. + +When working with pathspecs and prefix, you can use `get_pathspec()` +to auto prepend a given prefix to pathspecs. Other helpful functions +are `prefix_path()`, `prefix_filename()`
What do prefix_* do when there is no worktree?
Quoted 14 lines
Documentation/technical/api-setup.txt +1
-10-Talk about - + -* setup_git_directory() -* setup_git_directory_gently() -* is_inside_git_dir() -* is_inside_work_tree() -* setup_work_tree() -* get_pathspec() - -(Dscho)Signature · 1 line
1.5.4.2.281.g28d0e
Re: [PATCH 9/9] Documentation: update api-builtin and api-setup
2011/4/5 Jonathan Nieder <[email protected]>:
Quoted 9 lines
Hi,
Quoted 3 lines · Nguyễn Thái Ngọc Duy
Documentation/technical/api-builtin.txt | 10 ++++
Documentation/technical/api-setup.txt| 70 +++++++++++++++++++++++++++----2 files changed, 72 insertions(+), 8 deletions(-)I'm curious --- did anything ever come of this patch?
No idea. Perhaps nothing :) You should submit a new patch. Your description looks very good. Some comments..
Quoted 9 lines
Simpler advice might be:
. If the command is builtin and always needs a repository, use the
RUN_SETUPflag in the builtin table.
. If the command is builtin and can benefit from a repository, useRUN_SETUP_GENTLY.
. If you have to run a repository search later, call "setup_git_directory_gently" or the shortcut "setup_git_directory" (which means "setup_git_directory_gently(NULL)").
I would discourage people from calling setup_git_directory_* directly, at least for builtins. It complicates setup handling because there will be a short time since main() until that function where we are not sure if we can access repo. There's also alias handling which may set things up while the command may not want it
I'd rather explicitly mark (RUN_SETUP_NO_THANKS?) commands that want to setup repo manually (few of them, init/clone and server commands). Then main() just goes ahead and calls setup_gently() at the very beginning. Setup hack around alias handling would be gone. If it ends up with a RUN_SETUP_NO_THANKS one, it undoes the setup. Hmm... I need to get back to this.
Quoted 10 lines
Documentation/technical/api-setup.txt line 43
Quoted 4 lines
Documentation/technical/api-setup.txt +4
-0+ +Do not access git repository (even indirectly like `git_config()`) before +calling one of these functions. Otherwise you may encounter `die()` if git +fails to automatically find/setup a repository.. If you try to access the git repository (even indirectly like
git_config()) before callingsetup_git_directory_gentlythen git will look in the wrong place.
. When changing the value of theGIT_DIRenvironment variable, callset_git_dir. setup_git_directory_gently does this already.
You can also check startup_info.have_repository before you access repo because setup*gently may find no repo.
Quoted 2 lines
Did we ever figure out what happens/should happen when the requested worktree is not an ancestor of cwd?
prefix is NULL, cwd is unchanged. Repo-wide commands should work fine. cwd-sensitive ones may cry.
Quoted 5 lines
Documentation/technical/api-setup.txt line 67
Quoted 3 lines
Documentation/technical/api-setup.txt +3
-0+When working with pathspecs and prefix, you can use `get_pathspec()` +to auto prepend a given prefix to pathspecs. Other helpful functions +are `prefix_path()`, `prefix_filename()`What do prefix_* do when there is no worktree?
These functions are purely string manipulation. If there is no worktree, prefix would be NULL and be passed to the functions as such.
Signature · 1 line
Duy