diff --git a/build.go b/build.go
index b843465dca612..aa561413407bc 100644
--- a/build.go
+++ b/build.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
-//+build vendor
+//go:build vendor
+// +build vendor
 
 package main
 
diff --git a/build/generate-bindata.go b/build/generate-bindata.go
index fa1669fcf9fb1..efd172f779aac 100644
--- a/build/generate-bindata.go
+++ b/build/generate-bindata.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 package main
diff --git a/build/generate-emoji.go b/build/generate-emoji.go
index c97d865bdc294..da4e12373ce09 100644
--- a/build/generate-emoji.go
+++ b/build/generate-emoji.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build ignore
 // +build ignore
 
 package main
diff --git a/build/generate-gitignores.go b/build/generate-gitignores.go
index 846bb076365d2..d0b972e803e00 100644
--- a/build/generate-gitignores.go
+++ b/build/generate-gitignores.go
@@ -1,3 +1,4 @@
+//go:build ignore
 // +build ignore
 
 package main
diff --git a/build/generate-licenses.go b/build/generate-licenses.go
index 9dd13adf9a7bc..4009a0351d60a 100644
--- a/build/generate-licenses.go
+++ b/build/generate-licenses.go
@@ -1,3 +1,4 @@
+//go:build ignore
 // +build ignore
 
 package main
diff --git a/build/gocovmerge.go b/build/gocovmerge.go
index 65d6f2cd6ccc3..b38cf5ea3d5ce 100644
--- a/build/gocovmerge.go
+++ b/build/gocovmerge.go
@@ -6,6 +6,7 @@
 // gocovmerge takes the results from multiple `go test -coverprofile` runs and
 // merges them into one profile
 
+//go:build ignore
 // +build ignore
 
 package main
diff --git a/cmd/embedded.go b/cmd/embedded.go
index 528f32402e1a2..2aeaba4786fc4 100644
--- a/cmd/embedded.go
+++ b/cmd/embedded.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build bindata
 // +build bindata
 
 package cmd
diff --git a/cmd/embedded_stub.go b/cmd/embedded_stub.go
index 1f9af7b86b123..0e9e3e6ec3e14 100644
--- a/cmd/embedded_stub.go
+++ b/cmd/embedded_stub.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !bindata
 // +build !bindata
 
 package cmd
diff --git a/modules/auth/pam/pam.go b/modules/auth/pam/pam.go
index f21602c6b5663..73ecae0c2c29f 100644
--- a/modules/auth/pam/pam.go
+++ b/modules/auth/pam/pam.go
@@ -1,9 +1,10 @@
-// +build pam
-
 // Copyright 2014 The Gogs Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build pam
