2005-10-12 09:47:34 +08:00
|
|
|
/*
|
|
|
|
* We put all the git config variables in this same object
|
|
|
|
* file, so that programs can link against the config parser
|
|
|
|
* without having to link against all the rest of git.
|
|
|
|
*
|
|
|
|
* In particular, no need to bring in libz etc unless needed,
|
|
|
|
* even if you might want to know where the git directory etc
|
|
|
|
* are.
|
|
|
|
*/
|
|
|
|
#include "cache.h"
|
ref namespaces: infrastructure
Add support for dividing the refs of a single repository into multiple
namespaces, each of which can have its own branches, tags, and HEAD.
Git can expose each namespace as an independent repository to pull from
and push to, while sharing the object store, and exposing all the refs
to operations such as git-gc.
Storing multiple repositories as namespaces of a single repository
avoids storing duplicate copies of the same objects, such as when
storing multiple branches of the same source. The alternates mechanism
provides similar support for avoiding duplicates, but alternates do not
prevent duplication between new objects added to the repositories
without ongoing maintenance, while namespaces do.
To specify a namespace, set the GIT_NAMESPACE environment variable to
the namespace. For each ref namespace, git stores the corresponding
refs in a directory under refs/namespaces/. For example,
GIT_NAMESPACE=foo will store refs under refs/namespaces/foo/. You can
also specify namespaces via the --namespace option to git.
Note that namespaces which include a / will expand to a hierarchy of
namespaces; for example, GIT_NAMESPACE=foo/bar will store refs under
refs/namespaces/foo/refs/namespaces/bar/. This makes paths in
GIT_NAMESPACE behave hierarchically, so that cloning with
GIT_NAMESPACE=foo/bar produces the same result as cloning with
GIT_NAMESPACE=foo and cloning from that repo with GIT_NAMESPACE=bar. It
also avoids ambiguity with strange namespace paths such as
foo/refs/heads/, which could otherwise generate directory/file conflicts
within the refs directory.
Add the infrastructure for ref namespaces: handle the GIT_NAMESPACE
environment variable and --namespace option, and support iterating over
refs in a namespace.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-07-06 01:54:44 +08:00
|
|
|
#include "refs.h"
|
2011-10-10 01:33:34 +08:00
|
|
|
#include "fmt-merge-msg.h"
|
2013-12-05 21:02:45 +08:00
|
|
|
#include "commit.h"
|
2005-10-12 09:47:34 +08:00
|
|
|
|
|
|
|
int trust_executable_bit = 1;
|
2008-07-28 14:31:28 +08:00
|
|
|
int trust_ctime = 1;
|
2013-01-22 15:49:22 +08:00
|
|
|
int check_stat = 1;
|
2007-03-03 05:11:30 +08:00
|
|
|
int has_symlinks = 1;
|
2010-10-29 02:28:04 +08:00
|
|
|
int minimum_abbrev = 4, default_abbrev = 7;
|
2008-03-22 07:52:46 +08:00
|
|
|
int ignore_case;
|
2006-08-16 01:23:48 +08:00
|
|
|
int assume_unchanged;
|
|
|
|
int prefer_symlink_refs;
|
2007-01-07 18:00:28 +08:00
|
|
|
int is_bare_repository_cfg = -1; /* unspecified */
|
Move initialization of log_all_ref_updates
The patches to prevent Porcelainish that require working tree
from doing any damage in a bare repository make a lot of sense,
and I want to make the is_bare_git_dir() function more reliable.
In order to allow the repository owner override the heuristic
implemented in is_bare_git_dir() if/when it misidentifies a
particular repository, it would make sense to introduce a new
configuration variable "[core] bare = true/false", and make
is_bare_git_dir() notice it.
The scripts would do a 'repo-config --bool --get core.bare' and
iff the command fails (i.e. there is no such variable in the
configuration file), it would use the heuristic implemented at
the script level [*1*].
However, setup_git_env() which is called a lot earlier than we
even read from the repository configuration currently makes a
call to is_bare_git_dir(), in order to change the default
setting for log_all_ref_updates. It somehow feels that this is
a hack.
By the way, [*1*] is another thing I hate about the current
config mechanism. "git-repo-config --get" does not know what
the possible configuration variables are, let alone what the
default values for them are. It allows us not to maintain a
centralized configuration table, which makes it easy to
introduce ad-hoc variables and gives a warm fuzzy feeling of
being modular, but my feeling is that it is turning out to be a
rather high price to pay for scripts.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-07 17:35:34 +08:00
|
|
|
int log_all_ref_updates = -1; /* unspecified */
|
2006-03-24 15:42:40 +08:00
|
|
|
int warn_ambiguous_refs = 1;
|
cat-file: disable object/refname ambiguity check for batch mode
A common use of "cat-file --batch-check" is to feed a list
of objects from "rev-list --objects" or a similar command.
In this instance, all of our input objects are 40-byte sha1
ids. However, cat-file has always allowed arbitrary revision
specifiers, and feeds the result to get_sha1().
Fortunately, get_sha1() recognizes a 40-byte sha1 before
doing any hard work trying to look up refs, meaning this
scenario should end up spending very little time converting
the input into an object sha1. However, since 798c35f
(get_sha1: warn about full or short object names that look
like refs, 2013-05-29), when we encounter this case, we
spend the extra effort to do a refname lookup anyway, just
to print a warning. This is further exacerbated by ca91993
(get_packed_ref_cache: reload packed-refs file when it
changes, 2013-06-20), which makes individual ref lookup more
expensive by requiring a stat() of the packed-refs file for
each missing ref.
With no patches, this is the time it takes to run:
$ git rev-list --objects --all >objects
$ time git cat-file --batch-check='%(objectname)' <objects
on the linux.git repository:
real 1m13.494s
user 0m25.924s
sys 0m47.532s
If we revert ca91993, the packed-refs up-to-date check, it
gets a little better:
real 0m54.697s
user 0m21.692s
sys 0m32.916s
but we are still spending quite a bit of time on ref lookup
(and we would not want to revert that patch, anyway, which
has correctness issues). If we revert 798c35f, disabling
the warning entirely, we get a much more reasonable time:
real 0m7.452s
user 0m6.836s
sys 0m0.608s
This patch does the moral equivalent of this final case (and
gets similar speedups). We introduce a global flag that
callers of get_sha1() can use to avoid paying the price for
the warning.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-12 14:20:05 +08:00
|
|
|
int warn_on_object_refname_ambiguity = 1;
|
2015-03-21 02:43:06 +08:00
|
|
|
int ref_paranoia = -1;
|
2006-08-16 01:23:48 +08:00
|
|
|
int repository_format_version;
|
2015-06-23 18:54:11 +08:00
|
|
|
int repository_format_precious_objects;
|
2007-03-13 03:33:18 +08:00
|
|
|
const char *git_commit_encoding;
|
2007-03-07 09:44:17 +08:00
|
|
|
const char *git_log_output_encoding;
|
2006-06-10 14:09:49 +08:00
|
|
|
int shared_repository = PERM_UMASK;
|
2006-08-16 01:23:48 +08:00
|
|
|
const char *apply_default_whitespace;
|
2009-08-04 19:16:49 +08:00
|
|
|
const char *apply_default_ignorewhitespace;
|
2011-10-07 02:22:24 +08:00
|
|
|
const char *git_attributes_file;
|
Custom compression levels for objects and packs
Add config variables pack.compression and core.loosecompression ,
and switch --compression=level to pack-objects.
Loose objects will be compressed using core.loosecompression if set,
else core.compression if set, else Z_BEST_SPEED.
Packed objects will be compressed using --compression=level if seen,
else pack.compression if set, else core.compression if set,
else Z_DEFAULT_COMPRESSION. This is the "pack compression level".
Loose objects added to a pack undeltified will be recompressed
to the pack compression level if it is unequal to the current
loose compression level by the preceding rules, or if the loose
object was written while core.legacyheaders = true. Newly
deltified loose objects are always compressed to the current
pack compression level.
Previously packed objects added to a pack are recompressed
to the current pack compression level exactly when their
deltification status changes, since the previous pack data
cannot be reused.
In either case, the --no-reuse-object switch from the first
patch below will always force recompression to the current pack
compression level, instead of assuming the pack compression level
hasn't changed and pack data can be reused when possible.
This applies on top of the following patches from Nicolas Pitre:
[PATCH] allow for undeltified objects not to be reused
[PATCH] make "repack -f" imply "pack-objects --no-reuse-object"
Signed-off-by: Dana L. How <danahow@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-05-10 04:56:50 +08:00
|
|
|
int zlib_compression_level = Z_BEST_SPEED;
|
|
|
|
int core_compression_level;
|
|
|
|
int core_compression_seen;
|
2008-06-19 06:18:44 +08:00
|
|
|
int fsync_object_files;
|
2006-12-24 13:46:13 +08:00
|
|
|
size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE;
|
|
|
|
size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT;
|
2014-05-05 01:13:57 +08:00
|
|
|
size_t delta_base_cache_limit = 96 * 1024 * 1024;
|
2011-04-06 01:44:11 +08:00
|
|
|
unsigned long big_file_threshold = 512 * 1024 * 1024;
|
2008-02-16 13:01:11 +08:00
|
|
|
const char *pager_program;
|
2006-07-30 06:27:43 +08:00
|
|
|
int pager_use_color = 1;
|
2008-02-16 13:01:41 +08:00
|
|
|
const char *editor_program;
|
2010-08-30 21:38:38 +08:00
|
|
|
const char *askpass_program;
|
2008-02-16 13:01:59 +08:00
|
|
|
const char *excludes_file;
|
2010-05-20 04:43:10 +08:00
|
|
|
enum auto_crlf auto_crlf = AUTO_CRLF_FALSE;
|
2014-02-18 19:24:55 +08:00
|
|
|
int check_replace_refs = 1;
|
2015-06-12 05:34:59 +08:00
|
|
|
char *git_replace_ref_base;
|
2011-05-10 03:52:12 +08:00
|
|
|
enum eol core_eol = EOL_UNSET;
|
safecrlf: Add mechanism to warn about irreversible crlf conversions
CRLF conversion bears a slight chance of corrupting data.
autocrlf=true will convert CRLF to LF during commit and LF to
CRLF during checkout. A file that contains a mixture of LF and
CRLF before the commit cannot be recreated by git. For text
files this is the right thing to do: it corrects line endings
such that we have only LF line endings in the repository.
But for binary files that are accidentally classified as text the
conversion can corrupt data.
If you recognize such corruption early you can easily fix it by
setting the conversion type explicitly in .gitattributes. Right
after committing you still have the original file in your work
tree and this file is not yet corrupted. You can explicitly tell
git that this file is binary and git will handle the file
appropriately.
Unfortunately, the desired effect of cleaning up text files with
mixed line endings and the undesired effect of corrupting binary
files cannot be distinguished. In both cases CRLFs are removed
in an irreversible way. For text files this is the right thing
to do because CRLFs are line endings, while for binary files
converting CRLFs corrupts data.
This patch adds a mechanism that can either warn the user about
an irreversible conversion or can even refuse to convert. The
mechanism is controlled by the variable core.safecrlf, with the
following values:
- false: disable safecrlf mechanism
- warn: warn about irreversible conversions
- true: refuse irreversible conversions
The default is to warn. Users are only affected by this default
if core.autocrlf is set. But the current default of git is to
leave core.autocrlf unset, so users will not see warnings unless
they deliberately chose to activate the autocrlf mechanism.
The safecrlf mechanism's details depend on the git command. The
general principles when safecrlf is active (not false) are:
- we warn/error out if files in the work tree can modified in an
irreversible way without giving the user a chance to backup the
original file.
- for read-only operations that do not modify files in the work tree
we do not not print annoying warnings.
There are exceptions. Even though...
- "git add" itself does not touch the files in the work tree, the
next checkout would, so the safety triggers;
- "git apply" to update a text file with a patch does touch the files
in the work tree, but the operation is about text files and CRLF
conversion is about fixing the line ending inconsistencies, so the
safety does not trigger;
- "git diff" itself does not touch the files in the work tree, it is
often run to inspect the changes you intend to next "git add". To
catch potential problems early, safety triggers.
The concept of a safety check was originally proposed in a similar
way by Linus Torvalds. Thanks to Dimitry Potapov for insisting
on getting the naked LF/autocrlf=true case right.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
2008-02-06 19:25:58 +08:00
|
|
|
enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
|
2007-12-06 16:14:14 +08:00
|
|
|
unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
|
2008-02-20 00:24:37 +08:00
|
|
|
enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
|
2008-05-11 06:36:29 +08:00
|
|
|
enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
|
push: Provide situational hints for non-fast-forward errors
Pushing a non-fast-forward update to a remote repository will result in
an error, but the hint text doesn't provide the correct resolution in
every case. Give better resolution advice in three push scenarios:
1) If you push your current branch and it triggers a non-fast-forward
error, you should merge remote changes with 'git pull' before pushing
again.
2) If you push to a shared repository others push to, and your local
tracking branches are not kept up to date, the 'matching refs' default
will generate non-fast-forward errors on outdated branches. If this is
your workflow, the 'matching refs' default is not for you. Consider
setting the 'push.default' configuration variable to 'current' or
'upstream' to ensure only your current branch is pushed.
3) If you explicitly specify a ref that is not your current branch or
push matching branches with ':', you will generate a non-fast-forward
error if any pushed branch tip is out of date. You should checkout the
offending branch and merge remote changes before pushing again.
Teach transport.c to recognize these scenarios and configure push.c
to hint for them. If 'git push's default behavior changes or we
discover more scenarios, extension is easy. Standardize on the
advice API and add three new advice variables, 'pushNonFFCurrent',
'pushNonFFDefault', and 'pushNonFFMatching'. Setting any of these
to 'false' will disable their affiliated advice. Setting
'pushNonFastForward' to false will disable all three, thus preserving the
config option for users who already set it, but guaranteeing new
users won't disable push advice accidentally.
Based-on-patch-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Christopher Tiwald <christiwald@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-03-20 12:31:33 +08:00
|
|
|
enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
|
2009-04-28 06:32:25 +08:00
|
|
|
#ifndef OBJECT_CREATION_MODE
|
|
|
|
#define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS
|
2009-04-25 17:57:14 +08:00
|
|
|
#endif
|
2009-04-28 06:32:25 +08:00
|
|
|
enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
|
2009-10-09 18:21:57 +08:00
|
|
|
char *notes_ref_name;
|
2009-07-23 23:33:49 +08:00
|
|
|
int grafts_replace_parents = 1;
|
2009-08-20 21:47:08 +08:00
|
|
|
int core_apply_sparse_checkout;
|
2011-10-07 14:12:09 +08:00
|
|
|
int merge_log_config = -1;
|
git on Mac OS and precomposed unicode
Mac OS X mangles file names containing unicode on file systems HFS+,
VFAT or SAMBA. When a file using unicode code points outside ASCII
is created on a HFS+ drive, the file name is converted into
decomposed unicode and written to disk. No conversion is done if
the file name is already decomposed unicode.
Calling open("\xc3\x84", ...) with a precomposed "Ä" yields the same
result as open("\x41\xcc\x88",...) with a decomposed "Ä".
As a consequence, readdir() returns the file names in decomposed
unicode, even if the user expects precomposed unicode. Unlike on
HFS+, Mac OS X stores files on a VFAT drive (e.g. an USB drive) in
precomposed unicode, but readdir() still returns file names in
decomposed unicode. When a git repository is stored on a network
share using SAMBA, file names are send over the wire and written to
disk on the remote system in precomposed unicode, but Mac OS X
readdir() returns decomposed unicode to be compatible with its
behaviour on HFS+ and VFAT.
The unicode decomposition causes many problems:
- The names "git add" and other commands get from the end user may
often be precomposed form (the decomposed form is not easily input
from the keyboard), but when the commands read from the filesystem
to see what it is going to update the index with already is on the
filesystem, readdir() will give decomposed form, which is different.
- Similarly "git log", "git mv" and all other commands that need to
compare pathnames found on the command line (often but not always
precomposed form; a command line input resulting from globbing may
be in decomposed) with pathnames found in the tree objects (should
be precomposed form to be compatible with other systems and for
consistency in general).
- The same for names stored in the index, which should be
precomposed, that may need to be compared with the names read from
readdir().
NFS mounted from Linux is fully transparent and does not suffer from
the above.
As Mac OS X treats precomposed and decomposed file names as equal,
we can
- wrap readdir() on Mac OS X to return the precomposed form, and
- normalize decomposed form given from the command line also to the
precomposed form,
to ensure that all pathnames used in Git are always in the
precomposed form. This behaviour can be requested by setting
"core.precomposedunicode" configuration variable to true.
The code in compat/precomposed_utf8.c implements basically 4 new
functions: precomposed_utf8_opendir(), precomposed_utf8_readdir(),
precomposed_utf8_closedir() and precompose_argv(). The first three
are to wrap opendir(3), readdir(3), and closedir(3) functions.
The argv[] conversion allows to use the TAB filename completion done
by the shell on command line. It tolerates other tools which use
readdir() to feed decomposed file names into git.
When creating a new git repository with "git init" or "git clone",
"core.precomposedunicode" will be set "false".
The user needs to activate this feature manually. She typically
sets core.precomposedunicode to "true" on HFS and VFAT, or file
systems mounted via SAMBA.
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Torsten Bögershausen <tboegi@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-07-08 21:50:25 +08:00
|
|
|
int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
|
2010-08-06 10:40:35 +08:00
|
|
|
struct startup_info *startup_info;
|
2011-10-29 05:48:40 +08:00
|
|
|
unsigned long pack_size_limit_cfg;
|
2005-10-12 09:47:34 +08:00
|
|
|
|
2014-12-16 07:15:20 +08:00
|
|
|
#ifndef PROTECT_HFS_DEFAULT
|
|
|
|
#define PROTECT_HFS_DEFAULT 0
|
|
|
|
#endif
|
|
|
|
int protect_hfs = PROTECT_HFS_DEFAULT;
|
|
|
|
|
2014-12-17 06:46:59 +08:00
|
|
|
#ifndef PROTECT_NTFS_DEFAULT
|
|
|
|
#define PROTECT_NTFS_DEFAULT 0
|
|
|
|
#endif
|
|
|
|
int protect_ntfs = PROTECT_NTFS_DEFAULT;
|
|
|
|
|
2013-01-17 03:18:48 +08:00
|
|
|
/*
|
|
|
|
* The character that begins a commented line in user-editable file
|
|
|
|
* that is subject to stripspace.
|
|
|
|
*/
|
|
|
|
char comment_line_char = '#';
|
2014-05-17 09:52:23 +08:00
|
|
|
int auto_comment_line_char;
|
2013-01-17 03:18:48 +08:00
|
|
|
|
2008-11-14 08:36:30 +08:00
|
|
|
/* Parallel index stat data preload? */
|
2014-06-03 00:43:00 +08:00
|
|
|
int core_preload_index = 1;
|
2008-11-14 08:36:30 +08:00
|
|
|
|
Clean up work-tree handling
The old version of work-tree support was an unholy mess, barely readable,
and not to the point.
For example, why do you have to provide a worktree, when it is not used?
As in "git status". Now it works.
Another riddle was: if you can have work trees inside the git dir, why
are some programs complaining that they need a work tree?
IOW it is allowed to call
$ git --git-dir=../ --work-tree=. bla
when you really want to. In this case, you are both in the git directory
and in the working tree. So, programs have to actually test for the right
thing, namely if they are inside a working tree, and not if they are
inside a git directory.
Also, GIT_DIR=../.git should behave the same as if no GIT_DIR was
specified, unless there is a repository in the current working directory.
It does now.
The logic to determine if a repository is bare, or has a work tree
(tertium non datur), is this:
--work-tree=bla overrides GIT_WORK_TREE, which overrides core.bare = true,
which overrides core.worktree, which overrides GIT_DIR/.. when GIT_DIR
ends in /.git, which overrides the directory in which .git/ was found.
In related news, a long standing bug was fixed: when in .git/bla/x.git/,
which is a bare repository, git formerly assumed ../.. to be the
appropriate git dir. This problem was reported by Shawn Pearce to have
caused much pain, where a colleague mistakenly ran "git init" in "/" a
long time ago, and bare repositories just would not work.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-08-01 08:30:14 +08:00
|
|
|
/* This is set by setup_git_dir_gently() and/or git_default_config() */
|
|
|
|
char *git_work_tree_cfg;
|
2008-04-28 01:39:21 +08:00
|
|
|
static char *work_tree;
|
Clean up work-tree handling
The old version of work-tree support was an unholy mess, barely readable,
and not to the point.
For example, why do you have to provide a worktree, when it is not used?
As in "git status". Now it works.
Another riddle was: if you can have work trees inside the git dir, why
are some programs complaining that they need a work tree?
IOW it is allowed to call
$ git --git-dir=../ --work-tree=. bla
when you really want to. In this case, you are both in the git directory
and in the working tree. So, programs have to actually test for the right
thing, namely if they are inside a working tree, and not if they are
inside a git directory.
Also, GIT_DIR=../.git should behave the same as if no GIT_DIR was
specified, unless there is a repository in the current working directory.
It does now.
The logic to determine if a repository is bare, or has a work tree
(tertium non datur), is this:
--work-tree=bla overrides GIT_WORK_TREE, which overrides core.bare = true,
which overrides core.worktree, which overrides GIT_DIR/.. when GIT_DIR
ends in /.git, which overrides the directory in which .git/ was found.
In related news, a long standing bug was fixed: when in .git/bla/x.git/,
which is a bare repository, git formerly assumed ../.. to be the
appropriate git dir. This problem was reported by Shawn Pearce to have
caused much pain, where a colleague mistakenly ran "git init" in "/" a
long time ago, and bare repositories just would not work.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-08-01 08:30:14 +08:00
|
|
|
|
ref namespaces: infrastructure
Add support for dividing the refs of a single repository into multiple
namespaces, each of which can have its own branches, tags, and HEAD.
Git can expose each namespace as an independent repository to pull from
and push to, while sharing the object store, and exposing all the refs
to operations such as git-gc.
Storing multiple repositories as namespaces of a single repository
avoids storing duplicate copies of the same objects, such as when
storing multiple branches of the same source. The alternates mechanism
provides similar support for avoiding duplicates, but alternates do not
prevent duplication between new objects added to the repositories
without ongoing maintenance, while namespaces do.
To specify a namespace, set the GIT_NAMESPACE environment variable to
the namespace. For each ref namespace, git stores the corresponding
refs in a directory under refs/namespaces/. For example,
GIT_NAMESPACE=foo will store refs under refs/namespaces/foo/. You can
also specify namespaces via the --namespace option to git.
Note that namespaces which include a / will expand to a hierarchy of
namespaces; for example, GIT_NAMESPACE=foo/bar will store refs under
refs/namespaces/foo/refs/namespaces/bar/. This makes paths in
GIT_NAMESPACE behave hierarchically, so that cloning with
GIT_NAMESPACE=foo/bar produces the same result as cloning with
GIT_NAMESPACE=foo and cloning from that repo with GIT_NAMESPACE=bar. It
also avoids ambiguity with strange namespace paths such as
foo/refs/heads/, which could otherwise generate directory/file conflicts
within the refs directory.
Add the infrastructure for ref namespaces: handle the GIT_NAMESPACE
environment variable and --namespace option, and support iterating over
refs in a namespace.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-07-06 01:54:44 +08:00
|
|
|
static const char *namespace;
|
|
|
|
static size_t namespace_len;
|
|
|
|
|
$GIT_COMMON_DIR: a new environment variable
This variable is intended to support multiple working directories
attached to a repository. Such a repository may have a main working
directory, created by either "git init" or "git clone" and one or more
linked working directories. These working directories and the main
repository share the same repository directory.
In linked working directories, $GIT_COMMON_DIR must be defined to point
to the real repository directory and $GIT_DIR points to an unused
subdirectory inside $GIT_COMMON_DIR. File locations inside the
repository are reorganized from the linked worktree view point:
- worktree-specific such as HEAD, logs/HEAD, index, other top-level
refs and unrecognized files are from $GIT_DIR.
- the rest like objects, refs, info, hooks, packed-refs, shallow...
are from $GIT_COMMON_DIR (except info/sparse-checkout, but that's
a separate patch)
Scripts are supposed to retrieve paths in $GIT_DIR with "git rev-parse
--git-path", which will take care of "$GIT_DIR vs $GIT_COMMON_DIR"
business.
The redirection is done by git_path(), git_pathdup() and
strbuf_git_path(). The selected list of paths goes to $GIT_COMMON_DIR,
not the other way around in case a developer adds a new
worktree-specific file and it's accidentally promoted to be shared
across repositories (this includes unknown files added by third party
commands)
The list of known files that belong to $GIT_DIR are:
ADD_EDIT.patch BISECT_ANCESTORS_OK BISECT_EXPECTED_REV BISECT_LOG
BISECT_NAMES CHERRY_PICK_HEAD COMMIT_MSG FETCH_HEAD HEAD MERGE_HEAD
MERGE_MODE MERGE_RR NOTES_EDITMSG NOTES_MERGE_WORKTREE ORIG_HEAD
REVERT_HEAD SQUASH_MSG TAG_EDITMSG fast_import_crash_* logs/HEAD
next-index-* rebase-apply rebase-merge rsync-refs-* sequencer/*
shallow_*
Path mapping is NOT done for git_path_submodule(). Multi-checkouts are
not supported as submodules.
Helped-by: Jens Lehmann <Jens.Lehmann@web.de>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-30 16:24:36 +08:00
|
|
|
static const char *git_dir, *git_common_dir;
|
2010-10-02 16:35:29 +08:00
|
|
|
static char *git_object_dir, *git_index_file, *git_graft_file;
|
$GIT_COMMON_DIR: a new environment variable
This variable is intended to support multiple working directories
attached to a repository. Such a repository may have a main working
directory, created by either "git init" or "git clone" and one or more
linked working directories. These working directories and the main
repository share the same repository directory.
In linked working directories, $GIT_COMMON_DIR must be defined to point
to the real repository directory and $GIT_DIR points to an unused
subdirectory inside $GIT_COMMON_DIR. File locations inside the
repository are reorganized from the linked worktree view point:
- worktree-specific such as HEAD, logs/HEAD, index, other top-level
refs and unrecognized files are from $GIT_DIR.
- the rest like objects, refs, info, hooks, packed-refs, shallow...
are from $GIT_COMMON_DIR (except info/sparse-checkout, but that's
a separate patch)
Scripts are supposed to retrieve paths in $GIT_DIR with "git rev-parse
--git-path", which will take care of "$GIT_DIR vs $GIT_COMMON_DIR"
business.
The redirection is done by git_path(), git_pathdup() and
strbuf_git_path(). The selected list of paths goes to $GIT_COMMON_DIR,
not the other way around in case a developer adds a new
worktree-specific file and it's accidentally promoted to be shared
across repositories (this includes unknown files added by third party
commands)
The list of known files that belong to $GIT_DIR are:
ADD_EDIT.patch BISECT_ANCESTORS_OK BISECT_EXPECTED_REV BISECT_LOG
BISECT_NAMES CHERRY_PICK_HEAD COMMIT_MSG FETCH_HEAD HEAD MERGE_HEAD
MERGE_MODE MERGE_RR NOTES_EDITMSG NOTES_MERGE_WORKTREE ORIG_HEAD
REVERT_HEAD SQUASH_MSG TAG_EDITMSG fast_import_crash_* logs/HEAD
next-index-* rebase-apply rebase-merge rsync-refs-* sequencer/*
shallow_*
Path mapping is NOT done for git_path_submodule(). Multi-checkouts are
not supported as submodules.
Helped-by: Jens Lehmann <Jens.Lehmann@web.de>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-30 16:24:36 +08:00
|
|
|
int git_db_env, git_index_env, git_graft_env, git_common_dir_env;
|
2006-08-23 18:39:11 +08:00
|
|
|
|
2010-02-25 07:34:14 +08:00
|
|
|
/*
|
2013-03-08 17:29:08 +08:00
|
|
|
* Repository-local GIT_* environment variables; see cache.h for details.
|
2010-02-25 07:34:14 +08:00
|
|
|
*/
|
2013-03-08 17:29:08 +08:00
|
|
|
const char * const local_repo_env[] = {
|
2010-02-25 07:34:14 +08:00
|
|
|
ALTERNATE_DB_ENVIRONMENT,
|
|
|
|
CONFIG_ENVIRONMENT,
|
2010-08-24 14:41:14 +08:00
|
|
|
CONFIG_DATA_ENVIRONMENT,
|
2010-02-25 07:34:14 +08:00
|
|
|
DB_ENVIRONMENT,
|
|
|
|
GIT_DIR_ENVIRONMENT,
|
|
|
|
GIT_WORK_TREE_ENVIRONMENT,
|
setup: suppress implicit "." work-tree for bare repos
If an explicit GIT_DIR is given without a working tree, we
implicitly assume that the current working directory should
be used as the working tree. E.g.,:
GIT_DIR=/some/repo.git git status
would compare against the cwd.
Unfortunately, we fool this rule for sub-invocations of git
by setting GIT_DIR internally ourselves. For example:
git init foo
cd foo/.git
git status ;# fails, as we expect
git config alias.st status
git status ;# does not fail, but should
What happens is that we run setup_git_directory when doing
alias lookup (since we need to see the config), set GIT_DIR
as a result, and then leave GIT_WORK_TREE blank (because we
do not have one). Then when we actually run the status
command, we do setup_git_directory again, which sees our
explicit GIT_DIR and uses the cwd as an implicit worktree.
It's tempting to argue that we should be suppressing that
second invocation of setup_git_directory, as it could use
the values we already found in memory. However, the problem
still exists for sub-processes (e.g., if "git status" were
an external command).
You can see another example with the "--bare" option, which
sets GIT_DIR explicitly. For example:
git init foo
cd foo/.git
git status ;# fails
git --bare status ;# does NOT fail
We need some way of telling sub-processes "even though
GIT_DIR is set, do not use cwd as an implicit working tree".
We could do it by putting a special token into
GIT_WORK_TREE, but the obvious choice (an empty string) has
some portability problems.
Instead, we add a new boolean variable, GIT_IMPLICIT_WORK_TREE,
which suppresses the use of cwd as a working tree when
GIT_DIR is set. We trigger the new variable when we know we
are in a bare setting.
The variable is left intentionally undocumented, as this is
an internal detail (for now, anyway). If somebody comes up
with a good alternate use for it, and once we are confident
we have shaken any bugs out of it, we can consider promoting
it further.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-08 17:32:22 +08:00
|
|
|
GIT_IMPLICIT_WORK_TREE_ENVIRONMENT,
|
2010-02-25 07:34:14 +08:00
|
|
|
GRAFT_ENVIRONMENT,
|
|
|
|
INDEX_ENVIRONMENT,
|
|
|
|
NO_REPLACE_OBJECTS_ENVIRONMENT,
|
2015-06-12 05:34:59 +08:00
|
|
|
GIT_REPLACE_REF_BASE_ENVIRONMENT,
|
2013-03-08 17:30:25 +08:00
|
|
|
GIT_PREFIX_ENVIRONMENT,
|
2013-12-05 21:02:45 +08:00
|
|
|
GIT_SHALLOW_FILE_ENVIRONMENT,
|
$GIT_COMMON_DIR: a new environment variable
This variable is intended to support multiple working directories
attached to a repository. Such a repository may have a main working
directory, created by either "git init" or "git clone" and one or more
linked working directories. These working directories and the main
repository share the same repository directory.
In linked working directories, $GIT_COMMON_DIR must be defined to point
to the real repository directory and $GIT_DIR points to an unused
subdirectory inside $GIT_COMMON_DIR. File locations inside the
repository are reorganized from the linked worktree view point:
- worktree-specific such as HEAD, logs/HEAD, index, other top-level
refs and unrecognized files are from $GIT_DIR.
- the rest like objects, refs, info, hooks, packed-refs, shallow...
are from $GIT_COMMON_DIR (except info/sparse-checkout, but that's
a separate patch)
Scripts are supposed to retrieve paths in $GIT_DIR with "git rev-parse
--git-path", which will take care of "$GIT_DIR vs $GIT_COMMON_DIR"
business.
The redirection is done by git_path(), git_pathdup() and
strbuf_git_path(). The selected list of paths goes to $GIT_COMMON_DIR,
not the other way around in case a developer adds a new
worktree-specific file and it's accidentally promoted to be shared
across repositories (this includes unknown files added by third party
commands)
The list of known files that belong to $GIT_DIR are:
ADD_EDIT.patch BISECT_ANCESTORS_OK BISECT_EXPECTED_REV BISECT_LOG
BISECT_NAMES CHERRY_PICK_HEAD COMMIT_MSG FETCH_HEAD HEAD MERGE_HEAD
MERGE_MODE MERGE_RR NOTES_EDITMSG NOTES_MERGE_WORKTREE ORIG_HEAD
REVERT_HEAD SQUASH_MSG TAG_EDITMSG fast_import_crash_* logs/HEAD
next-index-* rebase-apply rebase-merge rsync-refs-* sequencer/*
shallow_*
Path mapping is NOT done for git_path_submodule(). Multi-checkouts are
not supported as submodules.
Helped-by: Jens Lehmann <Jens.Lehmann@web.de>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-30 16:24:36 +08:00
|
|
|
GIT_COMMON_DIR_ENVIRONMENT,
|
2010-02-25 07:34:14 +08:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
ref namespaces: infrastructure
Add support for dividing the refs of a single repository into multiple
namespaces, each of which can have its own branches, tags, and HEAD.
Git can expose each namespace as an independent repository to pull from
and push to, while sharing the object store, and exposing all the refs
to operations such as git-gc.
Storing multiple repositories as namespaces of a single repository
avoids storing duplicate copies of the same objects, such as when
storing multiple branches of the same source. The alternates mechanism
provides similar support for avoiding duplicates, but alternates do not
prevent duplication between new objects added to the repositories
without ongoing maintenance, while namespaces do.
To specify a namespace, set the GIT_NAMESPACE environment variable to
the namespace. For each ref namespace, git stores the corresponding
refs in a directory under refs/namespaces/. For example,
GIT_NAMESPACE=foo will store refs under refs/namespaces/foo/. You can
also specify namespaces via the --namespace option to git.
Note that namespaces which include a / will expand to a hierarchy of
namespaces; for example, GIT_NAMESPACE=foo/bar will store refs under
refs/namespaces/foo/refs/namespaces/bar/. This makes paths in
GIT_NAMESPACE behave hierarchically, so that cloning with
GIT_NAMESPACE=foo/bar produces the same result as cloning with
GIT_NAMESPACE=foo and cloning from that repo with GIT_NAMESPACE=bar. It
also avoids ambiguity with strange namespace paths such as
foo/refs/heads/, which could otherwise generate directory/file conflicts
within the refs directory.
Add the infrastructure for ref namespaces: handle the GIT_NAMESPACE
environment variable and --namespace option, and support iterating over
refs in a namespace.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-07-06 01:54:44 +08:00
|
|
|
static char *expand_namespace(const char *raw_namespace)
|
|
|
|
{
|
|
|
|
struct strbuf buf = STRBUF_INIT;
|
|
|
|
struct strbuf **components, **c;
|
|
|
|
|
|
|
|
if (!raw_namespace || !*raw_namespace)
|
|
|
|
return xstrdup("");
|
|
|
|
|
|
|
|
strbuf_addstr(&buf, raw_namespace);
|
|
|
|
components = strbuf_split(&buf, '/');
|
|
|
|
strbuf_reset(&buf);
|
|
|
|
for (c = components; *c; c++)
|
|
|
|
if (strcmp((*c)->buf, "/") != 0)
|
|
|
|
strbuf_addf(&buf, "refs/namespaces/%s", (*c)->buf);
|
|
|
|
strbuf_list_free(components);
|
2011-09-16 05:10:25 +08:00
|
|
|
if (check_refname_format(buf.buf, 0))
|
ref namespaces: infrastructure
Add support for dividing the refs of a single repository into multiple
namespaces, each of which can have its own branches, tags, and HEAD.
Git can expose each namespace as an independent repository to pull from
and push to, while sharing the object store, and exposing all the refs
to operations such as git-gc.
Storing multiple repositories as namespaces of a single repository
avoids storing duplicate copies of the same objects, such as when
storing multiple branches of the same source. The alternates mechanism
provides similar support for avoiding duplicates, but alternates do not
prevent duplication between new objects added to the repositories
without ongoing maintenance, while namespaces do.
To specify a namespace, set the GIT_NAMESPACE environment variable to
the namespace. For each ref namespace, git stores the corresponding
refs in a directory under refs/namespaces/. For example,
GIT_NAMESPACE=foo will store refs under refs/namespaces/foo/. You can
also specify namespaces via the --namespace option to git.
Note that namespaces which include a / will expand to a hierarchy of
namespaces; for example, GIT_NAMESPACE=foo/bar will store refs under
refs/namespaces/foo/refs/namespaces/bar/. This makes paths in
GIT_NAMESPACE behave hierarchically, so that cloning with
GIT_NAMESPACE=foo/bar produces the same result as cloning with
GIT_NAMESPACE=foo and cloning from that repo with GIT_NAMESPACE=bar. It
also avoids ambiguity with strange namespace paths such as
foo/refs/heads/, which could otherwise generate directory/file conflicts
within the refs directory.
Add the infrastructure for ref namespaces: handle the GIT_NAMESPACE
environment variable and --namespace option, and support iterating over
refs in a namespace.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-07-06 01:54:44 +08:00
|
|
|
die("bad git namespace path \"%s\"", raw_namespace);
|
|
|
|
strbuf_addch(&buf, '/');
|
|
|
|
return strbuf_detach(&buf, NULL);
|
|
|
|
}
|
|
|
|
|
$GIT_COMMON_DIR: a new environment variable
This variable is intended to support multiple working directories
attached to a repository. Such a repository may have a main working
directory, created by either "git init" or "git clone" and one or more
linked working directories. These working directories and the main
repository share the same repository directory.
In linked working directories, $GIT_COMMON_DIR must be defined to point
to the real repository directory and $GIT_DIR points to an unused
subdirectory inside $GIT_COMMON_DIR. File locations inside the
repository are reorganized from the linked worktree view point:
- worktree-specific such as HEAD, logs/HEAD, index, other top-level
refs and unrecognized files are from $GIT_DIR.
- the rest like objects, refs, info, hooks, packed-refs, shallow...
are from $GIT_COMMON_DIR (except info/sparse-checkout, but that's
a separate patch)
Scripts are supposed to retrieve paths in $GIT_DIR with "git rev-parse
--git-path", which will take care of "$GIT_DIR vs $GIT_COMMON_DIR"
business.
The redirection is done by git_path(), git_pathdup() and
strbuf_git_path(). The selected list of paths goes to $GIT_COMMON_DIR,
not the other way around in case a developer adds a new
worktree-specific file and it's accidentally promoted to be shared
across repositories (this includes unknown files added by third party
commands)
The list of known files that belong to $GIT_DIR are:
ADD_EDIT.patch BISECT_ANCESTORS_OK BISECT_EXPECTED_REV BISECT_LOG
BISECT_NAMES CHERRY_PICK_HEAD COMMIT_MSG FETCH_HEAD HEAD MERGE_HEAD
MERGE_MODE MERGE_RR NOTES_EDITMSG NOTES_MERGE_WORKTREE ORIG_HEAD
REVERT_HEAD SQUASH_MSG TAG_EDITMSG fast_import_crash_* logs/HEAD
next-index-* rebase-apply rebase-merge rsync-refs-* sequencer/*
shallow_*
Path mapping is NOT done for git_path_submodule(). Multi-checkouts are
not supported as submodules.
Helped-by: Jens Lehmann <Jens.Lehmann@web.de>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-30 16:24:36 +08:00
|
|
|
static char *git_path_from_env(const char *envvar, const char *git_dir,
|
|
|
|
const char *path, int *fromenv)
|
2014-06-25 04:58:15 +08:00
|
|
|
{
|
|
|
|
const char *value = getenv(envvar);
|
2014-11-30 16:24:31 +08:00
|
|
|
if (!value) {
|
|
|
|
char *buf = xmalloc(strlen(git_dir) + strlen(path) + 2);
|
|
|
|
sprintf(buf, "%s/%s", git_dir, path);
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
if (fromenv)
|
|
|
|
*fromenv = 1;
|
|
|
|
return xstrdup(value);
|
2014-06-25 04:58:15 +08:00
|
|
|
}
|
|
|
|
|
2005-10-12 09:47:34 +08:00
|
|
|
static void setup_git_env(void)
|
|
|
|
{
|
2014-11-30 16:24:44 +08:00
|
|
|
struct strbuf sb = STRBUF_INIT;
|
2013-08-31 09:04:14 +08:00
|
|
|
const char *gitfile;
|
2013-12-05 21:02:45 +08:00
|
|
|
const char *shallow_file;
|
2015-06-12 05:34:59 +08:00
|
|
|
const char *replace_ref_base;
|
2013-08-31 09:04:14 +08:00
|
|
|
|
2005-10-12 09:47:34 +08:00
|
|
|
git_dir = getenv(GIT_DIR_ENVIRONMENT);
|
|
|
|
if (!git_dir)
|
|
|
|
git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
|
2013-08-31 09:04:14 +08:00
|
|
|
gitfile = read_gitfile(git_dir);
|
|
|
|
git_dir = xstrdup(gitfile ? gitfile : git_dir);
|
2014-11-30 16:24:44 +08:00
|
|
|
if (get_common_dir(&sb, git_dir))
|
$GIT_COMMON_DIR: a new environment variable
This variable is intended to support multiple working directories
attached to a repository. Such a repository may have a main working
directory, created by either "git init" or "git clone" and one or more
linked working directories. These working directories and the main
repository share the same repository directory.
In linked working directories, $GIT_COMMON_DIR must be defined to point
to the real repository directory and $GIT_DIR points to an unused
subdirectory inside $GIT_COMMON_DIR. File locations inside the
repository are reorganized from the linked worktree view point:
- worktree-specific such as HEAD, logs/HEAD, index, other top-level
refs and unrecognized files are from $GIT_DIR.
- the rest like objects, refs, info, hooks, packed-refs, shallow...
are from $GIT_COMMON_DIR (except info/sparse-checkout, but that's
a separate patch)
Scripts are supposed to retrieve paths in $GIT_DIR with "git rev-parse
--git-path", which will take care of "$GIT_DIR vs $GIT_COMMON_DIR"
business.
The redirection is done by git_path(), git_pathdup() and
strbuf_git_path(). The selected list of paths goes to $GIT_COMMON_DIR,
not the other way around in case a developer adds a new
worktree-specific file and it's accidentally promoted to be shared
across repositories (this includes unknown files added by third party
commands)
The list of known files that belong to $GIT_DIR are:
ADD_EDIT.patch BISECT_ANCESTORS_OK BISECT_EXPECTED_REV BISECT_LOG
BISECT_NAMES CHERRY_PICK_HEAD COMMIT_MSG FETCH_HEAD HEAD MERGE_HEAD
MERGE_MODE MERGE_RR NOTES_EDITMSG NOTES_MERGE_WORKTREE ORIG_HEAD
REVERT_HEAD SQUASH_MSG TAG_EDITMSG fast_import_crash_* logs/HEAD
next-index-* rebase-apply rebase-merge rsync-refs-* sequencer/*
shallow_*
Path mapping is NOT done for git_path_submodule(). Multi-checkouts are
not supported as submodules.
Helped-by: Jens Lehmann <Jens.Lehmann@web.de>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-30 16:24:36 +08:00
|
|
|
git_common_dir_env = 1;
|
2014-11-30 16:24:44 +08:00
|
|
|
git_common_dir = strbuf_detach(&sb, NULL);
|
$GIT_COMMON_DIR: a new environment variable
This variable is intended to support multiple working directories
attached to a repository. Such a repository may have a main working
directory, created by either "git init" or "git clone" and one or more
linked working directories. These working directories and the main
repository share the same repository directory.
In linked working directories, $GIT_COMMON_DIR must be defined to point
to the real repository directory and $GIT_DIR points to an unused
subdirectory inside $GIT_COMMON_DIR. File locations inside the
repository are reorganized from the linked worktree view point:
- worktree-specific such as HEAD, logs/HEAD, index, other top-level
refs and unrecognized files are from $GIT_DIR.
- the rest like objects, refs, info, hooks, packed-refs, shallow...
are from $GIT_COMMON_DIR (except info/sparse-checkout, but that's
a separate patch)
Scripts are supposed to retrieve paths in $GIT_DIR with "git rev-parse
--git-path", which will take care of "$GIT_DIR vs $GIT_COMMON_DIR"
business.
The redirection is done by git_path(), git_pathdup() and
strbuf_git_path(). The selected list of paths goes to $GIT_COMMON_DIR,
not the other way around in case a developer adds a new
worktree-specific file and it's accidentally promoted to be shared
across repositories (this includes unknown files added by third party
commands)
The list of known files that belong to $GIT_DIR are:
ADD_EDIT.patch BISECT_ANCESTORS_OK BISECT_EXPECTED_REV BISECT_LOG
BISECT_NAMES CHERRY_PICK_HEAD COMMIT_MSG FETCH_HEAD HEAD MERGE_HEAD
MERGE_MODE MERGE_RR NOTES_EDITMSG NOTES_MERGE_WORKTREE ORIG_HEAD
REVERT_HEAD SQUASH_MSG TAG_EDITMSG fast_import_crash_* logs/HEAD
next-index-* rebase-apply rebase-merge rsync-refs-* sequencer/*
shallow_*
Path mapping is NOT done for git_path_submodule(). Multi-checkouts are
not supported as submodules.
Helped-by: Jens Lehmann <Jens.Lehmann@web.de>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-30 16:24:36 +08:00
|
|
|
git_object_dir = git_path_from_env(DB_ENVIRONMENT, git_common_dir,
|
|
|
|
"objects", &git_db_env);
|
|
|
|
git_index_file = git_path_from_env(INDEX_ENVIRONMENT, git_dir,
|
|
|
|
"index", &git_index_env);
|
|
|
|
git_graft_file = git_path_from_env(GRAFT_ENVIRONMENT, git_common_dir,
|
|
|
|
"info/grafts", &git_graft_env);
|
2009-11-18 14:50:58 +08:00
|
|
|
if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
|
2014-02-18 19:24:55 +08:00
|
|
|
check_replace_refs = 0;
|
2015-06-12 05:34:59 +08:00
|
|
|
replace_ref_base = getenv(GIT_REPLACE_REF_BASE_ENVIRONMENT);
|
|
|
|
git_replace_ref_base = xstrdup(replace_ref_base ? replace_ref_base
|
|
|
|
: "refs/replace/");
|
ref namespaces: infrastructure
Add support for dividing the refs of a single repository into multiple
namespaces, each of which can have its own branches, tags, and HEAD.
Git can expose each namespace as an independent repository to pull from
and push to, while sharing the object store, and exposing all the refs
to operations such as git-gc.
Storing multiple repositories as namespaces of a single repository
avoids storing duplicate copies of the same objects, such as when
storing multiple branches of the same source. The alternates mechanism
provides similar support for avoiding duplicates, but alternates do not
prevent duplication between new objects added to the repositories
without ongoing maintenance, while namespaces do.
To specify a namespace, set the GIT_NAMESPACE environment variable to
the namespace. For each ref namespace, git stores the corresponding
refs in a directory under refs/namespaces/. For example,
GIT_NAMESPACE=foo will store refs under refs/namespaces/foo/. You can
also specify namespaces via the --namespace option to git.
Note that namespaces which include a / will expand to a hierarchy of
namespaces; for example, GIT_NAMESPACE=foo/bar will store refs under
refs/namespaces/foo/refs/namespaces/bar/. This makes paths in
GIT_NAMESPACE behave hierarchically, so that cloning with
GIT_NAMESPACE=foo/bar produces the same result as cloning with
GIT_NAMESPACE=foo and cloning from that repo with GIT_NAMESPACE=bar. It
also avoids ambiguity with strange namespace paths such as
foo/refs/heads/, which could otherwise generate directory/file conflicts
within the refs directory.
Add the infrastructure for ref namespaces: handle the GIT_NAMESPACE
environment variable and --namespace option, and support iterating over
refs in a namespace.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-07-06 01:54:44 +08:00
|
|
|
namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT));
|
|
|
|
namespace_len = strlen(namespace);
|
2013-12-05 21:02:45 +08:00
|
|
|
shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);
|
|
|
|
if (shallow_file)
|
|
|
|
set_alternate_shallow_file(shallow_file, 0);
|
2006-12-15 06:41:17 +08:00
|
|
|
}
|
|
|
|
|
2007-01-07 18:00:28 +08:00
|
|
|
int is_bare_repository(void)
|
2006-12-15 06:41:17 +08:00
|
|
|
{
|
Clean up work-tree handling
The old version of work-tree support was an unholy mess, barely readable,
and not to the point.
For example, why do you have to provide a worktree, when it is not used?
As in "git status". Now it works.
Another riddle was: if you can have work trees inside the git dir, why
are some programs complaining that they need a work tree?
IOW it is allowed to call
$ git --git-dir=../ --work-tree=. bla
when you really want to. In this case, you are both in the git directory
and in the working tree. So, programs have to actually test for the right
thing, namely if they are inside a working tree, and not if they are
inside a git directory.
Also, GIT_DIR=../.git should behave the same as if no GIT_DIR was
specified, unless there is a repository in the current working directory.
It does now.
The logic to determine if a repository is bare, or has a work tree
(tertium non datur), is this:
--work-tree=bla overrides GIT_WORK_TREE, which overrides core.bare = true,
which overrides core.worktree, which overrides GIT_DIR/.. when GIT_DIR
ends in /.git, which overrides the directory in which .git/ was found.
In related news, a long standing bug was fixed: when in .git/bla/x.git/,
which is a bare repository, git formerly assumed ../.. to be the
appropriate git dir. This problem was reported by Shawn Pearce to have
caused much pain, where a colleague mistakenly ran "git init" in "/" a
long time ago, and bare repositories just would not work.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-08-01 08:30:14 +08:00
|
|
|
/* if core.bare is not 'false', let's see if there is a work tree */
|
|
|
|
return is_bare_repository_cfg && !get_git_work_tree();
|
2005-10-12 09:47:34 +08:00
|
|
|
}
|
|
|
|
|
2006-08-23 18:39:11 +08:00
|
|
|
const char *get_git_dir(void)
|
2005-10-12 09:47:34 +08:00
|
|
|
{
|
|
|
|
if (!git_dir)
|
|
|
|
setup_git_env();
|
|
|
|
return git_dir;
|
|
|
|
}
|
|
|
|
|
$GIT_COMMON_DIR: a new environment variable
This variable is intended to support multiple working directories
attached to a repository. Such a repository may have a main working
directory, created by either "git init" or "git clone" and one or more
linked working directories. These working directories and the main
repository share the same repository directory.
In linked working directories, $GIT_COMMON_DIR must be defined to point
to the real repository directory and $GIT_DIR points to an unused
subdirectory inside $GIT_COMMON_DIR. File locations inside the
repository are reorganized from the linked worktree view point:
- worktree-specific such as HEAD, logs/HEAD, index, other top-level
refs and unrecognized files are from $GIT_DIR.
- the rest like objects, refs, info, hooks, packed-refs, shallow...
are from $GIT_COMMON_DIR (except info/sparse-checkout, but that's
a separate patch)
Scripts are supposed to retrieve paths in $GIT_DIR with "git rev-parse
--git-path", which will take care of "$GIT_DIR vs $GIT_COMMON_DIR"
business.
The redirection is done by git_path(), git_pathdup() and
strbuf_git_path(). The selected list of paths goes to $GIT_COMMON_DIR,
not the other way around in case a developer adds a new
worktree-specific file and it's accidentally promoted to be shared
across repositories (this includes unknown files added by third party
commands)
The list of known files that belong to $GIT_DIR are:
ADD_EDIT.patch BISECT_ANCESTORS_OK BISECT_EXPECTED_REV BISECT_LOG
BISECT_NAMES CHERRY_PICK_HEAD COMMIT_MSG FETCH_HEAD HEAD MERGE_HEAD
MERGE_MODE MERGE_RR NOTES_EDITMSG NOTES_MERGE_WORKTREE ORIG_HEAD
REVERT_HEAD SQUASH_MSG TAG_EDITMSG fast_import_crash_* logs/HEAD
next-index-* rebase-apply rebase-merge rsync-refs-* sequencer/*
shallow_*
Path mapping is NOT done for git_path_submodule(). Multi-checkouts are
not supported as submodules.
Helped-by: Jens Lehmann <Jens.Lehmann@web.de>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-30 16:24:36 +08:00
|
|
|
const char *get_git_common_dir(void)
|
|
|
|
{
|
|
|
|
return git_common_dir;
|
|
|
|
}
|
|
|
|
|
ref namespaces: infrastructure
Add support for dividing the refs of a single repository into multiple
namespaces, each of which can have its own branches, tags, and HEAD.
Git can expose each namespace as an independent repository to pull from
and push to, while sharing the object store, and exposing all the refs
to operations such as git-gc.
Storing multiple repositories as namespaces of a single repository
avoids storing duplicate copies of the same objects, such as when
storing multiple branches of the same source. The alternates mechanism
provides similar support for avoiding duplicates, but alternates do not
prevent duplication between new objects added to the repositories
without ongoing maintenance, while namespaces do.
To specify a namespace, set the GIT_NAMESPACE environment variable to
the namespace. For each ref namespace, git stores the corresponding
refs in a directory under refs/namespaces/. For example,
GIT_NAMESPACE=foo will store refs under refs/namespaces/foo/. You can
also specify namespaces via the --namespace option to git.
Note that namespaces which include a / will expand to a hierarchy of
namespaces; for example, GIT_NAMESPACE=foo/bar will store refs under
refs/namespaces/foo/refs/namespaces/bar/. This makes paths in
GIT_NAMESPACE behave hierarchically, so that cloning with
GIT_NAMESPACE=foo/bar produces the same result as cloning with
GIT_NAMESPACE=foo and cloning from that repo with GIT_NAMESPACE=bar. It
also avoids ambiguity with strange namespace paths such as
foo/refs/heads/, which could otherwise generate directory/file conflicts
within the refs directory.
Add the infrastructure for ref namespaces: handle the GIT_NAMESPACE
environment variable and --namespace option, and support iterating over
refs in a namespace.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-07-06 01:54:44 +08:00
|
|
|
const char *get_git_namespace(void)
|
|
|
|
{
|
|
|
|
if (!namespace)
|
|
|
|
setup_git_env();
|
|
|
|
return namespace;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *strip_namespace(const char *namespaced_ref)
|
|
|
|
{
|
2013-12-01 04:55:40 +08:00
|
|
|
if (!starts_with(namespaced_ref, get_git_namespace()))
|
ref namespaces: infrastructure
Add support for dividing the refs of a single repository into multiple
namespaces, each of which can have its own branches, tags, and HEAD.
Git can expose each namespace as an independent repository to pull from
and push to, while sharing the object store, and exposing all the refs
to operations such as git-gc.
Storing multiple repositories as namespaces of a single repository
avoids storing duplicate copies of the same objects, such as when
storing multiple branches of the same source. The alternates mechanism
provides similar support for avoiding duplicates, but alternates do not
prevent duplication between new objects added to the repositories
without ongoing maintenance, while namespaces do.
To specify a namespace, set the GIT_NAMESPACE environment variable to
the namespace. For each ref namespace, git stores the corresponding
refs in a directory under refs/namespaces/. For example,
GIT_NAMESPACE=foo will store refs under refs/namespaces/foo/. You can
also specify namespaces via the --namespace option to git.
Note that namespaces which include a / will expand to a hierarchy of
namespaces; for example, GIT_NAMESPACE=foo/bar will store refs under
refs/namespaces/foo/refs/namespaces/bar/. This makes paths in
GIT_NAMESPACE behave hierarchically, so that cloning with
GIT_NAMESPACE=foo/bar produces the same result as cloning with
GIT_NAMESPACE=foo and cloning from that repo with GIT_NAMESPACE=bar. It
also avoids ambiguity with strange namespace paths such as
foo/refs/heads/, which could otherwise generate directory/file conflicts
within the refs directory.
Add the infrastructure for ref namespaces: handle the GIT_NAMESPACE
environment variable and --namespace option, and support iterating over
refs in a namespace.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-07-06 01:54:44 +08:00
|
|
|
return NULL;
|
|
|
|
return namespaced_ref + namespace_len;
|
|
|
|
}
|
|
|
|
|
2008-04-28 01:39:21 +08:00
|
|
|
static int git_work_tree_initialized;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Note. This works only before you used a work tree. This was added
|
|
|
|
* primarily to support git-clone to work in a new repository it just
|
|
|
|
* created, and is not meant to flip between different work trees.
|
|
|
|
*/
|
|
|
|
void set_git_work_tree(const char *new_work_tree)
|
|
|
|
{
|
2010-11-26 23:32:40 +08:00
|
|
|
if (git_work_tree_initialized) {
|
2011-03-17 19:26:46 +08:00
|
|
|
new_work_tree = real_path(new_work_tree);
|
2010-11-26 23:32:40 +08:00
|
|
|
if (strcmp(new_work_tree, work_tree))
|
|
|
|
die("internal error: work tree has already been set\n"
|
|
|
|
"Current worktree: %s\nNew worktree: %s",
|
|
|
|
work_tree, new_work_tree);
|
|
|
|
return;
|
|
|
|
}
|
2008-04-28 01:39:21 +08:00
|
|
|
git_work_tree_initialized = 1;
|
2011-03-17 19:26:46 +08:00
|
|
|
work_tree = xstrdup(real_path(new_work_tree));
|
setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR
In the test case, we run setup_git_dir_gently() the first time to read
$GIT_DIR/config so that we can resolve aliases. We'll enter
setup_discovered_git_dir() and may or may not call set_git_dir() near
the end of the function, depending on whether the detected git dir is
".git" or not. This set_git_dir() will set env var $GIT_DIR.
For normal repo, git dir detected via setup_discovered_git_dir() will be
".git", and set_git_dir() is not called. If .git file is used however,
the git dir can't be ".git" and set_git_dir() is called and $GIT_DIR
set. This is the key of this problem.
If we expand an alias (or autocorrect command names), then
setup_git_dir_gently() is run the second time. If $GIT_DIR is not set in
the first run, we run the same setup_discovered_git_dir() as before.
Nothing to see. If it is, however, we'll enter setup_explicit_git_dir()
this time.
This is where the "fun" is. If $GIT_WORK_TREE is not set but
$GIT_DIR is, you are supposed to be at the root level of the
worktree. But if you are in a subdir "foo/bar" (real worktree's top
is "foo"), this rule bites you: your detected worktree is now
"foo/bar", even though the first run correctly detected worktree as
"foo". You get "internal error: work tree has already been set" as a
result.
Bottom line is, when $GIT_DIR is set, $GIT_WORK_TREE should be set too
unless there's no work tree. But setting $GIT_WORK_TREE inside
set_git_dir() may backfire. We don't know at that point if work tree is
already configured by the caller. So set it when work tree is
detected. It does not harm if $GIT_WORK_TREE is set while $GIT_DIR is
not.
Reported-by: Bjørnar Snoksrud <snoksrud@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-26 18:37:35 +08:00
|
|
|
if (setenv(GIT_WORK_TREE_ENVIRONMENT, work_tree, 1))
|
|
|
|
die("could not set GIT_WORK_TREE to '%s'", work_tree);
|
2008-04-28 01:39:21 +08:00
|
|
|
}
|
|
|
|
|
Clean up work-tree handling
The old version of work-tree support was an unholy mess, barely readable,
and not to the point.
For example, why do you have to provide a worktree, when it is not used?
As in "git status". Now it works.
Another riddle was: if you can have work trees inside the git dir, why
are some programs complaining that they need a work tree?
IOW it is allowed to call
$ git --git-dir=../ --work-tree=. bla
when you really want to. In this case, you are both in the git directory
and in the working tree. So, programs have to actually test for the right
thing, namely if they are inside a working tree, and not if they are
inside a git directory.
Also, GIT_DIR=../.git should behave the same as if no GIT_DIR was
specified, unless there is a repository in the current working directory.
It does now.
The logic to determine if a repository is bare, or has a work tree
(tertium non datur), is this:
--work-tree=bla overrides GIT_WORK_TREE, which overrides core.bare = true,
which overrides core.worktree, which overrides GIT_DIR/.. when GIT_DIR
ends in /.git, which overrides the directory in which .git/ was found.
In related news, a long standing bug was fixed: when in .git/bla/x.git/,
which is a bare repository, git formerly assumed ../.. to be the
appropriate git dir. This problem was reported by Shawn Pearce to have
caused much pain, where a colleague mistakenly ran "git init" in "/" a
long time ago, and bare repositories just would not work.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-08-01 08:30:14 +08:00
|
|
|
const char *get_git_work_tree(void)
|
|
|
|
{
|
|
|
|
return work_tree;
|
|
|
|
}
|
|
|
|
|
2005-10-12 09:47:34 +08:00
|
|
|
char *get_object_directory(void)
|
|
|
|
{
|
|
|
|
if (!git_object_dir)
|
|
|
|
setup_git_env();
|
|
|
|
return git_object_dir;
|
|
|
|
}
|
|
|
|
|
2010-11-06 19:45:38 +08:00
|
|
|
int odb_mkstemp(char *template, size_t limit, const char *pattern)
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
/*
|
|
|
|
* we let the umask do its job, don't try to be more
|
|
|
|
* restrictive except to remove write permission.
|
|
|
|
*/
|
|
|
|
int mode = 0444;
|
|
|
|
snprintf(template, limit, "%s/%s",
|
|
|
|
get_object_directory(), pattern);
|
|
|
|
fd = git_mkstemp_mode(template, mode);
|
|
|
|
if (0 <= fd)
|
|
|
|
return fd;
|
|
|
|
|
|
|
|
/* slow path */
|
|
|
|
/* some mkstemp implementations erase template on failure */
|
|
|
|
snprintf(template, limit, "%s/%s",
|
|
|
|
get_object_directory(), pattern);
|
|
|
|
safe_create_leading_directories(template);
|
|
|
|
return xmkstemp_mode(template, mode);
|
|
|
|
}
|
|
|
|
|
2014-03-16 21:35:00 +08:00
|
|
|
int odb_pack_keep(char *name, size_t namesz, const unsigned char *sha1)
|
2010-11-06 19:45:38 +08:00
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
snprintf(name, namesz, "%s/pack/pack-%s.keep",
|
|
|
|
get_object_directory(), sha1_to_hex(sha1));
|
|
|
|
fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
|
|
|
|
if (0 <= fd)
|
|
|
|
return fd;
|
|
|
|
|
|
|
|
/* slow path */
|
|
|
|
safe_create_leading_directories(name);
|
|
|
|
return open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
|
|
|
|
}
|
|
|
|
|
2005-10-12 09:47:34 +08:00
|
|
|
char *get_index_file(void)
|
|
|
|
{
|
|
|
|
if (!git_index_file)
|
|
|
|
setup_git_env();
|
|
|
|
return git_index_file;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *get_graft_file(void)
|
|
|
|
{
|
|
|
|
if (!git_graft_file)
|
|
|
|
setup_git_env();
|
|
|
|
return git_graft_file;
|
|
|
|
}
|
2007-08-01 08:29:38 +08:00
|
|
|
|
|
|
|
int set_git_dir(const char *path)
|
|
|
|
{
|
|
|
|
if (setenv(GIT_DIR_ENVIRONMENT, path, 1))
|
|
|
|
return error("Could not set GIT_DIR to '%s'", path);
|
|
|
|
setup_git_env();
|
|
|
|
return 0;
|
|
|
|
}
|
2010-11-03 03:59:07 +08:00
|
|
|
|
|
|
|
const char *get_log_output_encoding(void)
|
|
|
|
{
|
|
|
|
return git_log_output_encoding ? git_log_output_encoding
|
|
|
|
: get_commit_output_encoding();
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *get_commit_output_encoding(void)
|
|
|
|
{
|
|
|
|
return git_commit_encoding ? git_commit_encoding : "UTF-8";
|
|
|
|
}
|