Skip to content

Commit

Permalink
Merge branch 'mh/init-delete-refs-api'
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Junio C Hamano committed Aug 3, 2015
2 parents 5f02274 + 1c03c4d commit be9cb56
Show file tree
Hide file tree
Showing 16 changed files with 371 additions and 205 deletions.
1 change: 1 addition & 0 deletions archive.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "cache.h"
#include "refs.h"
#include "commit.h"
#include "tree-walk.h"
#include "attr.h"
Expand Down
1 change: 1 addition & 0 deletions builtin/blame.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

#include "cache.h"
#include "refs.h"
#include "builtin.h"
#include "blob.h"
#include "commit.h"
Expand Down
5 changes: 3 additions & 2 deletions builtin/branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ static int branch_merged(int kind, const char *name,
}

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)
{
struct commit *rev = lookup_commit_reference(sha1);
Expand Down Expand Up @@ -253,7 +253,8 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
continue;
}

if (delete_ref(name, sha1, REF_NODEREF)) {
if (delete_ref(name, is_null_sha1(sha1) ? NULL : sha1,
REF_NODEREF)) {
error(remote_branch
? _("Error deleting remote-tracking branch '%s'")
: _("Error deleting branch '%s'"),
Expand Down
18 changes: 14 additions & 4 deletions builtin/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,16 +484,26 @@ static void write_remote_refs(const struct ref *local_refs)
{
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) {
if (!r->peer_ref)
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())
die_errno("unable to overwrite old ref-pack file");
if (initial_ref_transaction_commit(t, &err))
die("%s", err.buf);

strbuf_release(&err);
ref_transaction_free(t);
}

static void write_followtags(const struct ref *refs, const char *msg)
Expand Down
1 change: 1 addition & 0 deletions builtin/fast-export.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
#include "builtin.h"
#include "cache.h"
#include "refs.h"
#include "commit.h"
#include "object.h"
#include "tag.h"
Expand Down
25 changes: 17 additions & 8 deletions builtin/fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
url_len = i - 3;

for (ref = stale_refs; ref; ref = ref->next) {
if (!dry_run)
result |= delete_ref(ref->name, NULL, 0);
if (verbosity >= 0 && !shown_url) {
fprintf(stderr, _("From %.*s\n"), url_len, url);
shown_url = 1;
}
if (verbosity >= 0) {
if (!dry_run) {
struct string_list refnames = STRING_LIST_INIT_NODUP;

for (ref = stale_refs; ref; ref = ref->next)
string_list_append(&refnames, ref->name);

result = delete_refs(&refnames);
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",
TRANSPORT_SUMMARY(_("[deleted]")),
REFCOL_WIDTH, _("(none)"), prettify_refname(ref->name));
warn_dangling_symref(stderr, dangling_msg, ref->name);
}
}

free(url);
free_refs(stale_refs);
return result;
Expand Down
1 change: 1 addition & 0 deletions builtin/fmt-merge-msg.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "builtin.h"
#include "cache.h"
#include "refs.h"
#include "commit.h"
#include "diff.h"
#include "revision.h"
Expand Down
1 change: 1 addition & 0 deletions builtin/init-db.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Copyright (C) Linus Torvalds, 2005
*/
#include "cache.h"
#include "refs.h"
#include "builtin.h"
#include "exec_cmd.h"
#include "parse-options.h"
Expand Down
1 change: 1 addition & 0 deletions builtin/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2006 Junio Hamano
*/
#include "cache.h"
#include "refs.h"
#include "color.h"
#include "commit.h"
#include "diff.h"
Expand Down
33 changes: 3 additions & 30 deletions builtin/remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -746,26 +746,6 @@ static int mv(int argc, const char **argv)
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)
{
struct option options[] = {
Expand Down Expand Up @@ -822,7 +802,7 @@ static int rm(int argc, const char **argv)
strbuf_release(&buf);

if (!result)
result = remove_branches(&branches);
result = delete_refs(&branches);
string_list_clear(&branches, 0);

if (skipped.nr) {
Expand Down Expand Up @@ -1334,19 +1314,12 @@ static int prune_remote(const char *remote, int dry_run)
string_list_append(&refs_to_prune, item->util);
string_list_sort(&refs_to_prune);

if (!dry_run) {
struct strbuf err = STRBUF_INIT;
if (repack_without_refs(&refs_to_prune, &err))
result |= error("%s", err.buf);
strbuf_release(&err);
}
if (!dry_run)
result |= delete_refs(&refs_to_prune);

for_each_string_list_item(item, &states.stale) {
const char *refname = item->util;

if (!dry_run)
result |= delete_ref(refname, NULL, 0);

if (dry_run)
printf_ln(_(" * [would prune] %s"),
abbrev_ref(refname, "refs/remotes/"));
Expand Down
21 changes: 17 additions & 4 deletions builtin/update-ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,14 +408,27 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
die("%s: not a valid SHA1", value);
}

hashclr(oldsha1); /* all-zero hash in case oldval is the empty string */
if (oldval && *oldval && get_sha1(oldval, oldsha1))
die("%s: not a valid old SHA1", oldval);
if (oldval) {
if (!*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)
flags = REF_NODEREF;
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
return update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,
flags, UPDATE_REFS_DIE_ON_ERR);
Expand Down
68 changes: 0 additions & 68 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 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 */
extern int trust_executable_bit;
extern int trust_ctime;
Expand Down Expand Up @@ -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 *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 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 base_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2);
Expand Down
6 changes: 3 additions & 3 deletions fast-import.c
Original file line number Diff line number Diff line change
Expand Up @@ -1692,13 +1692,13 @@ static int update_branch(struct branch *b)
unsigned char old_sha1[20];
struct strbuf err = STRBUF_INIT;

if (read_ref(b->name, old_sha1))
hashclr(old_sha1);
if (is_null_sha1(b->sha1)) {
if (b->delete)
delete_ref(b->name, old_sha1, 0);
delete_ref(b->name, NULL, 0);
return 0;
}
if (read_ref(b->name, old_sha1))
hashclr(old_sha1);
if (!force_update && !is_null_sha1(old_sha1)) {
struct commit *old_cmit, *new_cmit;

Expand Down
Loading

0 comments on commit be9cb56

Please sign in to comment.