+// +build pam
+
 package pam
 
 import (
diff --git a/modules/auth/pam/pam_stub.go b/modules/auth/pam/pam_stub.go
index 02d8da3c57ad2..815ccf2b0e2db 100644
--- a/modules/auth/pam/pam_stub.go
+++ b/modules/auth/pam/pam_stub.go
@@ -1,9 +1,10 @@
-// +build !pam
-
 // Copyright 2014 The Gogs Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !pam
+// +build !pam
+
 package pam
 
 import (
diff --git a/modules/auth/pam/pam_test.go b/modules/auth/pam/pam_test.go
index fa16ff0fe78cd..d6d78a748b7aa 100644
--- a/modules/auth/pam/pam_test.go
+++ b/modules/auth/pam/pam_test.go
@@ -1,3 +1,4 @@
+//go:build pam
 // +build pam
 
 // Copyright 2021 The Gitea Authors. All rights reserved.
diff --git a/modules/git/blob_gogit.go b/modules/git/blob_gogit.go
index 7a82eb5c3706f..ef7a90c3f40b8 100644
--- a/modules/git/blob_gogit.go
+++ b/modules/git/blob_gogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/blob_nogogit.go b/modules/git/blob_nogogit.go
index 5b42920ebe1d4..26815a63f1abb 100644
--- a/modules/git/blob_nogogit.go
+++ b/modules/git/blob_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/command_test.go b/modules/git/command_test.go
index 00801ae31ff25..58d616a0385d5 100644
--- a/modules/git/command_test.go
+++ b/modules/git/command_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build race
 // +build race
 
 package git
diff --git a/modules/git/commit_convert_gogit.go b/modules/git/commit_convert_gogit.go
index be2b948b363f3..b328b3c0edfb7 100644
--- a/modules/git/commit_convert_gogit.go
+++ b/modules/git/commit_convert_gogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/commit_info_gogit.go b/modules/git/commit_info_gogit.go
index a8006dcef2e64..8b82f3f66cbae 100644
--- a/modules/git/commit_info_gogit.go
+++ b/modules/git/commit_info_gogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/commit_info_nogogit.go b/modules/git/commit_info_nogogit.go
index 060ecba26190b..f57355d16ed40 100644
--- a/modules/git/commit_info_nogogit.go
+++ b/modules/git/commit_info_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/last_commit_cache_gogit.go b/modules/git/last_commit_cache_gogit.go
index b8e0db46a9265..fb09af6f2a762 100644
--- a/modules/git/last_commit_cache_gogit.go
+++ b/modules/git/last_commit_cache_gogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/last_commit_cache_nogogit.go b/modules/git/last_commit_cache_nogogit.go
index faf6e23fa8166..f71e7350a1fec 100644
--- a/modules/git/last_commit_cache_nogogit.go
+++ b/modules/git/last_commit_cache_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/notes_gogit.go b/modules/git/notes_gogit.go
index 9da45ca65c25d..84f66d86bf67b 100644
--- a/modules/git/notes_gogit.go
+++ b/modules/git/notes_gogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/notes_nogogit.go b/modules/git/notes_nogogit.go
index 697f998288f5d..9a54b4810638e 100644
--- a/modules/git/notes_nogogit.go
+++ b/modules/git/notes_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/parse_gogit.go b/modules/git/parse_gogit.go
index a50ebec3dd72b..c42e32929e457 100644
--- a/modules/git/parse_gogit.go
+++ b/modules/git/parse_gogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/parse_gogit_test.go b/modules/git/parse_gogit_test.go
index c6374133c0951..c27f5172d5e46 100644
--- a/modules/git/parse_gogit_test.go
+++ b/modules/git/parse_gogit_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/parse_nogogit.go b/modules/git/parse_nogogit.go
index 667111ec4a313..dd5554b5dd747 100644
--- a/modules/git/parse_nogogit.go
+++ b/modules/git/parse_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/parse_nogogit_test.go b/modules/git/parse_nogogit_test.go
index 502c38d4e8d9f..5f58237de832e 100644
--- a/modules/git/parse_nogogit_test.go
+++ b/modules/git/parse_nogogit_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/pipeline/lfs.go b/modules/git/pipeline/lfs.go
index d47b7d91ea86c..46a48b710c6f9 100644
--- a/modules/git/pipeline/lfs.go
+++ b/modules/git/pipeline/lfs.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package pipeline
diff --git a/modules/git/pipeline/lfs_nogogit.go b/modules/git/pipeline/lfs_nogogit.go
index d3696fcda219c..a441e37b60e1e 100644
--- a/modules/git/pipeline/lfs_nogogit.go
+++ b/modules/git/pipeline/lfs_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package pipeline
diff --git a/modules/git/repo.go b/modules/git/repo.go
index f2bbbf4716e95..e7d42dacb165d 100644
--- a/modules/git/repo.go
+++ b/modules/git/repo.go
@@ -13,6 +13,7 @@ import (
 	"net/url"
 	"os"
 	"path"
+	"path/filepath"
 	"strconv"
 	"strings"
 	"time"
@@ -415,3 +416,33 @@ func GetDivergingCommits(repoPath string, baseBranch string, targetBranch string
 
 	return DivergeObject{ahead, behind}, nil
 }
+
+// CreateBundle create bundle content to the target path
+func (repo *Repository) CreateBundle(ctx context.Context, commit string, out io.Writer) error {
+	tmp, err := os.MkdirTemp(os.TempDir(), "gitea-bundle")
+	if err != nil {
+		return err
+	}
+	defer os.RemoveAll(tmp)
+
+	tmpFile := filepath.Join(tmp, "bundle")
+	args := []string{
+		"bundle",
+		"create",
+		tmpFile,
+		commit,
+	}
+	_, err = NewCommandContext(ctx, args...).RunInDir(repo.Path)
+	if err != nil {
+		return err
+	}
+
+	fi, err := os.Open(tmpFile)
+	if err != nil {
+		return err
+	}
+	defer fi.Close()
+
+	_, err = io.Copy(out, fi)
+	return err
+}
diff --git a/modules/git/repo_archive.go b/modules/git/repo_archive.go
index 07003aa6b2c13..83df082ad3da5 100644
--- a/modules/git/repo_archive.go
+++ b/modules/git/repo_archive.go
@@ -21,6 +21,8 @@ const (
 	ZIP ArchiveType = iota + 1
 	// TARGZ tar gz archive type
 	TARGZ
+	// BUNDLE bundle archive type
+	BUNDLE
 )
 
 // String converts an ArchiveType to string
@@ -30,6 +32,8 @@ func (a ArchiveType) String() string {
 		return "zip"
 	case TARGZ:
 		return "tar.gz"
+	case BUNDLE:
+		return "bundle"
 	}
 	return "unknown"
 }
diff --git a/modules/git/repo_base_gogit.go b/modules/git/repo_base_gogit.go
index 6186824c0b9f6..afa5383b1164b 100644
--- a/modules/git/repo_base_gogit.go
+++ b/modules/git/repo_base_gogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/repo_base_nogogit.go b/modules/git/repo_base_nogogit.go
index 1675967d181bc..22c4dfdcb3b8d 100644
--- a/modules/git/repo_base_nogogit.go
+++ b/modules/git/repo_base_nogogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/repo_blob_gogit.go b/modules/git/repo_blob_gogit.go
index 485c233ff8914..b11e9f58fe9bf 100644
--- a/modules/git/repo_blob_gogit.go
+++ b/modules/git/repo_blob_gogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/repo_blob_nogogit.go b/modules/git/repo_blob_nogogit.go
index afb08d29cb982..775b3835dd5de 100644
--- a/modules/git/repo_blob_nogogit.go
+++ b/modules/git/repo_blob_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/repo_branch_gogit.go b/modules/git/repo_branch_gogit.go
index e8386b2dbd98f..6bf14b3999865 100644
--- a/modules/git/repo_branch_gogit.go
+++ b/modules/git/repo_branch_gogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/repo_branch_nogogit.go b/modules/git/repo_branch_nogogit.go
index 7d10b8ba0faeb..666ca81c1e8f8 100644
--- a/modules/git/repo_branch_nogogit.go
+++ b/modules/git/repo_branch_nogogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/repo_commit_gogit.go b/modules/git/repo_commit_gogit.go
index 2f9b1c4206f42..175b6e644660c 100644
--- a/modules/git/repo_commit_gogit.go
+++ b/modules/git/repo_commit_gogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/repo_commit_nogogit.go b/modules/git/repo_commit_nogogit.go
index afd5166f1d549..b7e49a6501b17 100644
--- a/modules/git/repo_commit_nogogit.go
+++ b/modules/git/repo_commit_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/repo_commitgraph_gogit.go b/modules/git/repo_commitgraph_gogit.go
index 67731094513cc..84a2edb664bb4 100644
--- a/modules/git/repo_commitgraph_gogit.go
+++ b/modules/git/repo_commitgraph_gogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/repo_language_stats_gogit.go b/modules/git/repo_language_stats_gogit.go
index 20a7b061f2107..0a4cfbbc7bfb9 100644
--- a/modules/git/repo_language_stats_gogit.go
+++ b/modules/git/repo_language_stats_gogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/repo_language_stats_nogogit.go b/modules/git/repo_language_stats_nogogit.go
index 1684f21d1675d..7425e2dbb1d1b 100644
--- a/modules/git/repo_language_stats_nogogit.go
+++ b/modules/git/repo_language_stats_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/repo_ref_gogit.go b/modules/git/repo_ref_gogit.go
index 2e83e6c4627be..9f0e11366f677 100644
--- a/modules/git/repo_ref_gogit.go
+++ b/modules/git/repo_ref_gogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/repo_ref_nogogit.go b/modules/git/repo_ref_nogogit.go
index 540961592b4c0..ec0c5ec4cad30 100644
--- a/modules/git/repo_ref_nogogit.go
+++ b/modules/git/repo_ref_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/repo_tag_gogit.go b/modules/git/repo_tag_gogit.go
index 3ac097c9a8c2c..3022fe96f7772 100644
--- a/modules/git/repo_tag_gogit.go
+++ b/modules/git/repo_tag_gogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/repo_tag_nogogit.go b/modules/git/repo_tag_nogogit.go
index a9e122aeaa7d6..0170f0cc76e7d 100644
--- a/modules/git/repo_tag_nogogit.go
+++ b/modules/git/repo_tag_nogogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/repo_tree_gogit.go b/modules/git/repo_tree_gogit.go
index d878f5e7a7258..2ddffcf79b679 100644
--- a/modules/git/repo_tree_gogit.go
+++ b/modules/git/repo_tree_gogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/repo_tree_nogogit.go b/modules/git/repo_tree_nogogit.go
index 967f8aea3f44d..9d4268b13a286 100644
--- a/modules/git/repo_tree_nogogit.go
+++ b/modules/git/repo_tree_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/sha1_gogit.go b/modules/git/sha1_gogit.go
index 5953af58bfcc3..30290f14b7385 100644
--- a/modules/git/sha1_gogit.go
+++ b/modules/git/sha1_gogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/sha1_nogogit.go b/modules/git/sha1_nogogit.go
index 09b5baacd5c98..53665fc9217d3 100644
--- a/modules/git/sha1_nogogit.go
+++ b/modules/git/sha1_nogogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/signature_gogit.go b/modules/git/signature_gogit.go
index 804c0074d351c..903a48133f80d 100644
--- a/modules/git/signature_gogit.go
+++ b/modules/git/signature_gogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/signature_nogogit.go b/modules/git/signature_nogogit.go
index 753d87b6059f1..c6fe8e6d1a99e 100644
--- a/modules/git/signature_nogogit.go
+++ b/modules/git/signature_nogogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/tree_blob_gogit.go b/modules/git/tree_blob_gogit.go
index 93ebc8a367da4..a8d619cd18ed6 100644
--- a/modules/git/tree_blob_gogit.go
+++ b/modules/git/tree_blob_gogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/tree_blob_nogogit.go b/modules/git/tree_blob_nogogit.go
index fdd8d79c8b632..df23ff01b474b 100644
--- a/modules/git/tree_blob_nogogit.go
+++ b/modules/git/tree_blob_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/tree_entry_gogit.go b/modules/git/tree_entry_gogit.go
index 219251a77e42c..20e767eea1f72 100644
--- a/modules/git/tree_entry_gogit.go
+++ b/modules/git/tree_entry_gogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/tree_entry_nogogit.go b/modules/git/tree_entry_nogogit.go
index 41356ceba2326..288ec4db6e194 100644
--- a/modules/git/tree_entry_nogogit.go
+++ b/modules/git/tree_entry_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/git/tree_entry_test.go b/modules/git/tree_entry_test.go
index 3382de41028d6..402c345887f8d 100644
--- a/modules/git/tree_entry_test.go
+++ b/modules/git/tree_entry_test.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/tree_gogit.go b/modules/git/tree_gogit.go
index 79132c5548a92..bc020883660d7 100644
--- a/modules/git/tree_gogit.go
+++ b/modules/git/tree_gogit.go
@@ -3,6 +3,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package git
diff --git a/modules/git/tree_nogogit.go b/modules/git/tree_nogogit.go
index 9661d8faea158..3d3fd26ece768 100644
--- a/modules/git/tree_nogogit.go
+++ b/modules/git/tree_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package git
diff --git a/modules/graceful/manager_unix.go b/modules/graceful/manager_unix.go
index 20d9b3905c4fb..fcbb16a3bb96f 100644
--- a/modules/graceful/manager_unix.go
+++ b/modules/graceful/manager_unix.go
@@ -1,9 +1,10 @@
-// +build !windows
-
 // Copyright 2019 The Gitea Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows
+// +build !windows
+
 package graceful
 
 import (
diff --git a/modules/graceful/manager_windows.go b/modules/graceful/manager_windows.go
index 51f29778ba7af..e5f5541ed3c3c 100644
--- a/modules/graceful/manager_windows.go
+++ b/modules/graceful/manager_windows.go
@@ -1,10 +1,11 @@
-// +build windows
-
 // Copyright 2019 The Gitea Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 // This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
 
+//go:build windows
+// +build windows
+
 package graceful
 
 import (
diff --git a/modules/graceful/net_unix.go b/modules/graceful/net_unix.go
index 2dc714955e1ed..6ffa8150cc1a4 100644
--- a/modules/graceful/net_unix.go
+++ b/modules/graceful/net_unix.go
@@ -1,10 +1,11 @@
-// +build !windows
-
 // Copyright 2019 The Gitea Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 // This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
 
+//go:build !windows
+// +build !windows
+
 package graceful
 
 import (
diff --git a/modules/graceful/net_windows.go b/modules/graceful/net_windows.go
index 3fc14334912a0..35b7a9d1feae3 100644
--- a/modules/graceful/net_windows.go
+++ b/modules/graceful/net_windows.go
@@ -1,10 +1,11 @@
-// +build windows
-
 // Copyright 2019 The Gitea Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 // This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
 
+//go:build windows
+// +build windows
+
 package graceful
 
 import "net"
diff --git a/modules/graceful/restart_unix.go b/modules/graceful/restart_unix.go
index 9a94e5fa677bd..392ed60cb381b 100644
--- a/modules/graceful/restart_unix.go
+++ b/modules/graceful/restart_unix.go
@@ -1,10 +1,11 @@
-// +build !windows
-
 // Copyright 2019 The Gitea Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 // This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
 
+//go:build !windows
+// +build !windows
+
 package graceful
 
 import (
diff --git a/modules/lfs/pointer_scanner_gogit.go b/modules/lfs/pointer_scanner_gogit.go
index abd882990c137..7e8b812f466de 100644
--- a/modules/lfs/pointer_scanner_gogit.go
+++ b/modules/lfs/pointer_scanner_gogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gogit
 // +build gogit
 
 package lfs
diff --git a/modules/lfs/pointer_scanner_nogogit.go b/modules/lfs/pointer_scanner_nogogit.go
index b5654d5de751e..d8076b90216f2 100644
--- a/modules/lfs/pointer_scanner_nogogit.go
+++ b/modules/lfs/pointer_scanner_nogogit.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !gogit
 // +build !gogit
 
 package lfs
diff --git a/modules/options/dynamic.go b/modules/options/dynamic.go
index ffb89df88274b..13fa5d6aa7ebd 100644
--- a/modules/options/dynamic.go
+++ b/modules/options/dynamic.go
@@ -1,9 +1,10 @@
-// +build !bindata
-
 // Copyright 2016 The Gitea Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !bindata
+// +build !bindata
+
 package options
 
 import (
diff --git a/modules/options/options_bindata.go b/modules/options/options_bindata.go
index 262bd0de3e093..64da772c6fbb3 100644
--- a/modules/options/options_bindata.go
+++ b/modules/options/options_bindata.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
-//+build bindata
+//go:build bindata
+// +build bindata
 
 package options
 
diff --git a/modules/options/static.go b/modules/options/static.go
index 5f4ffdda78e49..49e8445cd5950 100644
--- a/modules/options/static.go
+++ b/modules/options/static.go
@@ -1,9 +1,10 @@
-// +build bindata
-
 // Copyright 2016 The Gitea Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build bindata
+// +build bindata
+
 package options
 
 import (
diff --git a/modules/public/dynamic.go b/modules/public/dynamic.go
index 0bfe38bc3f3f1..955c01e510313 100644
--- a/modules/public/dynamic.go
+++ b/modules/public/dynamic.go
@@ -1,9 +1,10 @@
-// +build !bindata
-
 // Copyright 2016 The Gitea Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !bindata
+// +build !bindata
+
 package public
 
 import (
diff --git a/modules/public/public_bindata.go b/modules/public/public_bindata.go
index 05648aea80939..eb10d96426bf1 100644
--- a/modules/public/public_bindata.go
+++ b/modules/public/public_bindata.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
-//+build bindata
+//go:build bindata
+// +build bindata
 
 package public
 
diff --git a/modules/public/static.go b/modules/public/static.go
index 827dc2a1e0e8d..6994ed6508574 100644
--- a/modules/public/static.go
+++ b/modules/public/static.go
@@ -1,9 +1,10 @@
-// +build bindata
-
 // Copyright 2016 The Gitea Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build bindata
+// +build bindata
+
 package public
 
 import (
diff --git a/modules/setting/database_sqlite.go b/modules/setting/database_sqlite.go
index 623326ddc2fc1..798292fec86bc 100644
--- a/modules/setting/database_sqlite.go
+++ b/modules/setting/database_sqlite.go
@@ -1,3 +1,4 @@
+//go:build sqlite
 // +build sqlite
 
 // Copyright 2014 The Gogs Authors. All rights reserved.
diff --git a/modules/svg/discover_bindata.go b/modules/svg/discover_bindata.go
index 1f7af0c9f89d5..e11951ff7ec97 100644
--- a/modules/svg/discover_bindata.go
+++ b/modules/svg/discover_bindata.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build bindata
 // +build bindata
 
 package svg
diff --git a/modules/svg/discover_nobindata.go b/modules/svg/discover_nobindata.go
index d667da2d660ca..8d857551dc47e 100644
--- a/modules/svg/discover_nobindata.go
+++ b/modules/svg/discover_nobindata.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !bindata
 // +build !bindata
 
 package svg
diff --git a/modules/templates/dynamic.go b/modules/templates/dynamic.go
index 160e4e05f2501..4732fce421fa7 100644
--- a/modules/templates/dynamic.go
+++ b/modules/templates/dynamic.go
@@ -1,9 +1,10 @@
-// +build !bindata
-
 // Copyright 2016 The Gitea Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !bindata
+// +build !bindata
+
 package templates
 
 import (
diff --git a/modules/templates/static.go b/modules/templates/static.go
index 7f95d77ad3242..ee20b2af3b3a5 100644
--- a/modules/templates/static.go
+++ b/modules/templates/static.go
@@ -1,9 +1,10 @@
-// +build bindata
-
 // Copyright 2016 The Gitea Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build bindata
+// +build bindata
+
 package templates
 
 import (
diff --git a/modules/templates/templates_bindata.go b/modules/templates/templates_bindata.go
index 5a59286c7a98a..887f9eeba25b9 100644
--- a/modules/templates/templates_bindata.go
+++ b/modules/templates/templates_bindata.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
-//+build bindata
+//go:build bindata
+// +build bindata
 
 package templates
 
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 3eb38257768a4..e5561b6d72250 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -771,6 +771,7 @@ use_template = Use this template
 clone_in_vsc = Clone in VS Code
 download_zip = Download ZIP
 download_tar = Download TAR.GZ
+download_bundle = Download BUNDLE
 generate_repo = Generate Repository
 generate_from = Generate From
 repo_desc = Description
diff --git a/routers/private/manager_unix.go b/routers/private/manager_unix.go
index 60ae9b68e82ca..1738c06a05fb0 100644
--- a/routers/private/manager_unix.go
+++ b/routers/private/manager_unix.go
@@ -1,9 +1,10 @@
-// +build !windows
-
 // Copyright 2020 The Gitea Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows
+// +build !windows
+
 package private
 
 import (
diff --git a/routers/private/manager_windows.go b/routers/private/manager_windows.go
index f6c9b7ec8ff25..a8a477313fb02 100644
--- a/routers/private/manager_windows.go
+++ b/routers/private/manager_windows.go
@@ -1,9 +1,10 @@
-// +build windows
-
 // Copyright 2020 The Gitea Authors. All rights reserved.
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build windows
+// +build windows
+
 package private
 
 import (
diff --git a/services/archiver/archiver.go b/services/archiver/archiver.go
index 00c0281306814..7ae0a94d7ecac 100644
--- a/services/archiver/archiver.go
+++ b/services/archiver/archiver.go
@@ -54,6 +54,9 @@ func NewRequest(repoID int64, repo *git.Repository, uri string) (*ArchiveRequest
 	case strings.HasSuffix(uri, ".tar.gz"):
 		ext = ".tar.gz"
 		r.Type = git.TARGZ
+	case strings.HasSuffix(uri, ".bundle"):
+		ext = ".bundle"
+		r.Type = git.BUNDLE
 	default:
 		return nil, fmt.Errorf("Unknown format: %s", uri)
 	}
@@ -165,13 +168,21 @@ func doArchive(r *ArchiveRequest) (*models.RepoArchiver, error) {
 			}
 		}()
 
-		err = gitRepo.CreateArchive(
-			graceful.GetManager().ShutdownContext(),
-			archiver.Type,
-			w,
-			setting.Repository.PrefixArchiveFiles,
-			archiver.CommitID,
-		)
+		if archiver.Type == git.BUNDLE {
+			err = gitRepo.CreateBundle(
+				graceful.GetManager().ShutdownContext(),
+				archiver.CommitID,
+				w,
+			)
+		} else {
+			err = gitRepo.CreateArchive(
+				graceful.GetManager().ShutdownContext(),
+				archiver.Type,
+				w,
+				setting.Repository.PrefixArchiveFiles,
+				archiver.CommitID,
+			)
+		}
 		_ = w.CloseWithError(err)
 		done <- err
 	}(done, w, archiver, gitRepo)
diff --git a/services/auth/placeholder.go b/services/auth/placeholder.go
index 50e3061885f80..d9a0ceae7c45a 100644
--- a/services/auth/placeholder.go
+++ b/services/auth/placeholder.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build !windows
 // +build !windows
 
 package auth
diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl
index 5629c7ee121fd..0c377251fa3f6 100644
--- a/templates/repo/home.tmpl
+++ b/templates/repo/home.tmpl
@@ -118,6 +118,7 @@
 								</a>
 								<a class="item archive-link" data-url="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.zip">{{svg "octicon-file-zip"}}&nbsp;{{.i18n.Tr "repo.download_zip"}}</a>
 								<a class="item archive-link" data-url="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.tar.gz">{{svg "octicon-file-zip"}}&nbsp;{{.i18n.Tr "repo.download_tar"}}</a>
+								<a class="item archive-link" data-url="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.bundle">{{svg "octicon-package"}}&nbsp;{{.i18n.Tr "repo.download_bundle"}}</a>
 							</div>
 						</button>
 					</div>
diff --git a/tools/fuzz.go b/tools/fuzz.go
index ca35ff4f00826..2f980b3b895fd 100644
--- a/tools/fuzz.go
+++ b/tools/fuzz.go
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
+//go:build gofuzz
 // +build gofuzz
 
 package fuzz