Skip to content

Commit 0270083

Browse files
Petr BaudisJunio C Hamano
Petr Baudis
authored and
Junio C Hamano
committed
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 998c4da commit 0270083

File tree

7 files changed

+114
-24
lines changed

7 files changed

+114
-24
lines changed

cache.h

+3
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ extern struct cache_entry **active_cache;
116116
extern unsigned int active_nr, active_alloc, active_cache_changed;
117117
extern struct cache_tree *active_cache_tree;
118118

119+
extern void setup_git(char *new_git_dir, char *new_git_object_dir,
120+
char *new_git_index_file, char *new_git_graft_file);
121+
119122
#define GIT_DIR_ENVIRONMENT "GIT_DIR"
120123
#define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
121124
#define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"

commit.c

+19-4
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,14 @@ int register_commit_graft(struct commit_graft *graft, int ignore_dups)
163163
return 0;
164164
}
165165

166+
void free_commit_grafts(void)
167+
{
168+
int pos = commit_graft_nr;
169+
while (pos >= 0)
170+
free(commit_graft[pos--]);
171+
commit_graft_nr = 0;
172+
}
173+
166174
struct commit_graft *read_graft_line(char *buf, int len)
167175
{
168176
/* The format is just "Commit Parent1 Parent2 ...\n" */
@@ -215,11 +223,18 @@ int read_graft_file(const char *graft_file)
215223
static void prepare_commit_graft(void)
216224
{
217225
static int commit_graft_prepared;
218-
char *graft_file;
226+
static char *last_graft_file;
227+
char *graft_file = get_graft_file();
228+
229+
if (last_graft_file) {
230+
if (!strcmp(graft_file, last_graft_file))
231+
return;
232+
free_commit_grafts();
233+
}
234+
if (last_graft_file)
235+
free(last_graft_file);
236+
last_graft_file = strdup(graft_file);
219237

220-
if (commit_graft_prepared)
221-
return;
222-
graft_file = get_graft_file();
223238
read_graft_file(graft_file);
224239
commit_graft_prepared = 1;
225240
}

environment.c

+39-6
Original file line numberDiff line numberDiff line change
@@ -21,28 +21,61 @@ char git_commit_encoding[MAX_ENCODING_LENGTH] = "utf-8";
2121
int shared_repository = PERM_UMASK;
2222
const char *apply_default_whitespace = NULL;
2323

24+
static int dyn_git_object_dir, dyn_git_index_file, dyn_git_graft_file;
2425
static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir,
2526
*git_graft_file;
26-
static void setup_git_env(void)
27+
28+
void setup_git(char *new_git_dir, char *new_git_object_dir,
29+
char *new_git_index_file, char *new_git_graft_file)
2730
{
28-
git_dir = getenv(GIT_DIR_ENVIRONMENT);
31+
git_dir = new_git_dir;
2932
if (!git_dir)
3033
git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
31-
git_object_dir = getenv(DB_ENVIRONMENT);
34+
35+
if (dyn_git_object_dir)
36+
free(git_object_dir);
37+
git_object_dir = new_git_object_dir;
3238
if (!git_object_dir) {
3339
git_object_dir = xmalloc(strlen(git_dir) + 9);
3440
sprintf(git_object_dir, "%s/objects", git_dir);
41+
dyn_git_object_dir = 1;
42+
} else {
43+
dyn_git_object_dir = 0;
3544
}
45+
46+
if (git_refs_dir)
47+
free(git_refs_dir);
3648
git_refs_dir = xmalloc(strlen(git_dir) + 6);
3749
sprintf(git_refs_dir, "%s/refs", git_dir);
38-
git_index_file = getenv(INDEX_ENVIRONMENT);
50+
51+
if (dyn_git_index_file)
52+
free(git_index_file);
53+
git_index_file = new_git_index_file;
3954
if (!git_index_file) {
4055
git_index_file = xmalloc(strlen(git_dir) + 7);
4156
sprintf(git_index_file, "%s/index", git_dir);
57+
dyn_git_index_file = 1;
58+
} else {
59+
dyn_git_index_file = 0;
4260
}
43-
git_graft_file = getenv(GRAFT_ENVIRONMENT);
44-
if (!git_graft_file)
61+
62+
if (dyn_git_graft_file)
63+
free(git_graft_file);
64+
git_graft_file = new_git_graft_file;
65+
if (!git_graft_file) {
4566
git_graft_file = strdup(git_path("info/grafts"));
67+
dyn_git_graft_file = 1;
68+
} else {
69+
dyn_git_graft_file = 0;
70+
}
71+
}
72+
73+
static void setup_git_env(void)
74+
{
75+
setup_git(getenv(GIT_DIR_ENVIRONMENT),
76+
getenv(DB_ENVIRONMENT),
77+
getenv(INDEX_ENVIRONMENT),
78+
getenv(GRAFT_ENVIRONMENT));
4679
}
4780

4881
char *get_git_dir(void)

perl/Git.pm

+6-5
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ XSLoader::load('Git', $VERSION);
9898

9999
}
100100

101+
my $instance_id = 0;
102+
101103

102104
=head1 CONSTRUCTORS
103105
@@ -215,7 +217,7 @@ sub repository {
215217
delete $opts{Directory};
216218
}
217219

218-
$self = { opts => \%opts };
220+
$self = { opts => \%opts, id => $instance_id++ };
219221
bless $self, $class;
220222
}
221223

