Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hide git-annex branch #45

Open
wants to merge 13 commits into
base: git-annex
Choose a base branch
from
12 changes: 8 additions & 4 deletions .github/workflows/pull-db-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ jobs:
- name: Add hosts to /etc/hosts
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 pgsql ldap minio" | sudo tee -a /etc/hosts'
- run: make deps-backend
- run: sudo apt update && sudo DEBIAN_FRONTEND=noninteractive apt install -y git-annex
- run: make backend
env:
TAGS: bindata
- run: make test-pgsql-migration test-pgsql
- run: make test-pgsql-migration test-pgsql#TestGitAnnex
timeout-minutes: 50
env:
TAGS: bindata gogit
Expand All @@ -69,10 +70,11 @@ jobs:
go-version-file: go.mod
check-latest: true
- run: make deps-backend
- run: sudo apt update && sudo DEBIAN_FRONTEND=noninteractive apt install -y git-annex
- run: make backend
env:
TAGS: bindata gogit sqlite sqlite_unlock_notify
- run: make test-sqlite-migration test-sqlite
- run: make test-sqlite-migration test-sqlite#TestGitAnnex
timeout-minutes: 50
env:
TAGS: bindata gogit sqlite sqlite_unlock_notify
Expand Down Expand Up @@ -172,11 +174,12 @@ jobs:
- name: Add hosts to /etc/hosts
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mysql elasticsearch smtpimap" | sudo tee -a /etc/hosts'
- run: make deps-backend
- run: sudo apt update && sudo DEBIAN_FRONTEND=noninteractive apt install -y git-annex
- run: make backend
env:
TAGS: bindata
- name: run tests
run: make test-mysql-migration integration-test-coverage
run: make test-mysql-migration test-mysql#TestGitAnnex
env:
TAGS: bindata
RACE_ENABLED: true
Expand Down Expand Up @@ -205,10 +208,11 @@ jobs:
- name: Add hosts to /etc/hosts
run: '[ -e "/.dockerenv" ] || [ -e "/run/.containerenv" ] || echo "127.0.0.1 mssql" | sudo tee -a /etc/hosts'
- run: make deps-backend
- run: sudo apt update && sudo DEBIAN_FRONTEND=noninteractive apt install -y git-annex
- run: make backend
env:
TAGS: bindata
- run: make test-mssql-migration test-mssql
- run: make test-mssql-migration test-mssql#TestGitAnnex
timeout-minutes: 50
env:
TAGS: bindata
Expand Down
7 changes: 4 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ self := $(location)
@tmpdir=`mktemp --tmpdir -d` ; \
echo Using temporary directory $$tmpdir for test repositories ; \
USE_REPO_TEST_DIR= $(MAKE) -f $(self) --no-print-directory REPO_TEST_DIR=$$tmpdir/ $@ ; \
STATUS=$$? ; rm -r "$$tmpdir" ; exit $$STATUS
STATUS=$$? ; chmod -R +w "$$tmpdir" && rm -r "$$tmpdir" ; exit $$STATUS

else

Expand Down Expand Up @@ -114,8 +114,9 @@ LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(G
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64

GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./... | grep -v /vendor/))
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./... | grep -v /vendor/))

# Only test code modified in the git-annex feature branch; upstream can handle testing the full suite.
# This list was generated by `git diff --stat --name-only main.. -- '*.go' | xargs dirname | sort | uniq`
GO_TEST_PACKAGES ?= code.gitea.io/gitea/modules/annex code.gitea.io/gitea/modules/base code.gitea.io/gitea/modules/git code.gitea.io/gitea/modules/private code.gitea.io/gitea/modules/setting code.gitea.io/gitea/modules/util code.gitea.io/gitea/routers/private code.gitea.io/gitea/routers/web code.gitea.io/gitea/services/auth
FOMANTIC_WORK_DIR := web_src/fomantic

WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f)
Expand Down
2 changes: 1 addition & 1 deletion cmd/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ Gitea or set your environment appropriately.`, "")

func hookPrintResults(results []private.HookPostReceiveBranchResult) {
for _, res := range results {
if !res.Message {
if !res.Message || res.Branch == "git-annex" || strings.HasPrefix(res.Branch, "synced/") {
continue
}

Expand Down
72 changes: 67 additions & 5 deletions cmd/serv.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (

const (
lfsAuthenticateVerb = "git-lfs-authenticate"
gitAnnexShellVerb = "git-annex-shell"
)

// CmdServ represents the available serv sub-command.
Expand Down Expand Up @@ -89,6 +90,7 @@ var (
"git-upload-archive": perm.AccessModeRead,
"git-receive-pack": perm.AccessModeWrite,
lfsAuthenticateVerb: perm.AccessModeNone,
gitAnnexShellVerb: perm.AccessModeNone, // annex permissions are enforced by GIT_ANNEX_SHELL_READONLY, rather than the Gitea API
}
alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
)
Expand Down Expand Up @@ -201,6 +203,7 @@ func runServ(c *cli.Context) error {

verb := words[0]
repoPath := words[1]

if repoPath[0] == '/' {
repoPath = repoPath[1:]
}
Expand All @@ -216,9 +219,43 @@ func runServ(c *cli.Context) error {
}
}

if verb == gitAnnexShellVerb {
if !setting.Annex.Enabled {
return fail(ctx, "Unknown git command", "git-annex request over SSH denied, git-annex support is disabled")
}

if len(words) < 3 {
return fail(ctx, "Too few arguments", "Too few arguments in cmd: %s", cmd)
}

// git-annex always puts the repo in words[2], unlike most other
// git subcommands; and it sometimes names repos like /~/, as if
// $HOME should get expanded while also being rooted. e.g.:
// git-annex-shell 'configlist' '/~/user/repo'
// git-annex-shell 'sendkey' '/user/repo 'key'
repoPath = words[2]
repoPath = strings.TrimPrefix(repoPath, "/")
repoPath = strings.TrimPrefix(repoPath, "~/")
}

// LowerCase and trim the repoPath as that's how they are stored.
repoPath = strings.ToLower(strings.TrimSpace(repoPath))

// prevent directory traversal attacks
repoPath = filepath.Clean("/" + repoPath)[1:]

// put the sanitized repoPath back into the argument list for later
if verb == gitAnnexShellVerb {
// git-annex-shell demands an absolute path
absRepoPath, err := filepath.Abs(filepath.Join(setting.RepoRootPath, repoPath))
if err != nil {
return fail(ctx, "Error locating repoPath", "%v", err)
}
words[2] = absRepoPath
} else {
words[1] = repoPath
}

rr := strings.SplitN(repoPath, "/", 2)
if len(rr) != 2 {
return fail(ctx, "Invalid repository path", "Invalid repository path: %v", repoPath)
Expand Down Expand Up @@ -305,21 +342,46 @@ func runServ(c *cli.Context) error {
return nil
}

var gitcmd *exec.Cmd
gitBinPath := filepath.Dir(git.GitExecutable) // e.g. /usr/bin
gitBinVerb := filepath.Join(gitBinPath, verb) // e.g. /usr/bin/git-upload-pack
if _, err := os.Stat(gitBinVerb); err != nil {
// if the command "git-upload-pack" doesn't exist, try to split "git-upload-pack" to use the sub-command with git
// ps: Windows only has "git.exe" in the bin path, so Windows always uses this way
// ps: git-annex-shell and other extensions may not necessarily be in gitBinPath,
// but '{gitBinPath}/git annex-shell' should be able to find them on $PATH.
verbFields := strings.SplitN(verb, "-", 2)
if len(verbFields) == 2 {
// use git binary with the sub-command part: "C:\...\bin\git.exe", "upload-pack", ...
gitcmd = exec.CommandContext(ctx, git.GitExecutable, verbFields[1], repoPath)
gitBinVerb = git.GitExecutable
words = append([]string{verbFields[1]}, words...)
}
}
if gitcmd == nil {
// by default, use the verb (it has been checked above by allowedCommands)
gitcmd = exec.CommandContext(ctx, gitBinVerb, repoPath)

// by default, use the verb (it has been checked above by allowedCommands)
gitcmd := exec.CommandContext(ctx, gitBinVerb, words[1:]...)

if verb == gitAnnexShellVerb {
// This doesn't get its own isolated section like LFS does, because LFS
// is handled by internal Gitea routines, but git-annex has to be shelled out
// to like other git subcommands, so we need to build up gitcmd.

// TODO: does this work on Windows?
gitcmd.Env = append(gitcmd.Env,
// "If set, disallows running git-shell to handle unknown commands."
// - git-annex-shell(1)
"GIT_ANNEX_SHELL_LIMITED=True",
// "If set, git-annex-shell will refuse to run commands
// that do not operate on the specified directory."
// - git-annex-shell(1)
fmt.Sprintf("GIT_ANNEX_SHELL_DIRECTORY=%s", words[2]),
)
if results.UserMode < perm.AccessModeWrite {
// "If set, disallows any action that could modify the git-annex repository."
// - git-annex-shell(1)
// We set this when the backend API has told us that we don't have write permission to this repo.
log.Debug("Setting GIT_ANNEX_SHELL_READONLY=True")
gitcmd.Env = append(gitcmd.Env, "GIT_ANNEX_SHELL_READONLY=True")
}
}

process.SetSysProcAttribute(gitcmd)
Expand Down
4 changes: 4 additions & 0 deletions cmd/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,10 @@ func listen(m http.Handler, handleRedirector bool) error {
log.Info("LFS server enabled")
}

if setting.Annex.Enabled {
log.Info("git-annex enabled")
}

var err error
switch setting.Protocol {
case setting.HTTP:
Expand Down
9 changes: 9 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2520,6 +2520,15 @@ LEVEL = Info
;; override the minio base path if storage type is minio
;MINIO_BASE_PATH = lfs/

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[annex]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Whether git-annex is enabled; defaults to false
;ENABLED = false

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; settings for packages, will override storage setting
Expand Down
5 changes: 5 additions & 0 deletions models/activities/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,11 @@ func activityQueryCondition(ctx context.Context, opts GetFeedsOptions) (builder.
}
}

// Hide actions related to the git-annex branch
cond = cond.And(builder.Neq{"ref_name": git.BranchPrefix + "git-annex"})
// Hide actions related to git-annex's synced/* branches
cond = cond.And(builder.Not{builder.Like{"ref_name", git.BranchPrefix + "synced/%"}})

return cond, nil
}

Expand Down
2 changes: 2 additions & 0 deletions models/git/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,8 @@ func FindRecentlyPushedNewBranches(ctx context.Context, repoID, userID int64, ex
err := db.GetEngine(ctx).
Where("pusher_id=? AND is_deleted=?", userID, false).
And("name <> ?", excludeBranchName).
And("name <> ?", "git-annex").
And("NOT name LIKE ?", "synced/%").
And("repo_id = ?", repoID).
And("commit_time >= ?", time.Now().Add(-time.Hour*6).Unix()).
NotIn("name", subQuery).
Expand Down
5 changes: 5 additions & 0 deletions models/git/branch_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ func (opts *FindBranchOptions) Cond() builder.Cond {
cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
}

// Hide the git-annex branch if it exists
cond = cond.And(builder.Neq{"name": "git-annex"})
// Hide synced/* branches that git-annex might have created
cond = cond.And(builder.Not{builder.Like{"name", "synced/%"}})

if len(opts.ExcludeBranchNames) > 0 {
cond = cond.And(builder.NotIn("name", opts.ExcludeBranchNames))
}
Expand Down
Loading