Skip to content

Commit c3512fe

Browse files
authored
Merge branch 'main' into multi-pack-index-odb-write
2 parents ea28590 + 78cd762 commit c3512fe

File tree

16 files changed

+352
-114
lines changed

16 files changed

+352
-114
lines changed

.devcontainer/devcontainer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"postCreateCommand": "bash .devcontainer/setup.sh"
3+
}

.devcontainer/setup.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/sh
2+
set -e
3+
4+
sudo apt-get update
5+
sudo apt-get -y --no-install-recommends install cmake
6+
7+
mkdir build
8+
cd build
9+
cmake ..

.vscode/launch.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "(gdb) Launch",
9+
"type": "cppdbg",
10+
"request": "launch",
11+
"program": "${workspaceFolder}/build/libgit2_clar",
12+
"args": [],
13+
"stopAtEntry": false,
14+
"cwd": "${fileDirname}",
15+
"environment": [],
16+
"externalConsole": false,
17+
"MIMode": "gdb",
18+
"setupCommands": [
19+
{
20+
"description": "Enable pretty-printing for gdb",
21+
"text": "-enable-pretty-printing",
22+
"ignoreFailures": true
23+
}
24+
]
25+
}
26+
]
27+
}

.vscode/tasks.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
// See https://go.microsoft.com/fwlink/?LinkId=733558
3+
// for the documentation about the tasks.json format
4+
"version": "2.0.0",
5+
"tasks": [
6+
{
7+
"label": "Build",
8+
"type": "shell",
9+
"command": "cd build && cmake --build . --parallel",
10+
"group": "build",
11+
"presentation": {
12+
"reveal": "always",
13+
"panel": "new"
14+
}
15+
},
16+
{
17+
"label": "Run Tests",
18+
"type": "shell",
19+
"command": "build/libgit2_clar -v",
20+
"group": "test",
21+
"presentation": {
22+
"reveal": "always",
23+
"panel": "new"
24+
}
25+
}
26+
]
27+
}

cmake/SelectHashes.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ ELSE()
5656
MESSAGE(FATAL_ERROR "Asked for unknown SHA1 backend: ${USE_SHA1}")
5757
ENDIF()
5858

59+
list(APPEND SRC_SHA1 "hash/sha1.h")
5960
list(SORT SRC_SHA1)
6061

6162
ADD_FEATURE_INFO(SHA ON "using ${USE_SHA1}")

src/array.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141

4242
typedef git_array_t(char) git_array_generic_t;
4343

44-
/* use a generic array for growth so this can return the new item */
45-
GIT_INLINE(void *) git_array_grow(void *_a, size_t item_size)
44+
/* use a generic array for growth, return 0 on success */
45+
GIT_INLINE(int) git_array_grow(void *_a, size_t item_size)
4646
{
4747
volatile git_array_generic_t *a = _a;
4848
size_t new_size;
@@ -59,18 +59,18 @@ GIT_INLINE(void *) git_array_grow(void *_a, size_t item_size)
5959
if ((new_array = git__reallocarray(a->ptr, new_size, item_size)) == NULL)
6060
goto on_oom;
6161

62-
a->ptr = new_array; a->asize = new_size; a->size++;
63-
return a->ptr + (a->size - 1) * item_size;
62+
a->ptr = new_array;
63+
a->asize = new_size;
64+
return 0;
6465

6566
on_oom:
6667
git_array_clear(*a);
67-
return NULL;
68+
return -1;
6869
}
6970

7071
#define git_array_alloc(a) \
71-
(((a).size >= (a).asize) ? \
72-
git_array_grow(&(a), sizeof(*(a).ptr)) : \
73-
((a).ptr ? &(a).ptr[(a).size++] : (void *)NULL))
72+
(((a).size < (a).asize || git_array_grow(&(a), sizeof(*(a).ptr)) == 0) ? \
73+
&(a).ptr[(a).size++] : (void *)NULL)
7474

7575
#define git_array_last(a) ((a).size ? &(a).ptr[(a).size - 1] : (void *)NULL)
7676

