static int reference__rename(git_reference **out, git_reference *ref, const char *new_name, int force, const git_signature *signature, const char *message) { git_refname_t normalized; bool should_head_be_updated = false; int error = 0; assert(ref && new_name && signature); if ((error = reference_normalize_for_repo( normalized, git_reference_owner(ref), new_name)) < 0) return error; /* Check if we have to update HEAD. */ if ((error = git_branch_is_head(ref)) < 0) return error; should_head_be_updated = (error > 0); if ((error = git_refdb_rename(out, ref->db, ref->name, normalized, force, signature, message)) < 0) return error; /* Update HEAD it was pointing to the reference being renamed */ if (should_head_be_updated && (error = git_repository_set_head(ref->db->repo, normalized)) < 0) { giterr_set(GITERR_REFERENCE, "Failed to update HEAD after renaming reference"); return error; } return 0; }
int git_reference_lookup_resolved( git_reference **ref_out, git_repository *repo, const char *name, int max_nesting) { char scan_name[GIT_REFNAME_MAX]; git_ref_t scan_type; int error = 0, nesting; git_reference *ref = NULL; git_refdb *refdb; assert(ref_out && repo && name); *ref_out = NULL; if (max_nesting > MAX_NESTING_LEVEL) max_nesting = MAX_NESTING_LEVEL; else if (max_nesting < 0) max_nesting = DEFAULT_NESTING_LEVEL; scan_type = GIT_REF_SYMBOLIC; if ((error = reference_normalize_for_repo( scan_name, sizeof(scan_name), repo, name)) < 0) return error; if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0) return error; for (nesting = max_nesting; nesting >= 0 && scan_type == GIT_REF_SYMBOLIC; nesting--) { if (nesting != max_nesting) { strncpy(scan_name, ref->target.symbolic, sizeof(scan_name)); git_reference_free(ref); } if ((error = git_refdb_lookup(&ref, refdb, scan_name)) < 0) return error; scan_type = ref->type; } if (scan_type != GIT_REF_OID && max_nesting != 0) { giterr_set(GITERR_REFERENCE, "Cannot resolve reference (>%u levels deep)", max_nesting); git_reference_free(ref); return -1; } *ref_out = ref; return 0; }
static int reference__rename(git_reference **out, git_reference *ref, const char *new_name, int force, const git_signature *signature, const char *message) { git_repository *repo; git_refname_t normalized; bool should_head_be_updated = false; int error = 0; assert(ref && new_name && signature); repo = git_reference_owner(ref); if ((error = reference_normalize_for_repo( normalized, repo, new_name, true)) < 0) return error; /* Check if we have to update HEAD. */ if ((error = git_branch_is_head(ref)) < 0) return error; should_head_be_updated = (error > 0); if ((error = git_refdb_rename(out, ref->db, ref->name, normalized, force, signature, message)) < 0) return error; /* Update HEAD if it was pointing to the reference being renamed */ if (should_head_be_updated) { error = git_repository_set_head(ref->db->repo, normalized); } else { rename_cb_data payload; payload.old_name = ref->name; memcpy(&payload.new_name, &normalized, sizeof(normalized)); error = git_repository_foreach_head(repo, update_wt_heads, &payload); } return error; }
static int reference__create( git_reference **ref_out, git_repository *repo, const char *name, const git_oid *oid, const char *symbolic, int force, const git_signature *signature, const char *log_message, const git_oid *old_id, const char *old_target) { git_refname_t normalized; git_refdb *refdb; git_reference *ref = NULL; int error = 0; assert(repo && name); assert(symbolic || signature); if (ref_out) *ref_out = NULL; error = reference_normalize_for_repo(normalized, repo, name); if (error < 0) return error; error = git_repository_refdb__weakptr(&refdb, repo); if (error < 0) return error; if (oid != NULL) { git_odb *odb; assert(symbolic == NULL); /* Sanity check the reference being created - target must exist. */ if ((error = git_repository_odb__weakptr(&odb, repo)) < 0) return error; if (!git_odb_exists(odb, oid)) { giterr_set(GITERR_REFERENCE, "Target OID for the reference doesn't exist on the repository"); return -1; } ref = git_reference__alloc(normalized, oid, NULL); } else { git_refname_t normalized_target; if ((error = reference_normalize_for_repo(normalized_target, repo, symbolic)) < 0) return error; ref = git_reference__alloc_symbolic(normalized, normalized_target); } GITERR_CHECK_ALLOC(ref); if ((error = git_refdb_write(refdb, ref, force, signature, log_message, old_id, old_target)) < 0) { git_reference_free(ref); return error; } if (ref_out == NULL) git_reference_free(ref); else *ref_out = ref; return 0; }
static int reference__create( git_reference **ref_out, git_repository *repo, const char *name, const git_oid *oid, const char *symbolic, int force, const git_signature *signature, const char *log_message, const git_oid *old_id, const char *old_target) { git_refname_t normalized; git_refdb *refdb; git_reference *ref = NULL; int error = 0; assert(repo && name); assert(symbolic || signature); if (ref_out) *ref_out = NULL; error = reference_normalize_for_repo(normalized, repo, name, true); if (error < 0) return error; error = git_repository_refdb__weakptr(&refdb, repo); if (error < 0) return error; if (oid != NULL) { assert(symbolic == NULL); if (!git_object__is_valid(repo, oid, GIT_OBJ_ANY)) { giterr_set(GITERR_REFERENCE, "target OID for the reference doesn't exist on the repository"); return -1; } ref = git_reference__alloc(normalized, oid, NULL); } else { git_refname_t normalized_target; error = reference_normalize_for_repo(normalized_target, repo, symbolic, git_reference__enable_symbolic_ref_target_validation); if (error < 0) return error; ref = git_reference__alloc_symbolic(normalized, normalized_target); } GITERR_CHECK_ALLOC(ref); if ((error = git_refdb_write(refdb, ref, force, signature, log_message, old_id, old_target)) < 0) { git_reference_free(ref); return error; } if (ref_out == NULL) git_reference_free(ref); else *ref_out = ref; return 0; }