Skip to content

Commit 47c52b2

Browse files
committed
Merge branch 'tb/rename-remote-progress'
"git remote rename A B", depending on the number of remote-tracking refs involved, takes long time renaming them. The command has been taught to show progress bar while making the user wait. * tb/rename-remote-progress: builtin/remote.c: show progress when renaming remote references builtin/remote.c: parse options in 'rename'
2 parents 190f9bf + 56710a7 commit 47c52b2

File tree

3 files changed

+35
-10
lines changed

3 files changed

+35
-10
lines changed

Documentation/git-remote.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ SYNOPSIS
1111
[verse]
1212
'git remote' [-v | --verbose]
1313
'git remote add' [-t <branch>] [-m <master>] [-f] [--[no-]tags] [--mirror=(fetch|push)] <name> <URL>
14-
'git remote rename' <old> <new>
14+
'git remote rename' [--[no-]progress] <old> <new>
1515
'git remote remove' <name>
1616
'git remote set-head' <name> (-a | --auto | -d | --delete | <branch>)
1717
'git remote set-branches' [--add] <name> <branch>...

builtin/remote.c

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@
1212
#include "object-store.h"
1313
#include "strvec.h"
1414
#include "commit-reach.h"
15+
#include "progress.h"
1516

1617
static const char * const builtin_remote_usage[] = {
1718
"git remote [-v | --verbose]",
1819
N_("git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--mirror=<fetch|push>] <name> <url>"),
19-
N_("git remote rename <old> <new>"),
20+
N_("git remote rename [--[no-]progress] <old> <new>"),
2021
N_("git remote remove <name>"),
2122
N_("git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"),
2223
N_("git remote [-v | --verbose] show [-n] <name>"),
@@ -36,7 +37,7 @@ static const char * const builtin_remote_add_usage[] = {
3637
};
3738

3839
static const char * const builtin_remote_rename_usage[] = {
39-
N_("git remote rename <old> <new>"),
40+
N_("git remote rename [--[no-]progress] <old> <new>"),
4041
NULL
4142
};
4243

@@ -571,6 +572,7 @@ struct rename_info {
571572
const char *old_name;
572573
const char *new_name;
573574
struct string_list *remote_branches;
575+
uint32_t symrefs_nr;
574576
};
575577

576578
static int read_remote_branches(const char *refname,
@@ -587,10 +589,12 @@ static int read_remote_branches(const char *refname,
587589
item = string_list_append(rename->remote_branches, refname);
588590
symref = resolve_ref_unsafe(refname, RESOLVE_REF_READING,
589591
NULL, &flag);
590-
if (symref && (flag & REF_ISSYMREF))
592+
if (symref && (flag & REF_ISSYMREF)) {
591593
item->util = xstrdup(symref);
592-
else
594+
rename->symrefs_nr++;
595+
} else {
593596
item->util = NULL;
597+
}
594598
}
595599
strbuf_release(&buf);
596600

@@ -674,22 +678,29 @@ static void handle_push_default(const char* old_name, const char* new_name)
674678

675679
static int mv(int argc, const char **argv)
676680
{
681+
int show_progress = isatty(2);
677682
struct option options[] = {
683+
OPT_BOOL(0, "progress", &show_progress, N_("force progress reporting")),
678684
OPT_END()
679685
};
680686
struct remote *oldremote, *newremote;
681687
struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT, buf3 = STRBUF_INIT,
682688
old_remote_context = STRBUF_INIT;
683689
struct string_list remote_branches = STRING_LIST_INIT_DUP;
684690
struct rename_info rename;
685-
int i, refspec_updated = 0;
691+
int i, refs_renamed_nr = 0, refspec_updated = 0;
692+
struct progress *progress = NULL;
693+
694+
argc = parse_options(argc, argv, NULL, options,
695+
builtin_remote_rename_usage, 0);
686696

687-
if (argc != 3)
697+
if (argc != 2)
688698
usage_with_options(builtin_remote_rename_usage, options);
689699

690-
rename.old_name = argv[1];
691-
rename.new_name = argv[2];
700+
rename.old_name = argv[0];
701+
rename.new_name = argv[1];
692702
rename.remote_branches = &remote_branches;
703+
rename.symrefs_nr = 0;
693704

694705
oldremote = remote_get(rename.old_name);
695706
if (!remote_is_configured(oldremote, 1)) {
@@ -764,6 +775,14 @@ static int mv(int argc, const char **argv)
764775
* the new symrefs.
765776
*/
766777
for_each_ref(read_remote_branches, &rename);
778+
if (show_progress) {
779+
/*
780+
* Count symrefs twice, since "renaming" them is done by
781+
* deleting and recreating them in two separate passes.
782+
*/
783+
progress = start_progress(_("Renaming remote references"),
784+
rename.remote_branches->nr + rename.symrefs_nr);
785+
}
767786
for (i = 0; i < remote_branches.nr; i++) {
768787
struct string_list_item *item = remote_branches.items + i;
769788
struct strbuf referent = STRBUF_INIT;
@@ -775,6 +794,7 @@ static int mv(int argc, const char **argv)
775794
die(_("deleting '%s' failed"), item->string);
776795

777796
strbuf_release(&referent);
797+
display_progress(progress, ++refs_renamed_nr);
778798
}
779799
for (i = 0; i < remote_branches.nr; i++) {
780800
struct string_list_item *item = remote_branches.items + i;
@@ -790,6 +810,7 @@ static int mv(int argc, const char **argv)
790810
item->string, buf.buf);
791811
if (rename_ref(item->string, buf.buf, buf2.buf))
792812
die(_("renaming '%s' failed"), item->string);
813+
display_progress(progress, ++refs_renamed_nr);
793814
}
794815
for (i = 0; i < remote_branches.nr; i++) {
795816
struct string_list_item *item = remote_branches.items + i;
@@ -809,7 +830,9 @@ static int mv(int argc, const char **argv)
809830
item->string, buf.buf);
810831
if (create_symref(buf.buf, buf2.buf, buf3.buf))
811832
die(_("creating '%s' failed"), buf.buf);
833+
display_progress(progress, ++refs_renamed_nr);
812834
}
835+
stop_progress(&progress);
813836
string_list_clear(&remote_branches, 1);
814837

815838
handle_push_default(rename.old_name, rename.new_name);

t/t5505-remote.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,9 @@ test_expect_success 'rename a remote' '
753753
(
754754
cd four &&
755755
git config branch.main.pushRemote origin &&
756-
git remote rename origin upstream &&
756+
GIT_TRACE2_EVENT=$(pwd)/trace \
757+
git remote rename --progress origin upstream &&
758+
test_region progress "Renaming remote references" trace &&
757759
grep "pushRemote" .git/config &&
758760
test -z "$(git for-each-ref refs/remotes/origin)" &&
759761
test "$(git symbolic-ref refs/remotes/upstream/HEAD)" = "refs/remotes/upstream/main" &&

0 commit comments

Comments
 (0)