Skip to content

Commit 6ebed3e

Browse files
committed
Merge branch 'jk/update-ref-rename' into HEAD
* jk/update-ref-rename: teach update-ref a "--rename" option
2 parents 113eaab + 7103d7e commit 6ebed3e

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

builtin/update-ref.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
static const char * const git_update_ref_usage[] = {
1616
N_("git update-ref [<options>] -d <refname> [<old-oid>]"),
1717
N_("git update-ref [<options>] <refname> <new-oid> [<old-oid>]"),
18+
N_("git update-ref [<options>] --rename <refname> <refname>"),
1819
N_("git update-ref [<options>] --stdin [-z] [--batch-updates]"),
1920
NULL
2021
};
@@ -25,6 +26,19 @@ static unsigned int default_flags;
2526
static unsigned create_reflog_flag;
2627
static const char *msg;
2728

29+
static int do_rename_ref(const char *from, const char *to)
30+
{
31+
struct strbuf msg = STRBUF_INIT;
32+
int ret;
33+
34+
strbuf_addf(&msg, "update-ref: renamed %s to %s", from, to);
35+
ret = refs_rename_ref(get_main_ref_store(the_repository),
36+
from, to, msg.buf);
37+
strbuf_release(&msg);
38+
39+
return !!ret;
40+
}
41+
2842
/*
2943
* Parse one whitespace- or NUL-terminated, possibly C-quoted argument
3044
* and append the result to arg. Return a pointer to the terminator.
@@ -756,10 +770,12 @@ int cmd_update_ref(int argc,
756770
int delete = 0, no_deref = 0, read_stdin = 0, end_null = 0;
757771
int create_reflog = 0;
758772
unsigned int flags = 0;
773+
int rename = 0;
759774

760775
struct option options[] = {
761776
OPT_STRING( 'm', NULL, &msg, N_("reason"), N_("reason of the update")),
762777
OPT_BOOL('d', NULL, &delete, N_("delete the reference")),
778+
OPT_BOOL( 0 , "rename", &rename, N_("rename the reference")),
763779
OPT_BOOL( 0 , "no-deref", &no_deref,
764780
N_("update <refname> not the one it points to")),
765781
OPT_BOOL('z', NULL, &end_null, N_("stdin has NUL-terminated arguments")),
@@ -784,7 +800,7 @@ int cmd_update_ref(int argc,
784800
}
785801

786802
if (read_stdin) {
787-
if (delete || argc > 0)
803+
if (delete || rename || argc > 0)
788804
usage_with_options(git_update_ref_usage, options);
789805
if (end_null)
790806
line_termination = '\0';
@@ -797,6 +813,12 @@ int cmd_update_ref(int argc,
797813
if (end_null)
798814
usage_with_options(git_update_ref_usage, options);
799815

816+
if (rename) {
817+
if (delete || argc < 2 || argc > 2)
818+
usage_with_options(git_update_ref_usage, options);
819+
return do_rename_ref(argv[0], argv[1]);
820+
}
821+
800822
if (delete) {
801823
if (argc < 1 || argc > 2)
802824
usage_with_options(git_update_ref_usage, options);

t/t1400-update-ref.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Z=$ZERO_OID
1212
m=refs/heads/main
1313
outside=refs/foo
1414
bare=bare-repo
15+
d=refs/heads/dst
1516

1617
create_test_commits ()
1718
{
@@ -424,8 +425,30 @@ test_expect_success 'Query "main@{2005-05-28}" (past end of history)' '
424425
test_grep -F "warning: log for ref $m unexpectedly ended on $ld" e
425426
'
426427

428+
test_expect_success 'rename a ref' '
429+
git rev-parse --verify $m >expect &&
430+
431+
# set the date to match the reflog entries we created
432+
# above, which do not follow test_tick; otherwise
433+
# the we write an out-of-order entry into the reflog,
434+
# which confuses the reflog parser
435+
GIT_COMMITTER_DATE=$ld \
436+
git update-ref --rename $m $d &&
437+
438+
test_must_fail git rev-parse --verify $m &&
439+
git rev-parse --verify $d >o &&
440+
test_cmp expect o
441+
'
442+
443+
test_expect_success 'renames copy reflogs' '
444+
echo "$C" >expect &&
445+
git rev-parse --verify "$d@{2005-05-26 23:32:00}" >o &&
446+
test_cmp expect o
447+
'
448+
427449
rm -f expect
428450
git update-ref -d $m
451+
git update-ref -d $d
429452

430453
test_expect_success 'query reflog with gap' '
431454
test_when_finished "git update-ref -d $m" &&

0 commit comments

Comments
 (0)