Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
forked fromgit/git

Commit9b25a0b

Browse files
peffgitster
authored andcommitted
config: add include directive
It can be useful to split your ~/.gitconfig across multiplefiles. For example, you might have a "main" file which isused on many machines, but a small set of per-machinetweaks. Or you may want to make some of your config public(e.g., clever aliases) while keeping other data back (e.g.,your name or other identifying information). Or you may wantto include a number of config options in some subset of yourrepos without copying and pasting (e.g., you want toreference them from the .git/config of participating repos).This patch introduces an include directive for config files.It looks like: [include] path = /path/to/fileThis is syntactically backwards-compatible with existing gitconfig parsers (i.e., they will see it as another configentry and ignore it unless you are looking up include.path).The implementation provides a "git_config_include" callbackwhich wraps regular config callbacks. Callers can pass it togit_config_from_file, and it will transparently follow anyinclude directives, passing all of the discovered options tothe real callback.Include directives are turned on automatically for "regular"git config parsing. This includes calls to git_config, aswell as calls to the "git config" program that do notspecify a single file (e.g., using "-f", "--global", etc).They are not turned on in other cases, including: 1. Parsing of other config-like files, like .gitmodules. There isn't a real need, and I'd rather be conservative and avoid unnecessary incompatibility or confusion. 2. Reading single files via "git config". This is for two reasons: a. backwards compatibility with scripts looking at config-like files. b. inspection of a specific file probably means you care about just what's in that file, not a general lookup for "do we have this value anywhere at all". If that is not the case, the caller can always specify "--includes". 3. Writing files via "git config"; we want to treat include.* variables as literal items to be copied (or modified), and not expand them. So "git config --unset-all foo.bar" would operate _only_ on .git/config, not any of its included files (just as it also does not operate on ~/.gitconfig).Signed-off-by: Jeff King <peff@peff.net>Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent4a7bb5b commit9b25a0b

File tree

7 files changed

+292
-14
lines changed

7 files changed

+292
-14
lines changed

‎Documentation/config.txt‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,17 @@ customary UNIX fashion.
8484

8585
Some variables may require a special value format.
8686

87+
Includes
88+
~~~~~~~~
89+
90+
You can include one config file from another by setting the special
91+
`include.path` variable to the name of the file to be included. The
92+
included file is expanded immediately, as if its contents had been
93+
found at the location of the include directive. If the value of the
94+
`include.path` variable is a relative path, the path is considered to be
95+
relative to the configuration file in which the include directive was
96+
found. See below for examples.
97+
8798
Example
8899
~~~~~~~
89100

@@ -106,6 +117,10 @@ Example
106117
gitProxy="ssh" for "kernel.org"
107118
gitProxy=default-proxy ; for the rest
108119

120+
[include]
121+
path = /path/to/foo.inc ; include by absolute path
122+
path = foo ; expand "foo" relative to the current file
123+
109124
Variables
110125
~~~~~~~~~
111126

‎Documentation/git-config.txt‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ See also <<FILES>>.
178178
Opens an editor to modify the specified config file; either
179179
'--system', '--global', or repository (default).
180180

181+
--includes::
182+
--no-includes::
183+
Respect `include.*` directives in config files when looking up
184+
values. Defaults to on.
185+
181186
[[FILES]]
182187
FILES
183188
-----

‎Documentation/technical/api-config.txt‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,17 @@ while adjusting some of the default behavior of `git_config`. It should
5252
almost never be used by "regular" git code that is looking up
5353
configuration variables. It is intended for advanced callers like
5454
`git-config`, which are intentionally tweaking the normal config-lookup
55-
process. It takesone extraparameter:
55+
process. It takestwo extraparameters:
5656

5757
`filename`::
5858
If this parameter is non-NULL, it specifies the name of a file to
5959
parse for configuration, rather than looking in the usual files. Regular
6060
`git_config` defaults to `NULL`.
6161

62+
`respect_includes`::
63+
Specify whether include directives should be followed in parsed files.
64+
Regular `git_config` defaults to `1`.
65+
6266
There is a special version of `git_config` called `git_config_early`.
6367
This version takes an additional parameter to specify the repository
6468
config, instead of having it looked up via `git_path`. This is useful
@@ -108,6 +112,28 @@ string is given, prints an error message and returns -1.
108112
Similar to `git_config_string`, but expands `~` or `~user` into the
109113
user's home directory when found at the beginning of the path.
110114

