Make it possible to set up libgit directly (instead of from the environment)

This introduces a setup_git() function which is essentialy a (public)
backend for setup_git_env() which lets anyone specify custom sources
for the various paths instead of environment variables. Since the repositories
may get switched on the fly, this also updates code that caches paths to
invalidate them properly; I hope neither of those is a sweet spot.

It is used by Git.xs' xs__call_gate() to set up per-repository data
for libgit's consumption. No code actually takes advantage of it yet
but get_object() will in the next patches.

Signed-off-by: Petr Baudis <pasky@suse.cz>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Petr Baudis
2006-07-03 22:48:03 +02:00
committed by Junio C Hamano
parent 998c4daaf4
commit 0270083ded
7 changed files with 114 additions and 24 deletions

View File

@ -116,6 +116,9 @@ extern struct cache_entry **active_cache;
extern unsigned int active_nr, active_alloc, active_cache_changed; extern unsigned int active_nr, active_alloc, active_cache_changed;
extern struct cache_tree *active_cache_tree; extern struct cache_tree *active_cache_tree;
extern void setup_git(char *new_git_dir, char *new_git_object_dir,
char *new_git_index_file, char *new_git_graft_file);
#define GIT_DIR_ENVIRONMENT "GIT_DIR" #define GIT_DIR_ENVIRONMENT "GIT_DIR"
#define DEFAULT_GIT_DIR_ENVIRONMENT ".git" #define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
#define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY" #define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"

View File

