Commit 8d5ec910 by Carlos Martín Nieto

refs: expose a way to ensure a ref has a log

Sometimes (e.g. stash) we want to make sure that a log will be written,
even if it's not in one of the standard locations. Let's make that
easier.
parent 6f13a305
...@@ -556,6 +556,18 @@ GIT_EXTERN(int) git_reference_foreach_glob( ...@@ -556,6 +556,18 @@ GIT_EXTERN(int) git_reference_foreach_glob(
GIT_EXTERN(int) git_reference_has_log(git_reference *ref); GIT_EXTERN(int) git_reference_has_log(git_reference *ref);
/** /**
* Ensure there is a reflog for a particular reference.
*
* Make sure that successive updates to the reference will append to
* its log.
*
* @param repo the repository
* @param refname the reference's name
* @return 0 or an error code.
*/
GIT_EXTERN(int) git_reference_ensure_log(git_repository *repo, const char *refname);
/**
* Check if a reference is a local branch. * Check if a reference is a local branch.
* *
* @param ref A git reference * @param ref A git reference
......
...@@ -117,6 +117,12 @@ struct git_refdb_backend { ...@@ -117,6 +117,12 @@ struct git_refdb_backend {
int (*compress)(git_refdb_backend *backend); int (*compress)(git_refdb_backend *backend);
/** /**
* Make sure a particular reference will have a reflog which
* will be appended to on writes.
*/
int (*ensure_log)(git_refdb_backend *backend, const char *refname);
/**
* Frees any resources held by the refdb. A refdb implementation may * Frees any resources held by the refdb. A refdb implementation may
* provide this function; if it is not provided, nothing will be done. * provide this function; if it is not provided, nothing will be done.
*/ */
......
...@@ -221,3 +221,10 @@ int git_refdb_reflog_read(git_reflog **out, git_refdb *db, const char *name) ...@@ -221,3 +221,10 @@ int git_refdb_reflog_read(git_reflog **out, git_refdb *db, const char *name)
return 0; return 0;
} }
int git_refdb_ensure_log(git_refdb *db, const char *refname)
{
assert(db && refname);
return db->backend->ensure_log(db->backend, refname);
}
...@@ -48,5 +48,8 @@ int git_refdb_delete(git_refdb *refdb, const char *ref_name); ...@@ -48,5 +48,8 @@ int git_refdb_delete(git_refdb *refdb, const char *ref_name);
int git_refdb_reflog_read(git_reflog **out, git_refdb *db, const char *name); int git_refdb_reflog_read(git_reflog **out, git_refdb *db, const char *name);
int git_refdb_reflog_write(git_reflog *reflog); int git_refdb_reflog_write(git_reflog *reflog);
int git_refdb_ensure_log(git_refdb *refdb, const char *refname);
#endif #endif
...@@ -1233,7 +1233,7 @@ static int create_new_reflog_file(const char *filepath) ...@@ -1233,7 +1233,7 @@ static int create_new_reflog_file(const char *filepath)
return error; return error;
if ((fd = p_open(filepath, if ((fd = p_open(filepath,
O_WRONLY | O_CREAT | O_TRUNC, O_WRONLY | O_CREAT,
GIT_REFLOG_FILE_MODE)) < 0) GIT_REFLOG_FILE_MODE)) < 0)
return -1; return -1;
...@@ -1245,6 +1245,24 @@ GIT_INLINE(int) retrieve_reflog_path(git_buf *path, git_repository *repo, const ...@@ -1245,6 +1245,24 @@ GIT_INLINE(int) retrieve_reflog_path(git_buf *path, git_repository *repo, const
return git_buf_join_n(path, '/', 3, repo->path_repository, GIT_REFLOG_DIR, name); return git_buf_join_n(path, '/', 3, repo->path_repository, GIT_REFLOG_DIR, name);
} }
static int refdb_reflog_fs__ensure_log(git_refdb_backend *_backend, const char *name)
{
refdb_fs_backend *backend;
git_repository *repo;
git_buf path = GIT_BUF_INIT;
int error;
assert(_backend && name);
backend = (refdb_fs_backend *) _backend;
repo = backend->repo;
if ((error = retrieve_reflog_path(&path, repo, name)) < 0)
return error;
return create_new_reflog_file(git_buf_cstr(&path));
}
static int has_reflog(git_repository *repo, const char *name) static int has_reflog(git_repository *repo, const char *name)
{ {
int ret = 0; int ret = 0;
...@@ -1590,6 +1608,7 @@ int git_refdb_backend_fs( ...@@ -1590,6 +1608,7 @@ int git_refdb_backend_fs(
backend->parent.del = &refdb_fs_backend__delete; backend->parent.del = &refdb_fs_backend__delete;
backend->parent.rename = &refdb_fs_backend__rename; backend->parent.rename = &refdb_fs_backend__rename;
backend->parent.compress = &refdb_fs_backend__compress; backend->parent.compress = &refdb_fs_backend__compress;
backend->parent.ensure_log = &refdb_reflog_fs__ensure_log;
backend->parent.free = &refdb_fs_backend__free; backend->parent.free = &refdb_fs_backend__free;
backend->parent.reflog_read = &refdb_reflog_fs__read; backend->parent.reflog_read = &refdb_reflog_fs__read;
backend->parent.reflog_write = &refdb_reflog_fs__write; backend->parent.reflog_write = &refdb_reflog_fs__write;
......
...@@ -1068,6 +1068,19 @@ int git_reference_has_log( ...@@ -1068,6 +1068,19 @@ int git_reference_has_log(
return result; return result;
} }
int git_reference_ensure_log(git_repository *repo, const char *refname)
{
int error;
git_refdb *refdb;
assert(repo && refname);
if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
return error;
return git_refdb_ensure_log(refdb, refname);
}
int git_reference__is_branch(const char *ref_name) int git_reference__is_branch(const char *ref_name)
{ {
return git__prefixcmp(ref_name, GIT_REFS_HEADS_DIR) == 0; return git__prefixcmp(ref_name, GIT_REFS_HEADS_DIR) == 0;
......
...@@ -414,6 +414,9 @@ static int update_reflog( ...@@ -414,6 +414,9 @@ static int update_reflog(
git_reference *stash; git_reference *stash;
int error; int error;
if ((error = git_reference_ensure_log(repo, GIT_REFS_STASH_FILE)) < 0)
return error;
error = git_reference_create_with_log(&stash, repo, GIT_REFS_STASH_FILE, w_commit_oid, 1, stasher, message); error = git_reference_create_with_log(&stash, repo, GIT_REFS_STASH_FILE, w_commit_oid, 1, stasher, message);
git_reference_free(stash); git_reference_free(stash);
......
...@@ -212,12 +212,9 @@ void test_refs_reflog_reflog__write_when_explicitly_active(void) ...@@ -212,12 +212,9 @@ void test_refs_reflog_reflog__write_when_explicitly_active(void)
{ {
git_reference *ref; git_reference *ref;
git_oid id; git_oid id;
git_buf path = GIT_BUF_INIT;
git_oid_fromstr(&id, current_master_tip); git_oid_fromstr(&id, current_master_tip);
cl_git_pass(git_buf_join(&path, '/', git_repository_path(g_repo), "logs/refs/tags/foo")); git_reference_ensure_log(g_repo, "refs/tags/foo");
cl_git_pass(git_futils_mkpath2file(git_buf_cstr(&path), 0777));
cl_git_mkfile(git_buf_cstr(&path), "");
cl_git_pass(git_reference_create(&ref, g_repo, "refs/tags/foo", &id, 1)); cl_git_pass(git_reference_create(&ref, g_repo, "refs/tags/foo", &id, 1));
git_reference_free(ref); git_reference_free(ref);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment