Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d154456

Browse files
committed
remote: handle symrefs when renaming
A symref inside the namespace gets renamed, we should make it point to the target's new name. This is for the origin/HEAD -> origin/master type of situations.
1 parent eb6aa79 commit d154456

File tree

1 file changed

+39
-10
lines changed

1 file changed

+39
-10
lines changed

src/remote.c

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,32 +1359,61 @@ static int update_branch_remote_config_entry(
13591359
}
13601360

13611361
static int rename_one_remote_reference(
1362-
git_reference *reference,
1362+
git_reference *reference_in,
13631363
const char *old_remote_name,
13641364
const char *new_remote_name)
13651365
{
13661366
int error;
1367+
git_reference *ref = NULL, *dummy = NULL;
1368+
git_buf namespace = GIT_BUF_INIT, old_namespace = GIT_BUF_INIT;
13671369
git_buf new_name = GIT_BUF_INIT;
13681370
git_buf log_message = GIT_BUF_INIT;
1371+
size_t pfx_len;
1372+
const char *target;
13691373

1370-
if ((error = git_buf_printf(
1371-
&new_name,
1372-
GIT_REFS_REMOTES_DIR "%s%s",
1373-
new_remote_name,
1374-
reference->name + strlen(GIT_REFS_REMOTES_DIR) + strlen(old_remote_name))) < 0)
1374+
if ((error = git_buf_printf(&namespace, GIT_REFS_REMOTES_DIR "%s/", new_remote_name)) < 0)
1375+
return error;
1376+
1377+
pfx_len = strlen(GIT_REFS_REMOTES_DIR) + strlen(old_remote_name) + 1;
1378+
git_buf_puts(&new_name, namespace.ptr);
1379+
if ((error = git_buf_puts(&new_name, git_reference_name(reference_in) + pfx_len)) < 0)
13751380
goto cleanup;
13761381

13771382
if ((error = git_buf_printf(&log_message,
13781383
"renamed remote %s to %s",
13791384
old_remote_name, new_remote_name)) < 0)
13801385
goto cleanup;
13811386

1382-
error = git_reference_rename(
1383-
NULL, reference, git_buf_cstr(&new_name), 1,
1384-
NULL, git_buf_cstr(&log_message));
1385-
git_reference_free(reference);
1387+
if ((error = git_reference_rename(&ref, reference_in, git_buf_cstr(&new_name), 1,
1388+
NULL, git_buf_cstr(&log_message))) < 0)
1389+
goto cleanup;
1390+
1391+
if (git_reference_type(ref) != GIT_REF_SYMBOLIC)
1392+
goto cleanup;
1393+
1394+
/* Handle refs like origin/HEAD -> origin/master */
1395+
target = git_reference_symbolic_target(ref);
1396+
if ((error = git_buf_printf(&old_namespace, GIT_REFS_REMOTES_DIR "%s/", old_remote_name)) < 0)
1397+
goto cleanup;
1398+
1399+
if (git__prefixcmp(target, old_namespace.ptr))
1400+
goto cleanup;
1401+
1402+
git_buf_clear(&new_name);
1403+
git_buf_puts(&new_name, namespace.ptr);
1404+
if ((error = git_buf_puts(&new_name, target + pfx_len)) < 0)
1405+
goto cleanup;
1406+
1407+
error = git_reference_symbolic_set_target(&dummy, ref, git_buf_cstr(&new_name),
1408+
NULL, git_buf_cstr(&log_message));
1409+
1410+
git_reference_free(dummy);
13861411

13871412
cleanup:
1413+
git_reference_free(reference_in);
1414+
git_reference_free(ref);
1415+
git_buf_free(&namespace);
1416+
git_buf_free(&old_namespace);
13881417
git_buf_free(&new_name);
13891418
git_buf_free(&log_message);
13901419
return error;

0 commit comments

Comments
 (0)