@ -163,6 +163,14 @@ int register_commit_graft(struct commit_graft *graft, int ignore_dups)
return 0; return 0;
} }
void free_commit_grafts(void)
{
int pos = commit_graft_nr;
while (pos >= 0)
free(commit_graft[pos--]);
commit_graft_nr = 0;
}
struct commit_graft *read_graft_line(char *buf, int len) struct commit_graft *read_graft_line(char *buf, int len)
{ {
/* The format is just "Commit Parent1 Parent2 ...\n" */ /* The format is just "Commit Parent1 Parent2 ...\n" */
@ -215,11 +223,18 @@ int read_graft_file(const char *graft_file)
static void prepare_commit_graft(void) static void prepare_commit_graft(void)
{ {
static int commit_graft_prepared; static int commit_graft_prepared;
char *graft_file; static char *last_graft_file;
char *graft_file = get_graft_file();
if (last_graft_file) {
if (!strcmp(graft_file, last_graft_file))
return;
free_commit_grafts();
}
if (last_graft_file)
free(last_graft_file);
last_graft_file = strdup(graft_file);
if (commit_graft_prepared)
return;
graft_file = get_graft_file();
read_graft_file(graft_file); read_graft_file(graft_file);
commit_graft_prepared = 1; commit_graft_prepared = 1;
} }

View File

@ -21,28 +21,61 @@ char git_commit_encoding[MAX_ENCODING_LENGTH] = "utf-8";
int shared_repository = PERM_UMASK; int shared_repository = PERM_UMASK;
const char *apply_default_whitespace = NULL; const char *apply_default_whitespace = NULL;
static int dyn_git_object_dir, dyn_git_index_file, dyn_git_graft_file;
static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir, static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir,
*git_graft_file; *git_graft_file;
static void setup_git_env(void)
void setup_git(char *new_git_dir, char *new_git_object_dir,
char *new_git_index_file, char *new_git_graft_file)
{ {
git_dir = getenv(GIT_DIR_ENVIRONMENT); git_dir = new_git_dir;
if (!git_dir) if (!git_dir)
git_dir = DEFAULT_GIT_DIR_ENVIRONMENT; git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
git_object_dir = getenv(DB_ENVIRONMENT);
if (dyn_git_object_dir)
free(git_object_dir);
git_object_dir = new_git_object_dir;
if (!git_object_dir) { if (!git_object_dir) {
git_object_dir = xmalloc(strlen(git_dir) + 9); git_object_dir = xmalloc(strlen(git_dir) + 9);
sprintf(git_object_dir, "%s/objects", git_dir); sprintf(git_object_dir, "%s/objects", git_dir);
dyn_git_object_dir = 1;
} else {
dyn_git_object_dir = 0;
} }
if (git_refs_dir)
free(git_refs_dir);
git_refs_dir = xmalloc(strlen(git_dir) + 6); git_refs_dir = xmalloc(strlen(git_dir) + 6);
sprintf(git_refs_dir, "%s/refs", git_dir); sprintf(git_refs_dir, "%s/refs", git_dir);
git_index_file = getenv(INDEX_ENVIRONMENT);
if (dyn_git_index_file)
free(git_index_file);
git_index_file = new_git_index_file;
if (!git_index_file) { if (!git_index_file) {
git_index_file = xmalloc(strlen(git_dir) + 7); git_index_file = xmalloc(strlen(git_dir) + 7);
sprintf(git_index_file, "%s/index", git_dir); sprintf(git_index_file, "%s/index", git_dir);
dyn_git_index_file = 1;
} else {
dyn_git_index_file = 0;
} }
git_graft_file = getenv(GRAFT_ENVIRONMENT);
if (!git_graft_file) if (dyn_git_graft_file)
free(git_graft_file);
git_graft_file = new_git_graft_file;
if (!git_graft_file) {
git_graft_file = strdup(git_path("info/grafts")); git_graft_file = strdup(git_path("info/grafts"));
dyn_git_graft_file = 1;
} else {
dyn_git_graft_file = 0;
}
}
static void setup_git_env(void)
{
setup_git(getenv(GIT_DIR_ENVIRONMENT),
getenv(DB_ENVIRONMENT),
getenv(INDEX_ENVIRONMENT),
getenv(GRAFT_ENVIRONMENT));
} }
char *get_git_dir(void) char *get_git_dir(void)

View File

@ -98,6 +98,8 @@ XSLoader::load('Git', $VERSION);
} }
my $instance_id = 0;
=head1 CONSTRUCTORS =head1 CONSTRUCTORS
@ -215,7 +217,7 @@ sub repository {
delete $opts{Directory}; delete $opts{Directory};
} }
$self = { opts => \%opts }; $self = { opts => \%opts, id => $instance_id++ };
bless $self, $class; bless $self, $class;
} }
@ -833,11 +835,10 @@ sub _call_gate {
if (defined $self) { if (defined $self) {
# XXX: We ignore the WorkingCopy! To properly support # XXX: We ignore the WorkingCopy! To properly support
# that will require heavy changes in libgit. # that will require heavy changes in libgit.
# For now, when we will need to do it we could temporarily
# chdir() there and then chdir() back after the call is done.
# XXX: And we ignore everything else as well. libgit xs__call_gate($self->{id}, $self->repo_path());
# at least needs to be extended to let us specify
# the $GIT_DIR instead of looking it up in environment.
#xs_call_gate($self->{opts}->{Repository});
} }
# Having to call throw from the C code is a sure path to insanity. # Having to call throw from the C code is a sure path to insanity.

View File

@ -52,7 +52,21 @@ BOOT:
} }
# /* TODO: xs_call_gate(). See Git.pm. */ void
xs__call_gate(repoid, git_dir)
long repoid;
char *git_dir;
CODE:
{
static long last_repoid;
if (repoid != last_repoid) {
setup_git(git_dir,
getenv(DB_ENVIRONMENT),
getenv(INDEX_ENVIRONMENT),
getenv(GRAFT_ENVIRONMENT));
last_repoid = repoid;
}
}
char * char *

View File

