diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index de25392d88..77e7f2b7de 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -943,6 +943,8 @@ fork_from = Fork From
 already_forked = You've already forked %s
 fork_to_different_account = Fork to a different account
 fork_visibility_helper = The visibility of a forked repository cannot be changed.
+fork_branch = Branch to be cloned to the fork
+all_branches = All branches
 fork_no_valid_owners = This repository can not be forked because there are no valid owners.
 use_template = Use this template
 clone_in_vsc = Clone in VS Code
diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go
index 63dfd0f7b5..6e69811901 100644
--- a/routers/web/repo/pull.go
+++ b/routers/web/repo/pull.go
@@ -180,6 +180,21 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository {
 		return nil
 	}
 
+	branches, err := git_model.FindBranchNames(ctx, git_model.FindBranchOptions{
+		RepoID: ctx.Repo.Repository.ID,
+		ListOptions: db.ListOptions{
+			ListAll: true,
+		},
+		IsDeletedBranch: util.OptionalBoolFalse,
+		// Add it as the first option
+		ExcludeBranchNames: []string{ctx.Repo.Repository.DefaultBranch},
+	})
+	if err != nil {
+		ctx.ServerError("FindBranchNames", err)
+		return nil
+	}
+	ctx.Data["Branches"] = append([]string{ctx.Repo.Repository.DefaultBranch}, branches...)
+
 	return forkRepo
 }
 
@@ -261,9 +276,10 @@ func ForkPost(ctx *context.Context) {
 	}
 
 	repo, err := repo_service.ForkRepository(ctx, ctx.Doer, ctxUser, repo_service.ForkRepoOptions{
-		BaseRepo:    forkRepo,
-		Name:        form.RepoName,
-		Description: form.Description,
+		BaseRepo:     forkRepo,
+		Name:         form.RepoName,
+		Description:  form.Description,
+		SingleBranch: form.ForkSingleBranch,
 	})
 	if err != nil {
 		ctx.Data["Err_RepoName"] = true
diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go
index b36c8cc9b6..5df7ec8fd6 100644
--- a/services/forms/repo_form.go
+++ b/services/forms/repo_form.go
@@ -51,6 +51,8 @@ type CreateRepoForm struct {
 	Labels          bool
 	ProtectedBranch bool
 	TrustModel      string
+
+	ForkSingleBranch string
 }
 
 // Validate validates the fields
diff --git a/services/repository/fork.go b/services/repository/fork.go
index 397e4cb909..d5ab42badd 100644
--- a/services/repository/fork.go
+++ b/services/repository/fork.go
@@ -44,9 +44,10 @@ func (err ErrForkAlreadyExist) Unwrap() error {
 
 // ForkRepoOptions contains the fork repository options
 type ForkRepoOptions struct {
-	BaseRepo    *repo_model.Repository
-	Name        string
-	Description string
+	BaseRepo     *repo_model.Repository
+	Name         string
+	Description  string
+	SingleBranch string
 }
 
 // ForkRepository forks a repository
@@ -70,6 +71,10 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
 		}
 	}
 
+	defaultBranch := opts.BaseRepo.DefaultBranch
+	if opts.SingleBranch != "" {
+		defaultBranch = opts.SingleBranch
+	}
 	repo := &repo_model.Repository{
 		OwnerID:       owner.ID,
 		Owner:         owner,
@@ -77,7 +82,7 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
 		Name:          opts.Name,
 		LowerName:     strings.ToLower(opts.Name),
 		Description:   opts.Description,
-		DefaultBranch: opts.BaseRepo.DefaultBranch,
+		DefaultBranch: defaultBranch,
 		IsPrivate:     opts.BaseRepo.IsPrivate || opts.BaseRepo.Owner.Visibility == structs.VisibleTypePrivate,
 		IsEmpty:       opts.BaseRepo.IsEmpty,
 		IsFork:        true,
@@ -134,9 +139,12 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
 
 		needsRollback = true
 
+		cloneCmd := git.NewCommand(txCtx, "clone", "--bare")
+		if opts.SingleBranch != "" {
+			cloneCmd.AddArguments("--single-branch", "--branch").AddDynamicArguments(opts.SingleBranch)
+		}
 		repoPath := repo_model.RepoPath(owner.Name, repo.Name)
-		if stdout, _, err := git.NewCommand(txCtx,
-			"clone", "--bare").AddDynamicArguments(oldRepoPath, repoPath).
+		if stdout, _, err := cloneCmd.AddDynamicArguments(oldRepoPath, repoPath).
 			SetDescription(fmt.Sprintf("ForkRepository(git clone): %s to %s", opts.BaseRepo.FullName(), repo.FullName())).
 			RunStdBytes(&git.RunOpts{Timeout: 10 * time.Minute}); err != nil {
 			log.Error("Fork Repository (git clone) Failed for %v (from %v):\nStdout: %s\nError: %v", repo, opts.BaseRepo, stdout, err)
diff --git a/templates/repo/pulls/fork.tmpl b/templates/repo/pulls/fork.tmpl
index 57d2269807..94de4d78eb 100644
--- a/templates/repo/pulls/fork.tmpl
+++ b/templates/repo/pulls/fork.tmpl
@@ -51,6 +51,26 @@
 						</div>
 						<span class="help">{{ctx.Locale.Tr "repo.fork_visibility_helper"}}</span>
 					</div>
+					<div class="inline field">
+						<label>{{ctx.Locale.Tr "repo.fork_branch"}}</label>
+						<div class="ui selection dropdown">
+							<input type="hidden" id="fork_single_branch" name="fork_single_branch" value="" required>
+							<span class="text truncated-item-container" data-value="" title="{{ctx.Locale.Tr "repo.all_branches"}}">
+								<span class="truncated-item-name">{{ctx.Locale.Tr "repo.all_branches"}}</span>
+							</span>
+							{{svg "octicon-triangle-down" 14 "dropdown icon"}}
+							<div class="menu">
+								<div class="item truncated-item-container" data-value="" title="{{ctx.Locale.Tr "repo.all_branches"}}">
+									<span class="truncated-item-name">{{ctx.Locale.Tr "repo.all_branches"}}</span>
+								</div>
+								{{range .Branches}}
+									<div class="item truncated-item-container" data-value="{{.}}" title="{{.}}">
+										<span class="truncated-item-name">{{.}}</span>
+									</div>
+								{{end}}
+							</div>
+						</div>
+					</div>
 					<div class="inline field {{if .Err_Description}}error{{end}}">
 						<label for="description">{{ctx.Locale.Tr "repo.repo_desc"}}</label>
 						<textarea id="description" name="description">{{.description}}</textarea>