Repository navigation
repo rename -> invalid memory access pattern #8675
Description
Activity
updated version. Bug persists.
gh version 2.43.1 (2024-01-31)
https://github.com/cli/cli/releases/tag/v2.43.1Reacted by Andy Fellerupdated version. Bug persists.
gh version 2.43.1 (2024-01-31)
https://github.com/cli/cli/releases/tag/v2.43.1@thor314 : thanks for opening this issue! 🙇
gh --version
gh version 2.4.0+dfsg1 (2022-03-23 Ubuntu 2.4.0+dfsg1-2) https://github.com/cli/cli/releases/latest(that's about 2 years ago so this may already be fixed)
Could you re-run this using
GH_DEBUG=apienv var and provide the terminal output here please?Testing this out locally using latest
ghgoing fromcronto.cronto.whatevertocronand finally.cronseemingly work:$ gh version gh version 2.43.1 (2024-01-31) https://github.com/cli/cli/releases/tag/v2.43.1 # Test .<nameA> to .<nameB> $ gh repo rename .whatever ? Rename tinyfists/.cron to .whatever? Yes ✓ Renamed repository tinyfists/.whatever ✓ Updated the "origin" remote # Test .<nameB> to .<nameB> $ gh repo rename .whatever ? Rename tinyfists/.whatever to .whatever? Yes ✓ Renamed repository tinyfists/.whatever ✓ Updated the "origin" remote # Test .<nameB> to <nameA> $ gh repo rename cron ? Rename tinyfists/.whatever to cron? Yes ✓ Renamed repository tinyfists/cron ✓ Updated the "origin" remote # Test <nameA> to .<nameA> $ gh repo rename .cron ? Rename tinyfists/cron to .cron? Yes ✓ Renamed repository tinyfists/.cron ✓ Updated the "origin" remote
- addedmore-info-neededMore info needed from user/contributorMore info needed from user/contributorgh-reporelating to the gh repo commandrelating to the gh repo commandand removedneeds-triageneeds to be reviewedneeds to be reviewed
on Feb 12, 2024 Hmm. I was able to reproduce the issue, but for whatever reason, running the command with
-yseems to have avoided the bug, and I can no longer reproduce the issue.I was able to capture the following with GH_DEBUG enabled:
~ ❯ cd .cron && GH_DEBUG=api gh repo rename .cron [git remote -v] [git config --get-regexp ^remote\..*\.gh-resolved$] * Request at 2024-02-13 20:27:00.053504767 -0800 PST m=+0.037150821 * Request to https://api.github.com/graphql > POST /graphql HTTP/1.1 > Host: api.github.com > Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview > Authorization: token ████████████████████ > Content-Length: 386 > Content-Type: application/json; charset=utf-8 > Graphql-Features: merge_queue > Time-Zone: America/Los_Angeles > User-Agent: GitHub CLI 2.43.1 GraphQL query: fragment repo on Repository { id name owner { login } viewerPermission defaultBranchRef { name } isPrivate } query RepositoryNetwork { viewer { login } repo_000: repository(owner: "thor314", name: "cron") { ...repo parent { ...repo } } } GraphQL variables: null < HTTP/2.0 200 OK < Access-Control-Allow-Origin: * < Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset < Content-Security-Policy: default-src 'none' < Content-Type: application/json; charset=utf-8 < Date: Wed, 14 Feb 2024 04:27:00 GMT < Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin < Server: GitHub.com < Strict-Transport-Security: max-age=31536000; includeSubdomains; preload < Vary: Accept-Encoding, Accept, X-Requested-With < X-Accepted-Oauth-Scopes: repo < X-Content-Type-Options: nosniff < X-Frame-Options: deny < X-Github-Media-Type: github.merge-info-preview; param=nebula-preview; format=json < X-Github-Request-Id: 94AA:47BB:354EF40:36D9747:65CC4114 < X-Oauth-Client-Id: 178c6fc778ccc68e1d6a < X-Oauth-Scopes: admin:public_key, admin:ssh_signing_key, delete_repo, gist, read:org, repo < X-Ratelimit-Limit: 5000 < X-Ratelimit-Remaining: 4999 < X-Ratelimit-Reset: 1707888420 < X-Ratelimit-Resource: graphql < X-Ratelimit-Used: 1 < X-Xss-Protection: 0 { "data": { "viewer": { "login": "thor314" }, "repo_000": { "id": "R_kgDOIYiKcA", "name": ".cron", "owner": { "login": "thor314" }, "viewerPermission": "ADMIN", "defaultBranchRef": { "name": "main" }, "isPrivate": false, "parent": null } } } * Request took 320.195337ms ? Rename thor314/.cron to .cron? Yes * Request at 2024-02-13 20:27:03.184540981 -0800 PST m=+3.168187073 * Request to https://api.github.com/repos/thor314/.cron > PATCH /repos/thor314/.cron HTTP/1.1 > Host: api.github.com > Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview > Authorization: token ████████████████████ > Content-Length: 17 > Content-Type: application/json; charset=utf-8 > Time-Zone: America/Los_Angeles > User-Agent: GitHub CLI 2.43.1 { "name": ".cron" } < HTTP/2.0 200 OK < Access-Control-Allow-Origin: * < Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset < Cache-Control: private, max-age=60, s-maxage=60 < Content-Security-Policy: default-src 'none' < Content-Type: application/json; charset=utf-8 < Date: Wed, 14 Feb 2024 04:27:03 GMT < Etag: W/"85119dd612bec76ae90bf7032fb3d3bf6ec61e7ceb6c3fc1a2eb504c4ed8dd10" < Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin < Server: GitHub.com < Strict-Transport-Security: max-age=31536000; includeSubdomains; preload < Vary: Accept, Authorization, Cookie, X-GitHub-OTP < Vary: Accept-Encoding, Accept, X-Requested-With < X-Accepted-Oauth-Scopes: < X-Content-Type-Options: nosniff < X-Frame-Options: deny < X-Github-Api-Version-Selected: 2022-11-28 < X-Github-Media-Type: github.merge-info-preview; param=nebula-preview; format=json < X-Github-Request-Id: 94AA:47BB:354F39D:36D9BC2:65CC4114 < X-Oauth-Client-Id: 178c6fc778ccc68e1d6a < X-Oauth-Scopes: admin:public_key, admin:ssh_signing_key, delete_repo, gist, read:org, repo < X-Ratelimit-Limit: 5000 < X-Ratelimit-Remaining: 4990 < X-Ratelimit-Reset: 1707887725 < X-Ratelimit-Resource: core < X-Ratelimit-Used: 10 < X-Xss-Protection: 0 { "id": 562596464, "node_id": "R_kgDOIYiKcA", "name": ".cron", "full_name": "thor314/.cron", "private": false, "owner": { "login": "thor314", "id": 7041313, "node_id": "MDQ6VXNlcjcwNDEzMTM=", "avatar_url": "https://avatars.githubusercontent.com/u/7041313?v=4", "gravatar_id": "", "url": "https://api.github.com/users/thor314", "html_url": "https://github.com/thor314", "followers_url": "https://api.github.com/users/thor314/followers", "following_url": "https://api.github.com/users/thor314/following{/other_user}", "gists_url": "https://api.github.com/users/thor314/gists{/gist_id}", "starred_url": "https://api.github.com/users/thor314/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/thor314/subscriptions", "organizations_url": "https://api.github.com/users/thor314/orgs", "repos_url": "https://api.github.com/users/thor314/repos", "events_url": "https://api.github.com/users/thor314/events{/privacy}", "received_events_url": "https://api.github.com/users/thor314/received_events", "type": "User", "site_admin": false }, "html_url": "https://github.com/thor314/.cron", "description": null, "fork": false, "url": "https://api.github.com/repos/thor314/.cron", "forks_url": "https://api.github.com/repos/thor314/.cron/forks", "keys_url": "https://api.github.com/repos/thor314/.cron/keys{/key_id}", "collaborators_url": "https://api.github.com/repos/thor314/.cron/collaborators{/collaborator}", "teams_url": "https://api.github.com/repos/thor314/.cron/teams", "hooks_url": "https://api.github.com/repos/thor314/.cron/hooks", "issue_events_url": "https://api.github.com/repos/thor314/.cron/issues/events{/number}", "events_url": "https://api.github.com/repos/thor314/.cron/events", "assignees_url": "https://api.github.com/repos/thor314/.cron/assignees{/user}", "branches_url": "https://api.github.com/repos/thor314/.cron/branches{/branch}", "tags_url": "https://api.github.com/repos/thor314/.cron/tags", "blobs_url": "https://api.github.com/repos/thor314/.cron/git/blobs{/sha}", "git_tags_url": "https://api.github.com/repos/thor314/.cron/git/tags{/sha}", "git_refs_url": "https://api.github.com/repos/thor314/.cron/git/refs{/sha}", "trees_url": "https://api.github.com/repos/thor314/.cron/git/trees{/sha}", "statuses_url": "https://api.github.com/repos/thor314/.cron/statuses/{sha}", "languages_url": "https://api.github.com/repos/thor314/.cron/languages", "stargazers_url": "https://api.github.com/repos/thor314/.cron/stargazers", "contributors_url": "https://api.github.com/repos/thor314/.cron/contributors", "subscribers_url": "https://api.github.com/repos/thor314/.cron/subscribers", "subscription_url": "https://api.github.com/repos/thor314/.cron/subscription", "commits_url": "https://api.github.com/repos/thor314/.cron/commits{/sha}", "git_commits_url": "https://api.github.com/repos/thor314/.cron/git/commits{/sha}", "comments_url": "https://api.github.com/repos/thor314/.cron/comments{/number}", "issue_comment_url": "https://api.github.com/repos/thor314/.cron/issues/comments{/number}", "contents_url": "https://api.github.com/repos/thor314/.cron/contents/{+path}", "compare_url": "https://api.github.com/repos/thor314/.cron/compare/{base}...{head}", "merges_url": "https://api.github.com/repos/thor314/.cron/merges", "archive_url": "https://api.github.com/repos/thor314/.cron/{archive_format}{/ref}", "downloads_url": "https://api.github.com/repos/thor314/.cron/downloads", "issues_url": "https://api.github.com/repos/thor314/.cron/issues{/number}", "pulls_url": "https://api.github.com/repos/thor314/.cron/pulls{/number}", "milestones_url": "https://api.github.com/repos/thor314/.cron/milestones{/number}", "notifications_url": "https://api.github.com/repos/thor314/.cron/notifications{?since,all,participating}", "labels_url": "https://api.github.com/repos/thor314/.cron/labels{/name}", "releases_url": "https://api.github.com/repos/thor314/.cron/releases{/id}", "deployments_url": "https://api.github.com/repos/thor314/.cron/deployments", "created_at": "2022-11-06T20:28:20Z", "updated_at": "2024-01-31T00:43:00Z", "pushed_at": "2024-02-13T22:18:33Z", "git_url": "git://github.com/thor314/.cron.git", "ssh_url": "[email protected]:thor314/.cron.git", "clone_url": "https://github.com/thor314/.cron.git", "svn_url": "https://github.com/thor314/.cron", "homepage": "", "size": 159, "stargazers_count": 0, "watchers_count": 0, "language": "Shell", "has_issues": true, "has_projects": true, "has_downloads": true, "has_wiki": true, "has_pages": false, "has_discussions": false, "forks_count": 0, "mirror_url": null, "archived": false, "disabled": false, "open_issues_count": 0, "license": null, "allow_forking": true, "is_template": false, "web_commit_signoff_required": false, "topics": [], "visibility": "public", "forks": 0, "open_issues": 0, "watchers": 0, "default_branch": "main", "permissions": { "admin": true, "maintain": true, "push": true, "triage": true, "pull": true }, "allow_squash_merge": true, "allow_merge_commit": true, "allow_rebase_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": false, "allow_update_branch": false, "use_squash_pr_title_as_default": false, "squash_merge_commit_message": "COMMIT_MESSAGES", "squash_merge_commit_title": "COMMIT_OR_PR_TITLE", "merge_commit_message": "PR_TITLE", "merge_commit_title": "MERGE_MESSAGE", "security_and_analysis": { "secret_scanning": { "status": "disabled" }, "secret_scanning_push_protection": { "status": "disabled" }, "dependabot_security_updates": { "status": "disabled" }, "secret_scanning_validity_checks": { "status": "disabled" } }, "network_count": 0, "subscribers_count": 1 } * Request took 194.792253ms ✓ Renamed repository thor314/.cron [git remote -v] [git config --get-regexp ^remote\..*\.gh-resolved$] panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x1259543] goroutine 1 [running]: github.com/cli/cli/v2/pkg/cmd/repo/rename.renameRun(0xc0003050e0) /home/runner/work/cli/cli/pkg/cmd/repo/rename/rename.go:138 +0x4a3 github.com/cli/cli/v2/pkg/cmd/repo/rename.NewCmdRename.func1(0xc00053d200?, {0xc0007c6db0, 0x1, 0x14fab9d?}) /home/runner/work/cli/cli/pkg/cmd/repo/rename/rename.go:77 +0x1a5 github.com/spf13/cobra.(*Command).execute(0xc000552300, {0xc0007c6d90, 0x1, 0x1}) /home/runner/go/pkg/mod/github.com/spf13/[email protected]/command.go:916 +0x87c github.com/spf13/cobra.(*Command).ExecuteC(0xc000004900) /home/runner/go/pkg/mod/github.com/spf13/[email protected]/command.go:1044 +0x3a5 github.com/spf13/cobra.(*Command).ExecuteContextC(...) /home/runner/go/pkg/mod/github.com/spf13/[email protected]/command.go:977 main.mainRun() /home/runner/work/cli/cli/cmd/gh/main.go:119 +0x5db main.main() /home/runner/work/cli/cli/cmd/gh/main.go:46 +0x13But with the
-yflag, bug fails to appear and can no longer be reproduced:~/.cron main ?1 ❯ gh repo rename .cron -y &> gh.log ~/.cron main ?1 ❯ bat --theme=zenburn --style=plain gh.log ~/.cron main ?1 ❯ gh repo rename .cron -y ✓ Renamed repository thor314/.cron ✓ Updated the "origin" remote ~/.cron main ?1 ❯ hub browse ~/.cron main ?1 ❯ gh repo rename cron ? Rename thor314/.cron to cron? Yes ✓ Renamed repository thor314/cron ✓ Updated the "origin" remote ~/.cron main ?1 ❯ gh repo rename .cron ? Rename thor314/cron to .cron? Yes ✓ Renamed repository thor314/.cron ✓ Updated the "origin" remoteI haven't got the time right now to investigate this further but this line is not idiomatic (we shouldn't be using
remoteiferr != nil) and that's where the nil pointer is coming from:cli/pkg/cmd/repo/rename/rename.go
Line 138 in 8948ee8
fmt.Fprintf(opts.IO.ErrOut, "%s Warning: unable to update remote %q: %v\n", cs.WarningIcon(), remote.Name, err) I'm not sure what's happening before because we don't print the error.
@thor314 if you're up for it can you just change this line:
fmt.Fprintf(opts.IO.ErrOut, "%s Warning: unable to update remote %q: %v\n", cs.WarningIcon(), remote.Name, err)
to
fmt.Fprintf(opts.IO.ErrOut, "%s Warning: unable to update remote: %v\n", cs.WarningIcon(), err)
You can use
maketo build and then./bin/ghto run the build binary.I can't see any possible reason that
-ywould impact this, it just determines whether to present a prompt or not. I wonder whether there was some other state change.cli/pkg/cmd/repo/rename/rename.go
Lines 109 to 118 in 8948ee8
if opts.DoConfirm { var confirmed bool if confirmed, err = opts.Prompter.Confirm(fmt.Sprintf( "Rename %s to %s?", ghrepo.FullName(currRepo), newRepoName), false); err != nil { return err } if !confirmed { return nil } } Doh, I see that you aren't able to reproduce this anymore. Well what I'd suggest is that we stick a
help wantedlabel on here and someone can open a PR to put something more sensible in the log message that won't try to deref anil, then maybe we'll see the right error in future.- addedhelp wantedContributions welcomeContributions welcomeand removedmore-info-neededMore info needed from user/contributorMore info needed from user/contributor
on Feb 15, 2024 yeah sorry I can't be more helpful. Bug has scuttled under a proverbial couch for now. Good luck and thanks.
Reacted by William Martin@williammartin I just submitted a PR to fix this.
Playing around a bit, at last I could reproduce the panic with these steps:
- Create a new repo, clone, and
cdinto it:gh repo create gh-some-repo --private --add-readme && \ gh repo clone gh-some-repo && \ cd gh-some-repo - Rename the repo (this will be successful and will also update the
originremote):gh repo rename gh-some-repo-renamed - Change the
originremote back to what it was before renaming the repo:git remote set-url origin [email protected]:babakks/gh-some-repo.git - Try renaming the repo back to its initial name (this can be with or without the
--yesoption):gh repo rename gh-some-repo --yes - Should see the panic log.
Note that, if you retry the last command (step 4), this time no panic will happen.
The problem
When we call
updateRemotehere:cli/pkg/cmd/repo/rename/rename.go
Line 136 in 8948ee8
remote, err := updateRemote(currRepo, newRepo, opts) it returns a
nilremote and an error sayingno matching remote found, which is actually returned from theFindByRepomethod when it was looking for a remote pointing to the old name (i.e.,gh-some-repo-renamed) but couldn't find any.Reacted by William MartinReacted by William Martin- Create a new repo, clone, and
@williammartin I just realized that there's already a PR (#8888) submitted for this issue by @satoqz. I didn't notice because it wasn't linked to the issue.
@babakks thanks for the ping, turns out I didn't find this issue before opening my PR 😅
Anyways, @williammartin I can confirm the reproducibility of this issue, plus the fix that you proposed (which incidentally is the same change that I ended up with while debugging it myself) does resolve it, see #8888.
Reacted by Babak K. Shandiz@babakks super work on the reproduction. I can confirm this, and I also understand why it doesn't panic the second time (because the API rename succeeds the first time, thus the second time we're looking for a remote with the name that already exists in our git remotes).
It's a shame (and funny) that you both happened to pick this up at the same time. Since I have the wisdom of Solomon I'm going to split the PR by:
- Merging @satoqz PR since it was opened first
- Asking @babakks to rebase and include the change they have in
remote.gowhich is handy
Thanks so much to you both for working on this!
Reacted by Jonas Köhnen and Babak K. Shandiz
gh --version
gh version 2.4.0+dfsg1 (2022-03-23 Ubuntu 2.4.0+dfsg1-2)
https://github.com/cli/cli/releases/latest
(that's about 2 years ago so this may already be fixed)
I attempted to rename a repo,
cron->.cron. The repo was called.cronat one point, and I intended to move the repo back to the initial name.bug discovery: