Merge pull request #491 from schu/refs-cleanup

reference_rename() cleanup
This commit is contained in:
Vicent Martí 2011-11-25 21:30:08 -08:00
commit e42ea1f488
5 changed files with 61 additions and 28 deletions

View File

@ -50,6 +50,23 @@ GIT_EXTERN(int) git_reflog_read(git_reflog **reflog, git_reference *ref);
*/ */
GIT_EXTERN(int) git_reflog_write(git_reference *ref, const git_oid *oid_old, const git_signature *committer, const char *msg); GIT_EXTERN(int) git_reflog_write(git_reference *ref, const git_oid *oid_old, const git_signature *committer, const char *msg);
/**
* Rename the reflog for the given reference
*
* @param ref the reference
* @param new_name the new name of the reference
* @return GIT_SUCCESS or an error code
*/
GIT_EXTERN(int) git_reflog_rename(git_reference *ref, const char *new_name);
/**
* Delete the reflog for the given reference
*
* @param ref the reference
* @return GIT_SUCCESS or an error code
*/
GIT_EXTERN(int) git_reflog_delete(git_reference *ref);
/** /**
* Get the number of log entries in a reflog * Get the number of log entries in a reflog
* *

View File

@ -183,6 +183,11 @@ GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id);
* If the `force` flag is not enabled, and there's already * If the `force` flag is not enabled, and there's already
* a reference with the given name, the renaming will fail. * a reference with the given name, the renaming will fail.
* *
* IMPORTANT:
* The user needs to write a proper reflog entry if the
* reflog is enabled for the repository. We only rename
* the reflog if it exists.
*
* @param ref The reference to rename * @param ref The reference to rename
* @param new_name The new name for the reference * @param new_name The new name for the reference
* @param force Overwrite an existing reference * @param force Overwrite an existing reference

View File

@ -89,11 +89,6 @@ extern int git_futils_rmdir_r(const char *path, int force);
*/ */
extern int git_futils_mktmp(char *path_out, const char *filename); extern int git_futils_mktmp(char *path_out, const char *filename);
/**
* Atomically rename a file on the filesystem
*/
extern int git_futils_mv_atomic(const char *from, const char *to);
/** /**
* Move a file on the filesystem, create the * Move a file on the filesystem, create the
* destination path if it doesn't exist * destination path if it doesn't exist

View File

@ -255,6 +255,32 @@ int git_reflog_write(git_reference *ref, const git_oid *oid_old,
return reflog_write(log_path, old, new, committer, msg); return reflog_write(log_path, old, new, committer, msg);
} }
int git_reflog_rename(git_reference *ref, const char *new_name)
{
char old_path[GIT_PATH_MAX];
char new_path[GIT_PATH_MAX];
git_path_join_n(old_path, 3, ref->owner->path_repository,
GIT_REFLOG_DIR, ref->name);
git_path_join_n(new_path, 3, ref->owner->path_repository,
GIT_REFLOG_DIR, new_name);
return p_rename(old_path, new_path);
}
int git_reflog_delete(git_reference *ref)
{
char path[GIT_PATH_MAX];
git_path_join_n(path, 3, ref->owner->path_repository,
GIT_REFLOG_DIR, ref->name);
if (git_futils_exists(path))
return GIT_SUCCESS;
return p_unlink(path);
}
unsigned int git_reflog_entrycount(git_reflog *reflog) unsigned int git_reflog_entrycount(git_reflog *reflog)
{ {
assert(reflog); assert(reflog);

View File

@ -10,6 +10,7 @@
#include "repository.h" #include "repository.h"
#include "fileops.h" #include "fileops.h"
#include "pack.h" #include "pack.h"
#include "reflog.h"
#include <git2/tag.h> #include <git2/tag.h>
#include <git2/object.h> #include <git2/object.h>
@ -1318,28 +1319,6 @@ int git_reference_rename(git_reference *ref, const char *new_name, int force)
} else goto rollback; } else goto rollback;
} }
/*
* Crude hack: delete any logs till we support proper reflogs.
* Otherwise git.git will possibly fail and leave a mess. git.git
* writes reflogs by default in any repo with a working directory:
*
* "We only enable reflogs in repositories that have a working directory
* associated with them, as shared/bare repositories do not have
* an easy means to prune away old log entries, or may fail logging
* entirely if the user's gecos information is not valid during a push.
* This heuristic was suggested on the mailing list by Junio."
*
* Shawn O. Pearce - 0bee59186976b1d9e6b2dd77332480c9480131d5
*
* TODO
*
*/
git_path_join_n(aux_path, 3, ref->owner->path_repository, "logs", ref->name);
if (git_futils_isfile(aux_path) == GIT_SUCCESS) {
if ((error = p_unlink(aux_path)) < GIT_SUCCESS)
goto rollback;
}
/* /*
* Finally we can create the new reference. * Finally we can create the new reference.
*/ */
@ -1352,7 +1331,7 @@ int git_reference_rename(git_reference *ref, const char *new_name, int force)
} }
if (error < GIT_SUCCESS) if (error < GIT_SUCCESS)
goto cleanup; goto rollback;
/* /*
* Check if we have to update HEAD. * Check if we have to update HEAD.
@ -1371,6 +1350,14 @@ int git_reference_rename(git_reference *ref, const char *new_name, int force)
goto cleanup; goto cleanup;
} }
/*
* Rename the reflog file.
*/
git_path_join_n(aux_path, 3, ref->owner->path_repository,
GIT_REFLOG_DIR, ref->name);
if (git_futils_exists(aux_path) == GIT_SUCCESS)
error = git_reflog_rename(ref, new_name);
/* /*
* Change the name of the reference given by the user. * Change the name of the reference given by the user.
*/ */
@ -1398,6 +1385,9 @@ rollback:
error = git_reference_create_oid( error = git_reference_create_oid(
NULL, ref->owner, ref->name, &ref->target.oid, 0); NULL, ref->owner, ref->name, &ref->target.oid, 0);
/* The reference is no longer packed */
ref->flags &= ~GIT_REF_PACKED;
return error == GIT_SUCCESS ? return error == GIT_SUCCESS ?
git__rethrow(GIT_ERROR, "Failed to rename reference. Did rollback") : git__rethrow(GIT_ERROR, "Failed to rename reference. Did rollback") :
git__rethrow(error, "Failed to rename reference. Failed to rollback"); git__rethrow(error, "Failed to rename reference. Failed to rollback");