115+
Include Directives
116+
------------------
117+
118+
By default, the config parser does not respect include directives.
119+
However, a caller can use the special `git_config_include` wrapper
120+
callback to support them. To do so, you simply wrap your "real" callback
121+
function and data pointer in a `struct config_include_data`, and pass
122+
the wrapper to the regular config-reading functions. For example:
123+
124+
-------------------------------------------
125+
int read_file_with_include(const char *file, config_fn_t fn, void *data)
126+
{
127+
struct config_include_data inc = CONFIG_INCLUDE_INIT;
128+
inc.fn = fn;
129+
inc.data = data;
130+
return git_config_from_file(git_config_include, file, &inc);
131+
}
132+
-------------------------------------------
133+
134+
`git_config` respects includes automatically. The lower-level
135+
`git_config_from_file` does not.
136+
111137
Writing Config Files
112138
--------------------
113139

‎builtin/config.c‎

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ static const char *given_config_file;
2525
staticintactions,types;
2626
staticconstchar*get_color_slot,*get_colorbool_slot;
2727
staticintend_null;
28+
staticintrespect_includes=-1;
2829

2930
#defineACTION_GET (1<<0)
3031
#defineACTION_GET_ALL (1<<1)
@@ -74,6 +75,7 @@ static struct option builtin_config_options[] = {
7475
OPT_BIT(0,"path",&types,"value is a path (file or directory name)",TYPE_PATH),
7576
OPT_GROUP("Other"),
7677
OPT_BOOLEAN('z',"null",&end_null,"terminate values with NUL byte"),
78+
OPT_BOOL(0,"includes",&respect_includes,"respect include directives on lookup"),
7779
OPT_END(),
7880
};
7981

@@ -161,6 +163,9 @@ static int get_value(const char *key_, const char *regex_)
161163
intret=-1;
162164
char*global=NULL,*repo_config=NULL;
163165
constchar*system_wide=NULL,*local;
166+
structconfig_include_datainc=CONFIG_INCLUDE_INIT;
167+
config_fn_tfn;
168+
void*data;
164169

165170
local=given_config_file;
166171
if (!local) {
@@ -213,19 +218,28 @@ static int get_value(const char *key_, const char *regex_)
213218
}
214219
}
215220

221+
fn=show_config;
222+
data=NULL;
223+
if (respect_includes) {
224+
inc.fn=fn;
225+
inc.data=data;
226+
fn=git_config_include;
227+
data=&inc;
228+
}
229+
216230
if (do_all&&system_wide)
217-
git_config_from_file(show_config,system_wide,NULL);
231+
git_config_from_file(fn,system_wide,data);
218232
if (do_all&&global)
219-
git_config_from_file(show_config,global,NULL);
233+
git_config_from_file(fn,global,data);
220234
if (do_all)
221-
git_config_from_file(show_config,local,NULL);
222-
git_config_from_parameters(show_config,NULL);
235+
git_config_from_file(fn,local,data);
236+
git_config_from_parameters(fn,data);
223237
if (!do_all&& !seen)
224-
git_config_from_file(show_config,local,NULL);
238+
git_config_from_file(fn,local,data);
225239
if (!do_all&& !seen&&global)
226-
git_config_from_file(show_config,global,NULL);
240+
git_config_from_file(fn,global,data);
227241
if (!do_all&& !seen&&system_wide)
228-
git_config_from_file(show_config,system_wide,NULL);
242+
git_config_from_file(fn,system_wide,data);
229243

230244
free(key);
231245
if (regexp) {
@@ -302,7 +316,7 @@ static void get_color(const char *def_color)
302316
get_color_found=0;
303317
parsed_color[0]='\0';
304318
git_config_with_options(git_get_color_config,NULL,
305-
given_config_file);
319+
given_config_file,respect_includes);
306320

307321
if (!get_color_found&&def_color)
308322
color_parse(def_color,"command line",parsed_color);
@@ -330,7 +344,7 @@ static int get_colorbool(int print)
330344
get_colorbool_found=-1;
331345
get_diff_color_found=-1;
332346
git_config_with_options(git_get_colorbool_config,NULL,
333-
given_config_file);
347+
given_config_file,respect_includes);
334348

335349
if (get_colorbool_found<0) {
336350
if (!strcmp(get_colorbool_slot,"color.diff"))
@@ -387,6 +401,9 @@ int cmd_config(int argc, const char **argv, const char *prefix)
387401
given_config_file=given_config_file;
388402
}
389403

404+
if (respect_includes==-1)
405+
respect_includes= !given_config_file;
406+
390407
if (end_null) {
391408
term='\0';
392409
delim='\n';
@@ -424,7 +441,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
424441
if (actions==ACTION_LIST) {
425442
check_argc(argc,0,0);
426443
if (git_config_with_options(show_all_config,NULL,
427-
given_config_file)<0) {
444+
given_config_file,
445+
respect_includes)<0) {
428446
if (given_config_file)
429447
die_errno("unable to read config file '%s'",
430448
given_config_file);

‎cache.h‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,8 @@ extern int git_config_from_file(config_fn_t fn, const char *, void *);
11131113
externvoidgit_config_push_parameter(constchar*text);
11141114
externintgit_config_from_parameters(config_fn_tfn,void*data);
11151115
externintgit_config(config_fn_tfn,void*);
1116-
externintgit_config_with_options(config_fn_tfn,void*,constchar*filename);
1116+
externintgit_config_with_options(config_fn_tfn,void*,
1117+
constchar*filename,intrespect_includes);
11171118
externintgit_config_early(config_fn_tfn,void*,constchar*repo_config);
11181119
externintgit_parse_ulong(constchar*,unsigned long*);
11191120
externintgit_config_int(constchar*,constchar*);
@@ -1140,6 +1141,14 @@ extern const char *get_commit_output_encoding(void);
11401141

11411142
externintgit_config_parse_parameter(constchar*,config_fn_tfn,void*data);
11421143

1144+
structconfig_include_data {
1145+
intdepth;
1146+
config_fn_tfn;
1147+
void*data;
1148+
};
1149+
#defineCONFIG_INCLUDE_INIT { 0 }
1150+
externintgit_config_include(constchar*name,constchar*value,void*data);
1151+
11431152
#defineMAX_GITNAME (1000)
11441153
externchargit_default_email[MAX_GITNAME];
11451154
externchargit_default_name[MAX_GITNAME];

‎config.c‎

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,69 @@ static config_file *cf;
2626

2727
staticintzlib_compression_seen;
2828

29+
#defineMAX_INCLUDE_DEPTH 10
30+
staticconstcharinclude_depth_advice[]=
31+
"exceeded maximum include depth (%d) while including\n"
32+
"%s\n"
33+
"from\n"
34+
"%s\n"
35+
"Do you have circular includes?";
36+
staticinthandle_path_include(constchar*path,structconfig_include_data*inc)
37+
{
38+
intret=0;
39+
structstrbufbuf=STRBUF_INIT;
40+
41+
/*
42+
* Use an absolute path as-is, but interpret relative paths
43+
* based on the including config file.
44+
*/
45+
if (!is_absolute_path(path)) {
46+
char*slash;
47+
48+
if (!cf|| !cf->name)
49+
returnerror("relative config includes must come from files");
50+
51+
slash=find_last_dir_sep(cf->name);
52+
if (slash)
53+
strbuf_add(&buf,cf->name,slash-cf->name+1);
54+
strbuf_addstr(&buf,path);
55+
path=buf.buf;
56+
}
57+
58+
if (!access(path,R_OK)) {
59+
if (++inc->depth>MAX_INCLUDE_DEPTH)
60+
die(include_depth_advice,MAX_INCLUDE_DEPTH,path,
61+
cf&&cf->name ?cf->name :"the command line");
62+
ret=git_config_from_file(git_config_include,path,inc);
63+
inc->depth--;
64+
}
65+
strbuf_release(&buf);
66+
returnret;
67+
}
68+
69+
intgit_config_include(constchar*var,constchar*value,void*data)
70+
{
71+
structconfig_include_data*inc=data;
72+
constchar*type;
73+
intret;
74+
75+
/*
76+
* Pass along all values, including "include" directives; this makes it
77+
* possible to query information on the includes themselves.
78+
*/
79+
ret=inc->fn(var,value,inc->data);
80+
if (ret<0)
81+
returnret;
82+
83+
type=skip_prefix(var,"include.");
84+
if (!type)
85+
returnret;
86+
87+
if (!strcmp(type,"path"))
88+
ret=handle_path_include(value,inc);
89+
returnret;
90+
}
91+
2992
staticvoidlowercase(char*p)
3093
{
3194
for (;*p;p++)
@@ -913,10 +976,18 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config)
913976
}
914977

915978
intgit_config_with_options(config_fn_tfn,void*data,
916-
constchar*filename)
979+
constchar*filename,intrespect_includes)
917980
{
918981
char*repo_config=NULL;
919982
intret;
983+
structconfig_include_datainc=CONFIG_INCLUDE_INIT;
984+
985+
if (respect_includes) {
986+
inc.fn=fn;
987+
inc.data=data;
988+
fn=git_config_include;
989+
data=&inc;
990+
}
920991

921992
/*
922993
* If we have a specific filename, use it. Otherwise, follow the
@@ -934,7 +1005,7 @@ int git_config_with_options(config_fn_t fn, void *data,
9341005

9351006
intgit_config(config_fn_tfn,void*data)
9361007
{
937-
returngit_config_with_options(fn,data,NULL);
1008+
returngit_config_with_options(fn,data,NULL,1);
9381009
}
9391010

9401011
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp