Skip to content

Make Wiki operations target default branch instead of HEAD

Quang-Minh Nguyen requested to merge qmnguyen0711/fix-head-inconsistency into master

What does this MR do and why?

For #373182 (closed), #360651 (closed)

In the above issues, we noticed some quirky behaviors with Wiki features. They form a common pattern that the problems occur after the default branch of Wiki repository is updated. There are multiple actions can lead to this change, for example:

  • Force push via direct Wiki git access
  • Import a repository from another source
  • Transfer a repository to another group having a different default branch.

After such actions, the HEAD ref of such repositories are not updated accordingly. Normal project repositories never face this concern because in Gitaly, we have a complicated heuristic to determine the default branch and fallback in case HEAD does not exist. I wrote an in-depth analysis here. Unfortunately, the wiki feature groups use HEAD directly for many operations, such as version such as versions management, file collision check, etc. All file updates/creations are committed to the default branch (repository.default_branch). This inconsistency causes many quirky behaviors.

This MR is to force them to use the default branch, instead of HEAD ref from Rails side.

Side note: the default branch of wiki repository is a big confusion. It is independent of the container project's default branch. We can consider adding more documentation, or add a place on the UI to state it out explicitly. I don't think we should add the ability to change the default branch of Wiki, though.

How to set up and validate locally

Here's a simple scenario that can reproduce:

  • Initialize Wiki feature for a project
  • Clone Wiki repository to local environment
  • Rename/delete the default branch, assuming it's recently main, and push to remote
git checkout -b master
git push origin --delete main
git branch -D main
  • Confirming the HEAD ref of that repository
[6] pry(main)> p = Project.find_by_full_path("flightjs/test-wiki-project"); wiki = p.wiki; wiki.default_branch
=> "master"
[7] pry(main)> Gitlab::Git::Commit.find_commit(p.wiki.repository, 'HEAD')
=> nil
[8] pry(main)> Gitlab::Git::Commit.find_commit(p.wiki.repository, 'main')
=> nil
[9] pry(main)> Gitlab::Git::Commit.find_commit(p.wiki.repository, 'master')
=> <Gitaly::GitCommit: id: "558ce4f10c203cb00596a7356d6295b38ea0a1d6", subject: "Create x", body: "Create x", author: <Gitaly::CommitAuthor: name: "Administrator", email: "admin@example.com", date: <Google::Protobuf::Timestamp: seconds: 1662828689, nanos: 0>, timezone: "+0000">, committer: <Gitaly::CommitAuthor: name: "Administrator", email: "admin@example.com", date: <Google::Protobuf::Timestamp: seconds: 1662828689, nanos: 0>, timezone: "+0000">, parent_ids: ["4e487a1f7f536c61c4525b3943d0f14414375080"], body_size: 8, signature_type: :NONE, tree_id: "f16a30b6f4a6aa34fff3005384dd654e0409b9f9", trailers: []>
  • Access the storage of repository, check the HEAD ref
cat @hashed/19/58/19581e27de7ced00ff1ce50b2047e7a567c76b1cbaebabe5ef03f7c301
7bb5b7.wiki.git/HEAD
ref: refs/heads/main

When wiki_find_page_with_normal_repository_rpcs flag is on

  • Accessing a random page, we'll face page creation form, while the sidebar shows it exists:

Screen_Shot_2022-09-14_at_15.04.48

  • Click Create page, we'll see file duplication error

Screen_Shot_2022-09-14_at_15.05.40

  • Sometimes, it would show an error page, matching the experience of user in the bug report:

Screen_Shot_2022-09-12_at_22.26.15

When wiki_find_page_with_normal_repository_rpcs flag is off

  • Edit a random page, we'll face conflict error:

Screen_Shot_2022-09-13_at_23.08.45

  • Visit the history page of a wiki page, there is no visible histories while that page has many prior versions, including the first initial one.

Screen_Shot_2022-09-13_at_23.52.13

After this fix, all features on the UIs work as normal.

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Quang-Minh Nguyen

Merge request reports