Skip to content

Commit d345e9f

Browse files
newrengitster
authored andcommitted
update-ref: allow --no-deref with --stdin
If passed both --no-deref and --stdin, update-ref would error out with a general usage message that did not at all suggest these options were incompatible. The manpage for update-ref did suggest through its synopsis line that --no-deref and --stdin were incompatible, but it sadly also incorrectly suggested that -d and --no-deref were incompatible. So the help around the --no-deref option is buggy in a few ways. The --stdin option did provide a different mechanism for avoiding dereferencing symbolic-refs: adding a line reading option no-deref before every other directive in the input. (Technically, if the user wants to do the extra work of first determining which refs they want to update or delete are symbolic, then they only need to put the extra "option no-deref" lines before the updates of those refs. But in some cases, that's more work than just adding the "option no-deref" before every other directive.) It's easier to allow the user to just pass --no-deref along with --stdin in order to tell update-ref that the user doesn't want any symbolic ref to be dereferenced. It also makes the update-ref documentation simpler. Implement that, and update the documentation to match. Signed-off-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e4c3485 commit d345e9f

File tree

3 files changed

+45
-11
lines changed

3 files changed

+45
-11
lines changed

Documentation/git-update-ref.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ git-update-ref - Update the object name stored in a ref safely
88
SYNOPSIS
99
--------
1010
[verse]
11-
'git update-ref' [-m <reason>] (-d <ref> [<oldvalue>] | [--no-deref] [--create-reflog] <ref> <newvalue> [<oldvalue>] | --stdin [-z])
11+
'git update-ref' [-m <reason>] [--no-deref] (-d <ref> [<oldvalue>] | [--create-reflog] <ref> <newvalue> [<oldvalue>] | --stdin [-z])
1212

1313
DESCRIPTION
1414
-----------

builtin/update-ref.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ static const char * const git_update_ref_usage[] = {
1515

1616
static char line_termination = '\n';
1717
static unsigned int update_flags;
18+
static unsigned int default_flags;
1819
static unsigned create_reflog_flag;
1920
static const char *msg;
2021

@@ -205,7 +206,7 @@ static const char *parse_cmd_update(struct ref_transaction *transaction,
205206
msg, &err))
206207
die("%s", err.buf);
207208

208-
update_flags = 0;
209+
update_flags = default_flags;
209210
free(refname);
210211
strbuf_release(&err);
211212

@@ -237,7 +238,7 @@ static const char *parse_cmd_create(struct ref_transaction *transaction,
237238
msg, &err))
238239
die("%s", err.buf);
239240

240-
update_flags = 0;
241+
update_flags = default_flags;
241242
free(refname);
242243
strbuf_release(&err);
243244

@@ -273,7 +274,7 @@ static const char *parse_cmd_delete(struct ref_transaction *transaction,
273274
update_flags, msg, &err))
274275
die("%s", err.buf);
275276

276-
update_flags = 0;
277+
update_flags = default_flags;
277278
free(refname);
278279
strbuf_release(&err);
279280

@@ -302,7 +303,7 @@ static const char *parse_cmd_verify(struct ref_transaction *transaction,
302303
update_flags, &err))
303304
die("%s", err.buf);
304305

305-
update_flags = 0;
306+
update_flags = default_flags;
306307
free(refname);
307308
strbuf_release(&err);
308309

@@ -357,7 +358,6 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
357358
const char *refname, *oldval;
358359
struct object_id oid, oldoid;
359360
int delete = 0, no_deref = 0, read_stdin = 0, end_null = 0;
360-
unsigned int flags = 0;
361361
int create_reflog = 0;
362362
struct option options[] = {
363363
OPT_STRING( 'm', NULL, &msg, N_("reason"), N_("reason of the update")),
@@ -378,14 +378,19 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
378378

379379
create_reflog_flag = create_reflog ? REF_FORCE_CREATE_REFLOG : 0;
380380

381+
if (no_deref) {
382+
default_flags = REF_NO_DEREF;
383+
update_flags = default_flags;
384+
}
385+
381386
if (read_stdin) {
382387
struct strbuf err = STRBUF_INIT;
383388
struct ref_transaction *transaction;
384389

385390
transaction = ref_transaction_begin(&err);
386391
if (!transaction)
387392
die("%s", err.buf);
388-
if (delete || no_deref || argc > 0)
393+
if (delete || argc > 0)
389394
usage_with_options(git_update_ref_usage, options);
390395
if (end_null)
391396
line_termination = '\0';
@@ -427,18 +432,16 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
427432
die("%s: not a valid old SHA1", oldval);
428433
}
429434

430-
if (no_deref)
431-
flags = REF_NO_DEREF;
432435
if (delete)
433436
/*
434437
* For purposes of backwards compatibility, we treat
435438
* NULL_SHA1 as "don't care" here:
436439
*/
437440
return delete_ref(msg, refname,
438441
(oldval && !is_null_oid(&oldoid)) ? &oldoid : NULL,
439-
flags);
442+
default_flags);
440443
else
441444
return update_ref(msg, refname, &oid, oldval ? &oldoid : NULL,
442-
flags | create_reflog_flag,
445+
default_flags | create_reflog_flag,
443446
UPDATE_REFS_DIE_ON_ERR);
444447
}

t/t1400-update-ref.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,37 @@ test_expect_success 'stdin delete symref works option no-deref' '
807807
test_cmp expect actual
808808
'
809809

810+
test_expect_success 'stdin update symref works flag --no-deref' '
811+
git symbolic-ref TESTSYMREFONE $b &&
812+
git symbolic-ref TESTSYMREFTWO $b &&
813+
cat >stdin <<-EOF &&
814+
update TESTSYMREFONE $a $b
815+
update TESTSYMREFTWO $a $b
816+
EOF
817+
git update-ref --no-deref --stdin <stdin &&
818+
git rev-parse TESTSYMREFONE TESTSYMREFTWO >expect &&
819+
git rev-parse $a $a >actual &&
820+
test_cmp expect actual &&
821+
git rev-parse $m~1 >expect &&
822+
git rev-parse $b >actual &&
823+
test_cmp expect actual
824+
'
825+
826+
test_expect_success 'stdin delete symref works flag --no-deref' '
827+
git symbolic-ref TESTSYMREFONE $b &&
828+
git symbolic-ref TESTSYMREFTWO $b &&
829+
cat >stdin <<-EOF &&
830+
delete TESTSYMREFONE $b
831+
delete TESTSYMREFTWO $b
832+
EOF
833+
git update-ref --no-deref --stdin <stdin &&
834+
test_must_fail git rev-parse --verify -q TESTSYMREFONE &&
835+
test_must_fail git rev-parse --verify -q TESTSYMREFTWO &&
836+
git rev-parse $m~1 >expect &&
837+
git rev-parse $b >actual &&
838+
test_cmp expect actual
839+
'
840+
810841
test_expect_success 'stdin delete ref works with right old value' '
811842
echo "delete $b $m~1" >stdin &&
812843
git update-ref --stdin <stdin &&

0 commit comments

Comments
 (0)