@ -126,16 +126,22 @@ static void fill_sha1_path(char *pathbuf, const unsigned char *sha1)
char *sha1_file_name(const unsigned char *sha1) char *sha1_file_name(const unsigned char *sha1)
{ {
static char *name, *base; static char *name, *base;
static const char *last_objdir;
const char *sha1_file_directory = get_object_directory();
if (!base) { if (!last_objdir || strcmp(last_objdir, sha1_file_directory)) {
const char *sha1_file_directory = get_object_directory();
int len = strlen(sha1_file_directory); int len = strlen(sha1_file_directory);
if (base)
free(base);
base = xmalloc(len + 60); base = xmalloc(len + 60);
memcpy(base, sha1_file_directory, len); memcpy(base, sha1_file_directory, len);
memset(base+len, 0, 60); memset(base+len, 0, 60);
base[len] = '/'; base[len] = '/';
base[len+3] = '/'; base[len+3] = '/';
name = base + len + 1; name = base + len + 1;
if (last_objdir)
free((char *) last_objdir);
last_objdir = strdup(sha1_file_directory);
} }
fill_sha1_path(name, sha1); fill_sha1_path(name, sha1);
return base; return base;
@ -145,14 +151,20 @@ char *sha1_pack_name(const unsigned char *sha1)
{ {
static const char hex[] = "0123456789abcdef"; static const char hex[] = "0123456789abcdef";
static char *name, *base, *buf; static char *name, *base, *buf;
static const char *last_objdir;
const char *sha1_file_directory = get_object_directory();
int i; int i;
if (!base) { if (!last_objdir || strcmp(last_objdir, sha1_file_directory)) {
const char *sha1_file_directory = get_object_directory();
int len = strlen(sha1_file_directory); int len = strlen(sha1_file_directory);
if (base)
free(base);
base = xmalloc(len + 60); base = xmalloc(len + 60);
sprintf(base, "%s/pack/pack-1234567890123456789012345678901234567890.pack", sha1_file_directory); sprintf(base, "%s/pack/pack-1234567890123456789012345678901234567890.pack", sha1_file_directory);
name = base + len + 11; name = base + len + 11;
if (last_objdir)
free((char *) last_objdir);
last_objdir = strdup(sha1_file_directory);
} }
buf = name; buf = name;
@ -170,14 +182,20 @@ char *sha1_pack_index_name(const unsigned char *sha1)
{ {
static const char hex[] = "0123456789abcdef"; static const char hex[] = "0123456789abcdef";
static char *name, *base, *buf; static char *name, *base, *buf;
static const char *last_objdir;
const char *sha1_file_directory = get_object_directory();
int i; int i;
if (!base) { if (!last_objdir || strcmp(last_objdir, sha1_file_directory)) {
const char *sha1_file_directory = get_object_directory();
int len = strlen(sha1_file_directory); int len = strlen(sha1_file_directory);
if (base)
free(base);
base = xmalloc(len + 60); base = xmalloc(len + 60);
sprintf(base, "%s/pack/pack-1234567890123456789012345678901234567890.idx", sha1_file_directory); sprintf(base, "%s/pack/pack-1234567890123456789012345678901234567890.idx", sha1_file_directory);
name = base + len + 11; name = base + len + 11;
if (last_objdir)
free((char *) last_objdir);
last_objdir = strdup(sha1_file_directory);
} }
buf = name; buf = name;

View File

@ -12,15 +12,21 @@ static int find_short_object_filename(int len, const char *name, unsigned char *
char hex[40]; char hex[40];
int found = 0; int found = 0;
static struct alternate_object_database *fakeent; static struct alternate_object_database *fakeent;
static const char *last_objdir;
const char *objdir = get_object_directory();
if (!fakeent) { if (!last_objdir || strcmp(last_objdir, objdir)) {
const char *objdir = get_object_directory();
int objdir_len = strlen(objdir); int objdir_len = strlen(objdir);
int entlen = objdir_len + 43; int entlen = objdir_len + 43;
if (fakeent)
free(fakeent);
fakeent = xmalloc(sizeof(*fakeent) + entlen); fakeent = xmalloc(sizeof(*fakeent) + entlen);
memcpy(fakeent->base, objdir, objdir_len); memcpy(fakeent->base, objdir, objdir_len);
fakeent->name = fakeent->base + objdir_len + 1; fakeent->name = fakeent->base + objdir_len + 1;
fakeent->name[-1] = '/'; fakeent->name[-1] = '/';
if (last_objdir)
free((char *) last_objdir);
last_objdir = strdup(objdir);
} }
fakeent->next = alt_odb_list; fakeent->next = alt_odb_list;