Repo cannot be forked. Fork hierarchies are limited to a maximum depth of 5

Still need help?

The Atlassian Community is here for you.

Ask the community

Platform notice: Server and Data Center only. This article only applies to Atlassian products on the Server and Data Center platforms.

Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.

*Except Fisheye and Crucible

Problem

Trying to create a fork fails with the following error:

<repo> cannot be forked. For performance reasons, fork hierarchies are limited to a maximum depth of 5 beneath a given root repository. Please create your fork from a repository higher up in the hierarchy, such as <repo-parent>.


Diagnosis

When forking repositories, there is a hierarchical limit to the number of times you can "fork a fork". Consider the following scenario:

  • original-repo.git is created
  • original-repo.git is forked to create fork-1.git
  • fork-1.git is forked to create fork-2.git
  • fork-2.git is forked to create fork-3.git
  • fork-3.git is forked to create fork-4.git
  • fork-4.git is forked to create fork-5.git

In the above scenario, if you attempt to fork fork-5.git you will be met with the following error:

Deleting the upstream repositories does not resolve the issue, because git alternates prevent referenced repositories from being removed on disk even if they are deleted from the UI.


Cause

Forks in Bitbucket Server rely on git alternates. Git alternates are basically a reference to another repository's objects. Using git alternates provides a few advantages to forks in Bitbucket Server:

  • Forks consume very little additional disk space, as objects from the upstream repository are referenced, not duplicated
  • Creating a new fork is nearly instantaneous because objects do not need to be duplicated on disk
  • Objects can be automatically synced (fork syncing) from the upstream repository

When you have multiple layers of forks, then the outer-most fork is referencing objects in a parent repository, which is in turn referencing objects in its parent repository, and so on, creating a situation where your repository has to traverse "recursive alternates", following the git alternate references through multiple upstream repositories to retrieve the target object. Git itself places a hard-coded limit of 5 on recursive alternates and this limit can't be overridden.

Resolution

The recommended solution to prevent this issue occurring is to adapt your workflow to prevent creating so many layers of forks. When a forking workflow is used instead of a branching workflow, forks should ideally be made from "higher up" - e.g. from the original repo, or from a direct fork of the original.

When this is not possible there are two potential solutions:

  1. Repack the repository and remove the git alternate references
  2. Disable the use of git alternates in forks (not recommended)

Repack the repository

Repacking the repository will pull upstream alternates into the repository's own packs, so it no longer references git alternate objects and can be forked.

To repack the repository:

  1. Find the location of the repository on disk (this can be seen in the repo settings)
  2. Copy the repo to another location
  3. On the copy, perform the following steps:
    1. Run git fsck and confirm there are no errors and that "Checking object directories" appears more than once: 

      git fsck --no-dangling
    2. Run git repack and confirm there are no errors

      git repack -adf --depth=200 --window=200
    3. Remove the alternates file from the repository: 

      rm objects/info/alternates
    4. Run git fsck again and confirm there are no errors, but this time check that "Checking object directories" only appears once

      git fsck --no-dangling
  4. If all of the above steps succeed exactly as expected, then we can do this for real:
    1. Shut down Bitbucket Server
    2. Back up the repository
    3. Perform the steps 3.1 - 3.4 to repack the repository and remove git alternate references
    4. Start Bitbucket Server

Disable git alternates

Disabling git alternates means that forks will no longer be subject to the max depth of 5, however there are significant drawbacks:

  1. Forks will use much more disk space, with each fork consuming disk space equal to the size of the upstream repository
  2. Fork syncing (aka ref syncing) would stop working, even for existing forks
  3. Forks will take much longer to create, as instead of creating an empty repo with an alternates file that references the upstream repo, the entire repository must be duplicated on disk

For these reasons, this solution is not recommended.

To disable git alternates:

  1. Shut down Bitbucket Server
  2. Add the following line to $BITBUCKET_HOME/shared/bitbucket.properties

    plugin.bitbucket-git.forks.usealternates=false
  3. Start Bitbucket Server 


Last modified on Jun 8, 2018

Was this helpful?

Yes
No
Provide feedback about this article
Powered by Confluence and Scroll Viewport.