[go: up one dir, main page]

Handle forking workflow

What does this MR do and why?

MR # Scope Status
1 Uses rest API to submit data
2 Reintroduce notifications
3 Editing file name is possible
4 File size validation
5 Handle fork workflow ⬅️

This MR handles the forking workflow when users edit files they don't have direct push access to. It covers two scenarios:

Scenario 1: Contributor editing in their own fork

  • Who: A contributor without push access to the upstream project
  • What: Edits a file via the web editor
  • Where: In their own fork of the project
  • Context: Wants to contribute changes back to the original project

The system now detects the user's fork and automatically redirects them to create a merge request from their fork back to the upstream project, with pre-filled source/target project and branch parameters. The source branch that is automatically created follows the pattern patch-N, where N is a number and ensures the branch name is unique.

How the branch name is generated for forked projects (click to expand)

When a blob is edited on a forked project, the new branch is created using the next_branch method in the Repository model. Here's how it works:

The generated_branch_name method in CreatesCommit calls project.repository.next_branch('patch'), which generates a branch name by:

  1. Scanning existing branches - It looks at all branch names in the repository and extracts any that match the pattern patch-N (where N is a number)
  2. Finding the highest number - It collects all the numeric IDs from matching branches and finds the maximum
  3. Incrementing - It adds 1 to the highest ID to create the next branch name (e.g., patch-1, patch-2, patch-3)

The next_branch method in app/models/repository.rb (lines 794-804) implements this logic:

def next_branch(name, opts = {})
  branch_ids = self.branch_names.map do |n|
    next 1 if n == name

    result = n.match(/\A#{name}-([0-9]+)\z/)
    result[1].to_i if result
  end.compact

  highest_branch_id = branch_ids.max || 0

  return name if opts[:mild] && 0 == highest_branch_id

  "#{name}-#{highest_branch_id + 1}"
end

The method uses a regex pattern to match branches like patch-1, patch-2, etc., extracts the numeric suffix, and returns the next sequential number. This ensures each new edit creates a uniquely numbered branch without conflicts.

Scenario 2: Maintainer editing in a contributor's fork

  • Who: A maintainer/developer of the upstream project (e.g., gitlab-org/gitlab)
  • What: Edits a file via the web editor
  • Where: On a branch that lives in someone else's fork (e.g., contributor/gitlab)
  • Context: Through an MR that has "allow commits from upstream members" enabled

The system recognizes they're editing in someone else's fork, routes API calls to the fork project, commits changes to the fork's branch, and redirects to the file's blob page in the fork project.

Key technical changes:

  • Passes fork project ID and path to the blob editor frontend
  • Detects when a user lacks push access and routes API calls to their fork
  • Refactors redirect logic into separate methods for maintainability
  • Updates API authorization to check branch-specific push permissions
  • Removes feature flag stubs from tests to enable the refactored blob editor

References

Screenshots or screen recordings

Scenario 1: Contributor editing in their own fork

Before After

Scenario 2: Maintainer editing in a contributor's fork

Before After

How to set up and validate locally

  1. In rails console enable the feature flag

    Feature.enable(:blob_edit_refactor)
  2. Go to Project / Members

  3. Select a member who has a role Guest and impersonate them.

  4. Go back to the project and choose a file to edit in single file editor.

  5. Commit the changes. Check that a fork is created and you redirected to the MR creation, where your branch from fork targets the source project at a branch you were browsing it.

  6. To check scenario number 2 you can follow https://docs.gitlab.com/user/project/merge_requests/allow_collaboration/#allow-commits-from-upstream-members.

  7. Stop impersonating the guest.

  8. As the project owner, got to the MR created by the guest and follow these steps: https://docs.gitlab.com/user/project/repository/web_editor/#edit-files-in-a-forked-merge-request

  9. Verify that changes have been made to the fork project.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #509968

Edited by Paulina Sedlak-Jakubowska

Merge request reports

Loading