@@ -833,11 +835,10 @@ sub _call_gate {
833835
if (defined $self) {
834836
# XXX: We ignore the WorkingCopy! To properly support
835837
# that will require heavy changes in libgit.
838+
# For now, when we will need to do it we could temporarily
839+
# chdir() there and then chdir() back after the call is done.
836840

837-
# XXX: And we ignore everything else as well. libgit
838-
# at least needs to be extended to let us specify
839-
# the $GIT_DIR instead of looking it up in environment.
840-
#xs_call_gate($self->{opts}->{Repository});
841+
xs__call_gate($self->{id}, $self->repo_path());
841842
}
842843

843844
# Having to call throw from the C code is a sure path to insanity.

perl/Git.xs

+15-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,21 @@ BOOT:
5252
}
5353

5454

55-
# /* TODO: xs_call_gate(). See Git.pm. */
55+
void
56+
xs__call_gate(repoid, git_dir)
57+
long repoid;
58+
char *git_dir;
59+
CODE:
60+
{
61+
static long last_repoid;
62+
if (repoid != last_repoid) {
63+
setup_git(git_dir,
64+
getenv(DB_ENVIRONMENT),
65+
getenv(INDEX_ENVIRONMENT),
66+
getenv(GRAFT_ENVIRONMENT));
67+
last_repoid = repoid;
68+
}
69+
}
5670

5771

5872
char *

sha1_file.c

+24-6
Original file line numberDiff line numberDiff line change
@@ -126,16 +126,22 @@ static void fill_sha1_path(char *pathbuf, const unsigned char *sha1)
126126
char *sha1_file_name(const unsigned char *sha1)
127127
{
128128
static char *name, *base;
129+
static const char *last_objdir;
130+
const char *sha1_file_directory = get_object_directory();
129131

130-
if (!base) {
131-
const char *sha1_file_directory = get_object_directory();
132+
if (!last_objdir || strcmp(last_objdir, sha1_file_directory)) {
132133
int len = strlen(sha1_file_directory);
134+
if (base)
135+
free(base);
133136
base = xmalloc(len + 60);
134137
memcpy(base, sha1_file_directory, len);
135138
memset(base+len, 0, 60);
136139
base[len] = '/';
137140
base[len+3] = '/';
138141
name = base + len + 1;
142+
if (last_objdir)
143+
free((char *) last_objdir);
144+
last_objdir = strdup(sha1_file_directory);
139145
}
140146
fill_sha1_path(name, sha1);
141147
return base;
@@ -145,14 +151,20 @@ char *sha1_pack_name(const unsigned char *sha1)
145151
{
146152
static const char hex[] = "0123456789abcdef";
147153
static char *name, *base, *buf;
154+
static const char *last_objdir;
155+
const char *sha1_file_directory = get_object_directory();
148156
int i;
149157

150-
if (!base) {
151-
const char *sha1_file_directory = get_object_directory();
158+
if (!last_objdir || strcmp(last_objdir, sha1_file_directory)) {
152159
int len = strlen(sha1_file_directory);
160+
if (base)
161+
free(base);
153162
base = xmalloc(len + 60);
154163
sprintf(base, "%s/pack/pack-1234567890123456789012345678901234567890.pack", sha1_file_directory);
155164
name = base + len + 11;
165+
if (last_objdir)
166+
free((char *) last_objdir);
167+
last_objdir = strdup(sha1_file_directory);
156168
}
157169

158170
buf = name;
@@ -170,14 +182,20 @@ char *sha1_pack_index_name(const unsigned char *sha1)
170182
{
171183
static const char hex[] = "0123456789abcdef";
172184
static char *name, *base, *buf;
185+
static const char *last_objdir;
186+
const char *sha1_file_directory = get_object_directory();
173187
int i;
174188

175-
if (!base) {
176-
const char *sha1_file_directory = get_object_directory();
189+
if (!last_objdir || strcmp(last_objdir, sha1_file_directory)) {
177190
int len = strlen(sha1_file_directory);
191+
if (base)
192+
free(base);
178193
base = xmalloc(len + 60);
179194
sprintf(base, "%s/pack/pack-1234567890123456789012345678901234567890.idx", sha1_file_directory);
180195
name = base + len + 11;
196+
if (last_objdir)
197+
free((char *) last_objdir);
198+
last_objdir = strdup(sha1_file_directory);
181199
}
182200

183201
buf = name;

sha1_name.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,21 @@ static int find_short_object_filename(int len, const char *name, unsigned char *
1212
char hex[40];
1313
int found = 0;
1414
static struct alternate_object_database *fakeent;
15+
static const char *last_objdir;
16+
const char *objdir = get_object_directory();
1517

16-
if (!fakeent) {
17-
const char *objdir = get_object_directory();
18+
if (!last_objdir || strcmp(last_objdir, objdir)) {
1819
int objdir_len = strlen(objdir);
1920
int entlen = objdir_len + 43;
21+
if (fakeent)
22+
free(fakeent);
2023
fakeent = xmalloc(sizeof(*fakeent) + entlen);
2124
memcpy(fakeent->base, objdir, objdir_len);
2225
fakeent->name = fakeent->base + objdir_len + 1;
2326
fakeent->name[-1] = '/';
27+
if (last_objdir)
28+
free((char *) last_objdir);
29+
last_objdir = strdup(objdir);
2430
}
2531
fakeent->next = alt_odb_list;
2632

0 commit comments

Comments
 (0)