diff options
author | Vicent Marti <vicent@github.com> | 2014-01-31 09:46:40 -0800 |
---|---|---|
committer | Vicent Marti <vicent@github.com> | 2014-01-31 09:46:40 -0800 |
commit | f9500b4524c62a2f443061bacea8171b435230f6 (patch) | |
tree | 104e0fadb7103e10ea2bf7a6376214d504a773da /src | |
parent | 8646b0a0689c89d9cad949754885ec542b4d0ce1 (diff) | |
parent | db092c1955ff5079d8ca475bbe1d6b0da782b38e (diff) | |
download | libgit2-f9500b4524c62a2f443061bacea8171b435230f6.tar.gz |
Merge pull request #2081 from libgit2/bs/reflog
Reflog completionism
Diffstat (limited to 'src')
-rw-r--r-- | src/branch.c | 56 | ||||
-rw-r--r-- | src/clone.c | 55 | ||||
-rw-r--r-- | src/refdb_fs.c | 11 | ||||
-rw-r--r-- | src/refs.c | 27 | ||||
-rw-r--r-- | src/remote.c | 28 | ||||
-rw-r--r-- | src/repository.c | 27 |
6 files changed, 132 insertions, 72 deletions
diff --git a/src/branch.c b/src/branch.c index d0dc21b85..133d6f6d4 100644 --- a/src/branch.c +++ b/src/branch.c @@ -54,24 +54,34 @@ int git_branch_create( git_repository *repository, const char *branch_name, const git_commit *commit, - int force) + int force, + const git_signature *signature, + const char *log_message) { git_reference *branch = NULL; - git_buf canonical_branch_name = GIT_BUF_INIT; - int error = 0; + git_buf canonical_branch_name = GIT_BUF_INIT, + log_message_buf = GIT_BUF_INIT; + int error = -1; assert(branch_name && commit && ref_out); assert(git_object_owner((const git_object *)commit) == repository); - if (!(error = git_buf_joinpath( - &canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name))) - error = git_reference_create( - &branch, repository, git_buf_cstr(&canonical_branch_name), - git_commit_id(commit), force, NULL, NULL); + if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0) + goto cleanup; - *ref_out = branch; + if (git_buf_sets(&log_message_buf, log_message ? log_message : "Branch: created") < 0) + goto cleanup; + error = git_reference_create(&branch, repository, + git_buf_cstr(&canonical_branch_name), git_commit_id(commit), force, signature, + git_buf_cstr(&log_message_buf)); + + if (!error) + *ref_out = branch; + +cleanup: git_buf_free(&canonical_branch_name); + git_buf_free(&log_message_buf); return error; } @@ -109,6 +119,9 @@ int git_branch_delete(git_reference *branch) if (git_reference_delete(branch) < 0) goto on_error; + if (git_reflog_delete(git_reference_owner(branch), git_reference_name(branch)) < 0) + goto on_error; + error = 0; on_error: @@ -185,11 +198,14 @@ int git_branch_move( git_reference **out, git_reference *branch, const char *new_branch_name, - int force) + int force, + const git_signature *signature, + const char *log_message) { git_buf new_reference_name = GIT_BUF_INIT, - old_config_section = GIT_BUF_INIT, - new_config_section = GIT_BUF_INIT; + old_config_section = GIT_BUF_INIT, + new_config_section = GIT_BUF_INIT, + log_message_buf = GIT_BUF_INIT; int error; assert(branch && new_branch_name); @@ -197,14 +213,23 @@ int git_branch_move( if (!git_reference_is_branch(branch)) return not_a_local_branch(git_reference_name(branch)); - error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name); - if (error < 0) + if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0) goto done; + if (log_message) { + if ((error = git_buf_sets(&log_message_buf, log_message)) < 0) + goto done; + } else { + if ((error = git_buf_printf(&log_message_buf, "Branch: renamed %s to %s", + git_reference_name(branch), git_buf_cstr(&new_reference_name))) < 0) + goto done; + } + /* first update ref then config so failure won't trash config */ error = git_reference_rename( - out, branch, git_buf_cstr(&new_reference_name), force); + out, branch, git_buf_cstr(&new_reference_name), force, + signature, git_buf_cstr(&log_message_buf)); if (error < 0) goto done; @@ -221,6 +246,7 @@ done: git_buf_free(&new_reference_name); git_buf_free(&old_config_section); git_buf_free(&new_config_section); + git_buf_free(&log_message_buf); return error; } diff --git a/src/clone.c b/src/clone.c index 2e9d72ab9..3443528f7 100644 --- a/src/clone.c +++ b/src/clone.c @@ -27,7 +27,9 @@ static int create_branch( git_reference **branch, git_repository *repo, const git_oid *target, - const char *name) + const char *name, + const git_signature *signature, + const char *log_message) { git_commit *head_obj = NULL; git_reference *branch_ref = NULL; @@ -38,7 +40,7 @@ static int create_branch( return error; /* Create the new branch */ - error = git_branch_create(&branch_ref, repo, name, head_obj, 0); + error = git_branch_create(&branch_ref, repo, name, head_obj, 0, signature, log_message); git_commit_free(head_obj); @@ -87,11 +89,13 @@ static int create_tracking_branch( git_reference **branch, git_repository *repo, const git_oid *target, - const char *branch_name) + const char *branch_name, + const git_signature *signature, + const char *log_message) { int error; - if ((error = create_branch(branch, repo, target, branch_name)) < 0) + if ((error = create_branch(branch, repo, target, branch_name, signature, log_message)) < 0) return error; return setup_tracking_config( @@ -152,21 +156,29 @@ static int reference_matches_remote_head( static int update_head_to_new_branch( git_repository *repo, const git_oid *target, - const char *name) + const char *name, + const git_signature *signature, + const char *reflog_message) { git_reference *tracking_branch = NULL; - int error = create_tracking_branch(&tracking_branch, repo, target, name); + int error = create_tracking_branch(&tracking_branch, repo, target, name, + signature, reflog_message); if (!error) error = git_repository_set_head( - repo, git_reference_name(tracking_branch)); + repo, git_reference_name(tracking_branch), + signature, reflog_message); git_reference_free(tracking_branch); return error; } -static int update_head_to_remote(git_repository *repo, git_remote *remote) +static int update_head_to_remote( + git_repository *repo, + git_remote *remote, + const git_signature *signature, + const char *reflog_message) { int error = 0; size_t refs_len; @@ -215,7 +227,8 @@ static int update_head_to_remote(git_repository *repo, git_remote *remote) error = update_head_to_new_branch( repo, &head_info.remote_head_oid, - git_buf_cstr(&head_info.branchname)); + git_buf_cstr(&head_info.branchname), + signature, reflog_message); goto cleanup; } @@ -229,10 +242,11 @@ static int update_head_to_remote(git_repository *repo, git_remote *remote) error = update_head_to_new_branch( repo, &head_info.remote_head_oid, - git_buf_cstr(&head_info.branchname)); + git_buf_cstr(&head_info.branchname), + signature, reflog_message); } else { error = git_repository_set_head_detached( - repo, &head_info.remote_head_oid); + repo, &head_info.remote_head_oid, signature, reflog_message); } cleanup: @@ -244,7 +258,9 @@ cleanup: static int update_head_to_branch( git_repository *repo, const char *remote_name, - const char *branch) + const char *branch, + const git_signature *signature, + const char *reflog_message) { int retcode; git_buf remote_branch_name = GIT_BUF_INIT; @@ -259,7 +275,8 @@ static int update_head_to_branch( if ((retcode = git_reference_lookup(&remote_ref, repo, git_buf_cstr(&remote_branch_name))) < 0) goto cleanup; - retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch); + retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch, + signature, reflog_message); cleanup: git_reference_free(remote_ref); @@ -319,10 +336,11 @@ static bool should_checkout( return !git_repository_head_unborn(repo); } -int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_opts *co_opts, const char *branch) +int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_opts *co_opts, const char *branch, const git_signature *signature) { int error = 0, old_fetchhead; git_strarray refspecs; + git_buf reflog_message = GIT_BUF_INIT; assert(repo && remote); @@ -340,15 +358,17 @@ int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_ old_fetchhead = git_remote_update_fetchhead(remote); git_remote_set_update_fetchhead(remote, 0); + git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote)); if ((error = git_remote_fetch(remote)) != 0) goto cleanup; if (branch) - error = update_head_to_branch(repo, git_remote_name(remote), branch); + error = update_head_to_branch(repo, git_remote_name(remote), branch, + signature, git_buf_cstr(&reflog_message)); /* Point HEAD to the same ref as the remote's head */ else - error = update_head_to_remote(repo, remote); + error = update_head_to_remote(repo, remote, signature, git_buf_cstr(&reflog_message)); if (!error && should_checkout(repo, git_repository_is_bare(repo), co_opts)) error = git_checkout_head(repo, co_opts); @@ -364,6 +384,7 @@ cleanup: } git_strarray_free(&refspecs); + git_buf_free(&reflog_message); return error; } @@ -403,7 +424,7 @@ int git_clone( if (!(error = create_and_configure_origin(&origin, repo, url, &options))) { error = git_clone_into( - repo, origin, &options.checkout_opts, options.checkout_branch); + repo, origin, &options.checkout_opts, options.checkout_branch, options.signature); git_remote_free(origin); } diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 53c42458f..41ff01998 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -1434,12 +1434,14 @@ success: static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, const git_signature *who, const char *message) { int error; - git_oid old_id, new_id; + git_oid old_id, new_id = {{0}}; git_buf buf = GIT_BUF_INIT, path = GIT_BUF_INIT; git_repository *repo = backend->repo; - /* Creation of symbolic references doesn't get a reflog entry */ - if (ref->type == GIT_REF_SYMBOLIC) + /* Creation of a symbolic reference doesn't get a reflog entry, except for + * HEAD. git_repository_set_head and friends go through here. */ + if (ref->type == GIT_REF_SYMBOLIC && + 0 != strcmp(ref->name, GIT_HEAD_FILE)) return 0; error = git_reference_name_to_id(&old_id, repo, ref->name); @@ -1450,7 +1452,8 @@ static int reflog_append(refdb_fs_backend *backend, const git_reference *ref, co if (error < 0) return error; - git_oid_cpy(&new_id, git_reference_target(ref)); + if (git_reference_target(ref) != NULL) + git_oid_cpy(&new_id, git_reference_target(ref)); if ((error = serialize_reflog_entry(&buf, &old_id, &new_id, who, message)) < 0) goto cleanup; diff --git a/src/refs.c b/src/refs.c index 0f0a380ea..eb2c34211 100644 --- a/src/refs.c +++ b/src/refs.c @@ -545,7 +545,7 @@ static int reference__rename(git_reference **out, git_reference *ref, const char /* Update HEAD it was pointing to the reference being renamed */ if (should_head_be_updated && - (error = git_repository_set_head(ref->db->repo, new_name)) < 0) { + (error = git_repository_set_head(ref->db->repo, new_name, signature, message)) < 0) { giterr_set(GITERR_REFERENCE, "Failed to update HEAD after renaming reference"); return error; } @@ -558,35 +558,28 @@ int git_reference_rename( git_reference **out, git_reference *ref, const char *new_name, - int force) + int force, + const git_signature *signature, + const char *log_message) { - git_signature *who; + git_signature *who = (git_signature*)signature; int error; /* Should we return an error if there is no default? */ - if (((error = git_signature_default(&who, ref->db->repo)) < 0) && + if (!who && + ((error = git_signature_default(&who, ref->db->repo)) < 0) && ((error = git_signature_now(&who, "unknown", "unknown")) < 0)) { return error; } - error = reference__rename(out, ref, new_name, force, who, NULL); + error = reference__rename(out, ref, new_name, force, who, log_message); - git_signature_free(who); + if (!signature) + git_signature_free(who); return error; } -int git_reference_rename_with_log( - git_reference **out, - git_reference *ref, - const char *new_name, - int force, - const git_signature *who, - const char * message) -{ - return reference__rename(out, ref, new_name, force, who, message); -} - int git_reference_resolve(git_reference **ref_out, const git_reference *ref) { switch (git_reference_type(ref)) { diff --git a/src/remote.c b/src/remote.c index 5d35affd1..f33f5ef3c 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1332,20 +1332,28 @@ static int rename_one_remote_reference( { int error; git_buf new_name = GIT_BUF_INIT; + git_buf log_message = GIT_BUF_INIT; - error = git_buf_printf( - &new_name, - GIT_REFS_REMOTES_DIR "%s%s", - new_remote_name, - reference->name + strlen(GIT_REFS_REMOTES_DIR) + strlen(old_remote_name)); + if ((error = git_buf_printf( + &new_name, + GIT_REFS_REMOTES_DIR "%s%s", + new_remote_name, + reference->name + strlen(GIT_REFS_REMOTES_DIR) + strlen(old_remote_name))) < 0) + goto cleanup; - if (!error) { - error = git_reference_rename( - NULL, reference, git_buf_cstr(&new_name), 0); - git_reference_free(reference); - } + if ((error = git_buf_printf(&log_message, + "renamed remote %s to %s", + old_remote_name, new_remote_name)) < 0) + goto cleanup; + + error = git_reference_rename( + NULL, reference, git_buf_cstr(&new_name), 0, + NULL, git_buf_cstr(&log_message)); + git_reference_free(reference); +cleanup: git_buf_free(&new_name); + git_buf_free(&log_message); return error; } diff --git a/src/repository.c b/src/repository.c index 285d8897f..2c1b60266 100644 --- a/src/repository.c +++ b/src/repository.c @@ -1830,7 +1830,9 @@ static bool looks_like_a_branch(const char *refname) int git_repository_set_head( git_repository* repo, - const char* refname) + const char* refname, + const git_signature *signature, + const char *log_message) { git_reference *ref, *new_head = NULL; @@ -1843,12 +1845,17 @@ int git_repository_set_head( return error; if (!error) { - if (git_reference_is_branch(ref)) - error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, git_reference_name(ref), 1, NULL, NULL); - else - error = git_repository_set_head_detached(repo, git_reference_target(ref)); - } else if (looks_like_a_branch(refname)) - error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname, 1, NULL, NULL); + if (git_reference_is_branch(ref)) { + error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, + git_reference_name(ref), true, signature, log_message); + } else { + error = git_repository_set_head_detached(repo, git_reference_target(ref), + signature, log_message); + } + } else if (looks_like_a_branch(refname)) { + error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname, + true, signature, log_message); + } git_reference_free(ref); git_reference_free(new_head); @@ -1857,7 +1864,9 @@ int git_repository_set_head( int git_repository_set_head_detached( git_repository* repo, - const git_oid* commitish) + const git_oid* commitish, + const git_signature *signature, + const char *log_message) { int error; git_object *object, @@ -1872,7 +1881,7 @@ int git_repository_set_head_detached( if ((error = git_object_peel(&peeled, object, GIT_OBJ_COMMIT)) < 0) goto cleanup; - error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), 1, NULL, NULL); + error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, signature, log_message); cleanup: git_object_free(object); |