src/attrcache.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ static int attr_cache_remove(git_attr_cache *cache, git_attr_file *file)
127127
{
128128
int error = 0;
129129
git_attr_file_entry *entry;
130-
git_attr_file *old = NULL;
130+
git_attr_file *oldfile = NULL;
131131

132132
if (!file)
133133
return 0;
@@ -136,13 +136,13 @@ static int attr_cache_remove(git_attr_cache *cache, git_attr_file *file)
136136
return error;
137137

138138
if ((entry = attr_cache_lookup_entry(cache, file->entry->path)) != NULL)
139-
old = git_atomic_compare_and_swap(&entry->file[file->source.type], file, NULL);
139+
oldfile = git_atomic_compare_and_swap(&entry->file[file->source.type], file, NULL);
140140

141141
attr_cache_unlock(cache);
142142

143-
if (old) {
144-
GIT_REFCOUNT_OWN(old, NULL);
145-
git_attr_file__free(old);
143+
if (oldfile == file) {
144+
GIT_REFCOUNT_OWN(file, NULL);
145+
git_attr_file__free(file);
146146
}
147147

148148
return error;
@@ -401,8 +401,7 @@ int git_attr_cache__init(git_repository *repo)
401401
(ret = git_pool_init(&cache->pool, 1)) < 0)
402402
goto cancel;
403403

404-
cache = git_atomic_compare_and_swap(&repo->attrcache, NULL, cache);
405-
if (cache)
404+
if (git_atomic_compare_and_swap(&repo->attrcache, NULL, cache) != NULL)
406405
goto cancel; /* raced with another thread, free this but no error */
407406

408407
git_config_free(cfg);

src/clone.c

Lines changed: 32 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -162,45 +162,16 @@ static int update_head_to_default(git_repository *repo)
162162
return error;
163163
}
164164

165-
static int update_remote_head_byname(
166-
git_repository *repo,
167-
const char *remote_name,
168-
const char *tracking_branch_name,
169-
const char *reflog_message)
170-
{
171-
git_buf tracking_head_name = GIT_BUF_INIT;
172-
git_reference *remote_head = NULL;
173-
int error;
174-
175-
if ((error = git_buf_printf(&tracking_head_name,
176-
"%s%s/%s",
177-
GIT_REFS_REMOTES_DIR,
178-
remote_name,
179-
GIT_HEAD_FILE)) < 0)
180-
goto cleanup;
181-
182-
error = git_reference_symbolic_create(
183-
&remote_head,
184-
repo,
185-
git_buf_cstr(&tracking_head_name),
186-
tracking_branch_name,
187-
true,
188-
reflog_message);
189-
190-
cleanup:
191-
git_reference_free(remote_head);
192-
git_buf_dispose(&tracking_head_name);
193-
return error;
194-
}
195-
196165
static int update_remote_head(
197166
git_repository *repo,
198167
git_remote *remote,
199168
git_buf *target,
200169
const char *reflog_message)
201170
{
202171
git_refspec *refspec;
203-
git_buf tracking_branch_name = GIT_BUF_INIT;
172+
git_reference *remote_head = NULL;
173+
git_buf remote_head_name = GIT_BUF_INIT;
174+
git_buf remote_branch_name = GIT_BUF_INIT;
204175
int error;
205176

206177
/* Determine the remote tracking ref name from the local branch */
@@ -213,19 +184,30 @@ static int update_remote_head(
213184
}
214185

215186
if ((error = git_refspec_transform(
216-
&tracking_branch_name,
187+
&remote_branch_name,
217188
refspec,
218189
git_buf_cstr(target))) < 0)
219190
goto cleanup;
220191

221-
error = update_remote_head_byname(
222-
repo,
192+
if ((error = git_buf_printf(&remote_head_name,
193+
"%s%s/%s",
194+
GIT_REFS_REMOTES_DIR,
223195
git_remote_name(remote),
224-
git_buf_cstr(&tracking_branch_name),
196+
GIT_HEAD_FILE)) < 0)
197+
goto cleanup;
198+
199+
error = git_reference_symbolic_create(
200+
&remote_head,
201+
repo,
202+
git_buf_cstr(&remote_head_name),
203+
git_buf_cstr(&remote_branch_name),
204+
true,
225205
reflog_message);
226206

227207
cleanup:
228-
git_buf_dispose(&tracking_branch_name);
208+
git_reference_free(remote_head);
209+
git_buf_dispose(&remote_branch_name);
210+
git_buf_dispose(&remote_head_name);
229211
return error;
230212
}
231213

@@ -277,19 +259,20 @@ static int update_head_to_remote(
277259

278260
static int update_head_to_branch(
279261
git_repository *repo,
280-
const char *remote_name,
262+
git_remote *remote,
281263
const char *branch,
282264
const char *reflog_message)
283265
{
284266
int retcode;
285267
git_buf remote_branch_name = GIT_BUF_INIT;
286268
git_reference* remote_ref = NULL;
269+
git_buf default_branch = GIT_BUF_INIT;
287270

288-
GIT_ASSERT_ARG(remote_name);
271+
GIT_ASSERT_ARG(remote);
289272
GIT_ASSERT_ARG(branch);
290273

291274
if ((retcode = git_buf_printf(&remote_branch_name, GIT_REFS_REMOTES_DIR "%s/%s",
292-
remote_name, branch)) < 0 )
275+
git_remote_name(remote), branch)) < 0 )
293276
goto cleanup;
294277

295278
if ((retcode = git_reference_lookup(&remote_ref, repo, git_buf_cstr(&remote_branch_name))) < 0)
@@ -299,11 +282,18 @@ static int update_head_to_branch(
299282
reflog_message)) < 0)
300283
goto cleanup;
301284

302-
retcode = update_remote_head_byname(repo, remote_name, remote_branch_name.ptr, reflog_message);
285+
if ((retcode = git_remote_default_branch(&default_branch, remote)) < 0)
286+
goto cleanup;
287+
288+
if (!git_remote__matching_refspec(remote, git_buf_cstr(&default_branch)))
289+
goto cleanup;
290+
291+
retcode = update_remote_head(repo, remote, &default_branch, reflog_message);
303292

304293
cleanup:
305294
git_reference_free(remote_ref);
306295
git_buf_dispose(&remote_branch_name);
296+
git_buf_dispose(&default_branch);
307297
return retcode;
308298
}
309299

@@ -388,8 +378,7 @@ static int checkout_branch(git_repository *repo, git_remote *remote, const git_c
388378
int error;
389379

390380
if (branch)
391-
error = update_head_to_branch(repo, git_remote_name(remote), branch,
392-
reflog_message);
381+
error = update_head_to_branch(repo, remote, branch, reflog_message);
393382
/* Point HEAD to the same ref as the remote's head */
394383
else
395384
error = update_head_to_remote(repo, remote, reflog_message);

src/diff_driver.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,18 +141,23 @@ static int diff_driver_funcname(const git_config_entry *entry, void *payload)
141141
static git_diff_driver_registry *git_repository_driver_registry(
142142
git_repository *repo)
143143
{
144-
if (!repo->diff_drivers) {
145-
git_diff_driver_registry *reg = git_diff_driver_registry_new();
146-
reg = git_atomic_compare_and_swap(&repo->diff_drivers, NULL, reg);
144+
git_diff_driver_registry *reg = git_atomic_load(repo->diff_drivers), *newreg;
145+
if (reg)
146+
return reg;
147147

148-
if (reg != NULL) /* if we race, free losing allocation */
149-
git_diff_driver_registry_free(reg);
150-
}
151-
152-
if (!repo->diff_drivers)
148+
newreg = git_diff_driver_registry_new();
149+
if (!newreg) {
153150
git_error_set(GIT_ERROR_REPOSITORY, "unable to create diff driver registry");
154-
155-
return repo->diff_drivers;
151+
return newreg;
152+
}
153+
reg = git_atomic_compare_and_swap(&repo->diff_drivers, NULL, newreg);
154+
if (!reg) {
155+
reg = newreg;
156+
} else {
157+
/* if we race, free losing allocation */
158+
git_diff_driver_registry_free(newreg);
159+
}
160+
return reg;
156161
}
157162

158163
static int diff_driver_alloc(

src/repository.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,8 +1093,7 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo)
10931093
if (!error) {
10941094
GIT_REFCOUNT_OWN(config, repo);
10951095

1096-
config = git_atomic_compare_and_swap(&repo->_config, NULL, config);
1097-
if (config != NULL) {
1096+
if (git_atomic_compare_and_swap(&repo->_config, NULL, config) != NULL) {
10981097
GIT_REFCOUNT_OWN(config, NULL);
10991098
git_config_free(config);
11001099
}
@@ -1164,8 +1163,7 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
11641163
return error;
11651164
}
11661165

1167-
odb = git_atomic_compare_and_swap(&repo->_odb, NULL, odb);
1168-
if (odb != NULL) {
1166+
if (git_atomic_compare_and_swap(&repo->_odb, NULL, odb) != NULL) {
11691167
GIT_REFCOUNT_OWN(odb, NULL);
11701168
git_odb_free(odb);
11711169
}
@@ -1209,8 +1207,7 @@ int git_repository_refdb__weakptr(git_refdb **out, git_repository *repo)
12091207
if (!error) {
12101208
GIT_REFCOUNT_OWN(refdb, repo);
12111209

1212-
refdb = git_atomic_compare_and_swap(&repo->_refdb, NULL, refdb);
1213-
if (refdb != NULL) {
1210+
if (git_atomic_compare_and_swap(&repo->_refdb, NULL, refdb) != NULL) {
12141211
GIT_REFCOUNT_OWN(refdb, NULL);
12151212
git_refdb_free(refdb);
12161213
}
@@ -1257,8 +1254,7 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo)
12571254
if (!error) {
12581255
GIT_REFCOUNT_OWN(index, repo);
12591256

1260-
index = git_atomic_compare_and_swap(&repo->_index, NULL, index);
1261-
if (index != NULL) {
1257+
if (git_atomic_compare_and_swap(&repo->_index, NULL, index) != NULL) {
12621258
GIT_REFCOUNT_OWN(index, NULL);
12631259
git_index_free(index);
12641260
}

0 commit comments

Comments
 (0)