Skip to content

Commit ec24e54

Browse files
author
Vicent Marti
committed
What are the chances, really
1 parent 56960b8 commit ec24e54

File tree

11 files changed

+234
-448
lines changed

11 files changed

+234
-448
lines changed

include/git2/refs.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,8 @@ GIT_EXTERN(int) git_reference_delete(git_reference *ref);
308308
*/
309309
GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo);
310310

311-
typedef int (*git_reference_foreach_cb)(const char *refname, void *payload);
311+
typedef int (*git_reference_foreach_cb)(git_reference *reference, void *payload);
312+
typedef int (*git_reference_foreach_name_cb)(const char *name, void *payload);
312313

313314
/**
314315
* Perform a callback on each reference in the repository.
@@ -328,6 +329,11 @@ GIT_EXTERN(int) git_reference_foreach(
328329
git_reference_foreach_cb callback,
329330
void *payload);
330331

332+
GIT_EXTERN(int) git_reference_foreach_name(
333+
git_repository *repo,
334+
git_reference_foreach_name_cb callback,
335+
void *payload);
336+
331337
/**
332338
* Free the given reference.
333339
*
@@ -378,6 +384,8 @@ GIT_EXTERN(int) git_reference_iterator_glob_new(
378384
*/
379385
GIT_EXTERN(int) git_reference_next(git_reference **out, git_reference_iterator *iter);
380386

387+
GIT_EXTERN(int) git_reference_next_name(const char **out, git_reference_iterator *iter);
388+
381389
/**
382390
* Free the iterator and its associated resources
383391
*
@@ -406,7 +414,7 @@ GIT_EXTERN(void) git_reference_iterator_free(git_reference_iterator *iter);
406414
GIT_EXTERN(int) git_reference_foreach_glob(
407415
git_repository *repo,
408416
const char *glob,
409-
git_reference_foreach_cb callback,
417+
git_reference_foreach_name_cb callback,
410418
void *payload);
411419

412420
/**

include/git2/sys/refdb_backend.h

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,27 @@ GIT_BEGIN_DECL
3333
* and assign `iter->parent.backend` to your `git_refdb_backend`.
3434
*/
3535
struct git_reference_iterator {
36-
git_refdb_backend *backend;
37-
char *glob;
36+
git_refdb *db;
37+
38+
/**
39+
* Return the current reference and advance the iterator.
40+
*/
41+
int (*next)(
42+
git_reference **ref,
43+
git_reference_iterator *iter);
44+
45+
/**
46+
* Return the name of the current reference and advance the iterator
47+
*/
48+
int (*next_name)(
49+
const char **ref_name,
50+
git_reference_iterator *iter);
51+
52+
/**
53+
* Free the iterator
54+
*/
55+
void (*free)(
56+
git_reference_iterator *iter);
3857
};
3958

4059
/** An instance for a custom backend */
@@ -65,36 +84,10 @@ struct git_refdb_backend {
6584
* A refdb implementation must provide this function.
6685
*/
6786
int (*iterator)(
68-
git_reference_iterator **iter,
69-
struct git_refdb_backend *backend);
70-
71-
/**
72-
* Allocate a glob-filtering iterator object for the backend.
73-
*
74-
* A refdb implementation may provide this function. If it's
75-
* not available, the glob matching will be done by the frontend.
76-
*/
77-
int (*iterator_glob)(
7887
git_reference_iterator **iter,
7988
struct git_refdb_backend *backend,
8089
const char *glob);
8190

82-
/**
83-
* Return the current value and advance the iterator.
84-
*
85-
* A refdb implementation must provide this function.
86-
*/
87-
int (*next)(
88-
git_reference **ref,
89-
git_reference_iterator *iter);
90-
91-
/**
92-
* Free the iterator
93-
*
94-
* A refdb implementation must provide this function.
95-
*/
96-
void (*iterator_free)(
97-
git_reference_iterator *iter);
9891
/*
9992
* Writes the given reference to the refdb. A refdb implementation
10093
* must provide this function.

src/clone.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ static int update_head_to_remote(git_repository *repo, git_remote *remote)
241241
}
242242

243243
/* Not master. Check all the other refs. */
244-
if (git_reference_foreach(
244+
if (git_reference_foreach_name(
245245
repo,
246246
reference_matches_remote_head,
247247
&head_info) < 0)

src/refdb.c

Lines changed: 23 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -114,99 +114,65 @@ int git_refdb_lookup(git_reference **out, git_refdb *db, const char *ref_name)
114114

115115
assert(db && db->backend && out && ref_name);
116116

117-
if (!(error = db->backend->lookup(&ref, db->backend, ref_name))) {
118-
ref->db = db;
119-
*out = ref;
120-
} else {
121-
*out = NULL;
122-
}
117+
error = db->backend->lookup(&ref, db->backend, ref_name);
118+
if (error < 0)
119+
return error;
120+
121+
GIT_REFCOUNT_INC(db);
122+
ref->db = db;
123123

124-
return error;
124+
*out = ref;
125+
return 0;
125126
}
126127

127-
int git_refdb_iterator(git_reference_iterator **out, git_refdb *db)
128+
int git_refdb_iterator(git_reference_iterator **out, git_refdb *db, const char *glob)
128129
{
129130
if (!db->backend || !db->backend->iterator) {
130131
giterr_set(GITERR_REFERENCE, "This backend doesn't support iterators");
131132
return -1;
132133
}
133134

134-
if (db->backend->iterator(out, db->backend) < 0)
135+
if (db->backend->iterator(out, db->backend, glob) < 0)
135136
return -1;
136137

138+
GIT_REFCOUNT_INC(db);
139+
(*out)->db = db;
140+
137141
return 0;
138142
}
139143

140-
int git_refdb_iterator_glob(git_reference_iterator **out, git_refdb *db, const char *glob)
144+
int git_refdb_iterator_next(git_reference **out, git_reference_iterator *iter)
141145
{
142-
if (!db->backend) {
143-
giterr_set(GITERR_REFERENCE, "There are no backends loaded");
144-
return -1;
145-
}
146-
147-
if (db->backend->iterator_glob)
148-
return db->backend->iterator_glob(out, db->backend, glob);
146+
int error;
149147

150-
/* If the backend doesn't support glob-filtering themselves, we have to do it */
151-
if (db->backend->iterator(out, db->backend) < 0)
152-
return -1;
148+
if ((error = iter->next(out, iter)) < 0)
149+
return error;
153150

154-
(*out)->glob = git__strdup(glob);
155-
if (!(*out)->glob) {
156-
db->backend->iterator_free(*out);
157-
return -1;
158-
}
151+
GIT_REFCOUNT_INC(iter->db);
152+
(*out)->db = iter->db;
159153

160154
return 0;
161155
}
162156

163-
int git_refdb_next(git_reference **out, git_reference_iterator *iter)
157+
int git_refdb_iterator_next_name(const char **out, git_reference_iterator *iter)
164158
{
165-
int error;
166-
167-
if (!iter->glob) {
168-
if ((error = iter->backend->next(out, iter)) < 0)
169-
return error;
170-
171-
(*out)->db = iter->backend;
172-
return 0;
173-
}
174-
175-
/* If the iterator has a glob, we need to filter */
176-
while ((error = iter->backend->next(out, iter)) == 0) {
177-
if (!p_fnmatch(iter->glob, (*out)->name, 0)) {
178-
(*out)->db = iter->backend;
179-
return 0;
180-
}
181-
182-
git_reference_free(*out);
183-
}
184-
185-
return error;
159+
return iter->next_name(out, iter);
186160
}
187161

188162
void git_refdb_iterator_free(git_reference_iterator *iter)
189163
{
190-
git__free(iter->glob);
191-
iter->backend->iterator_free(iter);
164+
GIT_REFCOUNT_DEC(iter->db, refdb_free);
165+
iter->free(iter);
192166
}
193167

194-
struct glob_cb_data {
195-
const char *glob;
196-
git_reference_foreach_cb callback;
197-
void *payload;
198-
};
199-
200168
int git_refdb_write(git_refdb *db, const git_reference *ref)
201169
{
202170
assert(db && db->backend);
203-
204171
return db->backend->write(db->backend, ref);
205172
}
206173

207174
int git_refdb_delete(struct git_refdb *db, const git_reference *ref)
208175
{
209176
assert(db && db->backend);
210-
211177
return db->backend->delete(db->backend, ref);
212178
}

src/refdb.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,12 @@ int git_refdb_lookup(
2626
git_refdb *refdb,
2727
const char *ref_name);
2828

29-
int git_refdb_iterator(git_reference_iterator **out, git_refdb *db);
30-
int git_refdb_iterator_glob(git_reference_iterator **out, git_refdb *db, const char *glob);
31-
int git_refdb_next(git_reference **out, git_reference_iterator *iter);
29+
int git_refdb_iterator(git_reference_iterator **out, git_refdb *db, const char *glob);
30+
int git_refdb_iterator_next(git_reference **out, git_reference_iterator *iter);
31+
int git_refdb_iterator_next_name(const char **out, git_reference_iterator *iter);
3232
void git_refdb_iterator_free(git_reference_iterator *iter);
3333

3434
int git_refdb_write(git_refdb *refdb, const git_reference *ref);
35-
3635
int git_refdb_delete(git_refdb *refdb, const git_reference *ref);
3736

3837
#endif

0 commit comments

Comments
 (0)