Skip to content

Commit ef5a385

Browse files
authored
Merge pull request libgit2#5257 from henkesn/master
Fix file locking on POSIX OS
2 parents 1f9b497 + 3335a03 commit ef5a385

File tree

8 files changed

+36
-19
lines changed

8 files changed

+36
-19
lines changed

src/cherrypick.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ static int write_cherrypick_head(
3030
int error = 0;
3131

3232
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_CHERRYPICK_HEAD_FILE)) >= 0 &&
33-
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_CHERRYPICK_FILE_MODE)) >= 0 &&
33+
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_CHERRYPICK_FILE_MODE)) >= 0 &&
3434
(error = git_filebuf_printf(&file, "%s\n", commit_oidstr)) >= 0)
3535
error = git_filebuf_commit(&file);
3636

@@ -51,7 +51,7 @@ static int write_merge_msg(
5151
int error = 0;
5252

5353
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 ||
54-
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_CHERRYPICK_FILE_MODE)) < 0 ||
54+
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_CHERRYPICK_FILE_MODE)) < 0 ||
5555
(error = git_filebuf_printf(&file, "%s", commit_msg)) < 0)
5656
goto cleanup;
5757

src/filebuf.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,14 @@ static int verify_last_error(git_filebuf *file)
4444
static int lock_file(git_filebuf *file, int flags, mode_t mode)
4545
{
4646
if (git_path_exists(file->path_lock) == true) {
47-
if (flags & GIT_FILEBUF_FORCE)
48-
p_unlink(file->path_lock);
49-
else {
50-
git_error_clear(); /* actual OS error code just confuses */
51-
git_error_set(GIT_ERROR_OS,
52-
"failed to lock file '%s' for writing", file->path_lock);
53-
return GIT_ELOCKED;
54-
}
47+
git_error_clear(); /* actual OS error code just confuses */
48+
git_error_set(GIT_ERROR_OS,
49+
"failed to lock file '%s' for writing", file->path_lock);
50+
return GIT_ELOCKED;
5551
}
5652

5753
/* create path to the file buffer is required */
58-
if (flags & GIT_FILEBUF_FORCE) {
54+
if (flags & GIT_FILEBUF_CREATE_LEADING_DIRS) {
5955
/* XXX: Should dirmode here be configurable? Or is 0777 always fine? */
6056
file->fd = git_futils_creat_locked_withpath(file->path_lock, 0777, mode);
6157
} else {

src/filebuf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
#define GIT_FILEBUF_HASH_CONTENTS (1 << 0)
2121
#define GIT_FILEBUF_APPEND (1 << 2)
22-
#define GIT_FILEBUF_FORCE (1 << 3)
22+
#define GIT_FILEBUF_CREATE_LEADING_DIRS (1 << 3)
2323
#define GIT_FILEBUF_TEMPORARY (1 << 4)
2424
#define GIT_FILEBUF_DO_NOT_BUFFER (1 << 5)
2525
#define GIT_FILEBUF_FSYNC (1 << 6)

src/merge.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2431,7 +2431,7 @@ static int write_merge_head(
24312431
assert(repo && heads);
24322432

24332433
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_HEAD_FILE)) < 0 ||
2434-
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_MERGE_FILE_MODE)) < 0)
2434+
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) < 0)
24352435
goto cleanup;
24362436

24372437
for (i = 0; i < heads_len; i++) {
@@ -2459,7 +2459,7 @@ static int write_merge_mode(git_repository *repo)
24592459
assert(repo);
24602460

24612461
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MODE_FILE)) < 0 ||
2462-
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_MERGE_FILE_MODE)) < 0)
2462+
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) < 0)
24632463
goto cleanup;
24642464

24652465
if ((error = git_filebuf_write(&file, "no-ff", 5)) < 0)
@@ -2690,7 +2690,7 @@ static int write_merge_msg(
26902690
entries[i].merge_head = heads[i];
26912691

26922692
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 ||
2693-
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_MERGE_FILE_MODE)) < 0 ||
2693+
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) < 0 ||
26942694
(error = git_filebuf_write(&file, "Merge ", 6)) < 0)
26952695
goto cleanup;
26962696

src/refdb_fs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,7 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *
804804
if (git_buf_joinpath(&ref_path, basedir, name) < 0)
805805
return -1;
806806

807-
filebuf_flags = GIT_FILEBUF_FORCE;
807+
filebuf_flags = GIT_FILEBUF_CREATE_LEADING_DIRS;
808808
if (backend->fsync)
809809
filebuf_flags |= GIT_FILEBUF_FSYNC;
810810

src/repository.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2485,7 +2485,7 @@ int git_repository__set_orig_head(git_repository *repo, const git_oid *orig_head
24852485
git_oid_fmt(orig_head_str, orig_head);
24862486

24872487
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_ORIG_HEAD_FILE)) == 0 &&
2488-
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_MERGE_FILE_MODE)) == 0 &&
2488+
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) == 0 &&
24892489
(error = git_filebuf_printf(&file, "%.*s\n", GIT_OID_HEXSZ, orig_head_str)) == 0)
24902490
error = git_filebuf_commit(&file);
24912491

src/revert.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ static int write_revert_head(
2929
int error = 0;
3030

3131
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_REVERT_HEAD_FILE)) >= 0 &&
32-
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_REVERT_FILE_MODE)) >= 0 &&
32+
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_REVERT_FILE_MODE)) >= 0 &&
3333
(error = git_filebuf_printf(&file, "%s\n", commit_oidstr)) >= 0)
3434
error = git_filebuf_commit(&file);
3535

@@ -51,7 +51,7 @@ static int write_merge_msg(
5151
int error = 0;
5252

5353
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_MERGE_MSG_FILE)) < 0 ||
54-
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_REVERT_FILE_MODE)) < 0 ||
54+
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_REVERT_FILE_MODE)) < 0 ||
5555
(error = git_filebuf_printf(&file, "Revert \"%s\"\n\nThis reverts commit %s.\n",
5656
commit_msgline, commit_oidstr)) < 0)
5757
goto cleanup;

tests/refs/transactions.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,24 @@ void test_refs_transactions__unlocked_set(void)
108108
cl_git_fail_with(GIT_ENOTFOUND, git_transaction_set_target(g_tx, "refs/heads/foo", &id, NULL, NULL));
109109
cl_git_pass(git_transaction_commit(g_tx));
110110
}
111+
112+
void test_refs_transactions__error_on_locking_locked_ref(void)
113+
{
114+
git_oid id;
115+
git_transaction *g_tx_with_lock;
116+
git_repository *g_repo_with_locking_tx;
117+
const char *g_repo_path = git_repository_path(g_repo);
118+
119+
/* prepare a separate transaction in another instance of testrepo and lock master */
120+
cl_git_pass(git_repository_open(&g_repo_with_locking_tx, g_repo_path));
121+
cl_git_pass(git_transaction_new(&g_tx_with_lock, g_repo_with_locking_tx));
122+
cl_git_pass(git_transaction_lock_ref(g_tx_with_lock, "refs/heads/master"));
123+
124+
/* lock reference for set_target */
125+
cl_git_pass(git_oid_fromstr(&id, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"));
126+
cl_git_fail_with(GIT_ELOCKED, git_transaction_lock_ref(g_tx, "refs/heads/master"));
127+
cl_git_fail_with(GIT_ENOTFOUND, git_transaction_set_target(g_tx, "refs/heads/master", &id, NULL, NULL));
128+
129+
git_transaction_free(g_tx_with_lock);
130+
git_repository_free(g_repo_with_locking_tx);
131+
}

0 commit comments

Comments
 (0)