Merge branch 'mh/init-delete-refs-api'
Clean up refs API and make "git clone" less intimate with the implementation detail. * mh/init-delete-refs-api: delete_ref(): use the usual convention for old_sha1 cmd_update_ref(): make logic more straightforward update_ref(): don't read old reference value before delete check_branch_commit(): make first parameter const refs.h: add some parameter names to function declarations refs: move the remaining ref module declarations to refs.h initial_ref_transaction_commit(): check for ref D/F conflicts initial_ref_transaction_commit(): check for duplicate refs refs: remove some functions from the module's public interface initial_ref_transaction_commit(): function for initial ref creation repack_without_refs(): make function private prune_refs(): use delete_refs() prune_remote(): use delete_refs() delete_refs(): bail early if the packed-refs file cannot be rewritten delete_refs(): make error message more generic delete_refs(): new function for the refs API delete_ref(): handle special case more explicitly remove_branches(): remove temporary delete_ref(): move declaration to refs.h
This commit is contained in:
@ -1,4 +1,5 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
#include "refs.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "tree-walk.h"
|
#include "tree-walk.h"
|
||||||
#include "attr.h"
|
#include "attr.h"
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
#include "refs.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "blob.h"
|
#include "blob.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
|
@ -160,7 +160,7 @@ static int branch_merged(int kind, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int check_branch_commit(const char *branchname, const char *refname,
|
static int check_branch_commit(const char *branchname, const char *refname,
|
||||||
unsigned char *sha1, struct commit *head_rev,
|
const unsigned char *sha1, struct commit *head_rev,
|
||||||
int kinds, int force)
|
int kinds, int force)
|
||||||
{
|
{
|
||||||
struct commit *rev = lookup_commit_reference(sha1);
|
struct commit *rev = lookup_commit_reference(sha1);
|
||||||
@ -253,7 +253,8 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delete_ref(name, sha1, REF_NODEREF)) {
|
if (delete_ref(name, is_null_sha1(sha1) ? NULL : sha1,
|
||||||
|
REF_NODEREF)) {
|
||||||
error(remote_branch
|
error(remote_branch
|
||||||
? _("Error deleting remote-tracking branch '%s'")
|
? _("Error deleting remote-tracking branch '%s'")
|
||||||
: _("Error deleting branch '%s'"),
|
: _("Error deleting branch '%s'"),
|
||||||
|
@ -484,16 +484,26 @@ static void write_remote_refs(const struct ref *local_refs)
|
|||||||
{
|
{
|
||||||
const struct ref *r;
|
const struct ref *r;
|
||||||
|
|
||||||
lock_packed_refs(LOCK_DIE_ON_ERROR);
|
struct ref_transaction *t;
|
||||||
|
struct strbuf err = STRBUF_INIT;
|
||||||
|
|
||||||
|
t = ref_transaction_begin(&err);
|
||||||
|
if (!t)
|
||||||
|
die("%s", err.buf);
|
||||||
|
|
||||||
for (r = local_refs; r; r = r->next) {
|
for (r = local_refs; r; r = r->next) {
|
||||||
if (!r->peer_ref)
|
if (!r->peer_ref)
|
||||||
continue;
|
continue;
|
||||||
add_packed_ref(r->peer_ref->name, r->old_sha1);
|
if (ref_transaction_create(t, r->peer_ref->name, r->old_sha1,
|
||||||
|
0, NULL, &err))
|
||||||
|
die("%s", err.buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commit_packed_refs())
|
if (initial_ref_transaction_commit(t, &err))
|
||||||
die_errno("unable to overwrite old ref-pack file");
|
die("%s", err.buf);
|
||||||
|
|
||||||
|
strbuf_release(&err);
|
||||||
|
ref_transaction_free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_followtags(const struct ref *refs, const char *msg)
|
static void write_followtags(const struct ref *refs, const char *msg)
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
#include "refs.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
|
@ -790,20 +790,29 @@ static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map,
|
|||||||
if (4 < i && !strncmp(".git", url + i - 3, 4))
|
if (4 < i && !strncmp(".git", url + i - 3, 4))
|
||||||
url_len = i - 3;
|
url_len = i - 3;
|
||||||
|
|
||||||
for (ref = stale_refs; ref; ref = ref->next) {
|
if (!dry_run) {
|
||||||
if (!dry_run)
|
struct string_list refnames = STRING_LIST_INIT_NODUP;
|
||||||
result |= delete_ref(ref->name, NULL, 0);
|
|
||||||
if (verbosity >= 0 && !shown_url) {
|
for (ref = stale_refs; ref; ref = ref->next)
|
||||||
fprintf(stderr, _("From %.*s\n"), url_len, url);
|
string_list_append(&refnames, ref->name);
|
||||||
shown_url = 1;
|
|
||||||
}
|
result = delete_refs(&refnames);
|
||||||
if (verbosity >= 0) {
|
string_list_clear(&refnames, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbosity >= 0) {
|
||||||
|
for (ref = stale_refs; ref; ref = ref->next) {
|
||||||
|
if (!shown_url) {
|
||||||
|
fprintf(stderr, _("From %.*s\n"), url_len, url);
|
||||||
|
shown_url = 1;
|
||||||
|
}
|
||||||
fprintf(stderr, " x %-*s %-*s -> %s\n",
|
fprintf(stderr, " x %-*s %-*s -> %s\n",
|
||||||
TRANSPORT_SUMMARY(_("[deleted]")),
|
TRANSPORT_SUMMARY(_("[deleted]")),
|
||||||
REFCOL_WIDTH, _("(none)"), prettify_refname(ref->name));
|
REFCOL_WIDTH, _("(none)"), prettify_refname(ref->name));
|
||||||
warn_dangling_symref(stderr, dangling_msg, ref->name);
|
warn_dangling_symref(stderr, dangling_msg, ref->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(url);
|
free(url);
|
||||||
free_refs(stale_refs);
|
free_refs(stale_refs);
|
||||||
return result;
|
return result;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
#include "refs.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "diff.h"
|
#include "diff.h"
|
||||||
#include "revision.h"
|
#include "revision.h"
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
* Copyright (C) Linus Torvalds, 2005
|
* Copyright (C) Linus Torvalds, 2005
|
||||||
*/
|
*/
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
#include "refs.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "exec_cmd.h"
|
#include "exec_cmd.h"
|
||||||
#include "parse-options.h"
|
#include "parse-options.h"
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
* 2006 Junio Hamano
|
* 2006 Junio Hamano
|
||||||
*/
|
*/
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
#include "refs.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "diff.h"
|
#include "diff.h"
|
||||||
|
@ -746,26 +746,6 @@ static int mv(int argc, const char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int remove_branches(struct string_list *branches)
|
|
||||||
{
|
|
||||||
struct strbuf err = STRBUF_INIT;
|
|
||||||
int i, result = 0;
|
|
||||||
|
|
||||||
if (repack_without_refs(branches, &err))
|
|
||||||
result |= error("%s", err.buf);
|
|
||||||
strbuf_release(&err);
|
|
||||||
|
|
||||||
for (i = 0; i < branches->nr; i++) {
|
|
||||||
struct string_list_item *item = branches->items + i;
|
|
||||||
const char *refname = item->string;
|
|
||||||
|
|
||||||
if (delete_ref(refname, NULL, 0))
|
|
||||||
result |= error(_("Could not remove branch %s"), refname);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rm(int argc, const char **argv)
|
static int rm(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
struct option options[] = {
|
struct option options[] = {
|
||||||
@ -822,7 +802,7 @@ static int rm(int argc, const char **argv)
|
|||||||
strbuf_release(&buf);
|
strbuf_release(&buf);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
result = remove_branches(&branches);
|
result = delete_refs(&branches);
|
||||||
string_list_clear(&branches, 0);
|
string_list_clear(&branches, 0);
|
||||||
|
|
||||||
if (skipped.nr) {
|
if (skipped.nr) {
|
||||||
@ -1334,19 +1314,12 @@ static int prune_remote(const char *remote, int dry_run)
|
|||||||
string_list_append(&refs_to_prune, item->util);
|
string_list_append(&refs_to_prune, item->util);
|
||||||
string_list_sort(&refs_to_prune);
|
string_list_sort(&refs_to_prune);
|
||||||
|
|
||||||
if (!dry_run) {
|
if (!dry_run)
|
||||||
struct strbuf err = STRBUF_INIT;
|
result |= delete_refs(&refs_to_prune);
|
||||||
if (repack_without_refs(&refs_to_prune, &err))
|
|
||||||
result |= error("%s", err.buf);
|
|
||||||
strbuf_release(&err);
|
|
||||||
}
|
|
||||||
|
|
||||||
for_each_string_list_item(item, &states.stale) {
|
for_each_string_list_item(item, &states.stale) {
|
||||||
const char *refname = item->util;
|
const char *refname = item->util;
|
||||||
|
|
||||||
if (!dry_run)
|
|
||||||
result |= delete_ref(refname, NULL, 0);
|
|
||||||
|
|
||||||
if (dry_run)
|
if (dry_run)
|
||||||
printf_ln(_(" * [would prune] %s"),
|
printf_ln(_(" * [would prune] %s"),
|
||||||
abbrev_ref(refname, "refs/remotes/"));
|
abbrev_ref(refname, "refs/remotes/"));
|
||||||
|
@ -408,14 +408,27 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
|
|||||||
die("%s: not a valid SHA1", value);
|
die("%s: not a valid SHA1", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
hashclr(oldsha1); /* all-zero hash in case oldval is the empty string */
|
if (oldval) {
|
||||||
if (oldval && *oldval && get_sha1(oldval, oldsha1))
|
if (!*oldval)
|
||||||
die("%s: not a valid old SHA1", oldval);
|
/*
|
||||||
|
* The empty string implies that the reference
|
||||||
|
* must not already exist:
|
||||||
|
*/
|
||||||
|
hashclr(oldsha1);
|
||||||
|
else if (get_sha1(oldval, oldsha1))
|
||||||
|
die("%s: not a valid old SHA1", oldval);
|
||||||
|
}
|
||||||
|
|
||||||
if (no_deref)
|
if (no_deref)
|
||||||
flags = REF_NODEREF;
|
flags = REF_NODEREF;
|
||||||
if (delete)
|
if (delete)
|
||||||
return delete_ref(refname, oldval ? oldsha1 : NULL, flags);
|
/*
|
||||||
|
* For purposes of backwards compatibility, we treat
|
||||||
|
* NULL_SHA1 as "don't care" here:
|
||||||
|
*/
|
||||||
|
return delete_ref(refname,
|
||||||
|
(oldval && !is_null_sha1(oldsha1)) ? oldsha1 : NULL,
|
||||||
|
flags);
|
||||||
else
|
else
|
||||||
return update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,
|
return update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,
|
||||||
flags, UPDATE_REFS_DIE_ON_ERR);
|
flags, UPDATE_REFS_DIE_ON_ERR);
|
||||||
|
68
cache.h
68
cache.h
@ -596,8 +596,6 @@ extern void update_index_if_able(struct index_state *, struct lock_file *);
|
|||||||
extern int hold_locked_index(struct lock_file *, int);
|
extern int hold_locked_index(struct lock_file *, int);
|
||||||
extern void set_alternate_index_output(const char *);
|
extern void set_alternate_index_output(const char *);
|
||||||
|
|
||||||
extern int delete_ref(const char *, const unsigned char *sha1, unsigned int flags);
|
|
||||||
|
|
||||||
/* Environment bits from configuration mechanism */
|
/* Environment bits from configuration mechanism */
|
||||||
extern int trust_executable_bit;
|
extern int trust_executable_bit;
|
||||||
extern int trust_ctime;
|
extern int trust_ctime;
|
||||||
@ -1032,76 +1030,10 @@ extern int get_oid_hex(const char *hex, struct object_id *sha1);
|
|||||||
|
|
||||||
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
|
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
|
||||||
extern char *oid_to_hex(const struct object_id *oid); /* same static buffer as sha1_to_hex */
|
extern char *oid_to_hex(const struct object_id *oid); /* same static buffer as sha1_to_hex */
|
||||||
extern int read_ref_full(const char *refname, int resolve_flags,
|
|
||||||
unsigned char *sha1, int *flags);
|
|
||||||
extern int read_ref(const char *refname, unsigned char *sha1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Resolve a reference, recursively following symbolic refererences.
|
|
||||||
*
|
|
||||||
* Store the referred-to object's name in sha1 and return the name of
|
|
||||||
* the non-symbolic reference that ultimately pointed at it. The
|
|
||||||
* return value, if not NULL, is a pointer into either a static buffer
|
|
||||||
* or the input ref.
|
|
||||||
*
|
|
||||||
* If the reference cannot be resolved to an object, the behavior
|
|
||||||
* depends on the RESOLVE_REF_READING flag:
|
|
||||||
*
|
|
||||||
* - If RESOLVE_REF_READING is set, return NULL.
|
|
||||||
*
|
|
||||||
* - If RESOLVE_REF_READING is not set, clear sha1 and return the name of
|
|
||||||
* the last reference name in the chain, which will either be a non-symbolic
|
|
||||||
* reference or an undefined reference. If this is a prelude to
|
|
||||||
* "writing" to the ref, the return value is the name of the ref
|
|
||||||
* that will actually be created or changed.
|
|
||||||
*
|
|
||||||
* If the RESOLVE_REF_NO_RECURSE flag is passed, only resolves one
|
|
||||||
* level of symbolic reference. The value stored in sha1 for a symbolic
|
|
||||||
* reference will always be null_sha1 in this case, and the return
|
|
||||||
* value is the reference that the symref refers to directly.
|
|
||||||
*
|
|
||||||
* If flags is non-NULL, set the value that it points to the
|
|
||||||
* combination of REF_ISPACKED (if the reference was found among the
|
|
||||||
* packed references), REF_ISSYMREF (if the initial reference was a
|
|
||||||
* symbolic reference), REF_BAD_NAME (if the reference name is ill
|
|
||||||
* formed --- see RESOLVE_REF_ALLOW_BAD_NAME below), and REF_ISBROKEN
|
|
||||||
* (if the ref is malformed or has a bad name). See refs.h for more detail
|
|
||||||
* on each flag.
|
|
||||||
*
|
|
||||||
* If ref is not a properly-formatted, normalized reference, return
|
|
||||||
* NULL. If more than MAXDEPTH recursive symbolic lookups are needed,
|
|
||||||
* give up and return NULL.
|
|
||||||
*
|
|
||||||
* RESOLVE_REF_ALLOW_BAD_NAME allows resolving refs even when their
|
|
||||||
* name is invalid according to git-check-ref-format(1). If the name
|
|
||||||
* is bad then the value stored in sha1 will be null_sha1 and the two
|
|
||||||
* flags REF_ISBROKEN and REF_BAD_NAME will be set.
|
|
||||||
*
|
|
||||||
* Even with RESOLVE_REF_ALLOW_BAD_NAME, names that escape the refs/
|
|
||||||
* directory and do not consist of all caps and underscores cannot be
|
|
||||||
* resolved. The function returns NULL for such ref names.
|
|
||||||
* Caps and underscores refers to the special refs, such as HEAD,
|
|
||||||
* FETCH_HEAD and friends, that all live outside of the refs/ directory.
|
|
||||||
*/
|
|
||||||
#define RESOLVE_REF_READING 0x01
|
|
||||||
#define RESOLVE_REF_NO_RECURSE 0x02
|
|
||||||
#define RESOLVE_REF_ALLOW_BAD_NAME 0x04
|
|
||||||
extern const char *resolve_ref_unsafe(const char *ref, int resolve_flags, unsigned char *sha1, int *flags);
|
|
||||||
extern char *resolve_refdup(const char *ref, int resolve_flags, unsigned char *sha1, int *flags);
|
|
||||||
|
|
||||||
extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref);
|
|
||||||
extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref);
|
|
||||||
extern int interpret_branch_name(const char *str, int len, struct strbuf *);
|
extern int interpret_branch_name(const char *str, int len, struct strbuf *);
|
||||||
extern int get_sha1_mb(const char *str, unsigned char *sha1);
|
extern int get_sha1_mb(const char *str, unsigned char *sha1);
|
||||||
|
|
||||||
/*
|
|
||||||
* Return true iff abbrev_name is a possible abbreviation for
|
|
||||||
* full_name according to the rules defined by ref_rev_parse_rules in
|
|
||||||
* refs.c.
|
|
||||||
*/
|
|
||||||
extern int refname_match(const char *abbrev_name, const char *full_name);
|
|
||||||
|
|
||||||
extern int create_symref(const char *ref, const char *refs_heads_master, const char *logmsg);
|
|
||||||
extern int validate_headref(const char *ref);
|
extern int validate_headref(const char *ref);
|
||||||
|
|
||||||
extern int base_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2);
|
extern int base_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2);
|
||||||
|
@ -1692,13 +1692,13 @@ static int update_branch(struct branch *b)
|
|||||||
unsigned char old_sha1[20];
|
unsigned char old_sha1[20];
|
||||||
struct strbuf err = STRBUF_INIT;
|
struct strbuf err = STRBUF_INIT;
|
||||||
|
|
||||||
if (read_ref(b->name, old_sha1))
|
|
||||||
hashclr(old_sha1);
|
|
||||||
if (is_null_sha1(b->sha1)) {
|
if (is_null_sha1(b->sha1)) {
|
||||||
if (b->delete)
|
if (b->delete)
|
||||||
delete_ref(b->name, old_sha1, 0);
|
delete_ref(b->name, NULL, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (read_ref(b->name, old_sha1))
|
||||||
|
hashclr(old_sha1);
|
||||||
if (!force_update && !is_null_sha1(old_sha1)) {
|
if (!force_update && !is_null_sha1(old_sha1)) {
|
||||||
struct commit *old_cmit, *new_cmit;
|
struct commit *old_cmit, *new_cmit;
|
||||||
|
|
||||||
|
182
refs.c
182
refs.c
@ -1314,7 +1314,13 @@ static struct ref_dir *get_packed_refs(struct ref_cache *refs)
|
|||||||
return get_packed_ref_dir(get_packed_ref_cache(refs));
|
return get_packed_ref_dir(get_packed_ref_cache(refs));
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_packed_ref(const char *refname, const unsigned char *sha1)
|
/*
|
||||||
|
* Add a reference to the in-memory packed reference cache. This may
|
||||||
|
* only be called while the packed-refs file is locked (see
|
||||||
|
* lock_packed_refs()). To actually write the packed-refs file, call
|
||||||
|
* commit_packed_refs().
|
||||||
|
*/
|
||||||
|
static void add_packed_ref(const char *refname, const unsigned char *sha1)
|
||||||
{
|
{
|
||||||
struct packed_ref_cache *packed_ref_cache =
|
struct packed_ref_cache *packed_ref_cache =
|
||||||
get_packed_ref_cache(&ref_cache);
|
get_packed_ref_cache(&ref_cache);
|
||||||
@ -1741,9 +1747,11 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *resolve_refdup(const char *ref, int resolve_flags, unsigned char *sha1, int *flags)
|
char *resolve_refdup(const char *refname, int resolve_flags,
|
||||||
|
unsigned char *sha1, int *flags)
|
||||||
{
|
{
|
||||||
return xstrdup_or_null(resolve_ref_unsafe(ref, resolve_flags, sha1, flags));
|
return xstrdup_or_null(resolve_ref_unsafe(refname, resolve_flags,
|
||||||
|
sha1, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The argument to filter_refs */
|
/* The argument to filter_refs */
|
||||||
@ -2531,8 +2539,12 @@ static int write_packed_entry_fn(struct ref_entry *entry, void *cb_data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This should return a meaningful errno on failure */
|
/*
|
||||||
int lock_packed_refs(int flags)
|
* Lock the packed-refs file for writing. Flags is passed to
|
||||||
|
* hold_lock_file_for_update(). Return 0 on success. On errors, set
|
||||||
|
* errno appropriately and return a nonzero value.
|
||||||
|
*/
|
||||||
|
static int lock_packed_refs(int flags)
|
||||||
{
|
{
|
||||||
static int timeout_configured = 0;
|
static int timeout_configured = 0;
|
||||||
static int timeout_value = 1000;
|
static int timeout_value = 1000;
|
||||||
@ -2562,10 +2574,12 @@ int lock_packed_refs(int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Commit the packed refs changes.
|
* Write the current version of the packed refs cache from memory to
|
||||||
* On error we must make sure that errno contains a meaningful value.
|
* disk. The packed-refs file must already be locked for writing (see
|
||||||
|
* lock_packed_refs()). Return zero on success. On errors, set errno
|
||||||
|
* and return a nonzero value
|
||||||
*/
|
*/
|
||||||
int commit_packed_refs(void)
|
static int commit_packed_refs(void)
|
||||||
{
|
{
|
||||||
struct packed_ref_cache *packed_ref_cache =
|
struct packed_ref_cache *packed_ref_cache =
|
||||||
get_packed_ref_cache(&ref_cache);
|
get_packed_ref_cache(&ref_cache);
|
||||||
@ -2594,7 +2608,12 @@ int commit_packed_refs(void)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rollback_packed_refs(void)
|
/*
|
||||||
|
* Rollback the lockfile for the packed-refs file, and discard the
|
||||||
|
* in-memory packed reference cache. (The packed-refs file will be
|
||||||
|
* read anew if it is needed again after this function is called.)
|
||||||
|
*/
|
||||||
|
static void rollback_packed_refs(void)
|
||||||
{
|
{
|
||||||
struct packed_ref_cache *packed_ref_cache =
|
struct packed_ref_cache *packed_ref_cache =
|
||||||
get_packed_ref_cache(&ref_cache);
|
get_packed_ref_cache(&ref_cache);
|
||||||
@ -2752,7 +2771,14 @@ int pack_refs(unsigned int flags)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int repack_without_refs(struct string_list *refnames, struct strbuf *err)
|
/*
|
||||||
|
* Rewrite the packed-refs file, omitting any refs listed in
|
||||||
|
* 'refnames'. On error, leave packed-refs unchanged, write an error
|
||||||
|
* message to 'err', and return a nonzero value.
|
||||||
|
*
|
||||||
|
* The refs in 'refnames' needn't be sorted. `err` must not be NULL.
|
||||||
|
*/
|
||||||
|
static int repack_without_refs(struct string_list *refnames, struct strbuf *err)
|
||||||
{
|
{
|
||||||
struct ref_dir *packed;
|
struct ref_dir *packed;
|
||||||
struct string_list_item *refname;
|
struct string_list_item *refname;
|
||||||
@ -2817,15 +2843,15 @@ static int delete_ref_loose(struct ref_lock *lock, int flag, struct strbuf *err)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int delete_ref(const char *refname, const unsigned char *sha1, unsigned int flags)
|
int delete_ref(const char *refname, const unsigned char *old_sha1,
|
||||||
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
struct ref_transaction *transaction;
|
struct ref_transaction *transaction;
|
||||||
struct strbuf err = STRBUF_INIT;
|
struct strbuf err = STRBUF_INIT;
|
||||||
|
|
||||||
transaction = ref_transaction_begin(&err);
|
transaction = ref_transaction_begin(&err);
|
||||||
if (!transaction ||
|
if (!transaction ||
|
||||||
ref_transaction_delete(transaction, refname,
|
ref_transaction_delete(transaction, refname, old_sha1,
|
||||||
(sha1 && !is_null_sha1(sha1)) ? sha1 : NULL,
|
|
||||||
flags, NULL, &err) ||
|
flags, NULL, &err) ||
|
||||||
ref_transaction_commit(transaction, &err)) {
|
ref_transaction_commit(transaction, &err)) {
|
||||||
error("%s", err.buf);
|
error("%s", err.buf);
|
||||||
@ -2838,6 +2864,44 @@ int delete_ref(const char *refname, const unsigned char *sha1, unsigned int flag
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int delete_refs(struct string_list *refnames)
|
||||||
|
{
|
||||||
|
struct strbuf err = STRBUF_INIT;
|
||||||
|
int i, result = 0;
|
||||||
|
|
||||||
|
if (!refnames->nr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
result = repack_without_refs(refnames, &err);
|
||||||
|
if (result) {
|
||||||
|
/*
|
||||||
|
* If we failed to rewrite the packed-refs file, then
|
||||||
|
* it is unsafe to try to remove loose refs, because
|
||||||
|
* doing so might expose an obsolete packed value for
|
||||||
|
* a reference that might even point at an object that
|
||||||
|
* has been garbage collected.
|
||||||
|
*/
|
||||||
|
if (refnames->nr == 1)
|
||||||
|
error(_("could not delete reference %s: %s"),
|
||||||
|
refnames->items[0].string, err.buf);
|
||||||
|
else
|
||||||
|
error(_("could not delete references: %s"), err.buf);
|
||||||
|
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < refnames->nr; i++) {
|
||||||
|
const char *refname = refnames->items[i].string;
|
||||||
|
|
||||||
|
if (delete_ref(refname, NULL, 0))
|
||||||
|
result |= error(_("could not remove reference %s"), refname);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
strbuf_release(&err);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* People using contrib's git-new-workdir have .git/logs/refs ->
|
* People using contrib's git-new-workdir have .git/logs/refs ->
|
||||||
* /some/other/path/.git/logs/refs, and that may live on another device.
|
* /some/other/path/.git/logs/refs, and that may live on another device.
|
||||||
@ -4039,6 +4103,98 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ref_present(const char *refname,
|
||||||
|
const struct object_id *oid, int flags, void *cb_data)
|
||||||
|
{
|
||||||
|
struct string_list *affected_refnames = cb_data;
|
||||||
|
|
||||||
|
return string_list_has_string(affected_refnames, refname);
|
||||||
|
}
|
||||||
|
|
||||||
|
int initial_ref_transaction_commit(struct ref_transaction *transaction,
|
||||||
|
struct strbuf *err)
|
||||||
|
{
|
||||||
|
struct ref_dir *loose_refs = get_loose_refs(&ref_cache);
|
||||||
|
struct ref_dir *packed_refs = get_packed_refs(&ref_cache);
|
||||||
|
int ret = 0, i;
|
||||||
|
int n = transaction->nr;
|
||||||
|
struct ref_update **updates = transaction->updates;
|
||||||
|
struct string_list affected_refnames = STRING_LIST_INIT_NODUP;
|
||||||
|
|
||||||
|
assert(err);
|
||||||
|
|
||||||
|
if (transaction->state != REF_TRANSACTION_OPEN)
|
||||||
|
die("BUG: commit called for transaction that is not open");
|
||||||
|
|
||||||
|
/* Fail if a refname appears more than once in the transaction: */
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
string_list_append(&affected_refnames, updates[i]->refname);
|
||||||
|
string_list_sort(&affected_refnames);
|
||||||
|
if (ref_update_reject_duplicates(&affected_refnames, err)) {
|
||||||
|
ret = TRANSACTION_GENERIC_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It's really undefined to call this function in an active
|
||||||
|
* repository or when there are existing references: we are
|
||||||
|
* only locking and changing packed-refs, so (1) any
|
||||||
|
* simultaneous processes might try to change a reference at
|
||||||
|
* the same time we do, and (2) any existing loose versions of
|
||||||
|
* the references that we are setting would have precedence
|
||||||
|
* over our values. But some remote helpers create the remote
|
||||||
|
* "HEAD" and "master" branches before calling this function,
|
||||||
|
* so here we really only check that none of the references
|
||||||
|
* that we are creating already exists.
|
||||||
|
*/
|
||||||
|
if (for_each_rawref(ref_present, &affected_refnames))
|
||||||
|
die("BUG: initial ref transaction called with existing refs");
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
struct ref_update *update = updates[i];
|
||||||
|
|
||||||
|
if ((update->flags & REF_HAVE_OLD) &&
|
||||||
|
!is_null_sha1(update->old_sha1))
|
||||||
|
die("BUG: initial ref transaction with old_sha1 set");
|
||||||
|
if (verify_refname_available(update->refname,
|
||||||
|
&affected_refnames, NULL,
|
||||||
|
loose_refs, err) ||
|
||||||
|
verify_refname_available(update->refname,
|
||||||
|
&affected_refnames, NULL,
|
||||||
|
packed_refs, err)) {
|
||||||
|
ret = TRANSACTION_NAME_CONFLICT;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lock_packed_refs(0)) {
|
||||||
|
strbuf_addf(err, "unable to lock packed-refs file: %s",
|
||||||
|
strerror(errno));
|
||||||
|
ret = TRANSACTION_GENERIC_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
struct ref_update *update = updates[i];
|
||||||
|
|
||||||
|
if ((update->flags & REF_HAVE_NEW) &&
|
||||||
|
!is_null_sha1(update->new_sha1))
|
||||||
|
add_packed_ref(update->refname, update->new_sha1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commit_packed_refs()) {
|
||||||
|
strbuf_addf(err, "unable to commit packed-refs file: %s",
|
||||||
|
strerror(errno));
|
||||||
|
ret = TRANSACTION_GENERIC_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
transaction->state = REF_TRANSACTION_CLOSED;
|
||||||
|
string_list_clear(&affected_refnames, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
char *shorten_unambiguous_ref(const char *refname, int strict)
|
char *shorten_unambiguous_ref(const char *refname, int strict)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
211
refs.h
211
refs.h
@ -1,6 +1,98 @@
|
|||||||
#ifndef REFS_H
|
#ifndef REFS_H
|
||||||
#define REFS_H
|
#define REFS_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Resolve a reference, recursively following symbolic refererences.
|
||||||
|
*
|
||||||
|
* Store the referred-to object's name in sha1 and return the name of
|
||||||
|
* the non-symbolic reference that ultimately pointed at it. The
|
||||||
|
* return value, if not NULL, is a pointer into either a static buffer
|
||||||
|
* or the input ref.
|
||||||
|
*
|
||||||
|
* If the reference cannot be resolved to an object, the behavior
|
||||||
|
* depends on the RESOLVE_REF_READING flag:
|
||||||
|
*
|
||||||
|
* - If RESOLVE_REF_READING is set, return NULL.
|
||||||
|
*
|
||||||
|
* - If RESOLVE_REF_READING is not set, clear sha1 and return the name of
|
||||||
|
* the last reference name in the chain, which will either be a non-symbolic
|
||||||
|
* reference or an undefined reference. If this is a prelude to
|
||||||
|
* "writing" to the ref, the return value is the name of the ref
|
||||||
|
* that will actually be created or changed.
|
||||||
|
*
|
||||||
|
* If the RESOLVE_REF_NO_RECURSE flag is passed, only resolves one
|
||||||
|
* level of symbolic reference. The value stored in sha1 for a symbolic
|
||||||
|
* reference will always be null_sha1 in this case, and the return
|
||||||
|
* value is the reference that the symref refers to directly.
|
||||||
|
*
|
||||||
|
* If flags is non-NULL, set the value that it points to the
|
||||||
|
* combination of REF_ISPACKED (if the reference was found among the
|
||||||
|
* packed references), REF_ISSYMREF (if the initial reference was a
|
||||||
|
* symbolic reference), REF_BAD_NAME (if the reference name is ill
|
||||||
|
* formed --- see RESOLVE_REF_ALLOW_BAD_NAME below), and REF_ISBROKEN
|
||||||
|
* (if the ref is malformed or has a bad name). See refs.h for more detail
|
||||||
|
* on each flag.
|
||||||
|
*
|
||||||
|
* If ref is not a properly-formatted, normalized reference, return
|
||||||
|
* NULL. If more than MAXDEPTH recursive symbolic lookups are needed,
|
||||||
|
* give up and return NULL.
|
||||||
|
*
|
||||||
|
* RESOLVE_REF_ALLOW_BAD_NAME allows resolving refs even when their
|
||||||
|
* name is invalid according to git-check-ref-format(1). If the name
|
||||||
|
* is bad then the value stored in sha1 will be null_sha1 and the two
|
||||||
|
* flags REF_ISBROKEN and REF_BAD_NAME will be set.
|
||||||
|
*
|
||||||
|
* Even with RESOLVE_REF_ALLOW_BAD_NAME, names that escape the refs/
|
||||||
|
* directory and do not consist of all caps and underscores cannot be
|
||||||
|
* resolved. The function returns NULL for such ref names.
|
||||||
|
* Caps and underscores refers to the special refs, such as HEAD,
|
||||||
|
* FETCH_HEAD and friends, that all live outside of the refs/ directory.
|
||||||
|
*/
|
||||||
|
#define RESOLVE_REF_READING 0x01
|
||||||
|
#define RESOLVE_REF_NO_RECURSE 0x02
|
||||||
|
#define RESOLVE_REF_ALLOW_BAD_NAME 0x04
|
||||||
|
|
||||||
|
extern const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
|
||||||
|
unsigned char *sha1, int *flags);
|
||||||
|
|
||||||
|
extern char *resolve_refdup(const char *refname, int resolve_flags,
|
||||||
|
unsigned char *sha1, int *flags);
|
||||||
|
|
||||||
|
extern int read_ref_full(const char *refname, int resolve_flags,
|
||||||
|
unsigned char *sha1, int *flags);
|
||||||
|
extern int read_ref(const char *refname, unsigned char *sha1);
|
||||||
|
|
||||||
|
extern int ref_exists(const char *refname);
|
||||||
|
|
||||||
|
extern int is_branch(const char *refname);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If refname is a non-symbolic reference that refers to a tag object,
|
||||||
|
* and the tag can be (recursively) dereferenced to a non-tag object,
|
||||||
|
* store the SHA1 of the referred-to object to sha1 and return 0. If
|
||||||
|
* any of these conditions are not met, return a non-zero value.
|
||||||
|
* Symbolic references are considered unpeelable, even if they
|
||||||
|
* ultimately resolve to a peelable tag.
|
||||||
|
*/
|
||||||
|
extern int peel_ref(const char *refname, unsigned char *sha1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve refname in the nested "gitlink" repository that is located
|
||||||
|
* at path. If the resolution is successful, return 0 and set sha1 to
|
||||||
|
* the name of the object; otherwise, return a non-zero value.
|
||||||
|
*/
|
||||||
|
extern int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return true iff abbrev_name is a possible abbreviation for
|
||||||
|
* full_name according to the rules defined by ref_rev_parse_rules in
|
||||||
|
* refs.c.
|
||||||
|
*/
|
||||||
|
extern int refname_match(const char *abbrev_name, const char *full_name);
|
||||||
|
|
||||||
|
extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref);
|
||||||
|
extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A ref_transaction represents a collection of ref updates
|
* A ref_transaction represents a collection of ref updates
|
||||||
* that should succeed or fail together.
|
* that should succeed or fail together.
|
||||||
@ -78,15 +170,15 @@ typedef int each_ref_fn(const char *refname,
|
|||||||
* modifies the reference also returns a nonzero value to immediately
|
* modifies the reference also returns a nonzero value to immediately
|
||||||
* stop the iteration.
|
* stop the iteration.
|
||||||
*/
|
*/
|
||||||
extern int head_ref(each_ref_fn, void *);
|
extern int head_ref(each_ref_fn fn, void *cb_data);
|
||||||
extern int for_each_ref(each_ref_fn, void *);
|
extern int for_each_ref(each_ref_fn fn, void *cb_data);
|
||||||
extern int for_each_ref_in(const char *, each_ref_fn, void *);
|
extern int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data);
|
||||||
extern int for_each_tag_ref(each_ref_fn, void *);
|
extern int for_each_tag_ref(each_ref_fn fn, void *cb_data);
|
||||||
extern int for_each_branch_ref(each_ref_fn, void *);
|
extern int for_each_branch_ref(each_ref_fn fn, void *cb_data);
|
||||||
extern int for_each_remote_ref(each_ref_fn, void *);
|
extern int for_each_remote_ref(each_ref_fn fn, void *cb_data);
|
||||||
extern int for_each_replace_ref(each_ref_fn, void *);
|
extern int for_each_replace_ref(each_ref_fn fn, void *cb_data);
|
||||||
extern int for_each_glob_ref(each_ref_fn, const char *pattern, void *);
|
extern int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data);
|
||||||
extern int for_each_glob_ref_in(each_ref_fn, const char *pattern, const char* prefix, void *);
|
extern int for_each_glob_ref_in(each_ref_fn fn, const char *pattern, const char *prefix, void *cb_data);
|
||||||
|
|
||||||
extern int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data);
|
extern int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data);
|
||||||
extern int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data);
|
extern int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data);
|
||||||
@ -99,47 +191,17 @@ extern int for_each_remote_ref_submodule(const char *submodule, each_ref_fn fn,
|
|||||||
extern int head_ref_namespaced(each_ref_fn fn, void *cb_data);
|
extern int head_ref_namespaced(each_ref_fn fn, void *cb_data);
|
||||||
extern int for_each_namespaced_ref(each_ref_fn fn, void *cb_data);
|
extern int for_each_namespaced_ref(each_ref_fn fn, void *cb_data);
|
||||||
|
|
||||||
|
/* can be used to learn about broken ref and symref */
|
||||||
|
extern int for_each_rawref(each_ref_fn fn, void *cb_data);
|
||||||
|
|
||||||
static inline const char *has_glob_specials(const char *pattern)
|
static inline const char *has_glob_specials(const char *pattern)
|
||||||
{
|
{
|
||||||
return strpbrk(pattern, "?*[");
|
return strpbrk(pattern, "?*[");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* can be used to learn about broken ref and symref */
|
|
||||||
extern int for_each_rawref(each_ref_fn, void *);
|
|
||||||
|
|
||||||
extern void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname);
|
extern void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname);
|
||||||
extern void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list *refnames);
|
extern void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list *refnames);
|
||||||
|
|
||||||
/*
|
|
||||||
* Lock the packed-refs file for writing. Flags is passed to
|
|
||||||
* hold_lock_file_for_update(). Return 0 on success.
|
|
||||||
* Errno is set to something meaningful on error.
|
|
||||||
*/
|
|
||||||
extern int lock_packed_refs(int flags);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add a reference to the in-memory packed reference cache. This may
|
|
||||||
* only be called while the packed-refs file is locked (see
|
|
||||||
* lock_packed_refs()). To actually write the packed-refs file, call
|
|
||||||
* commit_packed_refs().
|
|
||||||
*/
|
|
||||||
extern void add_packed_ref(const char *refname, const unsigned char *sha1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Write the current version of the packed refs cache from memory to
|
|
||||||
* disk. The packed-refs file must already be locked for writing (see
|
|
||||||
* lock_packed_refs()). Return zero on success.
|
|
||||||
* Sets errno to something meaningful on error.
|
|
||||||
*/
|
|
||||||
extern int commit_packed_refs(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Rollback the lockfile for the packed-refs file, and discard the
|
|
||||||
* in-memory packed reference cache. (The packed-refs file will be
|
|
||||||
* read anew if it is needed again after this function is called.)
|
|
||||||
*/
|
|
||||||
extern void rollback_packed_refs(void);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flags for controlling behaviour of pack_refs()
|
* Flags for controlling behaviour of pack_refs()
|
||||||
* PACK_REFS_PRUNE: Prune loose refs after packing
|
* PACK_REFS_PRUNE: Prune loose refs after packing
|
||||||
@ -154,31 +216,6 @@ extern void rollback_packed_refs(void);
|
|||||||
*/
|
*/
|
||||||
int pack_refs(unsigned int flags);
|
int pack_refs(unsigned int flags);
|
||||||
|
|
||||||
/*
|
|
||||||
* Rewrite the packed-refs file, omitting any refs listed in
|
|
||||||
* 'refnames'. On error, packed-refs will be unchanged, the return
|
|
||||||
* value is nonzero, and a message about the error is written to the
|
|
||||||
* 'err' strbuf.
|
|
||||||
*
|
|
||||||
* The refs in 'refnames' needn't be sorted. `err` must not be NULL.
|
|
||||||
*/
|
|
||||||
extern int repack_without_refs(struct string_list *refnames,
|
|
||||||
struct strbuf *err);
|
|
||||||
|
|
||||||
extern int ref_exists(const char *);
|
|
||||||
|
|
||||||
extern int is_branch(const char *refname);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If refname is a non-symbolic reference that refers to a tag object,
|
|
||||||
* and the tag can be (recursively) dereferenced to a non-tag object,
|
|
||||||
* store the SHA1 of the referred-to object to sha1 and return 0. If
|
|
||||||
* any of these conditions are not met, return a non-zero value.
|
|
||||||
* Symbolic references are considered unpeelable, even if they
|
|
||||||
* ultimately resolve to a peelable tag.
|
|
||||||
*/
|
|
||||||
extern int peel_ref(const char *refname, unsigned char *sha1);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flags controlling ref_transaction_update(), ref_transaction_create(), etc.
|
* Flags controlling ref_transaction_update(), ref_transaction_create(), etc.
|
||||||
* REF_NODEREF: act on the ref directly, instead of dereferencing
|
* REF_NODEREF: act on the ref directly, instead of dereferencing
|
||||||
@ -202,6 +239,23 @@ extern int read_ref_at(const char *refname, unsigned int flags,
|
|||||||
/** Check if a particular reflog exists */
|
/** Check if a particular reflog exists */
|
||||||
extern int reflog_exists(const char *refname);
|
extern int reflog_exists(const char *refname);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete the specified reference. If old_sha1 is non-NULL, then
|
||||||
|
* verify that the current value of the reference is old_sha1 before
|
||||||
|
* deleting it. If old_sha1 is NULL, delete the reference if it
|
||||||
|
* exists, regardless of its old value. It is an error for old_sha1 to
|
||||||
|
* be NULL_SHA1. flags is passed through to ref_transaction_delete().
|
||||||
|
*/
|
||||||
|
extern int delete_ref(const char *refname, const unsigned char *old_sha1,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete the specified references. If there are any problems, emit
|
||||||
|
* errors but attempt to keep going (i.e., the deletes are not done in
|
||||||
|
* an all-or-nothing transaction).
|
||||||
|
*/
|
||||||
|
extern int delete_refs(struct string_list *refnames);
|
||||||
|
|
||||||
/** Delete a reflog */
|
/** Delete a reflog */
|
||||||
extern int delete_reflog(const char *refname);
|
extern int delete_reflog(const char *refname);
|
||||||
|
|
||||||
@ -230,17 +284,13 @@ extern int for_each_reflog(each_ref_fn, void *);
|
|||||||
extern int check_refname_format(const char *refname, int flags);
|
extern int check_refname_format(const char *refname, int flags);
|
||||||
|
|
||||||
extern const char *prettify_refname(const char *refname);
|
extern const char *prettify_refname(const char *refname);
|
||||||
|
|
||||||
extern char *shorten_unambiguous_ref(const char *refname, int strict);
|
extern char *shorten_unambiguous_ref(const char *refname, int strict);
|
||||||
|
|
||||||
/** rename ref, return 0 on success **/
|
/** rename ref, return 0 on success **/
|
||||||
extern int rename_ref(const char *oldref, const char *newref, const char *logmsg);
|
extern int rename_ref(const char *oldref, const char *newref, const char *logmsg);
|
||||||
|
|
||||||
/**
|
extern int create_symref(const char *ref, const char *refs_heads_master, const char *logmsg);
|
||||||
* Resolve refname in the nested "gitlink" repository that is located
|
|
||||||
* at path. If the resolution is successful, return 0 and set sha1 to
|
|
||||||
* the name of the object; otherwise, return a non-zero value.
|
|
||||||
*/
|
|
||||||
extern int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1);
|
|
||||||
|
|
||||||
enum action_on_err {
|
enum action_on_err {
|
||||||
UPDATE_REFS_MSG_ON_ERR,
|
UPDATE_REFS_MSG_ON_ERR,
|
||||||
@ -359,6 +409,20 @@ int ref_transaction_verify(struct ref_transaction *transaction,
|
|||||||
int ref_transaction_commit(struct ref_transaction *transaction,
|
int ref_transaction_commit(struct ref_transaction *transaction,
|
||||||
struct strbuf *err);
|
struct strbuf *err);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like ref_transaction_commit(), but optimized for creating
|
||||||
|
* references when originally initializing a repository (e.g., by "git
|
||||||
|
* clone"). It writes the new references directly to packed-refs
|
||||||
|
* without locking the individual references.
|
||||||
|
*
|
||||||
|
* It is a bug to call this function when there might be other
|
||||||
|
* processes accessing the repository or if there are existing
|
||||||
|
* references that might conflict with the ones being created. All
|
||||||
|
* old_sha1 values must either be absent or NULL_SHA1.
|
||||||
|
*/
|
||||||
|
int initial_ref_transaction_commit(struct ref_transaction *transaction,
|
||||||
|
struct strbuf *err);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free an existing transaction and all associated data.
|
* Free an existing transaction and all associated data.
|
||||||
*/
|
*/
|
||||||
@ -377,6 +441,7 @@ int update_ref(const char *msg, const char *refname,
|
|||||||
unsigned int flags, enum action_on_err onerr);
|
unsigned int flags, enum action_on_err onerr);
|
||||||
|
|
||||||
extern int parse_hide_refs_config(const char *var, const char *value, const char *);
|
extern int parse_hide_refs_config(const char *var, const char *value, const char *);
|
||||||
|
|
||||||
extern int ref_is_hidden(const char *);
|
extern int ref_is_hidden(const char *);
|
||||||
|
|
||||||
enum expire_reflog_flags {
|
enum expire_reflog_flags {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
#include "refs.h"
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
|
Reference in New Issue
Block a user