Skip to content

Commit 3d9f037

Browse files
jasamplergitster
authored andcommitted
Function for updating refs.
A function intended to be called from builtins updating refs by locking them before write, specially those that came from scripts using "git update-ref". [jc: with minor fixups] Signed-off-by: Carlos Rica <jasampler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 1e61b76 commit 3d9f037

5 files changed

Lines changed: 46 additions & 29 deletions

File tree

builtin-fetch--tool.c

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,19 @@ static void show_new(enum object_type type, unsigned char *sha1_new)
3131
find_unique_abbrev(sha1_new, DEFAULT_ABBREV));
3232
}
3333

34-
static int update_ref(const char *action,
34+
static int update_ref_env(const char *action,
3535
const char *refname,
3636
unsigned char *sha1,
3737
unsigned char *oldval)
3838
{
3939
char msg[1024];
4040
char *rla = getenv("GIT_REFLOG_ACTION");
41-
static struct ref_lock *lock;
4241

4342
if (!rla)
4443
rla = "(reflog update)";
45-
snprintf(msg, sizeof(msg), "%s: %s", rla, action);
46-
lock = lock_any_ref_for_update(refname, oldval, 0);
47-
if (!lock)
48-
return 1;
49-
if (write_ref_sha1(lock, sha1, msg) < 0)
50-
return 1;
51-
return 0;
44+
if (snprintf(msg, sizeof(msg), "%s: %s", rla, action) >= sizeof(msg))
45+
warning("reflog message too long: %.*s...", 50, msg);
46+
return update_ref(msg, refname, sha1, oldval, 0, QUIET_ON_ERR);
5247
}
5348

5449
static int update_local_ref(const char *name,
@@ -88,7 +83,7 @@ static int update_local_ref(const char *name,
8883
fprintf(stderr, "* %s: storing %s\n",
8984
name, note);
9085
show_new(type, sha1_new);
91-
return update_ref(msg, name, sha1_new, NULL);
86+
return update_ref_env(msg, name, sha1_new, NULL);
9287
}
9388

9489
if (!hashcmp(sha1_old, sha1_new)) {
@@ -102,7 +97,7 @@ static int update_local_ref(const char *name,
10297
if (!strncmp(name, "refs/tags/", 10)) {
10398
fprintf(stderr, "* %s: updating with %s\n", name, note);
10499
show_new(type, sha1_new);
105-
return update_ref("updating tag", name, sha1_new, NULL);
100+
return update_ref_env("updating tag", name, sha1_new, NULL);
106101
}
107102

108103
current = lookup_commit_reference(sha1_old);
@@ -117,7 +112,7 @@ static int update_local_ref(const char *name,
117112
fprintf(stderr, "* %s: fast forward to %s\n",
118113
name, note);
119114
fprintf(stderr, " old..new: %s..%s\n", oldh, newh);
120-
return update_ref("fast forward", name, sha1_new, sha1_old);
115+
return update_ref_env("fast forward", name, sha1_new, sha1_old);
121116
}
122117
if (!force) {
123118
fprintf(stderr,
@@ -131,7 +126,7 @@ static int update_local_ref(const char *name,
131126
"* %s: forcing update to non-fast forward %s\n",
132127
name, note);
133128
fprintf(stderr, " old...new: %s...%s\n", oldh, newh);
134-
return update_ref("forced-update", name, sha1_new, sha1_old);
129+
return update_ref_env("forced-update", name, sha1_new, sha1_old);
135130
}
136131

137132
static int append_fetch_head(FILE *fp,

builtin-update-ref.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ static const char git_update_ref_usage[] =
88
int cmd_update_ref(int argc, const char **argv, const char *prefix)
99
{
1010
const char *refname=NULL, *value=NULL, *oldval=NULL, *msg=NULL;
11-
struct ref_lock *lock;
1211
unsigned char sha1[20], oldsha1[20];
1312
int i, delete, ref_flags;
1413

@@ -62,10 +61,6 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
6261
if (oldval && *oldval && get_sha1(oldval, oldsha1))
6362
die("%s: not a valid old SHA1", oldval);
6463

65-
lock = lock_any_ref_for_update(refname, oldval ? oldsha1 : NULL, ref_flags);
66-
if (!lock)
67-
die("%s: cannot lock the ref", refname);
68-
if (write_ref_sha1(lock, sha1, msg) < 0)
69-
die("%s: cannot update the ref", refname);
70-
return 0;
64+
return update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,
65+
ref_flags, DIE_ON_ERR);
7166
}

refs.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,3 +1455,30 @@ int for_each_reflog(each_ref_fn fn, void *cb_data)
14551455
{
14561456
return do_for_each_reflog("", fn, cb_data);
14571457
}
1458+
1459+
int update_ref(const char *action, const char *refname,
1460+
const unsigned char *sha1, const unsigned char *oldval,
1461+
int flags, enum action_on_err onerr)
1462+
{
1463+
static struct ref_lock *lock;
1464+
lock = lock_any_ref_for_update(refname, oldval, flags);
1465+
if (!lock) {
1466+
const char *str = "Cannot lock the ref '%s'.";
1467+
switch (onerr) {
1468+
case MSG_ON_ERR: error(str, refname); break;
1469+
case DIE_ON_ERR: die(str, refname); break;
1470+
case QUIET_ON_ERR: break;
1471+
}
1472+
return 1;
1473+
}
1474+
if (write_ref_sha1(lock, sha1, action) < 0) {
1475+
const char *str = "Cannot update the ref '%s'.";
1476+
switch (onerr) {
1477+
case MSG_ON_ERR: error(str, refname); break;
1478+
case DIE_ON_ERR: die(str, refname); break;
1479+
case QUIET_ON_ERR: break;
1480+
}
1481+
return 1;
1482+
}
1483+
return 0;
1484+
}

refs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,10 @@ extern int rename_ref(const char *oldref, const char *newref, const char *logmsg
6464
/** resolve ref in nested "gitlink" repository */
6565
extern int resolve_gitlink_ref(const char *name, const char *refname, unsigned char *result);
6666

67+
/** lock a ref and then write its file */
68+
enum action_on_err { MSG_ON_ERR, DIE_ON_ERR, QUIET_ON_ERR };
69+
int update_ref(const char *action, const char *refname,
70+
const unsigned char *sha1, const unsigned char *oldval,
71+
int flags, enum action_on_err onerr);
72+
6773
#endif /* REFS_H */

send-pack.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -307,20 +307,14 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, cha
307307
rs.src = ref->name;
308308
rs.dst = NULL;
309309
if (!remote_find_tracking(remote, &rs)) {
310-
struct ref_lock *lock;
311310
fprintf(stderr, " Also local %s\n", rs.dst);
312311
if (will_delete_ref) {
313312
if (delete_ref(rs.dst, NULL)) {
314313
error("Failed to delete");
315314
}
316-
} else {
317-
lock = lock_any_ref_for_update(rs.dst, NULL, 0);
318-
if (!lock)
319-
error("Failed to lock");
320-
else
321-
write_ref_sha1(lock, ref->new_sha1,
322-
"update by push");
323-
}
315+
} else
316+
update_ref("update by push", rs.dst,
317+
ref->new_sha1, NULL, 0, 0);
324318
free(rs.dst);
325319
}
326320
}

0 commit comments

Comments
 (0)