Fork button links to the project itself instead of to the user's fork
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
Summary
The Fork button on a project page can link to that same project. Two symptoms, one cause:
- With a fork present, the button goes to the source project instead of to the fork.
- With the fork deleted, the button keeps the "Go to your fork" tooltip instead of returning to "Create new fork", so the user cannot reach the new-fork page from the project page.
It happens when the user forks their own project inside their own namespace and has no group that allows project creation.
Related issues
This has been reported four times since 2021 and closed every time without a fix:
- #329755 (closed) (2021-05-03) same symptom, closed as stale with no triage.
- #369498 (closed) (2022-08-02) a second trigger for the same wrong pointer: a fork marked for deletion keeps its fork network member, so the button points at the renamed
…-deletion_scheduled-<id>project. Closed by !95495 (merged), which disabled delayed deletion for personal projects rather than changing the lookup. - #375555 (closed) (2022-09-28) names the same cause, a fork network search that is too wide. Auto-closed as stale, carries
Seeking community contributions. - #422242 (closed) (2023-08-16) same symptom including the forks count 0 detail. Closed by the reporter, confirmed by a second user a month later, never reopened.
- #419719 still open and related, but proposes replacing the button with a dropdown of the user's forks.
Steps to reproduce
- Sign in as a user whose only namespace allowing project creation is the personal namespace, so a user in no groups.
- Create a project in that personal namespace.
- Fork it into the same personal namespace.
- Open the source project. Hover the Fork button: the tooltip reads "Go to your fork". Click it: you land back on the source project, not on the fork.
- Delete the fork.
- Reload the source project. The tooltip still reads "Go to your fork" and the button still links to the source project. The forks count reads 0.
- Create any group, then reload. The tooltip is back to "Create new fork" and the button works.
What is the current bug behavior?
While the fork exists, the Fork button tooltip reads "Go to your fork" and the button links to the source project. Clicking it reloads the page the user is already on. The fork cannot be reached from there.
After the fork is deleted, the tooltip and the link stay the same, and the forks count drops to 0. The button claims a fork while the counter says there is none, and the new-fork page can no longer be reached from the project page.
What is the expected correct behavior?
While the fork exists, the button opens the fork. Once the fork is gone, the tooltip reads "Create new fork" and the button opens the new-fork page.
Relevant logs and/or screenshots
Root Cause Analysis
GitLab records fork relationships in a fork network, and the original project is a member of its own network. "Does this user already have a fork of this project?" is answered by Namespace#find_fork_of, which returns whichever network member sits in the user's namespace. The lookup does not exclude the project being asked about, so when the original is in the user's own namespace it matches itself.
Forking another user's project is unaffected, because the original sits in a different namespace. Deleting the fork makes it worse, because the original is then the only network member left in the namespace.
fork_button_data_attributes builds user_fork_url straight from that answer when the user has no group allowing project creation, which is why creating a group hides the bug.
The forks count comes from a different query that never counts the original, so it reads 0 while the tooltip claims a fork.
The same wrong project reaches the other callers of already_forked? and fork_of, including the Web IDE button, the fork-to-edit links in blob_helper and the commit target in creates_commit.
Possible fixes
Exclude the project from its own fork lookup in Namespace#find_fork_of. Both symptoms follow from that one wrong return value.
The existing fork button spec stubs already_forked? and has_groups_allowing_project_creation?, so it cannot catch this. A regression test has to drive the real lookup.
I plan to open a merge request for this.