diff --git a/.forgejo/workflows-composite/apt-install-from/action.yaml b/.forgejo/workflows-composite/apt-install-from/action.yaml
index ab55883..615e7cb 100644
--- a/.forgejo/workflows-composite/apt-install-from/action.yaml
+++ b/.forgejo/workflows-composite/apt-install-from/action.yaml
@@ -13,8 +13,6 @@ runs:
run: |
export DEBIAN_FRONTEND=noninteractive
echo "deb http://deb.debian.org/debian/ ${RELEASE} main" > "/etc/apt/sources.list.d/${RELEASE}.list"
- wget -O- http://neuro.debian.net/lists/bookworm.de-fzj.libre | tee /etc/apt/sources.list.d/neurodebian.sources.list
- apt-key adv --recv-keys --keyserver hkps://keyserver.ubuntu.com 0xA5D32F012649A5A9
env:
RELEASE: ${{inputs.release}}
- name: install packages
@@ -26,7 +24,6 @@ runs:
- name: remove temporary package list to prevent using it in other steps
run: |
rm "/etc/apt/sources.list.d/${RELEASE}.list"
- rm "/etc/apt/sources.list.d/neurodebian.sources.list"
apt-get update -qq
env:
RELEASE: ${{inputs.release}}
diff --git a/.forgejo/workflows/build-oci-image.yml b/.forgejo/workflows/build-oci-image.yml
deleted file mode 100644
index 8e843b4..0000000
--- a/.forgejo/workflows/build-oci-image.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-on:
- push:
- branches:
- - 'forgejo'
- tags:
- - '*-git-annex*'
-
-jobs:
- build-oci-image:
- runs-on: docker
- strategy:
- matrix:
- type: ["rootful", "rootless"]
- steps:
- - uses: actions/checkout@v4
- with:
- fetch-depth: 0 # fetch the full history so that the Forgejo version is determined properly
- - name: Determine registry and username
- id: determine-registry-and-username
- run: |
- echo "registry=${GITHUB_SERVER_URL#https://}" >> "$GITHUB_OUTPUT"
- echo "username=${GITHUB_REPOSITORY%/*}" >> "$GITHUB_OUTPUT"
- - name: Install Docker
- run: curl -fsSL https://get.docker.com | sh
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v3
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
- - name: Login to Docker Hub
- uses: docker/login-action@v3
- with:
- registry: ${{ steps.determine-registry-and-username.outputs.registry }}
- username: ${{ steps.determine-registry-and-username.outputs.username }}
- password: ${{ secrets.REGISTRY_TOKEN }}
- - name: Build and push
- uses: docker/build-push-action@v6
- with:
- context: .
- file: ${{ (matrix.type == 'rootful' && 'Dockerfile') || (matrix.type == 'rootless' && 'Dockerfile.rootless') }}
- push: true
- tags: ${{ steps.determine-registry-and-username.outputs.registry }}/${{ github.repository }}:${{ github.ref_name }}${{ (matrix.type == 'rootful' && ' ') || (matrix.type == 'rootless' && '-rootless') }}
diff --git a/.forgejo/workflows/testing.yml b/.forgejo/workflows/testing.yml
index a93ca78..784bc45 100644
--- a/.forgejo/workflows/testing.yml
+++ b/.forgejo/workflows/testing.yml
@@ -10,6 +10,7 @@ on:
jobs:
backend-checks:
+ if: vars.ROLE == 'forgejo-coding' || vars.ROLE == 'forgejo-testing'
runs-on: docker
container:
image: 'data.forgejo.org/oci/node:20-bookworm'
@@ -26,6 +27,7 @@ jobs:
- run: su forgejo -c 'make --always-make -j$(nproc) lint-backend tidy-check swagger-check fmt-check swagger-validate' # ensure the "go-licenses" make target runs
- uses: ./.forgejo/workflows-composite/build-backend
frontend-checks:
+ if: vars.ROLE == 'forgejo-coding' || vars.ROLE == 'forgejo-testing'
runs-on: docker
container:
image: 'data.forgejo.org/oci/node:20-bookworm'
@@ -174,6 +176,7 @@ jobs:
TAGS: bindata
TEST_REDIS_SERVER: cacher:${{ matrix.cacher.port }}
test-mysql:
+ if: vars.ROLE == 'forgejo-coding' || vars.ROLE == 'forgejo-testing'
runs-on: docker
needs: [backend-checks, frontend-checks]
container:
@@ -196,13 +199,15 @@ jobs:
- name: install dependencies & git >= 2.42
uses: ./.forgejo/workflows-composite/apt-install-from
with:
- packages: git git-annex-standalone git-lfs
+ packages: git git-lfs
- uses: ./.forgejo/workflows-composite/build-backend
- run: |
su forgejo -c 'make test-mysql-migration test-mysql'
+ timeout-minutes: 120
env:
USE_REPO_TEST_DIR: 1
test-pgsql:
+ if: vars.ROLE == 'forgejo-coding' || vars.ROLE == 'forgejo-testing'
runs-on: docker
needs: [backend-checks, frontend-checks]
container:
@@ -231,15 +236,17 @@ jobs:
- name: install dependencies & git >= 2.42
uses: ./.forgejo/workflows-composite/apt-install-from
with:
- packages: git git-annex-standalone git-lfs
+ packages: git git-lfs
- uses: ./.forgejo/workflows-composite/build-backend
- run: |
su forgejo -c 'make test-pgsql-migration test-pgsql'
+ timeout-minutes: 120
env:
RACE_ENABLED: true
USE_REPO_TEST_DIR: 1
TEST_LDAP: 1
test-sqlite:
+ if: vars.ROLE == 'forgejo-coding' || vars.ROLE == 'forgejo-testing'
runs-on: docker
needs: [backend-checks, frontend-checks]
container:
@@ -251,21 +258,25 @@ jobs:
- name: install dependencies & git >= 2.42
uses: ./.forgejo/workflows-composite/apt-install-from
with:
- packages: git git-annex-standalone git-lfs
+ packages: git git-lfs
- uses: ./.forgejo/workflows-composite/build-backend
- run: |
su forgejo -c 'make test-sqlite-migration test-sqlite'
+ timeout-minutes: 120
env:
TAGS: sqlite sqlite_unlock_notify
RACE_ENABLED: true
TEST_TAGS: sqlite sqlite_unlock_notify
USE_REPO_TEST_DIR: 1
security-check:
+ if: vars.ROLE == 'forgejo-coding' || vars.ROLE == 'forgejo-testing'
runs-on: docker
needs:
- test-sqlite
- test-pgsql
- test-mysql
+ - test-remote-cacher
+ - test-unit
container:
image: 'data.forgejo.org/oci/node:20-bookworm'
options: --tmpfs /tmp:exec,noatime
diff --git a/Dockerfile b/Dockerfile
index 1f33f5d..af9269a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -78,7 +78,6 @@ RUN apk --no-cache add \
sqlite \
su-exec \
gnupg \
- git-annex \
&& rm -rf /var/cache/apk/*
RUN addgroup \
diff --git a/Dockerfile.rootless b/Dockerfile.rootless
index 63fb88a..82d15e8 100644
--- a/Dockerfile.rootless
+++ b/Dockerfile.rootless
@@ -71,7 +71,6 @@ RUN apk --no-cache add \
git \
curl \
gnupg \
- git-annex \
&& rm -rf /var/cache/apk/*
RUN addgroup \
diff --git a/Makefile b/Makefile
index 561d674..a9de57e 100644
--- a/Makefile
+++ b/Makefile
@@ -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=$$? ; chmod -R +w "$$tmpdir" && rm -r "$$tmpdir" ; exit $$STATUS
+ STATUS=$$? ; rm -r "$$tmpdir" ; exit $$STATUS
else
@@ -104,7 +104,7 @@ else
FORGEJO_VERSION_API ?= $(GITEA_VERSION)+${GITEA_COMPATIBILITY}
else
# drop the "g" prefix prepended by git describe to the commit hash
- FORGEJO_VERSION ?= $(shell git describe --exclude '*-test' --tags --always | sed 's/^v//' | sed 's/\-g/-/2')+${GITEA_COMPATIBILITY}
+ FORGEJO_VERSION ?= $(shell git describe --exclude '*-test' --tags --always | sed 's/^v//' | sed 's/\-g/-/')+${GITEA_COMPATIBILITY}
endif
endif
FORGEJO_VERSION_MAJOR=$(shell echo $(FORGEJO_VERSION) | sed -e 's/\..*//')
diff --git a/cmd/serv.go b/cmd/serv.go
index 5780403..db67e36 100644
--- a/cmd/serv.go
+++ b/cmd/serv.go
@@ -38,7 +38,6 @@ import (
const (
lfsAuthenticateVerb = "git-lfs-authenticate"
- gitAnnexShellVerb = "git-annex-shell"
)
// CmdServ represents the available serv sub-command.
@@ -80,7 +79,6 @@ 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-\.]`)
)
@@ -214,28 +212,6 @@ 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, "~/")
- }
-
- // prevent directory traversal attacks
- repoPath = filepath.Clean("/" + repoPath)[1:]
-
rr := strings.SplitN(repoPath, "/", 2)
if len(rr) != 2 {
return fail(ctx, "Invalid repository path", "Invalid repository path: %v", repoPath)
@@ -249,18 +225,6 @@ func runServ(c *cli.Context) error {
// so that username and reponame are not affected.
repoPath = strings.ToLower(strings.TrimSpace(repoPath))
- // 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
- }
-
if alphaDashDotPattern.MatchString(reponame) {
return fail(ctx, "Invalid repo name", "Invalid repo name: %s", reponame)
}
@@ -339,45 +303,21 @@ func runServ(c *cli.Context) error {
return nil
}
- gitBinVerb, err := exec.LookPath(verb)
- if err != 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", ...
- gitBinVerb = git.GitExecutable
- words = append([]string{verbFields[1]}, words...)
+ gitcmd = exec.CommandContext(ctx, git.GitExecutable, verbFields[1], 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")
- }
+ if gitcmd == nil {
+ // by default, use the verb (it has been checked above by allowedCommands)
+ gitcmd = exec.CommandContext(ctx, gitBinVerb, repoPath)
}
process.SetSysProcAttribute(gitcmd)
diff --git a/cmd/web.go b/cmd/web.go
index 661e6d1..44babd5 100644
--- a/cmd/web.go
+++ b/cmd/web.go
@@ -9,7 +9,6 @@ import (
"net"
"net/http"
"os"
- "os/exec"
"path/filepath"
"strconv"
"strings"
@@ -248,12 +247,6 @@ func runWeb(ctx *cli.Context) error {
createPIDFile(ctx.String("pid"))
}
- if setting.Annex.Enabled {
- if _, err := exec.LookPath("git-annex"); err != nil {
- log.Fatal("You have enabled git-annex support but git-annex is not installed. Please make sure that Forgejo's PATH contains the git-annex executable.")
- }
- }
-
if !setting.InstallLock {
if err := serveInstall(ctx); err != nil {
return err
@@ -318,10 +311,6 @@ 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:
diff --git a/modules/annex/annex.go b/modules/annex/annex.go
deleted file mode 100644
index dee24d2..0000000
--- a/modules/annex/annex.go
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2022 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-// Unlike modules/lfs, which operates mainly on git.Blobs, this operates on git.TreeEntrys.
-// The motivation for this is that TreeEntrys have an easy pointer to the on-disk repo path,
-// while blobs do not (in fact, if building with TAGS=gogit, blobs might exist only in a mock
-// filesystem, living only in process RAM). We must have the on-disk path to do anything
-// useful with git-annex because all of its interesting data is on-disk under .git/annex/.
-
-package annex
-
-import (
- "errors"
- "fmt"
- "io/fs"
- "os"
- "path"
- "path/filepath"
- "regexp"
- "strings"
-
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/typesniffer"
-)
-
-// ErrBlobIsNotAnnexed occurs if a blob does not contain a valid annex key
-var ErrBlobIsNotAnnexed = errors.New("not a git-annex pointer")
-
-func LookupKey(blob *git.Blob) (string, error) {
- stdout, _, err := git.NewCommand(git.DefaultContext, "annex", "lookupkey", "--ref").AddDynamicArguments(blob.ID.String()).RunStdString(&git.RunOpts{Dir: blob.Repo().Path})
- if err != nil {
- return "", ErrBlobIsNotAnnexed
- }
- key := strings.TrimSpace(stdout)
- return key, nil
-}
-
-func ContentLocationFromKey(repoPath, key string) (string, error) {
- contentLocation, _, err := git.NewCommandContextNoGlobals(git.DefaultContext, "annex", "contentlocation").AddDynamicArguments(key).RunStdString(&git.RunOpts{Dir: repoPath})
- if err != nil {
- return "", fmt.Errorf("in %s: %s does not seem to be a valid annexed file: %w", repoPath, key, err)
- }
- contentLocation = strings.TrimSpace(contentLocation)
- contentLocation = path.Clean("/" + contentLocation)[1:] // prevent directory traversals
- contentLocation = path.Join(repoPath, contentLocation)
-
- return contentLocation, nil
-}
-
-// return the absolute path of the content pointed to by the annex pointer stored in the git object
-// errors if the content is not found in this repo
-func ContentLocation(blob *git.Blob) (string, error) {
- key, err := LookupKey(blob)
- if err != nil {
- return "", err
- }
- return ContentLocationFromKey(blob.Repo().Path, key)
-}
-
-// returns a stream open to the annex content
-func Content(blob *git.Blob) (*os.File, error) {
- contentLocation, err := ContentLocation(blob)
- if err != nil {
- return nil, err
- }
-
- return os.Open(contentLocation)
-}
-
-// whether the object appears to be a valid annex pointer
-// does *not* verify if the content is actually in this repo;
-// for that, use ContentLocation()
-func IsAnnexed(blob *git.Blob) (bool, error) {
- if !setting.Annex.Enabled {
- return false, nil
- }
-
- // LookupKey is written to only return well-formed keys
- // so the test is just to see if it errors
- _, err := LookupKey(blob)
- if err != nil {
- if errors.Is(err, ErrBlobIsNotAnnexed) {
- return false, nil
- }
- return false, err
- }
- return true, nil
-}
-
-// IsAnnexRepo determines if repo is a git-annex enabled repository
-func IsAnnexRepo(repo *git.Repository) bool {
- _, _, err := git.NewCommand(repo.Ctx, "config", "annex.uuid").RunStdString(&git.RunOpts{Dir: repo.Path})
- return err == nil
-}
-
-var repoConfigFileRe = regexp.MustCompile("[^/]+/[^/]+.git/config$")
-
-var (
- uuid2repoPathCache = make(map[string]string)
- repoPath2uuidCache = make(map[string]string)
-)
-
-func Init() error {
- if !setting.Annex.Enabled {
- return nil
- }
- log.Info("Populating the git-annex UUID cache with existing repositories")
- return updateUUID2RepoPathCache()
-}
-
-func updateUUID2RepoPathCache() error {
- return filepath.WalkDir(setting.RepoRootPath, func(path string, d fs.DirEntry, err error) error {
- if err == nil && repoConfigFileRe.MatchString(path) {
- thisRepoPath := strings.TrimSuffix(path, "/config")
- _, ok := repoPath2uuidCache[thisRepoPath]
- if ok {
- return nil
- }
- stdout, _, err := git.NewCommand(git.DefaultContext, "config", "annex.uuid").RunStdString(&git.RunOpts{Dir: thisRepoPath})
- if err != nil {
- return nil
- }
- repoUUID := strings.TrimSpace(stdout)
- if repoUUID != "" {
- uuid2repoPathCache[repoUUID] = thisRepoPath
- repoPath2uuidCache[thisRepoPath] = repoUUID
- }
- }
- return nil
- })
-}
-
-func repoPathFromUUIDCache(uuid string) (string, error) {
- if repoPath, ok := uuid2repoPathCache[uuid]; ok {
- return repoPath, nil
- }
- // If the cache didn't contain an entry for the UUID then update the cache and try again
- if err := updateUUID2RepoPathCache(); err != nil {
- return "", err
- }
- if repoPath, ok := uuid2repoPathCache[uuid]; ok {
- return repoPath, nil
- }
- return "", fmt.Errorf("no repository known for UUID '%s'", uuid)
-}
-
-func checkValidity(uuid, repoPath string) (bool, error) {
- stdout, _, err := git.NewCommand(git.DefaultContext, "config", "annex.uuid").RunStdString(&git.RunOpts{Dir: repoPath})
- if err != nil {
- return false, err
- }
- repoUUID := strings.TrimSpace(stdout)
- return uuid == repoUUID, nil
-}
-
-func removeCachedEntries(uuid, repoPath string) {
- delete(uuid2repoPathCache, uuid)
- delete(repoPath2uuidCache, repoPath)
-}
-
-func UUID2RepoPath(uuid string) (string, error) {
- // Get the current cache entry for the UUID
- repoPath, err := repoPathFromUUIDCache(uuid)
- if err != nil {
- return "", err
- }
- // Check if it is still up-to-date
- valid, err := checkValidity(uuid, repoPath)
- if err != nil {
- return "", err
- }
- if !valid {
- // If it isn't, remove the cache entry and try again
- removeCachedEntries(uuid, repoPath)
- return UUID2RepoPath(uuid)
- }
- // Otherwise just return the cached entry
- return repoPath, nil
-}
-
-// GuessContentType guesses the content type of the annexed blob.
-func GuessContentType(blob *git.Blob) (typesniffer.SniffedType, error) {
- r, err := Content(blob)
- if err != nil {
- return typesniffer.SniffedType{}, err
- }
- defer r.Close()
-
- return typesniffer.DetectContentTypeFromReader(r)
-}
diff --git a/modules/base/tool.go b/modules/base/tool.go
index a885546..02f1db5 100644
--- a/modules/base/tool.go
+++ b/modules/base/tool.go
@@ -16,7 +16,6 @@ import (
"strings"
"unicode/utf8"
- "code.gitea.io/gitea/modules/annex"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
@@ -102,12 +101,6 @@ func Int64sToStrings(ints []int64) []string {
// EntryIcon returns the octicon class for displaying files/directories
func EntryIcon(entry *git.TreeEntry) string {
- isAnnexed, _ := annex.IsAnnexed(entry.Blob())
- if isAnnexed {
- // Show git-annex files as binary files to differentiate them from non-annexed files
- // TODO: find a more suitable icon, maybe something related to git-annex
- return "file-binary"
- }
switch {
case entry.IsLink():
te, _, err := entry.FollowLink()
diff --git a/modules/git/blob.go b/modules/git/blob.go
index bbfab7d..2f02693 100644
--- a/modules/git/blob.go
+++ b/modules/git/blob.go
@@ -126,10 +126,6 @@ func (b *blobReader) Close() error {
return nil
}
-func (b *Blob) Repo() *Repository {
- return b.repo
-}
-
// Name returns name of the tree entry this blob object was created from (or empty string)
func (b *Blob) Name() string {
return b.name
diff --git a/modules/git/command.go b/modules/git/command.go
index d3e6b7b..a3d43aa 100644
--- a/modules/git/command.go
+++ b/modules/git/command.go
@@ -457,13 +457,12 @@ func (c *Command) RunStdBytes(opts *RunOpts) (stdout, stderr []byte, runErr RunS
}
// AllowLFSFiltersArgs return globalCommandArgs with lfs filter, it should only be used for tests
-// It also re-enables git-credential(1), which is used to test git-annex's HTTP support
func AllowLFSFiltersArgs() TrustedCmdArgs {
// Now here we should explicitly allow lfs filters to run
filteredLFSGlobalArgs := make(TrustedCmdArgs, len(globalCommandArgs))
j := 0
for _, arg := range globalCommandArgs {
- if strings.Contains(string(arg), "lfs") || strings.Contains(string(arg), "credential") {
+ if strings.Contains(string(arg), "lfs") {
j--
} else {
filteredLFSGlobalArgs[j] = arg
diff --git a/modules/git/repo_index.go b/modules/git/repo_index.go
index 37988c3..f45b6e6 100644
--- a/modules/git/repo_index.go
+++ b/modules/git/repo_index.go
@@ -6,14 +6,12 @@ package git
import (
"bytes"
"context"
- "errors"
"os"
"path/filepath"
"strings"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/git/internal" //nolint:depguard // only this file can use the internal type CmdArg, other files and packages should use AddXxx functions
)
// ReadTreeToIndex reads a treeish to the index
@@ -104,32 +102,6 @@ func (repo *Repository) LsFiles(filenames ...string) ([]string, error) {
return filelist, err
}
-// Gives a list of all files in a directory and below
-func (repo *Repository) LsFilesFromDirectory(directory, branch string) ([]string, error) {
- if branch == "" {
- return nil, errors.New("branch not found in context URL")
- }
-
- cmd := NewCommand(repo.Ctx, "ls-files", internal.CmdArg("--with-tree=" + branch))
-
- if len(directory) > 0 {
- cmd = NewCommand(repo.Ctx, "ls-files", internal.CmdArg("--with-tree=" + branch), internal.CmdArg("--directory"), internal.CmdArg(directory))
- }
-
- res, stderror, err := cmd.RunStdBytes(&RunOpts{Dir: repo.Path})
- if err != nil {
- return nil, err
- }
-
- if len(stderror) > 0 {
- return nil, errors.New(string(stderror))
- }
-
- lines := strings.Split(string(res), "\n")
-
- return lines, nil
-}
-
// RemoveFilesFromIndex removes given filenames from the index - it does not check whether they are present.
func (repo *Repository) RemoveFilesFromIndex(filenames ...string) error {
objectFormat, err := repo.GetObjectFormat()
diff --git a/modules/markup/external/external.go b/modules/markup/external/external.go
index b976077..122517e 100644
--- a/modules/markup/external/external.go
+++ b/modules/markup/external/external.go
@@ -12,7 +12,6 @@ import (
"runtime"
"strings"
- "code.gitea.io/gitea/modules/annex"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
@@ -87,22 +86,8 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.
commands = strings.Fields(command)
args = commands[1:]
)
- isAnnexed, _ := annex.IsAnnexed(ctx.Blob)
- // if a renderer wants to read a file, and we have annexed content, we can
- // provide the annex key file location directly to the renderer. git-annex
- // takes care of having that location be read-only, so no critical
- // protection layer is needed. Moreover, the file readily exists, and
- // expensive temporary files can be avoided, also allowing an operator
- // to raise MAX_DISPLAY_FILE_SIZE without much negative impact.
- if p.IsInputFile && isAnnexed {
- // look for annexed content, will be empty, if there is none
- annexContentLocation, _ := annex.ContentLocation(ctx.Blob)
- // we call the renderer, even if there is no annex content present.
- // showing the pointer file content is not much use, and a topical
- // renderer might be able to produce something useful from the
- // filename alone (present in ENV)
- args = append(args, annexContentLocation)
- } else if p.IsInputFile {
+
+ if p.IsInputFile {
// write to temp file
f, err := os.CreateTemp("", "gitea_input")
if err != nil {
@@ -145,12 +130,6 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.
os.Environ(),
"GITEA_PREFIX_SRC="+ctx.Links.SrcLink(),
"GITEA_PREFIX_RAW="+ctx.Links.RawLink(),
- // also communicate the relative path of the to-be-rendered item.
- // this enables the renderer to make use of the original file name
- // and path, e.g., to make rendering or dtype-detection decisions
- // that go beyond the originally matched extension. Even if the
- // content is directly streamed to STDIN
- "GITEA_RELATIVE_PATH="+ctx.RelativePath,
)
if !p.IsInputFile {
cmd.Stdin = input
diff --git a/modules/markup/renderer.go b/modules/markup/renderer.go
index c00bd2b..2137302 100644
--- a/modules/markup/renderer.go
+++ b/modules/markup/renderer.go
@@ -67,18 +67,14 @@ type Header struct {
// RenderContext represents a render context
type RenderContext struct {
- Ctx context.Context
- RelativePath string // relative path from tree root of the branch
- Type string
- IsWiki bool
- Links Links
- Metas map[string]string
- DefaultLink string
- GitRepo *git.Repository
- // reporting the target blob that is to-be-rendered enables
- // deeper inspection in the handler for external renderer
- // (i.e., more targeted handling of annexed files)
- Blob *git.Blob
+ Ctx context.Context
+ RelativePath string // relative path from tree root of the branch
+ Type string
+ IsWiki bool
+ Links Links
+ Metas map[string]string
+ DefaultLink string
+ GitRepo *git.Repository
ShaExistCache map[string]bool
cancelFn func()
SidebarTocNode ast.Node
diff --git a/modules/private/serv.go b/modules/private/serv.go
index 6c7c753..480a446 100644
--- a/modules/private/serv.go
+++ b/modules/private/serv.go
@@ -40,7 +40,6 @@ type ServCommandResults struct {
UserName string
UserEmail string
UserID int64
- UserMode perm.AccessMode
OwnerName string
RepoName string
RepoID int64
diff --git a/modules/setting/annex.go b/modules/setting/annex.go
deleted file mode 100644
index 35e9e55..0000000
--- a/modules/setting/annex.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2023 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package setting
-
-import (
- "code.gitea.io/gitea/modules/log"
-)
-
-// Annex represents the configuration for git-annex
-var Annex = struct {
- Enabled bool `ini:"ENABLED"`
- DisableP2PHTTP bool `ini:"DISABLE_P2PHTTP"`
-}{}
-
-func loadAnnexFrom(rootCfg ConfigProvider) {
- sec := rootCfg.Section("annex")
- if err := sec.MapTo(&Annex); err != nil {
- log.Fatal("Failed to map Annex settings: %v", err)
- }
- if !sec.HasKey("DISABLE_P2PHTTP") {
- // If DisableP2PHTTP is not explicitly set then use DisableHTTPGit as its default
- Annex.DisableP2PHTTP = Repository.DisableHTTPGit
- }
-}
diff --git a/modules/setting/service.go b/modules/setting/service.go
index b877fbd..74ed5cd 100644
--- a/modules/setting/service.go
+++ b/modules/setting/service.go
@@ -85,8 +85,6 @@ var Service = struct {
DefaultOrgMemberVisible bool
UserDeleteWithCommentsMaxTime time.Duration
ValidSiteURLSchemes []string
- LandingPageInfoEnabled bool
- SignInForgottenPasswordEnabled bool
// OpenID settings
EnableOpenIDSignIn bool
@@ -215,8 +213,6 @@ func loadServiceFrom(rootCfg ConfigProvider) {
if Service.EnableTimetracking {
Service.DefaultEnableTimetracking = sec.Key("DEFAULT_ENABLE_TIMETRACKING").MustBool(true)
}
- Service.LandingPageInfoEnabled = sec.Key("ENABLE_LANDING_PAGE_INFO").MustBool(true)
- Service.SignInForgottenPasswordEnabled = sec.Key("SIGNIN_FORGOTTEN_PASSWORD_ENABLED").MustBool(true)
Service.DefaultEnableDependencies = sec.Key("DEFAULT_ENABLE_DEPENDENCIES").MustBool(true)
Service.AllowCrossRepositoryDependencies = sec.Key("ALLOW_CROSS_REPOSITORY_DEPENDENCIES").MustBool(true)
Service.DefaultAllowOnlyContributorsToTrackTime = sec.Key("DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME").MustBool(true)
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 9710fb2..c9d3083 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -153,7 +153,6 @@ func loadCommonSettingsFrom(cfg ConfigProvider) error {
loadCamoFrom(cfg)
loadI18nFrom(cfg)
loadGitFrom(cfg)
- loadAnnexFrom(cfg)
loadMirrorFrom(cfg)
loadMarkupFrom(cfg)
loadQuotaFrom(cfg)
diff --git a/modules/util/remove.go b/modules/util/remove.go
index 39556e5..d1e38fa 100644
--- a/modules/util/remove.go
+++ b/modules/util/remove.go
@@ -4,9 +4,7 @@
package util
import (
- "io/fs"
"os"
- "path/filepath"
"runtime"
"syscall"
"time"
@@ -43,48 +41,10 @@ func Remove(name string) error {
return err
}
-// MakeWritable recursively makes the named directory writable.
-func MakeWritable(name string) error {
- return filepath.WalkDir(name, func(path string, d fs.DirEntry, err error) error {
- // NB: this is called WalkDir but it works on a single file too
- if err == nil {
- info, err := d.Info()
- if err != nil {
- return err
- }
-
- // Don't try chmod'ing symlinks (will fail with broken symlinks)
- if info.Mode()&os.ModeSymlink != os.ModeSymlink {
- // 0200 == u+w, in octal unix permission notation
- err = os.Chmod(path, info.Mode()|0o200)
- if err != nil {
- return err
- }
- }
- }
- return nil
- })
-}
-
-// RemoveAll removes the named file or directory with at most 5 attempts.
+// RemoveAll removes the named file or (empty) directory with at most 5 attempts.
func RemoveAll(name string) error {
var err error
-
for i := 0; i < 5; i++ {
- // Do chmod -R +w to help ensure the removal succeeds.
- // In particular, in the git-annex case, this handles
- // https://git-annex.branchable.com/internals/lockdown/ :
- //
- // > (The only bad consequence of this is that rm -rf .git
- // > doesn't work unless you first run chmod -R +w .git)
-
- err = MakeWritable(name)
- if err != nil {
- // try again
- <-time.After(100 * time.Millisecond)
- continue
- }
-
err = os.RemoveAll(name)
if err == nil {
break
diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini
index 1894aeb..0143a9a 100644
--- a/options/locale/locale_cs-CZ.ini
+++ b/options/locale/locale_cs-CZ.ini
@@ -1317,7 +1317,6 @@ view_git_blame=Zobrazit git blame
video_not_supported_in_browser=Váš prohlížeč nepodporuje značku HTML5 „video“.
audio_not_supported_in_browser=Váš prohlížeč nepodporuje značku HTML5 „audio“.
stored_lfs=Uloženo pomocí Git LFS
-stored_annex=Uloženo pomocí Git Annex
symbolic_link=Symbolický odkaz
executable_file=Spustitelný soubor
vendored = Vendorováno
@@ -1343,7 +1342,6 @@ editor.upload_file=Nahrát soubor
editor.edit_file=Upravit soubor
editor.preview_changes=Náhled změn
editor.cannot_edit_lfs_files=LFS soubory nemohou být upravovány přes webové rozhraní.
-editor.cannot_edit_annex_files=Annex soubory nemohou být upravovány přes webové rozhraní.
editor.cannot_edit_non_text_files=Binární soubory nemohou být upravovány přes webové rozhraní.
editor.edit_this_file=Upravit soubor
editor.this_file_locked=Soubor je uzamčen
diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini
index a67390e..3064552 100644
--- a/options/locale/locale_de-DE.ini
+++ b/options/locale/locale_de-DE.ini
@@ -1317,8 +1317,6 @@ view_git_blame=„git blame“ ansehen
video_not_supported_in_browser=Dein Browser unterstützt das HTML5-„video“-Tag nicht.
audio_not_supported_in_browser=Dein Browser unterstützt das HTML5-„audio“-Tag nicht.
stored_lfs=Gespeichert mit Git LFS
-stored_annex=Gespeichert mit Git Annex
-stored_annex_not_present = hier nicht vorhanden, versuche git annex whereis
symbolic_link=Softlink
executable_file=Ausführbare Datei
commit_graph=Commit-Graph
@@ -1342,7 +1340,6 @@ editor.upload_file=Datei hochladen
editor.edit_file=Datei bearbeiten
editor.preview_changes=Vorschau der Änderungen
editor.cannot_edit_lfs_files=LFS-Dateien können im Webinterface nicht bearbeitet werden.
-editor.cannot_edit_annex_files=Annex-Dateien können im Webinterface nicht bearbeitet werden.
editor.cannot_edit_non_text_files=Binärdateien können nicht im Webinterface bearbeitet werden.
editor.edit_this_file=Datei bearbeiten
editor.this_file_locked=Datei ist gesperrt
diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini
index 2f6d82b..e80b815 100644
--- a/options/locale/locale_el-GR.ini
+++ b/options/locale/locale_el-GR.ini
@@ -1314,7 +1314,6 @@ view_git_blame=Προβολή git blame
video_not_supported_in_browser=Το πρόγραμμα περιήγησής σας δεν υποστηρίζει την ετικέτα HTML5 «video».
audio_not_supported_in_browser=Το πρόγραμμα περιήγησής σας δεν υποστηρίζει την ετικέτα HTML5 «audio».
stored_lfs=Αποθηκεύτηκε με το Git LFS
-stored_annex=Αποθηκεύτηκε με το Git Annex
symbolic_link=Symbolic link
executable_file=Εκτελέσιμο αρχείο
commit_graph=Γράφημα υποβολών
@@ -1338,7 +1337,6 @@ editor.upload_file=Ανέβασμα αρχείου
editor.edit_file=Επεξεργασία αρχείου
editor.preview_changes=Προεπισκόπηση αλλαγών
editor.cannot_edit_lfs_files=Τα αρχεία LFS δεν μπορούν να επεξεργαστούν στη διεπαφή web.
-editor.cannot_edit_annex_files=Τα αρχεία Annex δεν μπορούν να επεξεργαστούν στη διεπαφή web.
editor.cannot_edit_non_text_files=Τα δυαδικά αρχεία δεν μπορούν να επεξεργαστούν στη διεπαφή web.
editor.edit_this_file=Επεξεργασία αρχείου
editor.this_file_locked=Το αρχείο είναι κλειδωμένο
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index db58d50..53a47f0 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -1337,8 +1337,6 @@ view_git_blame = View git blame
video_not_supported_in_browser = Your browser does not support the HTML5 "video" tag.
audio_not_supported_in_browser = Your browser does not support the HTML5 "audio" tag.
stored_lfs = Stored with Git LFS
-stored_annex = Stored with Git Annex
-stored_annex_not_present = not present here, try using git annex whereis
symbolic_link = Symbolic link
executable_file = Executable file
vendored = Vendored
@@ -1366,7 +1364,6 @@ editor.upload_file = Upload file
editor.edit_file = Edit file
editor.preview_changes = Preview changes
editor.cannot_edit_lfs_files = LFS files cannot be edited in the web interface.
-editor.cannot_edit_annex_files = Annex files cannot be edited in the web interface.
editor.cannot_edit_non_text_files = Binary files cannot be edited in the web interface.
editor.edit_this_file = Edit file
editor.this_file_locked = File is locked
diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini
index 839d2d0..cc24e95 100644
--- a/options/locale/locale_es-ES.ini
+++ b/options/locale/locale_es-ES.ini
@@ -1312,7 +1312,6 @@ view_git_blame=Ver Git blame
video_not_supported_in_browser=Su navegador no soporta el tag "video" de HTML5.
audio_not_supported_in_browser=Su navegador no soporta el tag "audio" de HTML5.
stored_lfs=Almacenados con Git LFS
-stored_annex=Almacenados con Git Annex
symbolic_link=Enlace simbólico
executable_file=Archivo ejecutable
commit_graph=Gráfico de commits
@@ -1336,7 +1335,6 @@ editor.upload_file=Subir archivo
editor.edit_file=Editar archivo
editor.preview_changes=Vista previa de los cambios
editor.cannot_edit_lfs_files=Los archivos LFS no se pueden editar en la interfaz web.
-editor.cannot_edit_annex_files=Los archivos Annex no se pueden editar en la interfaz web.
editor.cannot_edit_non_text_files=Los archivos binarios no se pueden editar en la interfaz web.
editor.edit_this_file=Editar archivo
editor.this_file_locked=El archivo está bloqueado
diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini
index 01d931b..e2c9dc4 100644
--- a/options/locale/locale_fa-IR.ini
+++ b/options/locale/locale_fa-IR.ini
@@ -951,7 +951,6 @@ file_copy_permalink=پرمالینک را کپی کنید
video_not_supported_in_browser=مرورگر شما از تگ video که در HTML5 تعریف شده است، پشتیبانی نمی کند.
audio_not_supported_in_browser=مرورگر شما از تگ audio که در HTML5 تعریف شده است، پشتیبانی نمی کند.
stored_lfs=ذخیره شده با GIT LFS
-stored_annex=ذخیره شده با GIT Annex
symbolic_link=پیوند نمادین
commit_graph=نمودار کامیت
commit_graph.select=انتخاب برنچها
@@ -969,7 +968,6 @@ editor.upload_file=بارگذاری پرونده
editor.edit_file=ویرایش پرونده
editor.preview_changes=پیش نمایش تغییرات
editor.cannot_edit_lfs_files=پرونده های LFS در صحفه وب قابل تغییر نیست.
-editor.cannot_edit_annex_files=پرونده های Annex در صحفه وب قابل تغییر نیست.
editor.cannot_edit_non_text_files=پروندههای دودویی در صفحه وب قابل تغییر نیست.
editor.edit_this_file=ویرایش پرونده
editor.this_file_locked=پرونده قفل شده است
diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini
index aaaa2e7..92da5ee 100644
--- a/options/locale/locale_fr-FR.ini
+++ b/options/locale/locale_fr-FR.ini
@@ -1318,7 +1318,6 @@ view_git_blame=Voir Git blame
video_not_supported_in_browser=Votre navigateur ne supporte pas la balise « vidéo » HTML5.
audio_not_supported_in_browser=Votre navigateur ne supporte pas la balise « audio » HTML5.
stored_lfs=Stocké avec Git LFS
-stored_annex=Stocké avec Git Annex
symbolic_link=Lien symbolique
executable_file=Fichier exécutable
vendored = Vendored
@@ -1344,7 +1343,6 @@ editor.upload_file=Téléverser un fichier
editor.edit_file=Modifier le fichier
editor.preview_changes=Aperçu des modifications
editor.cannot_edit_lfs_files=Les fichiers LFS ne peuvent pas être modifiés dans l'interface web.
-editor.cannot_edit_annex_files=Les fichiers Annex ne peuvent pas être modifiés dans l'interface web.
editor.cannot_edit_non_text_files=Les fichiers binaires ne peuvent pas être édités dans l'interface web.
editor.edit_this_file=Modifier le fichier
editor.this_file_locked=Le fichier est verrouillé
diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini
index ef94d2d..57555b9 100644
--- a/options/locale/locale_hu-HU.ini
+++ b/options/locale/locale_hu-HU.ini
@@ -787,7 +787,6 @@ file_too_large=Ez a fájl túl nagy ahhoz, hogy megjelenítsük.
video_not_supported_in_browser=A böngésző nem támogatja a HTML5 video tag-et.
audio_not_supported_in_browser=A böngésző nem támogatja a HTML5 audio tag-et.
stored_lfs=Git LFS-el eltárolva
-stored_annex=Git Annex-el eltárolva
symbolic_link=Szimbolikus hivatkozás
commit_graph=Commit gráf
commit_graph.hide_pr_refs=Pull request-ek elrejtése
@@ -800,7 +799,6 @@ editor.upload_file=Fájl feltöltése
editor.edit_file=Fájl szerkesztése
editor.preview_changes=Változások előnézete
editor.cannot_edit_lfs_files=LFS fájlok nem szerkeszthetőek a webes felületen.
-editor.cannot_edit_annex_files=Annex fájlok nem szerkeszthetőek a webes felületen.
editor.cannot_edit_non_text_files=Bináris fájlok nem szerkeszthetőek a webes felületen.
editor.edit_this_file=Fájl szerkesztése
editor.this_file_locked=Zárolt állomány
diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini
index 8cf3457..1e0044e 100644
--- a/options/locale/locale_id-ID.ini
+++ b/options/locale/locale_id-ID.ini
@@ -596,7 +596,6 @@ file_permalink=Permalink
file_too_large=Berkas terlalu besar untuk ditampilkan.
stored_lfs=Tersimpan dengan GIT LFS
-stored_annex=Tersimpan dengan GIT Annex
commit_graph=Grafik Komit
blame=Salahkan
normal_view=Pandangan Normal
@@ -608,7 +607,6 @@ editor.upload_file=Unggah Berkas
editor.edit_file=Sunting Berkas
editor.preview_changes=Tinjau Perubahan
editor.cannot_edit_lfs_files=Berkas LFS tidak dapat disunting dalam antarmuka web.
-editor.cannot_edit_annex_files=Berkas Annex tidak dapat disunting dalam antarmuka web.
editor.cannot_edit_non_text_files=Berkas biner tidak dapat disunting dalam antarmuka web.
editor.edit_this_file=Sunting Berkas
editor.this_file_locked=Berkas terkunci
diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini
index b3cf17f..3a6e844 100644
--- a/options/locale/locale_is-IS.ini
+++ b/options/locale/locale_is-IS.ini
@@ -680,7 +680,6 @@ file_view_rendered=Skoða Unnið
file_copy_permalink=Afrita Varanlega Slóð
stored_lfs=Geymt með Git LFS
-stored_annex=Geymt með Git Annex
commit_graph.hide_pr_refs=Fela Sameiningarbeiðnir
commit_graph.monochrome=Einlitað
commit_graph.color=Litað
diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini
index 4bfc676..61753a7 100644
--- a/options/locale/locale_it-IT.ini
+++ b/options/locale/locale_it-IT.ini
@@ -1267,7 +1267,6 @@ view_git_blame=Visualizza git incolpa
video_not_supported_in_browser=Il tuo browser non supporta le etichette "video" di HTML5.
audio_not_supported_in_browser=Il tuo browser non supporta le etichette "audio" di HTML5.
stored_lfs=Memorizzati con Git LFS
-stored_annex=Memorizzati con Git Annex
symbolic_link=Link Simbolico
commit_graph=Grafico dei commit
commit_graph.select=Seleziona rami
@@ -1286,7 +1285,6 @@ editor.upload_file=Carica file
editor.edit_file=Modifica file
editor.preview_changes=Anteprima modifiche
editor.cannot_edit_lfs_files=I file LFS non possono essere modificati nell'interfaccia web.
-editor.cannot_edit_annex_files=I file Annex non possono essere modificati nell'interfaccia web.
editor.cannot_edit_non_text_files=I file binari non possono essere modificati tramite interfaccia web.
editor.edit_this_file=Modifica file
editor.this_file_locked=Il file è bloccato
diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini
index 2a4f075..890c2e8 100644
--- a/options/locale/locale_ja-JP.ini
+++ b/options/locale/locale_ja-JP.ini
@@ -1305,7 +1305,6 @@ view_git_blame=Git Blameを表示
video_not_supported_in_browser=このブラウザはHTML5のvideoタグをサポートしていません。
audio_not_supported_in_browser=このブラウザーはHTML5のaudioタグをサポートしていません。
stored_lfs=Git LFSで保管されています
-stored_annex=Git Annexで保管されています
symbolic_link=シンボリック リンク
executable_file=実行ファイル
commit_graph=コミットグラフ
@@ -1329,7 +1328,6 @@ editor.upload_file=ファイルをアップロード
editor.edit_file=ファイルを編集
editor.preview_changes=変更をプレビュー
editor.cannot_edit_lfs_files=LFSのファイルはWebインターフェースで編集できません。
-editor.cannot_edit_annex_files=AnnexのファイルはWebインターフェースで編集できません。
editor.cannot_edit_non_text_files=バイナリファイルはWebインターフェースで編集できません。
editor.edit_this_file=ファイルを編集
editor.this_file_locked=ファイルはロックされています
diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini
index 0573982..58e723d 100644
--- a/options/locale/locale_ko-KR.ini
+++ b/options/locale/locale_ko-KR.ini
@@ -821,7 +821,6 @@ file_too_large=보여주기에는 파일이 너무 큽니다.
video_not_supported_in_browser=당신의 브라우저가 HTML5의 "video" 태그를 지원하지 않습니다.
audio_not_supported_in_browser=당신의 브라우저가 HTML5의 "audio" 태그를 지원하지 않습니다.
stored_lfs=Git LFS에 저장되어 있습니다
-stored_annex=Git Annex에 저장되어 있습니다
commit_graph=커밋 그래프
editor.new_file=새 파일
diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini
index 30b53cb..bd77588 100644
--- a/options/locale/locale_lv-LV.ini
+++ b/options/locale/locale_lv-LV.ini
@@ -1316,7 +1316,6 @@ view_git_blame=Apskatīt Git izmaiņu veicējus
video_not_supported_in_browser=Pārlūks neatbalsta HTML5 tagu "video".
audio_not_supported_in_browser=Pārlūks neatbalsta HTML5 tagu "audio".
stored_lfs=Saglabāts Git LFS
-stored_annex=Saglabāts Git Annex
symbolic_link=Simboliska saite
executable_file=Izpildāma datne
commit_graph=Iesūtījumu karte
@@ -1340,7 +1339,6 @@ editor.upload_file=Augšupielādēt datni
editor.edit_file=Labot datni
editor.preview_changes=Priekšskatīt izmaiņas
editor.cannot_edit_lfs_files=LFS datnes tīmekļa saskarnē nevar labot.
-editor.cannot_edit_annex_files=Annex datnes tīmekļa saskarnē nevar labot.
editor.cannot_edit_non_text_files=Binārās datnes tīmekļa saskarnē nevar labot.
editor.edit_this_file=Labot datni
editor.this_file_locked=Datne ir slēgta
@@ -4029,4 +4027,4 @@ filepreview.lines = %[1]d. līdz %[2]d. rinda %[3]s
filepreview.truncated = Priekšskatījums tika saīsināts
[translation_meta]
-test = Šī ir pārbaudes virkne. Tā netiek attēlota Forgejo saskarnē, bet tiek izmantota pārbaudes nolūkiem. Droši var ievadīt "ok", lai ietaupītu laiku (vai kādu jautru faktu pēc izvēles), lai sasniegtu to saldo 100% pabeigšanas atzīmi.
+test = Šī ir pārbaudes virkne. Tā netiek attēlota Forgejo saskarnē, bet tiek izmantota pārbaudes nolūkiem. Droši var ievadīt "ok", lai ietaupītu laiku (vai kādu jautru faktu pēc izvēles), lai sasniegtu to saldo 100% pabeigšanas atzīmi.
\ No newline at end of file
diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini
index de2c1bd..83acf18 100644
--- a/options/locale/locale_nl-NL.ini
+++ b/options/locale/locale_nl-NL.ini
@@ -1285,7 +1285,6 @@ view_git_blame=Bekijk git blame
video_not_supported_in_browser=Uw browser ondersteunt de HTML5 "video" element niet.
audio_not_supported_in_browser=Uw browser ondersteunt de HTML5 "audio" element niet.
stored_lfs=Opgeslagen met Git LFS
-stored_annex=Opgeslagen met Git Annex
symbolic_link=Symbolische link
commit_graph=Commit grafiek
commit_graph.select=Selecteer branches
@@ -1304,7 +1303,6 @@ editor.upload_file=Upload bestand
editor.edit_file=Bewerk bestand
editor.preview_changes=Voorbeeld tonen
editor.cannot_edit_lfs_files=LFS-bestanden kunnen niet worden bewerkt in de webinterface.
-editor.cannot_edit_annex_files=Annex-bestanden kunnen niet worden bewerkt in de webinterface.
editor.cannot_edit_non_text_files=Binaire bestanden kunnen niet worden bewerkt in de webinterface.
editor.edit_this_file=Bewerk bestand
editor.this_file_locked=Bestand is vergrendeld
diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini
index 97678ea..11ea38e 100644
--- a/options/locale/locale_pl-PL.ini
+++ b/options/locale/locale_pl-PL.ini
@@ -1249,7 +1249,6 @@ file_copy_permalink=Kopiuj bezpośredni odnośnik
video_not_supported_in_browser=Twoja przeglądarka nie obsługuje znacznika HTML5 "video".
audio_not_supported_in_browser=Twoja przeglądarka nie obsługuje znacznika HTML5 "audio".
stored_lfs=Przechowane za pomocą Git LFS
-stored_annex=Przechowane za pomocą Git Annex
symbolic_link=Dowiązanie symboliczne
commit_graph=Wykres commitów
commit_graph.select=Wybierz gałęzie
@@ -1267,7 +1266,6 @@ editor.upload_file=Wyślij plik
editor.edit_file=Edytuj plik
editor.preview_changes=Podgląd zmian
editor.cannot_edit_lfs_files=Pliki LFS nie mogą być edytowane poprzez interfejs przeglądarkowy.
-editor.cannot_edit_annex_files=Pliki Annex nie mogą być edytowane poprzez interfejs przeglądarkowy.
editor.cannot_edit_non_text_files=Pliki binarne nie mogą być edytowane poprzez interfejs przeglądarkowy.
editor.edit_this_file=Edytuj plik
editor.this_file_locked=Plik jest zablokowany
diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini
index 78a871f..2280241 100644
--- a/options/locale/locale_pt-BR.ini
+++ b/options/locale/locale_pt-BR.ini
@@ -1310,7 +1310,6 @@ view_git_blame=Ver git blame
video_not_supported_in_browser=Seu navegador não tem suporte para a tag "video" do HTML5.
audio_not_supported_in_browser=Seu navegador não tem suporte para a tag "audio" do HTML5.
stored_lfs=Armazenado com Git LFS
-stored_annex=Armazenado com Git Annex
symbolic_link=Link simbólico
executable_file=Arquivo executável
commit_graph=Gráfico de commits
@@ -1334,7 +1333,6 @@ editor.upload_file=Enviar arquivo
editor.edit_file=Editar arquivo
editor.preview_changes=Pré-visualizar alterações
editor.cannot_edit_lfs_files=Arquivos LFS não podem ser editados na interface web.
-editor.cannot_edit_annex_files=Arquivos Annex não podem ser editados na interface web.
editor.cannot_edit_non_text_files=Arquivos binários não podem ser editados na interface web.
editor.edit_this_file=Editar arquivo
editor.this_file_locked=Arquivo está bloqueado
diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini
index 994f967..8e30b89 100644
--- a/options/locale/locale_pt-PT.ini
+++ b/options/locale/locale_pt-PT.ini
@@ -1321,7 +1321,6 @@ view_git_blame=Ver git blame
video_not_supported_in_browser=O seu navegador não suporta a etiqueta "video" do HTML5.
audio_not_supported_in_browser=O seu navegador não suporta a etiqueta "audio" do HTML5.
stored_lfs=Armazenado com Git LFS
-stored_annex=Armazenado com Git Annex
symbolic_link=Ligação simbólica
executable_file=Ficheiro executável
vendored=Externo
@@ -1347,7 +1346,6 @@ editor.upload_file=Carregar ficheiro
editor.edit_file=Editar ficheiro
editor.preview_changes=Pré-visualizar modificações
editor.cannot_edit_lfs_files=Ficheiros LFS não podem ser editados na interface web.
-editor.cannot_edit_annex_files=Ficheiros Annex não podem ser editados na interface web.
editor.cannot_edit_non_text_files=Ficheiros binários não podem ser editados na interface da web.
editor.edit_this_file=Editar ficheiro
editor.this_file_locked=Ficheiro bloqueado
diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini
index d45a251..83093fa 100644
--- a/options/locale/locale_ru-RU.ini
+++ b/options/locale/locale_ru-RU.ini
@@ -1304,7 +1304,6 @@ view_git_blame=Показать git blame
video_not_supported_in_browser=Ваш браузер не поддерживает тэг HTML5 «video».
audio_not_supported_in_browser=Ваш браузер не поддерживает тэг HTML5 «audio».
stored_lfs=Хранится Git LFS
-stored_annex=Хранится Git Annex
symbolic_link=Символическая ссылка
executable_file=Исполняемый файл
commit_graph=Граф коммитов
@@ -1328,7 +1327,6 @@ editor.upload_file=Загрузить файл
editor.edit_file=Редактировать файл
editor.preview_changes=Просмотр изменений
editor.cannot_edit_lfs_files=LFS файлы невозможно редактировать в веб-интерфейсе.
-editor.cannot_edit_annex_files=Annex файлы невозможно редактировать в веб-интерфейсе.
editor.cannot_edit_non_text_files=Двоичные файлы нельзя редактировать в веб-интерфейсе.
editor.edit_this_file=Редактировать файл
editor.this_file_locked=Файл заблокирован
diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini
index e26bf30..e52e5bc 100644
--- a/options/locale/locale_si-LK.ini
+++ b/options/locale/locale_si-LK.ini
@@ -889,7 +889,6 @@ file_copy_permalink=පිටපත් මාමලින්ක්
video_not_supported_in_browser=ඔබගේ බ්රව්සරය HTML5 'වීඩියෝ' ටැගය සඳහා සහය නොදක්වයි.
audio_not_supported_in_browser=ඔබගේ බ්රව්සරය HTML5 'ශ්රව්ය' ටැගය සඳහා සහය නොදක්වයි.
stored_lfs=Git LFS සමඟ ගබඩා
-stored_annex=Git Annex සමඟ ගබඩා
symbolic_link=සංකේතාත්මක සබැඳිය
commit_graph=ප්රස්තාරය කැප
commit_graph.select=ශාඛා තෝරන්න
@@ -907,7 +906,6 @@ editor.upload_file=ගොනුව උඩුගත කරන්න
editor.edit_file=ගොනුව සංස්කරණය
editor.preview_changes=වෙනස්කම් පෙරදසුන
editor.cannot_edit_lfs_files=LFS ගොනු වෙබ් අතුරු මුහුණත තුළ සංස්කරණය කළ නොහැක.
-editor.cannot_edit_annex_files=Annex ගොනු වෙබ් අතුරු මුහුණත තුළ සංස්කරණය කළ නොහැක.
editor.cannot_edit_non_text_files=ද්විමය ගොනු වෙබ් අතුරු මුහුණත තුළ සංස්කරණය කළ නොහැක.
editor.edit_this_file=ගොනුව සංස්කරණය
editor.this_file_locked=ගොනුවට අගුළු ලා ඇත
diff --git a/options/locale/locale_sk-SK.ini b/options/locale/locale_sk-SK.ini
index f714bdf..3e5b4a6 100644
--- a/options/locale/locale_sk-SK.ini
+++ b/options/locale/locale_sk-SK.ini
@@ -1010,7 +1010,6 @@ view_git_blame=Zobraziť Git Blame
video_not_supported_in_browser=Váš prehliadač nepodporuje HTML5 tag 'video'.
audio_not_supported_in_browser=Váš prehliadač nepodporuje HTML5 tag 'audio'.
stored_lfs=Uložené pomocou Git LFS
-stored_annex=Uložené pomocou Git Annex
symbolic_link=Symbolický odkaz
commit_graph=Graf commitov
line=riadok
diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini
index 3e8924f..4d94211 100644
--- a/options/locale/locale_sv-SE.ini
+++ b/options/locale/locale_sv-SE.ini
@@ -910,7 +910,6 @@ file_too_large=Filen är för stor för att visas.
video_not_supported_in_browser=Din webbläsare stödjer ej HTML5-taggen "video".
audio_not_supported_in_browser=Din webbläsare stödjer ej HTML5-taggen "audio".
stored_lfs=Sparad med Git LFS
-stored_annex=Sparad med Git Annex
symbolic_link=Symbolisk länk
commit_graph=Commitgraf
commit_graph.monochrome=Mono
@@ -924,7 +923,6 @@ editor.upload_file=Ladda upp fil
editor.edit_file=Redigera fil
editor.preview_changes=Förhandsgranska ändringar
editor.cannot_edit_lfs_files=LFS-filer kan inte redigeras i webbgränssnittet.
-editor.cannot_edit_annex_files=Annex-filer kan inte redigeras i webbgränssnittet.
editor.cannot_edit_non_text_files=Binära filer kan inte redigeras genom webbgränssnittet.
editor.edit_this_file=Redigera fil
editor.this_file_locked=Filen är låst
diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini
index 58384d9..49b52c3 100644
--- a/options/locale/locale_tr-TR.ini
+++ b/options/locale/locale_tr-TR.ini
@@ -1290,7 +1290,6 @@ view_git_blame=Git Suç Görüntüle
video_not_supported_in_browser=Tarayıcınız HTML5 'video' etiketini desteklemiyor.
audio_not_supported_in_browser=Tarayıcınız HTML5 'audio' etiketini desteklemiyor.
stored_lfs=Git LFS ile depolandı
-stored_annex=Git Annex ile depolandı
symbolic_link=Sembolik Bağlantı
executable_file=Çalıştırılabilir Dosya
commit_graph=İşleme Grafiği
@@ -1314,7 +1313,6 @@ editor.upload_file=Dosya Yükle
editor.edit_file=Dosyayı Düzenle
editor.preview_changes=Değişiklikleri Önizle
editor.cannot_edit_lfs_files=LFS dosyaları web arayüzünde düzenlenemez.
-editor.cannot_edit_annex_files=Annex dosyaları web arayüzünde düzenlenemez.
editor.cannot_edit_non_text_files=Bu tür dosyalar web arayüzünden düzenlenemez.
editor.edit_this_file=Dosyayı Düzenle
editor.this_file_locked=Dosya kilitlendi
diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini
index c306e7d..52303c2 100644
--- a/options/locale/locale_uk-UA.ini
+++ b/options/locale/locale_uk-UA.ini
@@ -1243,7 +1243,6 @@ file_copy_permalink=Копіювати постійне посилання
video_not_supported_in_browser=Ваш браузер не підтримує тег HTML5 «video».
audio_not_supported_in_browser=Ваш браузер не підтримує тег HTML5 «audio».
stored_lfs=Збережено з Git LFS
-stored_annex=Збережено з Git Annex
symbolic_link=Символічне посилання
commit_graph=Графік комітів
commit_graph.select=Виберіть гілки
@@ -1261,7 +1260,6 @@ editor.upload_file=Завантажити файл
editor.edit_file=Редагувати файл
editor.preview_changes=Попередній перегляд змін
editor.cannot_edit_lfs_files=Файли LFS не можна редагувати в веб-інтерфейсі.
-editor.cannot_edit_annex_files=Файли Annex не можна редагувати в веб-інтерфейсі.
editor.cannot_edit_non_text_files=Бінарні файли не можливо редагувати у веб-інтерфейсі.
editor.edit_this_file=Редагувати файл
editor.this_file_locked=Файл заблоковано
diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini
index 1c152e7..e809795 100644
--- a/options/locale/locale_zh-CN.ini
+++ b/options/locale/locale_zh-CN.ini
@@ -1319,7 +1319,6 @@ view_git_blame=查看 Git Blame
video_not_supported_in_browser=您的浏览器不支持 HTML5 “video” 标签。
audio_not_supported_in_browser=您的浏览器不支持 HTML5 “audio” 标签。
stored_lfs=存储到Git LFS
-stored_annex=存储到Git Annex
symbolic_link=符号链接
executable_file=可执行文件
vendored = Vendored
@@ -1345,7 +1344,6 @@ editor.upload_file=上传文件
editor.edit_file=编辑文件
editor.preview_changes=预览变更
editor.cannot_edit_lfs_files=无法在 web 界面中编辑 lfs 文件。
-editor.cannot_edit_annex_files=无法在 web 界面中编辑 lfs 文件。
editor.cannot_edit_non_text_files=网页不能编辑二进制文件。
editor.edit_this_file=编辑文件
editor.this_file_locked=文件已锁定
diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini
index 25dfcdf..e5080e6 100644
--- a/options/locale/locale_zh-HK.ini
+++ b/options/locale/locale_zh-HK.ini
@@ -472,7 +472,6 @@ file_view_raw=查看原始文件
file_permalink=永久連結
stored_lfs=儲存到到 Git LFS
-stored_annex=儲存到到 Git Annex
editor.preview_changes=預覽更改
editor.or=或
@@ -1133,4 +1132,4 @@ runners.labels = 標籤
[projects]
-[git.filemode]
+[git.filemode]
\ No newline at end of file
diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini
index 6506b67..720267f 100644
--- a/options/locale/locale_zh-TW.ini
+++ b/options/locale/locale_zh-TW.ini
@@ -1293,7 +1293,6 @@ view_git_blame=檢視 Git Blame
video_not_supported_in_browser=您的瀏覽器不支援 HTML5 的「video」標籤。
audio_not_supported_in_browser=您的瀏覽器不支援 HTML5 的「audio」標籤。
stored_lfs=已使用 Git LFS 儲存
-stored_annex=已使用 Git Annex 儲存
symbolic_link=符號連結
commit_graph=提交線圖
commit_graph.select=選擇分支
@@ -1313,7 +1312,6 @@ editor.upload_file=上傳檔案
editor.edit_file=編輯檔案
editor.preview_changes=預覽變更
editor.cannot_edit_lfs_files=無法在 web 介面中編輯 LFS 檔。
-editor.cannot_edit_annex_files=無法在 web 介面中編輯 Annex 檔。
editor.cannot_edit_non_text_files=網站介面不能編輯二進位檔案。
editor.edit_this_file=編輯檔案
editor.this_file_locked=檔案已被鎖定
diff --git a/package-lock.json b/package-lock.json
index 9088ea0..7b1c1ce 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,5 +1,5 @@
{
- "name": "forgejo-aneksajo",
+ "name": "forgejo",
"lockfileVersion": 3,
"requires": true,
"packages": {
diff --git a/routers/init.go b/routers/init.go
index d881edd..821a0ef 100644
--- a/routers/init.go
+++ b/routers/init.go
@@ -11,7 +11,6 @@ import (
"code.gitea.io/gitea/models"
asymkey_model "code.gitea.io/gitea/models/asymkey"
authmodel "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/modules/annex"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/eventsource"
"code.gitea.io/gitea/modules/git"
@@ -168,8 +167,6 @@ func InitWebInstalled(ctx context.Context) {
actions_service.Init()
- mustInit(annex.Init)
-
// Finally start up the cron
cron.NewContext(ctx)
}
diff --git a/routers/private/serv.go b/routers/private/serv.go
index a3a0c69..ef3920d 100644
--- a/routers/private/serv.go
+++ b/routers/private/serv.go
@@ -81,14 +81,12 @@ func ServCommand(ctx *context.PrivateContext) {
ownerName := ctx.Params(":owner")
repoName := ctx.Params(":repo")
mode := perm.AccessMode(ctx.FormInt("mode"))
- verbs := ctx.FormStrings("verb")
// Set the basic parts of the results to return
results := private.ServCommandResults{
RepoName: repoName,
OwnerName: ownerName,
KeyID: keyID,
- UserMode: perm.AccessModeNone,
}
// Now because we're not translating things properly let's just default some English strings here
@@ -289,10 +287,8 @@ func ServCommand(ctx *context.PrivateContext) {
repo.IsPrivate ||
owner.Visibility.IsPrivate() ||
(user != nil && user.IsRestricted) || // user will be nil if the key is a deploykey
- (setting.Annex.Enabled && len(verbs) > 0 && verbs[0] == "git-annex-shell") || // git-annex has its own permission enforcement, for which we expose results.UserMode
setting.Service.RequireSignInView) {
if key.Type == asymkey_model.KeyTypeDeploy {
- results.UserMode = deployKey.Mode
if deployKey.Mode < mode {
ctx.JSON(http.StatusUnauthorized, private.Response{
UserMsg: fmt.Sprintf("Deploy Key: %d:%s is not authorized to %s %s/%s.", key.ID, key.Name, modeString, results.OwnerName, results.RepoName),
@@ -314,9 +310,9 @@ func ServCommand(ctx *context.PrivateContext) {
return
}
- results.UserMode = perm.UnitAccessMode(unitType)
+ userMode := perm.UnitAccessMode(unitType)
- if results.UserMode < mode {
+ if userMode < mode {
log.Warn("Failed authentication attempt for %s with key %s (not authorized to %s %s/%s) from %s", user.Name, key.Name, modeString, ownerName, repoName, ctx.RemoteAddr())
ctx.JSON(http.StatusUnauthorized, private.Response{
UserMsg: fmt.Sprintf("User: %d:%s with Key: %d:%s is not authorized to %s %s/%s.", user.ID, user.Name, key.ID, key.Name, modeString, ownerName, repoName),
@@ -357,7 +353,6 @@ func ServCommand(ctx *context.PrivateContext) {
})
return
}
- results.UserMode = perm.AccessModeWrite
results.RepoID = repo.ID
}
@@ -386,14 +381,13 @@ func ServCommand(ctx *context.PrivateContext) {
return
}
}
- log.Debug("Serv Results:\nIsWiki: %t\nDeployKeyID: %d\nKeyID: %d\tKeyName: %s\nUserName: %s\nUserID: %d\nUserMode: %d\nOwnerName: %s\nRepoName: %s\nRepoID: %d",
+ log.Debug("Serv Results:\nIsWiki: %t\nDeployKeyID: %d\nKeyID: %d\tKeyName: %s\nUserName: %s\nUserID: %d\nOwnerName: %s\nRepoName: %s\nRepoID: %d",
results.IsWiki,
results.DeployKeyID,
results.KeyID,
results.KeyName,
results.UserName,
results.UserID,
- results.UserMode,
results.OwnerName,
results.RepoName,
results.RepoID)
diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go
index 968f596..ccab47a 100644
--- a/routers/web/auth/auth.go
+++ b/routers/web/auth/auth.go
@@ -169,8 +169,6 @@ func SignIn(ctx *context.Context) {
if setting.Service.EnableCaptcha && setting.Service.RequireCaptchaForLogin {
context.SetCaptchaData(ctx)
}
-
- ctx.Data["SignInForgottenPasswordEnabled"] = setting.Service.SignInForgottenPasswordEnabled
ctx.HTML(http.StatusOK, tplSignIn)
}
@@ -191,7 +189,6 @@ func SignInPost(ctx *context.Context) {
ctx.Data["PageIsLogin"] = true
ctx.Data["EnableSSPI"] = auth.IsSSPIEnabled(ctx)
ctx.Data["EnableInternalSignIn"] = setting.Service.EnableInternalSignIn
- ctx.Data["SignInForgottenPasswordEnabled"] = setting.Service.SignInForgottenPasswordEnabled
// Permission denied if EnableInternalSignIn is false
if !setting.Service.EnableInternalSignIn {
diff --git a/routers/web/home.go b/routers/web/home.go
index 3fa2524..d4be093 100644
--- a/routers/web/home.go
+++ b/routers/web/home.go
@@ -59,8 +59,6 @@ func Home(ctx *context.Context) {
return
}
- ctx.Data["LandingPageInfoEnabled"] = setting.Service.LandingPageInfoEnabled
-
ctx.Data["PageIsHome"] = true
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
ctx.HTML(http.StatusOK, tplHome)
diff --git a/routers/web/repo/annex.go b/routers/web/repo/annex.go
deleted file mode 100644
index 852b5a1..0000000
--- a/routers/web/repo/annex.go
+++ /dev/null
@@ -1,146 +0,0 @@
-package repo
-
-import (
- "context"
- "net"
- "net/http"
- "net/http/httputil"
- "net/url"
- "os"
- "os/exec"
- "strings"
- "syscall"
- "time"
-
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/annex"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- services_context "code.gitea.io/gitea/services/context"
-)
-
-type p2phttpRecordType struct {
- CancelFunc func()
- LastUsed time.Time
- Port string
-}
-
-var p2phttpRecords = make(map[string]*p2phttpRecordType)
-
-// AnnexP2PHTTP implements git-annex smart HTTP support by delegating to git annex p2phttp
-func AnnexP2PHTTP(ctx *services_context.Context) {
- uuid := ctx.Params(":uuid")
- repoPath, err := annex.UUID2RepoPath(uuid)
- if err != nil {
- ctx.PlainText(http.StatusNotFound, "Repository not found")
- return
- }
-
- parts := strings.Split(repoPath, "/")
- repoName := strings.TrimSuffix(parts[len(parts)-1], ".git")
- owner := parts[len(parts)-2]
- repo, err := repo_model.GetRepositoryByOwnerAndName(ctx, owner, repoName)
- if err != nil {
- ctx.PlainText(http.StatusNotFound, "Repository not found")
- return
- }
-
- p, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
- if err != nil {
- ctx.ServerError("GetUserRepoPermission", err)
- return
- }
-
- if !(ctx.Req.Method == "GET" && p.CanAccess(perm.AccessModeRead, unit.TypeCode) ||
- ctx.Req.Method == "POST" && p.CanAccess(perm.AccessModeWrite, unit.TypeCode) ||
- ctx.Req.Method == "POST" && strings.HasSuffix(ctx.Req.URL.Path, "/checkpresent") && p.CanAccess(perm.AccessModeRead, unit.TypeCode) ||
- ctx.Req.Method == "POST" && strings.HasSuffix(ctx.Req.URL.Path, "/keeplocked") ||
- ctx.Req.Method == "POST" && strings.HasSuffix(ctx.Req.URL.Path, "/lockcontent")) {
- // GET requests require at least read access; POST requests for
- // anything but checkpresent, lockcontent, and keeplocked
- // require write permissions; POST requests for checkpresent
- // only require read permissions, as it really is just a read.
- // POST requests for lockcontent and keeplocked require no
- // authentication at all, as is also the case for the
- // authentication in the git-annex-p2phttp server. See
- // https://git-annex.branchable.com/bugs/p2phttp__58___drop_difference_wideopen_unauth-readonly/
- // for reasoning.
- ctx.Resp.WriteHeader(http.StatusUnauthorized)
- return
- }
-
- p2phttpRecord, p2phttpProcessExists := p2phttpRecords[uuid]
- if p2phttpProcessExists {
- p2phttpRecord.LastUsed = time.Now()
- } else {
- // Start a new p2phttp process for the requested repository
- // There is a race condition here with the port selection, ideally git annex p2phttp could just listen on a unix socket...
- lis, err := net.Listen("tcp", "127.0.0.1:0")
- if err != nil {
- log.Error("Failed to listen on a free port: %v", err)
- ctx.Resp.WriteHeader(http.StatusInternalServerError)
- return
- }
- hopefullyFreePort := strings.SplitN(lis.Addr().String(), ":", 2)[1]
- lis.Close()
- p2phttpCtx, p2phttpCtxCancel := context.WithCancel(context.Background())
- go func(ctx context.Context) {
- cmd := exec.CommandContext(ctx, "git", "-C", repoPath, "annex", "p2phttp", "-J2", "--bind", "127.0.0.1", "--wideopen", "--port", hopefullyFreePort)
- cmd.SysProcAttr = &syscall.SysProcAttr{
- Pdeathsig: syscall.SIGINT,
- }
- cmd.Cancel = func() error { return cmd.Process.Signal(os.Interrupt) }
- _ = cmd.Run()
- }(p2phttpCtx)
- graceful.GetManager().RunAtTerminate(p2phttpCtxCancel)
-
- // Wait for the p2phttp server to get ready
- start := time.Now()
- sleepDuration := 1 * time.Millisecond
- for {
- if time.Since(start) > 5*time.Second {
- p2phttpCtxCancel()
- log.Error("Failed to start the p2phttp server in a reasonable amount of time")
- ctx.Resp.WriteHeader(http.StatusInternalServerError)
- return
- }
- conn, err := net.Dial("tcp", "127.0.0.1:"+hopefullyFreePort)
- if err == nil {
- conn.Close()
- break
- }
- time.Sleep(sleepDuration)
- sleepDuration *= 2
- if sleepDuration > 1*time.Second {
- sleepDuration = 1 * time.Second
- }
- }
-
- p2phttpRecord = &p2phttpRecordType{CancelFunc: p2phttpCtxCancel, LastUsed: time.Now(), Port: hopefullyFreePort}
- p2phttpRecords[uuid] = p2phttpRecord
- }
-
- // Cleanup p2phttp processes that haven't been used for a while
- for uuid, record := range p2phttpRecords {
- if time.Since(record.LastUsed) > 5*time.Minute {
- record.CancelFunc()
- delete(p2phttpRecords, uuid)
- }
- }
-
- url, err := url.Parse("http://127.0.0.1:" + p2phttpRecord.Port + strings.TrimPrefix(ctx.Req.RequestURI, "/git-annex-p2phttp"))
- if err != nil {
- log.Error("Failed to parse URL: %v", err)
- ctx.Resp.WriteHeader(http.StatusInternalServerError)
- return
- }
- proxy := httputil.ReverseProxy{
- Rewrite: func(r *httputil.ProxyRequest) {
- r.Out.URL = url
- },
- }
- proxy.ServeHTTP(ctx.Resp, ctx.Req)
-}
diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go
index 104655e..03d49fa 100644
--- a/routers/web/repo/compare.go
+++ b/routers/web/repo/compare.go
@@ -23,7 +23,6 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/annex"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/charset"
csv_module "code.gitea.io/gitea/modules/csv"
@@ -73,21 +72,7 @@ func setCompareContext(ctx *context.Context, before, head *git.Commit, headOwner
return st
}
- isAnnexed, err := annex.IsAnnexed(blob)
- if err != nil {
- log.Error("IsAnnexed failed: %v", err)
- return st
- }
- if isAnnexed {
- st, err = annex.GuessContentType(blob)
- if err != nil {
- log.Error("GuessContentType failed: %v", err)
- return st
- }
- return st
- }
-
- st, err = blob.GuessContentType()
+ st, err := blob.GuessContentType()
if err != nil {
log.Error("GuessContentType failed: %v", err)
return st
@@ -105,18 +90,18 @@ func SourceCommitURL(owner, name string, commit *git.Commit) string {
return setting.AppSubURL + "/" + url.PathEscape(owner) + "/" + url.PathEscape(name) + "/src/commit/" + url.PathEscape(commit.ID.String())
}
-// MediaCommitURL creates a relative URL for the commit media (plain git, LFS, or annex content) in the given repository
-func MediaCommitURL(owner, name string, commit *git.Commit) string {
- return setting.AppSubURL + "/" + url.PathEscape(owner) + "/" + url.PathEscape(name) + "/media/commit/" + url.PathEscape(commit.ID.String())
+// RawCommitURL creates a relative URL for the raw commit in the given repository
+func RawCommitURL(owner, name string, commit *git.Commit) string {
+ return setting.AppSubURL + "/" + url.PathEscape(owner) + "/" + url.PathEscape(name) + "/raw/commit/" + url.PathEscape(commit.ID.String())
}
// setPathsCompareContext sets context data for source and raw paths
func setPathsCompareContext(ctx *context.Context, base, head *git.Commit, headOwner, headName string) {
ctx.Data["SourcePath"] = SourceCommitURL(headOwner, headName, head)
- ctx.Data["RawPath"] = MediaCommitURL(headOwner, headName, head)
+ ctx.Data["RawPath"] = RawCommitURL(headOwner, headName, head)
if base != nil {
ctx.Data["BeforeSourcePath"] = SourceCommitURL(headOwner, headName, base)
- ctx.Data["BeforeRawPath"] = MediaCommitURL(headOwner, headName, base)
+ ctx.Data["BeforeRawPath"] = RawCommitURL(headOwner, headName, base)
}
}
diff --git a/routers/web/repo/download.go b/routers/web/repo/download.go
index aefaa79..1e87bbf 100644
--- a/routers/web/repo/download.go
+++ b/routers/web/repo/download.go
@@ -9,7 +9,6 @@ import (
"time"
git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/modules/annex"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/httpcache"
"code.gitea.io/gitea/modules/lfs"
@@ -80,26 +79,6 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob, lastModified *time.Tim
}
closed = true
- // check for git-annex files
- // (this code is weirdly redundant because I'm trying not to delete any lines in order to make merges easier)
- isAnnexed, err := annex.IsAnnexed(blob)
- if err != nil {
- ctx.ServerError("annex.IsAnnexed", err)
- return err
- }
- if isAnnexed {
- content, err := annex.Content(blob)
- if err != nil {
- // XXX are there any other possible failure cases here?
- // there are, there could be unrelated io errors; those should be ctx.ServerError()s
- ctx.NotFound("annex.Content", err)
- return err
- }
- defer content.Close()
- common.ServeContentByReadSeeker(ctx.Base, ctx.Repo.TreePath, lastModified, content)
- return nil
- }
-
return common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified)
}
diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go
index 2a43039..f27ad62 100644
--- a/routers/web/repo/editor.go
+++ b/routers/web/repo/editor.go
@@ -489,23 +489,8 @@ func DeleteFile(ctx *context.Context) {
ctx.HTML(http.StatusOK, tplDeleteFile)
}
-// DeletePath render delete file page
-func DeletePath(ctx *context.Context) {
- DeleteFile(ctx)
-}
-
// DeleteFilePost response for deleting file
func DeleteFilePost(ctx *context.Context) {
- DeletePathOrFilePost(ctx, false)
-}
-
-// DeletePathPost response for deleting path
-func DeletePathPost(ctx *context.Context) {
- DeletePathOrFilePost(ctx, true)
-}
-
-// DeletePathOrFilePost response for deleting path or file
-func DeletePathOrFilePost(ctx *context.Context, isdir bool) {
form := web.GetForm(ctx).(*forms.DeleteRepoFileForm)
canCommit := renderCommitRights(ctx)
branchName := ctx.Repo.BranchName
@@ -558,7 +543,6 @@ func DeletePathOrFilePost(ctx *context.Context, isdir bool) {
TreePath: ctx.Repo.TreePath,
},
},
- IsDir: isdir, // Add this flag to indicate directory deletion
Message: message,
Signoff: form.Signoff,
Author: gitIdentity,
@@ -774,7 +758,6 @@ func UploadFilePost(ctx *context.Context) {
TreePath: form.TreePath,
Message: message,
Files: form.Files,
- FullPaths: form.FullPaths,
Signoff: form.Signoff,
Author: gitIdentity,
Committer: gitIdentity,
diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go
index 53f18f9..c1adca1 100644
--- a/routers/web/repo/githttp.go
+++ b/routers/web/repo/githttp.go
@@ -10,7 +10,6 @@ import (
gocontext "context"
"fmt"
"net/http"
- "net/url"
"os"
"path/filepath"
"regexp"
@@ -79,24 +78,7 @@ func httpBase(ctx *context.Context) *serviceHandler {
strings.HasSuffix(ctx.Req.URL.Path, "git-upload-archive") {
isPull = true
} else {
- // In addition to GET requests, HEAD requests are also "pull"
- // operations (reads), so they should also not require
- // authentication. This is necessary for git-annex to operate
- // properly, as it emits HEAD requests to check for the
- // existence of keys, e.g. before dropping locally, and asking
- // for authentication would break unauthenticated http usage in
- // this situation.
- // It should be safe to make all HEAD requests require no
- // authentication, but as it is only necessary for the
- // annex/objects endpoints to fix git-annex' drop operations it
- // is limited to those for now.
- r, err := regexp.Compile("^/?" + username + "/" + reponame + "(.git)?/annex/objects")
- if err != nil {
- ctx.ServerError("failed to create URL path regex", err)
- return nil
- }
- isPull = ctx.Req.Method == "GET" ||
- r.MatchString(ctx.Req.URL.Path) && ctx.Req.Method == "HEAD"
+ isPull = ctx.Req.Method == "GET"
}
var accessMode perm.AccessMode
@@ -563,42 +545,6 @@ func GetInfoRefs(ctx *context.Context) {
}
}
-// GetConfig implements fetching the git config of a repository
-func GetConfig(ctx *context.Context) {
- h := httpBase(ctx)
- if h != nil {
- setHeaderNoCache(ctx)
- config, err := os.ReadFile(filepath.Join(h.getRepoDir(), "config"))
- if err != nil {
- log.Error("Failed to read git config file: %v", err)
- ctx.Resp.WriteHeader(http.StatusInternalServerError)
- return
- }
- if !setting.Annex.DisableP2PHTTP {
- appURL, err := url.Parse(setting.AppURL)
- if err != nil {
- log.Error("Could not parse 'setting.AppURL': %v", err)
- ctx.Resp.WriteHeader(http.StatusInternalServerError)
- return
- }
- if appURL.Port() == "" {
- // If there is no port set then set the http(s) default ports.
- // Without this, git-annex would try its own default port (9417) and fail.
- if appURL.Scheme == "http" {
- appURL.Host += ":80"
- }
- if appURL.Scheme == "https" {
- appURL.Host += ":443"
- }
- }
- config = append(config, []byte("[annex]\n\turl = annex+"+appURL.String()+"git-annex-p2phttp\n")...)
- }
- ctx.Resp.Header().Set("Content-Type", "text/plain")
- ctx.Resp.Header().Set("Content-Length", fmt.Sprintf("%d", len(config)))
- http.ServeContent(ctx.Resp, ctx.Req, "config", time.Now(), bytes.NewReader(config))
- }
-}
-
// GetTextFile implements Git dumb HTTP
func GetTextFile(p string) func(*context.Context) {
return func(ctx *context.Context) {
@@ -651,34 +597,3 @@ func GetIdxFile(ctx *context.Context) {
h.sendFile(ctx, "application/x-git-packed-objects-toc", "objects/pack/pack-"+ctx.Params("file")+".idx")
}
}
-
-// GetAnnexObject implements git-annex dumb HTTP
-func GetAnnexObject(ctx *context.Context) {
- h := httpBase(ctx)
- if h != nil {
- // git-annex objects are stored in .git/annex/objects/{hash1}/{hash2}/{key}/{key}
- // where key is a string containing the size and (usually SHA256) checksum of the file,
- // and hash1+hash2 are the first few bits of the md5sum of key itself.
- // ({hash1}/{hash2}/ is just there to avoid putting too many files in one directory)
- // ref: https://git-annex.branchable.com/internals/hashing/
-
- // keyDir should = key, but we don't enforce that
- object := filepath.Join(ctx.Params("hash1"), ctx.Params("hash2"), ctx.Params("keyDir"), ctx.Params("key"))
-
- // Sanitize the input against directory traversals.
- //
- // This works because at the filesystem root, "/.." = "/";
- // So if a path starts rooted ("/"), path.Clean(), which
- // path.Join() calls internally, removes all '..' prefixes.
- // After, this unroots the path unconditionally ([1:]), which
- // works because we know the input is never supposed to be rooted.
- //
- // The router code probably also disallows "..", so this
- // should be redundant, but it's defensive to keep it
- // whenever touching filesystem paths with user input.
- object = filepath.Join(string(filepath.Separator), object)[1:]
-
- setHeaderCacheForever(ctx)
- h.sendFile(ctx, "application/octet-stream", "annex/objects/"+object)
- }
-}
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index a3976ec..fd8c1da 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -34,7 +34,6 @@ import (
unit_model "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/actions"
- "code.gitea.io/gitea/modules/annex"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/charset"
"code.gitea.io/gitea/modules/git"
@@ -210,59 +209,14 @@ func localizedExtensions(ext, languageCode string) (localizedExts []string) {
}
type fileInfo struct {
- isTextFile bool
- isLFSFile bool
- isAnnexFile bool
- isAnnexFilePresent bool
- fileSize int64
- lfsMeta *lfs.Pointer
- st typesniffer.SniffedType
+ isTextFile bool
+ isLFSFile bool
+ fileSize int64
+ lfsMeta *lfs.Pointer
+ st typesniffer.SniffedType
}
func getFileReader(ctx gocontext.Context, repoID int64, blob *git.Blob) ([]byte, io.ReadCloser, *fileInfo, error) {
- isAnnexed, err := annex.IsAnnexed(blob)
- if err != nil {
- return nil, nil, nil, err
- }
- if isAnnexed {
- // TODO: this code could be merged with the LFS case, especially the redundant type sniffer,
- // but it is *currently* written this way to make merging with the non-annex upstream easier:
- // this way, the git-annex patch is (mostly) pure additions.
-
- annexContent, err := annex.Content(blob)
- if err != nil {
- // If annex.Content returns an error it can mean that the blob does not
- // refer to an annexed file or that it is not present here. Since we already
- // checked that it is annexed the latter must be the case. So we return the
- // content of the blob instead and indicate that the file is indeed annexed,
- // but not present here. The template can then communicate the situation.
- dataRc, err := blob.DataAsync()
- if err != nil {
- return nil, nil, nil, err
- }
-
- buf := make([]byte, 1024)
- n, _ := util.ReadAtMost(dataRc, buf)
- buf = buf[:n]
-
- st := typesniffer.DetectContentType(buf)
- return buf, dataRc, &fileInfo{st.IsText(), false, true, false, blob.Size(), nil, st}, nil
- }
-
- stat, err := annexContent.Stat()
- if err != nil {
- return nil, nil, nil, err
- }
-
- buf := make([]byte, 1024)
- n, _ := util.ReadAtMost(annexContent, buf)
- buf = buf[:n]
-
- st := typesniffer.DetectContentType(buf)
-
- return buf, annexContent, &fileInfo{st.IsText(), false, true, true, stat.Size(), nil, st}, nil
- }
-
dataRc, err := blob.DataAsync()
if err != nil {
return nil, nil, nil, err
@@ -277,18 +231,18 @@ func getFileReader(ctx gocontext.Context, repoID int64, blob *git.Blob) ([]byte,
// FIXME: what happens when README file is an image?
if !isTextFile || !setting.LFS.StartServer {
- return buf, dataRc, &fileInfo{isTextFile, false, false, false, blob.Size(), nil, st}, nil
+ return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
}
pointer, _ := lfs.ReadPointerFromBuffer(buf)
if !pointer.IsValid() { // fallback to plain file
- return buf, dataRc, &fileInfo{isTextFile, false, false, false, blob.Size(), nil, st}, nil
+ return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
}
meta, err := git_model.GetLFSMetaObjectByOid(ctx, repoID, pointer.Oid)
if err != nil { // fallback to plain file
log.Warn("Unable to access LFS pointer %s in repo %d: %v", pointer.Oid, repoID, err)
- return buf, dataRc, &fileInfo{isTextFile, false, false, false, blob.Size(), nil, st}, nil
+ return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
}
dataRc.Close()
@@ -308,7 +262,7 @@ func getFileReader(ctx gocontext.Context, repoID int64, blob *git.Blob) ([]byte,
st = typesniffer.DetectContentType(buf)
- return buf, dataRc, &fileInfo{st.IsText(), true, false, false, meta.Size, &meta.Pointer, st}, nil
+ return buf, dataRc, &fileInfo{st.IsText(), true, meta.Size, &meta.Pointer, st}, nil
}
func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.TreeEntry) {
@@ -371,7 +325,6 @@ func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.Tr
},
Metas: ctx.Repo.Repository.ComposeDocumentMetas(ctx),
GitRepo: ctx.Repo.GitRepo,
- Blob: target.Blob(),
}, rd)
if err != nil {
log.Error("Render failed for %s in %-v: %v Falling back to rendering source", readmeFile.Name(), ctx.Repo.Repository, err)
@@ -494,17 +447,10 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
isDisplayingSource := ctx.FormString("display") == "source"
isDisplayingRendered := !isDisplayingSource
- if fInfo.isLFSFile || fInfo.isAnnexFile {
+ if fInfo.isLFSFile {
ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/media/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
}
- if fInfo.isAnnexFile {
- // pre-git-annex v7, all annexed files were represented in-repo as symlinks;
- // but we pretend they aren't, since that's a distracting quirk of git-annex
- // and not a meaningful choice on the user's part
- ctx.Data["FileIsSymlink"] = false
- }
-
isRepresentableAsText := fInfo.st.IsRepresentableAsText()
if !isRepresentableAsText {
// If we can't show plain text, always try to render.
@@ -512,8 +458,6 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
isDisplayingRendered = true
}
ctx.Data["IsLFSFile"] = fInfo.isLFSFile
- ctx.Data["IsAnnexFile"] = fInfo.isAnnexFile
- ctx.Data["IsAnnexFilePresent"] = fInfo.isAnnexFilePresent
ctx.Data["FileSize"] = fInfo.fileSize
ctx.Data["IsTextFile"] = fInfo.isTextFile
ctx.Data["IsRepresentableAsText"] = isRepresentableAsText
@@ -548,8 +492,6 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
// Assume file is not editable first.
if fInfo.isLFSFile {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_lfs_files")
- } else if fInfo.isAnnexFile {
- ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_annex_files")
} else if !isRepresentableAsText {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_non_text_files")
}
@@ -604,7 +546,6 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
},
Metas: metas,
GitRepo: ctx.Repo.GitRepo,
- Blob: entry.Blob(),
}, rd)
if err != nil {
ctx.ServerError("Render", err)
@@ -658,7 +599,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
ctx.Data["FileContent"] = fileContent
ctx.Data["LineEscapeStatus"] = statuses
}
- if !fInfo.isLFSFile && !fInfo.isAnnexFile {
+ if !fInfo.isLFSFile {
if ctx.Repo.CanEnableEditor(ctx, ctx.Doer) {
if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID {
ctx.Data["CanEditFile"] = false
@@ -703,7 +644,6 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
},
Metas: ctx.Repo.Repository.ComposeDocumentMetas(ctx),
GitRepo: ctx.Repo.GitRepo,
- Blob: entry.Blob(),
}, rd)
if err != nil {
ctx.ServerError("Render", err)
@@ -1219,36 +1159,6 @@ PostRecentBranchCheck:
} else {
ctx.Data["CodeSearchOptions"] = git.GrepSearchOptions
}
-
- lfsLock, err := git_model.GetTreePathLock(ctx, ctx.Repo.Repository.ID, ctx.Repo.TreePath)
- if err != nil {
- ctx.ServerError("git_model.GetTreePathLock", err)
- return
- }
-
- if ctx.Repo.CanEnableEditor(ctx, ctx.Doer) {
- if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID {
- ctx.Data["CanDeleteFile"] = false
- ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.this_file_locked")
- } else {
- ctx.Data["CanDeleteFile"] = true
- ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.delete_this_file")
- }
- } else if !ctx.Repo.IsViewBranch {
- ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch")
- } else if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
- ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_have_write_access")
- }
-
- isAnnexFile, okAnnexFile := ctx.Data["IsAnnexFile"]
- isAnnexFilePresent, okAnnexFilePresent := ctx.Data["IsAnnexFilePresent"]
- if okAnnexFile && okAnnexFilePresent && isAnnexFile.(bool) && !isAnnexFilePresent.(bool) {
- // If the file to be viewed is annexed but not present then render it normally
- // (which will show the plain git blob content, i.e. the symlink or pointer target)
- // but make the status code a 404.
- ctx.HTML(http.StatusNotFound, tplRepoHome)
- return
- }
ctx.HTML(http.StatusOK, tplRepoHome)
}
diff --git a/routers/web/web.go b/routers/web/web.go
index a276fa2..4d8d280 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -51,7 +51,6 @@ import (
_ "code.gitea.io/gitea/modules/session" // to registers all internal adapters
- "code.forgejo.org/go-chi/binding"
"code.forgejo.org/go-chi/captcha"
chi_middleware "github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/cors"
@@ -357,20 +356,6 @@ func registerRoutes(m *web.Route) {
}
}
- annexEnabled := func(ctx *context.Context) {
- if !setting.Annex.Enabled {
- ctx.Error(http.StatusNotFound)
- return
- }
- }
-
- annexP2PHTTPEnabled := func(ctx *context.Context) {
- if setting.Annex.DisableP2PHTTP {
- ctx.Error(http.StatusNotFound)
- return
- }
- }
-
federationEnabled := func(ctx *context.Context) {
if !setting.Federation.Enabled {
ctx.Error(http.StatusNotFound)
@@ -970,9 +955,6 @@ func registerRoutes(m *web.Route) {
// ***** END: Organization *****
// ***** START: Repository *****
- m.Group("", func() {
- m.Methods("GET,POST", "/git-annex-p2phttp/git-annex/{uuid}/*", repo.AnnexP2PHTTP)
- }, ignSignInAndCsrf, annexEnabled, annexP2PHTTPEnabled)
m.Group("/repo", func() {
m.Get("/create", repo.Create)
m.Post("/create", web.Bind(forms.CreateRepoForm{}), repo.CreatePost)
@@ -1269,13 +1251,11 @@ func registerRoutes(m *web.Route) {
m.Combo("/_new/*").Get(repo.NewFile).
Post(web.Bind(forms.EditRepoFileForm{}), repo.NewFilePost)
m.Post("/_preview/*", web.Bind(forms.EditPreviewDiffForm{}), repo.DiffPreviewPost)
- m.Combo("/_delete_path/*").Get(repo.DeletePath).
- Post(web.Bind(forms.DeleteRepoFileForm{}), repo.DeletePathPost)
m.Combo("/_delete/*").Get(repo.DeleteFile).
Post(web.Bind(forms.DeleteRepoFileForm{}), repo.DeleteFilePost)
m.Combo("/_upload/*", repo.MustBeAbleToUpload).
Get(repo.UploadFile).
- Post(BindUpload(forms.UploadRepoFileForm{}), repo.UploadFilePost)
+ Post(web.Bind(forms.UploadRepoFileForm{}), repo.UploadFilePost)
m.Combo("/_diffpatch/*").Get(repo.NewDiffPatch).
Post(web.Bind(forms.EditRepoFileForm{}), repo.NewDiffPatchPost)
m.Combo("/_cherrypick/{sha:([a-f0-9]{4,64})}/*").Get(repo.CherryPick).
@@ -1655,12 +1635,6 @@ func registerRoutes(m *web.Route) {
})
}, ignSignInAndCsrf, lfsServerEnabled)
- m.Group("", func() {
- // for git-annex
- m.Methods("GET,OPTIONS", "/config", repo.GetConfig) // needed by clients reading annex.uuid during `git annex initremote`
- m.Methods("GET,OPTIONS", "/annex/objects/{hash1}/{hash2}/{keyDir}/{key}", repo.GetAnnexObject)
- }, ignSignInAndCsrf, annexEnabled, context.UserAssignmentWeb())
-
gitHTTPRouters(m)
})
})
@@ -1697,20 +1671,3 @@ func registerRoutes(m *web.Route) {
ctx.NotFound("", nil)
})
}
-
-func BindUpload(f forms.UploadRepoFileForm) http.HandlerFunc {
- return func(resp http.ResponseWriter, req *http.Request) {
- theObj := new(forms.UploadRepoFileForm) // create a new form obj for every request but not use obj directly
- data := middleware.GetContextData(req.Context())
- binding.Bind(req, theObj)
- files := theObj.Files
- var fullpaths []string
- for _, fileID := range files {
- fullPath := req.Form.Get("files_fullpath[" + fileID + "]")
- fullpaths = append(fullpaths, fullPath)
- }
- theObj.FullPaths = fullpaths
- data.GetData()["__form"] = theObj
- middleware.AssignForm(theObj, data)
- }
-}
diff --git a/services/auth/auth.go b/services/auth/auth.go
index ddd3191..c108723 100644
--- a/services/auth/auth.go
+++ b/services/auth/auth.go
@@ -61,17 +61,6 @@ func isArchivePath(req *http.Request) bool {
return archivePathRe.MatchString(req.URL.Path)
}
-var annexPathRe = regexp.MustCompile(`^(/git-annex-p2phttp/|/[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+/annex/)`)
-
-func isAnnexPath(req *http.Request) bool {
- if setting.Annex.Enabled {
- // "/config" is git's config, not specifically git-annex's; but the only current
- // user of it is when git-annex downloads the annex.uuid during 'git annex init'.
- return strings.HasSuffix(req.URL.Path, "/config") || annexPathRe.MatchString(req.URL.Path)
- }
- return false
-}
-
// handleSignIn clears existing session variables and stores new ones for the specified user object
func handleSignIn(resp http.ResponseWriter, req *http.Request, sess SessionStore, user *user_model.User) {
// We need to regenerate the session...
diff --git a/services/auth/basic.go b/services/auth/basic.go
index 8e8fbfc..d489164 100644
--- a/services/auth/basic.go
+++ b/services/auth/basic.go
@@ -43,8 +43,8 @@ func (b *Basic) Name() string {
// name/token on successful validation.
// Returns nil if header is empty or validation fails.
func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) {
- // Basic authentication should only fire on API, Download or on Git, LFSPaths or Git-Annex paths
- if !middleware.IsAPIPath(req) && !isContainerPath(req) && !isAttachmentDownload(req) && !isGitRawOrAttachOrLFSPath(req) && !isAnnexPath(req) {
+ // Basic authentication should only fire on API, Download or on Git or LFSPaths
+ if !middleware.IsAPIPath(req) && !isContainerPath(req) && !isAttachmentDownload(req) && !isGitRawOrAttachOrLFSPath(req) {
return nil, nil
}
diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go
index 75936f8..1ce9b29 100644
--- a/services/forms/repo_form.go
+++ b/services/forms/repo_form.go
@@ -671,7 +671,6 @@ type UploadRepoFileForm struct {
CommitChoice string `binding:"Required;MaxSize(50)"`
NewBranchName string `binding:"GitRefName;MaxSize(100)"`
Files []string
- FullPaths []string
CommitMailID int64 `binding:"Required"`
Signoff bool
}
diff --git a/services/repository/files/temp_repo.go b/services/repository/files/temp_repo.go
index 566ae5f..6e7570b 100644
--- a/services/repository/files/temp_repo.go
+++ b/services/repository/files/temp_repo.go
@@ -202,26 +202,6 @@ func (t *TemporaryUploadRepository) AddObjectToIndex(mode, objectHash, objectPat
return nil
}
-// InitPrivateAnnex initializes a private annex in the repository
-func (t *TemporaryUploadRepository) InitPrivateAnnex() error {
- if _, _, err := git.NewCommand(t.ctx, "config", "annex.private", "true").RunStdString(&git.RunOpts{Dir: t.basePath}); err != nil {
- return err
- }
- if _, _, err := git.NewCommand(t.ctx, "annex", "init").RunStdString(&git.RunOpts{Dir: t.basePath}); err != nil {
- return err
- }
- return nil
-}
-
-// AddAnnex adds the file at path to the repository using git annex add
-// This requires a non-bare repository
-func (t *TemporaryUploadRepository) AddAnnex(path string) error {
- if _, _, err := git.NewCommand(t.ctx, "annex", "add").AddDynamicArguments(path).RunStdString(&git.RunOpts{Dir: t.basePath}); err != nil {
- return err
- }
- return nil
-}
-
// WriteTree writes the current index as a tree to the object db and returns its hash
func (t *TemporaryUploadRepository) WriteTree() (string, error) {
stdout, _, err := git.NewCommand(t.ctx, "write-tree").RunStdString(&git.RunOpts{Dir: t.basePath})
diff --git a/services/repository/files/update.go b/services/repository/files/update.go
index 5ef778c..d6025b6 100644
--- a/services/repository/files/update.go
+++ b/services/repository/files/update.go
@@ -10,7 +10,6 @@ import (
"path"
"strings"
"time"
- "errors"
"code.gitea.io/gitea/models"
git_model "code.gitea.io/gitea/models/git"
@@ -57,7 +56,6 @@ type ChangeRepoFilesOptions struct {
Committer *IdentityOptions
Dates *CommitDateOptions
Signoff bool
- IsDir bool `default:"false"`
}
type RepoFileOptions struct {
@@ -92,30 +90,6 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use
return nil, err
}
- if opts.IsDir {
- var new_opts_files []*ChangeRepoFile
- for _, file := range opts.Files {
- if file.Operation != "delete" {
- return nil, errors.New("invalid operation: only delete is allowed for directory paths")
- }
- treePath := CleanUploadFileName(file.TreePath)
- filelist, err := gitRepo.LsFilesFromDirectory(treePath, opts.OldBranch)
- if err != nil {
- return nil, err
- }
- for _, filename := range filelist {
- if len(filename) > 0{
-
- new_opts_files = append(new_opts_files, &ChangeRepoFile{
- Operation: "delete",
- TreePath: filename,
- })
- }
- }
- }
- opts.Files = new_opts_files
- }
-
var treePaths []string
for _, file := range opts.Files {
// If FromTreePath is not set, set it to the opts.TreePath
diff --git a/services/repository/files/upload.go b/services/repository/files/upload.go
index a43e688..1330116 100644
--- a/services/repository/files/upload.go
+++ b/services/repository/files/upload.go
@@ -6,18 +6,13 @@ package files
import (
"context"
"fmt"
- "html"
- "io"
"os"
"path"
- "path/filepath"
- "regexp"
"strings"
git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/annex"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/setting"
@@ -32,8 +27,7 @@ type UploadRepoFileOptions struct {
Message string
Author *IdentityOptions
Committer *IdentityOptions
- Files []string // In UUID format
- FullPaths []string
+ Files []string // In UUID format.
Signoff bool
}
@@ -62,10 +56,6 @@ func UploadRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use
return nil
}
- if len(opts.Files) != len(opts.FullPaths) {
- return nil
- }
-
uploads, err := repo_model.GetUploadsByUUIDs(ctx, opts.Files)
if err != nil {
return fmt.Errorf("GetUploadsByUUIDs [uuids: %v]: %w", opts.Files, err)
@@ -75,7 +65,6 @@ func UploadRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use
infos := make([]uploadInfo, len(uploads))
for i, upload := range uploads {
// Check file is not lfs locked, will return nil if lock setting not enabled
- upload.Name = fileNameSanitize(html.UnescapeString(opts.FullPaths[i]))
filepath := path.Join(opts.TreePath, upload.Name)
lfsLock, err := git_model.GetTreePathLock(ctx, repo.ID, filepath)
if err != nil {
@@ -100,7 +89,7 @@ func UploadRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use
defer t.Close()
hasOldBranch := true
- if err = t.Clone(opts.OldBranch, false); err != nil {
+ if err = t.Clone(opts.OldBranch, true); err != nil {
if !git.IsErrBranchNotExist(err) || !repo.IsEmpty {
return err
}
@@ -116,30 +105,10 @@ func UploadRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use
}
}
- r, err := git.OpenRepository(ctx, repo.RepoPath())
- if err != nil {
+ // Copy uploaded files into repository.
+ if err := copyUploadedLFSFilesIntoRepository(infos, t, opts.TreePath); err != nil {
return err
}
- if annex.IsAnnexRepo(r) {
- // Initialize annex privately in temporary clone
- if err := t.InitPrivateAnnex(); err != nil {
- return err
- }
- // Copy uploaded files into git-annex repository
- if err := copyUploadedFilesIntoAnnexRepository(infos, t, opts.TreePath); err != nil {
- return err
- }
- // Move all annexed content in the temporary repository, i.e. everything we have just added, to the origin
- author, committer := GetAuthorAndCommitterUsers(opts.Author, opts.Committer, doer)
- if err := moveAnnexedFilesToOrigin(t, author, committer); err != nil {
- return err
- }
- } else {
- // Copy uploaded files into repository.
- if err := copyUploadedLFSFilesIntoRepository(infos, t, opts.TreePath); err != nil {
- return err
- }
- }
// Now write the tree
treeHash, err := t.WriteTree()
@@ -186,19 +155,6 @@ func UploadRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use
return repo_model.DeleteUploads(ctx, uploads...)
}
-// From forgejo/services/repository/generate.go (but now allows /)
-var fileNameSanitizeRegexp = regexp.MustCompile(`(?i)\.\.|[<>:\"\\|?*\x{0000}-\x{001F}]|^(con|prn|aux|nul|com\d|lpt\d)$`)
-
-// Sanitize user input to valid OS filenames
-//
-// Based on https://github.com/sindresorhus/filename-reserved-regex
-// Adds ".." to prevent directory traversal
-func fileNameSanitize(s string) string {
- // Added this because I am not sure what Windows will deliver us \ or / but we need /.
- s = strings.ReplaceAll(s, "\\", "/")
- return strings.TrimSpace(fileNameSanitizeRegexp.ReplaceAllString(s, "_"))
-}
-
func copyUploadedLFSFilesIntoRepository(infos []uploadInfo, t *TemporaryUploadRepository, treePath string) error {
var storeInLFSFunc func(string) (bool, error)
@@ -290,57 +246,3 @@ func uploadToLFSContentStore(info uploadInfo, contentStore *lfs.ContentStore) er
}
return nil
}
-
-func copyUploadedFilesIntoAnnexRepository(infos []uploadInfo, t *TemporaryUploadRepository, treePath string) error {
- for i := range len(infos) {
- if err := copyUploadedFileIntoAnnexRepository(&infos[i], t, treePath); err != nil {
- return err
- }
- }
- return nil
-}
-
-func copyUploadedFileIntoAnnexRepository(info *uploadInfo, t *TemporaryUploadRepository, treePath string) error {
- pathInRepo := path.Join(t.basePath, treePath, info.upload.Name)
- if err := os.MkdirAll(filepath.Dir(pathInRepo), 0o700); err != nil {
- return err
- }
- if err := os.Rename(info.upload.LocalPath(), pathInRepo); err != nil {
- // Rename didn't work, try copy and remove
- inputFile, err := os.Open(info.upload.LocalPath())
- if err != nil {
- return fmt.Errorf("could not open source file: %v", err)
- }
- defer inputFile.Close()
- outputFile, err := os.Create(pathInRepo)
- if err != nil {
- return fmt.Errorf("could not open dest file: %v", err)
- }
- defer outputFile.Close()
- _, err = io.Copy(outputFile, inputFile)
- if err != nil {
- return fmt.Errorf("could not copy to dest from source: %v", err)
- }
- inputFile.Close()
- err = os.Remove(info.upload.LocalPath())
- if err != nil {
- return fmt.Errorf("could not remove source file: %v", err)
- }
- }
- return t.AddAnnex(pathInRepo)
-}
-
-func moveAnnexedFilesToOrigin(t *TemporaryUploadRepository, author, committer *user_model.User) error {
- authorSig := author.NewGitSig()
- committerSig := committer.NewGitSig()
- env := append(os.Environ(),
- "GIT_AUTHOR_NAME="+authorSig.Name,
- "GIT_AUTHOR_EMAIL="+authorSig.Email,
- "GIT_COMMITTER_NAME="+committerSig.Name,
- "GIT_COMMITTER_EMAIL="+committerSig.Email,
- )
- if _, _, err := git.NewCommand(t.ctx, "annex", "move", "--to", "origin").RunStdString(&git.RunOpts{Dir: t.basePath, Env: env}); err != nil {
- return err
- }
- return nil
-}
diff --git a/templates/home.tmpl b/templates/home.tmpl
index 5f84fca..a974344 100644
--- a/templates/home.tmpl
+++ b/templates/home.tmpl
@@ -11,10 +11,41 @@
-
- {{if .LandingPageInfoEnabled}}
- {{template "landing-page" .}}
- {{end}}
-
+
+
+
+
+ {{ctx.Locale.Tr "startpage.install_desc" "https://forgejo.org/download/#installation-from-binary" "https://forgejo.org/download/#container-image" "https://forgejo.org/download"}}
+
+
+
+
+
+ {{ctx.Locale.Tr "startpage.platform_desc"}}
+
+
+
+
+
+
+
+ {{ctx.Locale.Tr "startpage.lightweight_desc"}}
+
+
+
+
+
+ {{ctx.Locale.Tr "startpage.license_desc" "https://forgejo.org/download" "https://codeberg.org/forgejo/forgejo"}}
+
+
+
{{template "base/footer" .}}
diff --git a/templates/landing-page.tmpl b/templates/landing-page.tmpl
deleted file mode 100644
index 5eb6822..0000000
--- a/templates/landing-page.tmpl
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
- {{ctx.Locale.Tr "startpage.install_desc" "https://forgejo.org/download/#installation-from-binary" "https://forgejo.org/download/#container-image" "https://forgejo.org/download"}}
-
-
-
-
-
- {{ctx.Locale.Tr "startpage.platform_desc"}}
-
-
-
-
-
-
-
- {{ctx.Locale.Tr "startpage.lightweight_desc"}}
-
-
-
-
-
- {{ctx.Locale.Tr "startpage.license_desc" "https://forgejo.org/download" "https://codeberg.org/forgejo/forgejo"}}
-
-
-
\ No newline at end of file
diff --git a/templates/repo/file_info.tmpl b/templates/repo/file_info.tmpl
index 8655404..6ae7c15 100644
--- a/templates/repo/file_info.tmpl
+++ b/templates/repo/file_info.tmpl
@@ -17,7 +17,6 @@
{{if .FileSize}}
{{ctx.Locale.TrSize .FileSize}}{{if .IsLFSFile}} ({{ctx.Locale.Tr "repo.stored_lfs"}}){{end}}
- {{if .IsAnnexFile}} ({{ctx.Locale.Tr "repo.stored_annex"}}{{if not .IsAnnexFilePresent}} - {{ctx.Locale.Tr "repo.stored_annex_not_present"}}{{end}}){{end}}
{{end}}
{{if .LFSLock}}
diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl
index 7b98665..7bf4ee4 100644
--- a/templates/repo/home.tmpl
+++ b/templates/repo/home.tmpl
@@ -114,15 +114,6 @@
{{- end -}}
{{end}}
-
- {{if (not .IsViewFile)}}
- {{if and .CanDeleteFile (not .IsBlame)}}
- {{svg "octicon-trash"}}
- {{else}}
- {{svg "octicon-trash"}}
- {{end}}
- {{end}}
-
diff --git a/templates/user/auth/signin_inner.tmpl b/templates/user/auth/signin_inner.tmpl
index 6862f5c..ddef34f 100644
--- a/templates/user/auth/signin_inner.tmpl
+++ b/templates/user/auth/signin_inner.tmpl
@@ -50,21 +50,18 @@
-{{if .SignInForgottenPasswordEnabled}}
-
- {{template "user/auth/webauthn_error" .}}
+
+ {{template "user/auth/webauthn_error" .}}
-
+
diff --git a/tests/integration/api_helper_for_declarative_test.go b/tests/integration/api_helper_for_declarative_test.go
index 5bd8dc5..dae71ca 100644
--- a/tests/integration/api_helper_for_declarative_test.go
+++ b/tests/integration/api_helper_for_declarative_test.go
@@ -22,7 +22,6 @@ import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/services/forms"
- "github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -462,27 +461,3 @@ func doAPIAddRepoToOrganizationTeam(ctx APITestContext, teamID int64, orgName, r
ctx.Session.MakeRequest(t, req, http.StatusNoContent)
}
}
-
-// generate and activate an ssh key for the user attached to the APITestContext
-// TODO: pick a better name; golang doesn't do method overriding.
-func withCtxKeyFile(t *testing.T, ctx APITestContext, callback func()) {
- // we need to have write:public_key to do this step
- // the easiest way is to create a throwaway ctx that is identical but only has that permission
- ctxKeyWriter := ctx
- ctxKeyWriter.Token = getTokenForLoggedInUser(t, ctx.Session, auth.AccessTokenScopeWriteUser)
-
- keyName := "One of " + ctx.Username + "'s keys: #" + uuid.New().String()
- withKeyFile(t, keyName, func(keyFile string) {
- var key api.PublicKey
-
- doAPICreateUserKey(ctxKeyWriter, keyName, keyFile,
- func(t *testing.T, _key api.PublicKey) {
- // save the key ID so we can delete it at the end
- key = _key
- })(t)
-
- defer doAPIDeleteUserKey(ctxKeyWriter, key.ID)(t)
-
- callback()
- })
-}
diff --git a/tests/integration/git_annex_test.go b/tests/integration/git_annex_test.go
deleted file mode 100644
index efcb571..0000000
--- a/tests/integration/git_annex_test.go
+++ /dev/null
@@ -1,2925 +0,0 @@
-// Copyright 2022 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.
-
-package integration
-
-import (
- "bytes"
- "errors"
- "fmt"
- "io"
- "math/rand"
- "mime/multipart"
- "net/http"
- "net/url"
- "os"
- "path"
- "path/filepath"
- "regexp"
- "strings"
- "testing"
-
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/annex"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/tests"
-
- "github.com/stretchr/testify/require"
-)
-
-// Some guidelines:
-//
-// * a APITestContext is an awkward union of session credential + username + target repo
-// which is assumed to be owned by that username; if you want to target a different
-// repo, you need to edit its .Reponame or just ignore it and write "username/reponame.git"
-
-func doCreateRemoteAnnexRepository(t *testing.T, u *url.URL, ctx APITestContext, private bool, objectFormat git.ObjectFormat) (err error) {
- // creating a repo counts as editing the user's profile (is done by POSTing
- // to /api/v1/user/repos/) -- which means it needs a User-scoped token and
- // both that and editing need a Repo-scoped token because they edit repositories.
- rescopedCtx := ctx
- rescopedCtx.Token = getTokenForLoggedInUser(t, ctx.Session, auth_model.AccessTokenScopeWriteUser, auth_model.AccessTokenScopeWriteRepository)
- doAPICreateRepository(rescopedCtx, false, objectFormat)(t)
- t.Cleanup(func() { util.MakeWritable(setting.RepoRootPath) })
- doAPIEditRepository(rescopedCtx, &api.EditRepoOption{Private: &private})(t)
-
- repoURL := createSSHUrl(ctx.GitPath(), u)
-
- // Fill in fixture data
- withAnnexCtxKeyFile(t, ctx, func() {
- err = doInitRemoteAnnexRepository(t, repoURL)
- })
- if err != nil {
- return fmt.Errorf("Unable to initialize remote repo with git-annex fixture: %w", err)
- }
- return nil
-}
-
-func TestGitAnnexWebUpload(t *testing.T) {
- if !setting.Annex.Enabled {
- t.Skip("Skipping since annex support is disabled.")
- }
-
- onGiteaRun(t, func(t *testing.T, u *url.URL) {
- forEachObjectFormat(t, func(t *testing.T, objectFormat git.ObjectFormat) {
- ctx := NewAPITestContext(t, "user2", "annex-web-upload-test"+objectFormat.Name(), auth_model.AccessTokenScopeWriteRepository)
- require.NoError(t, doCreateRemoteAnnexRepository(t, u, ctx, false, objectFormat))
-
- uploadFile := func(t *testing.T, path string) string {
- t.Helper()
-
- body := &bytes.Buffer{}
- mpForm := multipart.NewWriter(body)
- err := mpForm.WriteField("_csrf", GetCSRF(t, ctx.Session, ctx.Username+"/"+ctx.Reponame+"/_upload/"+setting.Repository.DefaultBranch))
- require.NoError(t, err)
-
- file, err := mpForm.CreateFormFile("file", filepath.Base(path))
- require.NoError(t, err)
-
- srcFile, err := os.Open(path)
- require.NoError(t, err)
-
- io.Copy(file, srcFile)
- require.NoError(t, mpForm.Close())
-
- req := NewRequestWithBody(t, "POST", "/"+ctx.Username+"/"+ctx.Reponame+"/upload-file", body)
- req.Header.Add("Content-Type", mpForm.FormDataContentType())
- resp := ctx.Session.MakeRequest(t, req, http.StatusOK)
-
- respMap := map[string]string{}
- DecodeJSON(t, resp, &respMap)
- return respMap["uuid"]
- }
-
- // Generate random file
- tmpFile := path.Join(t.TempDir(), "web-upload-test-file.bin")
- require.NoError(t, generateRandomFile(1024*1024/4, tmpFile))
- expectedContent, err := os.ReadFile(tmpFile)
- require.NoError(t, err)
-
- // Upload generated file
- fileUUID := uploadFile(t, tmpFile)
- req := NewRequestWithValues(t, "POST", ctx.Username+"/"+ctx.Reponame+"/_upload/"+setting.Repository.DefaultBranch, map[string]string{
- "commit_choice": "direct",
- "files": fileUUID,
- "_csrf": GetCSRF(t, ctx.Session, ctx.Username+"/"+ctx.Reponame+"/_upload/"+setting.Repository.DefaultBranch),
- "commit_mail_id": "-1",
- })
- ctx.Session.MakeRequest(t, req, http.StatusSeeOther)
-
- // Get some handles on the target repository and file
- remoteRepoPath := path.Join(setting.RepoRootPath, ctx.GitPath())
- repo, err := git.OpenRepository(git.DefaultContext, remoteRepoPath)
- require.NoError(t, err)
- defer repo.Close()
- tree, err := repo.GetTree(setting.Repository.DefaultBranch)
- require.NoError(t, err)
- treeEntry, err := tree.GetTreeEntryByPath(filepath.Base(tmpFile))
- require.NoError(t, err)
- blob := treeEntry.Blob()
-
- // Check that the uploaded file is annexed
- isAnnexed, err := annex.IsAnnexed(blob)
- require.NoError(t, err)
- require.True(t, isAnnexed)
-
- // Check that the uploaded file has the correct content
- annexedFile, err := annex.Content(blob)
- require.NoError(t, err)
- actualContent, err := io.ReadAll(annexedFile)
- require.NoError(t, err)
- require.Equal(t, expectedContent, actualContent)
- })
- })
-}
-
-func TestGitAnnexMedia(t *testing.T) {
- if !setting.Annex.Enabled {
- t.Skip("Skipping since annex support is disabled.")
- }
-
- onGiteaRun(t, func(t *testing.T, u *url.URL) {
- forEachObjectFormat(t, func(t *testing.T, objectFormat git.ObjectFormat) {
- ctx := NewAPITestContext(t, "user2", "annex-media-test"+objectFormat.Name(), auth_model.AccessTokenScopeWriteRepository)
-
- // create a public repo
- require.NoError(t, doCreateRemoteAnnexRepository(t, u, ctx, false, objectFormat))
-
- // the filenames here correspond to specific cases defined in doInitAnnexRepository()
- t.Run("AnnexSymlink", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- doAnnexMediaTest(t, ctx, "annexed.tiff")
- })
- t.Run("AnnexPointer", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- doAnnexMediaTest(t, ctx, "annexed.bin")
- })
- })
- })
-}
-
-func doAnnexMediaTest(t *testing.T, ctx APITestContext, file string) {
- // Make sure that downloading via /media on the website recognizes it should give the annexed content
-
- // TODO:
- // - [ ] roll this into TestGitAnnexPermissions to ensure that permission enforcement works correctly even on /media?
-
- session := loginUser(t, ctx.Username) // logs in to the http:// site/API, storing a cookie;
- // this is a different auth method than the git+ssh:// or git+http:// protocols TestGitAnnexPermissions uses!
-
- // compute server-side path of the annexed file
- remoteRepoPath := path.Join(setting.RepoRootPath, ctx.GitPath())
- remoteObjectPath, err := contentLocation(remoteRepoPath, file)
- require.NoError(t, err)
-
- // download annexed file
- localObjectPath := path.Join(t.TempDir(), file)
- fd, err := os.OpenFile(localObjectPath, os.O_CREATE|os.O_WRONLY, 0o777)
- defer fd.Close()
- require.NoError(t, err)
-
- mediaLink := path.Join("/", ctx.Username, ctx.Reponame, "/media/branch/master", file)
- req := NewRequest(t, "GET", mediaLink)
- resp := session.MakeRequest(t, req, http.StatusOK)
-
- _, err = io.Copy(fd, resp.Body)
- require.NoError(t, err)
- fd.Close()
-
- // verify the download
- match, err := tests.FileCmp(localObjectPath, remoteObjectPath, 0)
- require.NoError(t, err)
- require.True(t, match, "Annexed files should be the same")
-}
-
-func TestGitAnnexViews(t *testing.T) {
- if !setting.Annex.Enabled {
- t.Skip("Skipping since annex support is disabled.")
- }
-
- onGiteaRun(t, func(t *testing.T, u *url.URL) {
- forEachObjectFormat(t, func(t *testing.T, objectFormat git.ObjectFormat) {
- ctx := NewAPITestContext(t, "user2", "annex-template-render-test"+objectFormat.Name(), auth_model.AccessTokenScopeWriteRepository)
-
- // create a public repo
- require.NoError(t, doCreateRemoteAnnexRepository(t, u, ctx, false, objectFormat))
-
- session := loginUser(t, ctx.Username)
-
- t.Run("Index", func(t *testing.T) {
- // test that annexed files render with the binary file icon on the main list
- defer tests.PrintCurrentTest(t)()
-
- repoLink := path.Join("/", ctx.Username, ctx.Reponame)
- req := NewRequest(t, "GET", repoLink)
- resp := session.MakeRequest(t, req, http.StatusOK)
-
- htmlDoc := NewHTMLParser(t, resp.Body)
- isFileBinaryIconLocked := htmlDoc.Find("tr[data-entryname='annexed.tiff'] > td.name svg").HasClass("octicon-file-binary")
- require.True(t, isFileBinaryIconLocked, "locked annexed files should render a binary file icon")
- isFileBinaryIconUnlocked := htmlDoc.Find("tr[data-entryname='annexed.bin'] > td.name svg").HasClass("octicon-file-binary")
- require.True(t, isFileBinaryIconUnlocked, "unlocked annexed files should render a binary file icon")
- })
-
- t.Run("View", func(t *testing.T) {
- // test how routers/web/repo/view.go + templates/repo/view_file.tmpl handle annexed files
- defer tests.PrintCurrentTest(t)()
-
- doViewTest := func(file string) (htmlDoc *HTMLDoc, viewLink, mediaLink string) {
- viewLink = path.Join("/", ctx.Username, ctx.Reponame, "/src/branch/master", file)
- // rawLink := strings.Replace(viewLink, "/src/", "/raw/", 1) // TODO: do something with this?
- mediaLink = strings.Replace(viewLink, "/src/", "/media/", 1)
-
- req := NewRequest(t, "GET", viewLink)
- resp := session.MakeRequest(t, req, http.StatusOK)
-
- htmlDoc = NewHTMLParser(t, resp.Body)
- // the first button on the toolbar on the view template is the "Raw" button
- // this CSS selector is the most precise I can think to use
- buttonLink, exists := htmlDoc.Find(".file-header").Find("a[download]").Attr("href")
- require.True(t, exists, "Download button should exist on the file header")
- require.EqualValues(t, mediaLink, buttonLink, "Download link should use /media URL for annex files")
-
- return htmlDoc, viewLink, mediaLink
- }
-
- t.Run("Binary", func(t *testing.T) {
- // test that annexing a file renders the /media link in /src and NOT the /raw link
- defer tests.PrintCurrentTest(t)()
-
- doBinaryViewTest := func(file string) {
- htmlDoc, _, mediaLink := doViewTest(file)
-
- rawLink, exists := htmlDoc.Find("div.file-view > div.view-raw > a").Attr("href")
- require.True(t, exists, "Download link should render instead of content because this is a binary file")
- require.EqualValues(t, mediaLink, rawLink)
- }
-
- t.Run("AnnexSymlink", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- doBinaryViewTest("annexed.tiff")
- })
- t.Run("AnnexPointer", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- doBinaryViewTest("annexed.bin")
- })
- })
-
- t.Run("Text", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- doTextViewTest := func(file string) {
- htmlDoc, _, _ := doViewTest(file)
- require.True(t, htmlDoc.Find("div.file-view").Is(".code-view"), "should render as code")
- }
-
- t.Run("AnnexSymlink", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- doTextViewTest("annexed.txt")
-
- t.Run("Markdown", func(t *testing.T) {
- // special case: check that markdown can be pulled out of the annex and rendered, too
- defer tests.PrintCurrentTest(t)()
- htmlDoc, _, _ := doViewTest("annexed.md")
- require.True(t, htmlDoc.Find("div.file-view").Is(".markdown"), "should render as markdown")
- })
- })
- t.Run("AnnexPointer", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- doTextViewTest("annexed.rst")
-
- t.Run("Markdown", func(t *testing.T) {
- // special case: check that markdown can be pulled out of the annex and rendered, too
- defer tests.PrintCurrentTest(t)()
- htmlDoc, _, _ := doViewTest("annexed.markdown")
- require.True(t, htmlDoc.Find("div.file-view").Is(".markdown"), "should render as markdown")
- })
- })
- })
- })
- })
- })
-}
-
-/*
-Test that permissions are enforced on git-annex-shell commands.
-
- Along the way, this also tests that uploading, downloading, and deleting all work,
- so we haven't written separate tests for those.
-*/
-func TestGitAnnexPermissions(t *testing.T) {
- if !setting.Annex.Enabled {
- t.Skip("Skipping since annex support is disabled.")
- }
-
- // Each case below is split so that 'clone' is done as
- // the repo owner, but 'copy' as the user under test.
- //
- // Otherwise, in cases where permissions block the
- // initial 'clone', the test would simply end there
- // and never verify if permissions apply properly to
- // 'annex copy' -- potentially leaving a security gap.
-
- onGiteaRun(t, func(t *testing.T, u *url.URL) {
- // Tell git-annex to allow http://127.0.0.1, http://localhost and http://::1. Without
- // this, all `git annex` commands will silently fail when run against http:// remotes
- // without explaining what's wrong.
- //
- // Note: onGiteaRun() sets up an alternate HOME so this actually edits
- // tests/integration/gitea-integration-*/data/home/.gitconfig and
- // if you're debugging you need to remember to match that.
- _, _, err := git.NewCommandContextNoGlobals(git.DefaultContext, "config").AddOptionValues("--global").AddArguments("annex.security.allowed-ip-addresses", "all").RunStdString(&git.RunOpts{})
- require.NoError(t, err)
-
- forEachObjectFormat(t, func(t *testing.T, objectFormat git.ObjectFormat) {
- t.Run("Public", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- ownerCtx := NewAPITestContext(t, "user2", "annex-public"+objectFormat.Name(), auth_model.AccessTokenScopeWriteRepository)
-
- // create a public repo
- require.NoError(t, doCreateRemoteAnnexRepository(t, u, ownerCtx, false, objectFormat))
-
- // double-check it's public
- repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, ownerCtx.Username, ownerCtx.Reponame)
- require.NoError(t, err)
- require.False(t, repo.IsPrivate)
-
- remoteRepoPath := path.Join(setting.RepoRootPath, ownerCtx.GitPath()) // path on disk -- which can be examined directly because we're testing from localhost
-
- // Different sessions, so we can test different permissions.
- // We leave Reponame blank because we don't actually then later add it according to each case if needed
- //
- // NB: these usernames need to match appropriate entries in models/fixtures/user.yml
- writerCtx := NewAPITestContext(t, "user5", "", auth_model.AccessTokenScopeWriteRepository)
- readerCtx := NewAPITestContext(t, "user4", "", auth_model.AccessTokenScopeReadRepository)
- outsiderCtx := NewAPITestContext(t, "user8", "", auth_model.AccessTokenScopeReadRepository) // a user with no specific access
-
- // set up collaborators
- doAPIAddCollaborator(ownerCtx, readerCtx.Username, perm.AccessModeRead)(t)
- doAPIAddCollaborator(ownerCtx, writerCtx.Username, perm.AccessModeWrite)(t)
-
- // tests
- t.Run("Owner", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- t.Run("SSH", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createSSHUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("HTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- // Unset annexurl so that git-annex uses the dumb http support
- _, _, err := git.NewCommand(git.DefaultContext, "config", "--unset", "remote.origin.annexurl").RunStdString(&git.RunOpts{Dir: repoPath})
- require.NoError(t, err)
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("P2PHTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
- })
-
- t.Run("Writer", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- t.Run("SSH", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createSSHUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("HTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- // Unset annexurl so that git-annex uses the dumb http support
- _, _, err := git.NewCommand(git.DefaultContext, "config", "--unset", "remote.origin.annexurl").RunStdString(&git.RunOpts{Dir: repoPath})
- require.NoError(t, err)
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("P2PHTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
- })
-
- t.Run("Reader", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- t.Run("SSH", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createSSHUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath), "Uploading should fail due to permissions")
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("HTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- // Unset annexurl so that git-annex uses the dumb http support
- _, _, err := git.NewCommand(git.DefaultContext, "config", "--unset", "remote.origin.annexurl").RunStdString(&git.RunOpts{Dir: repoPath})
- require.NoError(t, err)
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("P2PHTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
- })
-
- t.Run("Outsider", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- t.Run("SSH", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createSSHUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath), "Uploading should fail due to permissions")
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("HTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- // Unset annexurl so that git-annex uses the dumb http support
- _, _, err = git.NewCommand(git.DefaultContext, "config", "--unset", "remote.origin.annexurl").RunStdString(&git.RunOpts{Dir: repoPath})
- require.NoError(t, err)
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("P2PHTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
- })
-
- t.Run("Anonymous", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- // Only HTTP and P2PHTTP have an anonymous mode
- t.Run("HTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- // unlike the other tests, at this step we *do not* define credentials:
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
-
- // Unset annexurl so that git-annex uses the dumb http support
- _, _, err := git.NewCommand(git.DefaultContext, "config", "--unset", "remote.origin.annexurl").RunStdString(&git.RunOpts{Dir: repoPath})
- require.NoError(t, err)
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
-
- t.Run("P2PHTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- // unlike the other tests, at this step we *do not* define credentials:
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("Delete", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- // Delete the repo, make sure it's fully gone
- doAPIDeleteRepository(ownerCtx)(t)
- _, statErr := os.Stat(remoteRepoPath)
- require.True(t, os.IsNotExist(statErr), "Remote annex repo should be removed from disk")
- })
- })
-
- t.Run("Private", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- ownerCtx := NewAPITestContext(t, "user2", "annex-private"+objectFormat.Name(), auth_model.AccessTokenScopeWriteRepository)
-
- // create a private repo
- require.NoError(t, doCreateRemoteAnnexRepository(t, u, ownerCtx, true, objectFormat))
-
- // double-check it's private
- repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, ownerCtx.Username, ownerCtx.Reponame)
- require.NoError(t, err)
- require.True(t, repo.IsPrivate)
-
- remoteRepoPath := path.Join(setting.RepoRootPath, ownerCtx.GitPath()) // path on disk -- which can be examined directly because we're testing from localhost
-
- // Different sessions, so we can test different permissions.
- // We leave Reponame blank because we don't actually then later add it according to each case if needed
- //
- // NB: these usernames need to match appropriate entries in models/fixtures/user.yml
- writerCtx := NewAPITestContext(t, "user5", "", auth_model.AccessTokenScopeWriteRepository)
- readerCtx := NewAPITestContext(t, "user4", "", auth_model.AccessTokenScopeReadRepository)
- outsiderCtx := NewAPITestContext(t, "user8", "", auth_model.AccessTokenScopeReadRepository) // a user with no specific access
- // Note: there's also full anonymous access, which is only available for public HTTP repos;
- // it should behave the same as 'outsider' but we (will) test it separately below anyway
-
- // set up collaborators
- doAPIAddCollaborator(ownerCtx, readerCtx.Username, perm.AccessModeRead)(t)
- doAPIAddCollaborator(ownerCtx, writerCtx.Username, perm.AccessModeWrite)(t)
-
- // tests
- t.Run("Owner", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- t.Run("SSH", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createSSHUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("HTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- // Unset annexurl so that git-annex uses the dumb http support
- _, _, err := git.NewCommand(git.DefaultContext, "config", "--unset", "remote.origin.annexurl").RunStdString(&git.RunOpts{Dir: repoPath})
- require.NoError(t, err)
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("P2PHTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
- })
-
- t.Run("Writer", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- t.Run("SSH", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createSSHUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, writerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("HTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- // Unset annexurl so that git-annex uses the dumb http support
- _, _, err := git.NewCommand(git.DefaultContext, "config", "--unset", "remote.origin.annexurl").RunStdString(&git.RunOpts{Dir: repoPath})
- require.NoError(t, err)
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("P2PHTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, writerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
- })
-
- t.Run("Reader", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- t.Run("SSH", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createSSHUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath), "Uploading should fail due to permissions")
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, readerCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("HTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- // Unset annexurl so that git-annex uses the dumb http support
- _, _, err := git.NewCommand(git.DefaultContext, "config", "--unset", "remote.origin.annexurl").RunStdString(&git.RunOpts{Dir: repoPath})
- require.NoError(t, err)
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("P2PHTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.NoError(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, readerCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("Outsider", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- t.Run("SSH", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createSSHUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxKeyFile(t, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.Error(t, doAnnexInitTest(remoteRepoPath, repoPath), "annex init should fail due to permissions")
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.Error(t, doAnnexDownloadTest(remoteRepoPath, repoPath), "annex copy --from should fail due to permissions")
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.Error(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.Error(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath), "annex copy --to should fail due to permissions")
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.Error(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxKeyFile(t, outsiderCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("HTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- // Try unsetting annexurl
- _, _, err := git.NewCommand(git.DefaultContext, "config", "--unset", "remote.origin.annexurl").RunStdString(&git.RunOpts{Dir: repoPath})
- require.Error(t, err)
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("P2PHTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexLocalDropTest(repoPath))
- })
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- withAnnexCtxHTTPPassword(t, u, outsiderCtx, func() {
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
- })
- })
-
- t.Run("Anonymous", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- // Only HTTP and P2PHTTP have an anonymous mode
- t.Run("HTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- // unlike the other tests, at this step we *do not* define credentials:
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
-
- // Try unsetting annexurl
- _, _, err := git.NewCommand(git.DefaultContext, "config", "--unset", "remote.origin.annexurl").RunStdString(&git.RunOpts{Dir: repoPath})
- require.Error(t, err)
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexLocalDropTest(repoPath))
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
-
- t.Run("P2PHTTP", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- repoURL := createHTTPUrl(ownerCtx.GitPath(), u)
-
- repoPath := path.Join(t.TempDir(), ownerCtx.Reponame)
- defer util.RemoveAll(repoPath) // cleans out git-annex lockdown permissions
-
- withAnnexCtxHTTPPassword(t, u, ownerCtx, func() {
- doGitClone(repoPath, repoURL)(t)
- })
-
- // unlike the other tests, at this step we *do not* define credentials:
-
- t.Run("Init", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexInitTest(remoteRepoPath, repoPath))
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
-
- t.Run("LocalDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexLocalDropTest(repoPath))
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexDownloadTest(remoteRepoPath, repoPath))
- })
-
- t.Run("RemoteDrop", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexRemoteDropTest(remoteRepoPath, repoPath))
- })
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexUploadTest(remoteRepoPath, repoPath))
- })
-
- t.Run("TestremoteReadOnly", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexTestremoteReadOnlyTest(repoPath))
- })
-
- t.Run("TestremoteReadWrite", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- require.Error(t, doAnnexTestremoteReadWriteTest(repoPath))
- })
- })
- })
-
- t.Run("Delete", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- // Delete the repo, make sure it's fully gone
- doAPIDeleteRepository(ownerCtx)(t)
- _, statErr := os.Stat(remoteRepoPath)
- require.True(t, os.IsNotExist(statErr), "Remote annex repo should be removed from disk")
- })
- })
- })
- })
-}
-
-/*
-Test that 'git annex init' works.
-
- precondition: repoPath contains a pre-cloned repo set up by doInitAnnexRepository().
-*/
-func doAnnexInitTest(remoteRepoPath, repoPath string) (err error) {
- _, _, err = git.NewCommandContextNoGlobals(git.DefaultContext, "annex", "init", "cloned-repo").RunStdString(&git.RunOpts{Dir: repoPath})
- if err != nil {
- return fmt.Errorf("Couldn't `git annex init`: %w", err)
- }
-
- // - method 0: 'git config remote.origin.annex-uuid'.
- // Demonstrates that 'git annex init' successfully contacted
- // the remote git-annex and was able to learn its ID number.
- readAnnexUUID, _, err := git.NewCommandContextNoGlobals(git.DefaultContext, "config", "remote.origin.annex-uuid").RunStdString(&git.RunOpts{Dir: repoPath})
- if err != nil {
- return fmt.Errorf("Couldn't read remote `git config remote.origin.annex-uuid`: %w", err)
- }
- readAnnexUUID = strings.TrimSpace(readAnnexUUID)
-
- match := regexp.MustCompile("^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$").MatchString(readAnnexUUID)
- if !match {
- return fmt.Errorf("'git config remote.origin.annex-uuid' should have been able to download the remote's uuid; but instead read '%s'", readAnnexUUID)
- }
-
- remoteAnnexUUID, _, err := git.NewCommandContextNoGlobals(git.DefaultContext, "config", "annex.uuid").RunStdString(&git.RunOpts{Dir: remoteRepoPath})
- if err != nil {
- return fmt.Errorf("Couldn't read local `git config annex.uuid`: %w", err)
- }
-
- remoteAnnexUUID = strings.TrimSpace(remoteAnnexUUID)
- match = regexp.MustCompile("^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$").MatchString(remoteAnnexUUID)
- if !match {
- return fmt.Errorf("'git annex init' should have been able to download the remote's uuid; but instead read '%s'", remoteAnnexUUID)
- }
-
- if readAnnexUUID != remoteAnnexUUID {
- return fmt.Errorf("'git annex init' should have read the expected annex UUID '%s', but instead got '%s'", remoteAnnexUUID, readAnnexUUID)
- }
-
- // - method 1: 'git annex whereis'.
- // Demonstrates that git-annex understands annexed files can be found in the remote annex.
- annexWhereis, _, err := git.NewCommandContextNoGlobals(git.DefaultContext, "annex", "whereis", "annexed.bin").RunStdString(&git.RunOpts{Dir: repoPath})
- if err != nil {
- return fmt.Errorf("Couldn't `git annex whereis`: %w", err)
- }
- // Note: this regex is unanchored because 'whereis' outputs multiple lines containing
- // headers and 1+ remotes and we just want to find one of them.
- match = regexp.MustCompile(regexp.QuoteMeta(remoteAnnexUUID) + " -- .* \\[origin\\]\n").MatchString(annexWhereis)
- if !match {
- return errors.New("'git annex whereis' should report files are known to be in [origin]")
- }
-
- return nil
-}
-
-func doAnnexTestremoteReadWriteTest(repoPath string) (err error) {
- _, _, err = git.NewCommandContextNoGlobals(git.DefaultContext, "annex", "testremote", "origin").RunStdString(&git.RunOpts{Dir: repoPath})
- if err != nil {
- return err
- }
- return nil
-}
-
-func doAnnexTestremoteReadOnlyTest(repoPath string) (err error) {
- _, _, err = git.NewCommandContextNoGlobals(git.DefaultContext, "annex", "testremote", "origin", "--test-readonly", "annexed.tiff").RunStdString(&git.RunOpts{Dir: repoPath})
- if err != nil {
- return err
- }
- return nil
-}
-
-func doAnnexDownloadTest(remoteRepoPath, repoPath string) (err error) {
- // NB: this test does something slightly different if run separately from "doAnnexInitTest()":
- // "git annex copy" will notice and run "git annex init", silently.
- // This shouldn't change any results, but be aware in case it does.
-
- _, _, err = git.NewCommandContextNoGlobals(git.DefaultContext, "annex", "copy", "--from", "origin").RunStdString(&git.RunOpts{Dir: repoPath})
- if err != nil {
- return err
- }
-
- // verify the files downloaded
-
- cmp := func(filename string) error {
- localObjectPath, err := contentLocation(repoPath, filename)
- if err != nil {
- return err
- }
- // localObjectPath := path.Join(repoPath, filename) // or, just compare against the checked-out file
-
- remoteObjectPath, err := contentLocation(remoteRepoPath, filename)
- if err != nil {
- return err
- }
-
- match, err := tests.FileCmp(localObjectPath, remoteObjectPath, 0)
- if err != nil {
- return err
- }
- if !match {
- return errors.New("Annexed files should be the same")
- }
-
- return nil
- }
-
- // this is the annex-symlink file
- stat, err := os.Lstat(path.Join(repoPath, "annexed.tiff"))
- if err != nil {
- return fmt.Errorf("Lstat: %w", err)
- }
- if !((stat.Mode() & os.ModeSymlink) != 0) {
- // this line is really just double-checking that the text fixture is set up correctly
- return errors.New("*.tiff should be a symlink")
- }
- if err = cmp("annexed.tiff"); err != nil {
- return err
- }
-
- // this is the annex-pointer file
- stat, err = os.Lstat(path.Join(repoPath, "annexed.bin"))
- if err != nil {
- return fmt.Errorf("Lstat: %w", err)
- }
- if !((stat.Mode() & os.ModeSymlink) == 0) {
- // this line is really just double-checking that the text fixture is set up correctly
- return errors.New("*.bin should not be a symlink")
- }
- err = cmp("annexed.bin")
-
- return err
-}
-
-func doAnnexLocalDropTest(repoPath string) (err error) {
- // This test assumes that files are present in repoPath, i.e. it is run after doAnnexDownloadTest.
- // This test drops all files from the repository clone.
- binPath, err := contentLocation(repoPath, "annexed.bin")
- if err != nil {
- return err
- }
- _, err = os.Stat(binPath)
- if err != nil {
- return err
- }
- tiffPath, err := contentLocation(repoPath, "annexed.tiff")
- if err != nil {
- return err
- }
- _, err = os.Stat(tiffPath)
- if err != nil {
- return err
- }
- _, _, err = git.NewCommandContextNoGlobals(git.DefaultContext, "annex", "drop").RunStdString(&git.RunOpts{Dir: repoPath})
- if err != nil {
- return err
- }
- _, err = os.Stat(binPath)
- if !errors.Is(err, os.ErrNotExist) {
- return fmt.Errorf("annexed.bin wasn't dropped properly: %w", err)
- }
- _, err = os.Stat(tiffPath)
- if !errors.Is(err, os.ErrNotExist) {
- return fmt.Errorf("annexed.tiff wasn't dropped properly: %w", err)
- }
- return nil
-}
-
-func doAnnexUploadTest(remoteRepoPath, repoPath string) (err error) {
- // NB: this test does something slightly different if run separately from "Init":
- // it first runs "git annex init" silently in the background.
- // This shouldn't change any results, but be aware in case it does.
-
- err = generateRandomFile(1024*1024/4, path.Join(repoPath, "contribution.bin"))
- if err != nil {
- return err
- }
-
- err = git.AddChanges(repoPath, false, ".")
- if err != nil {
- return err
- }
-
- err = git.CommitChanges(repoPath, git.CommitChangesOptions{Message: "Annex another file"})
- if err != nil {
- return err
- }
-
- _, _, err = git.NewCommandContextNoGlobals(git.DefaultContext, "annex", "copy", "--to", "origin").RunStdString(&git.RunOpts{Dir: repoPath})
- if err != nil {
- return err
- }
-
- // verify the file was uploaded
- blob, err := blobForFile(repoPath, "contribution.bin")
- if err != nil {
- return err
- }
- key, err := annex.LookupKey(blob)
- if err != nil {
- return err
- }
- localObjectPath, err := annex.ContentLocationFromKey(repoPath, key)
- if err != nil {
- return err
- }
-
- remoteObjectPath, err := annex.ContentLocationFromKey(remoteRepoPath, key)
- if err != nil {
- return err
- }
-
- match, err := tests.FileCmp(localObjectPath, remoteObjectPath, 0)
- if err != nil {
- return err
- }
- if !match {
- return errors.New("Annexed files should be the same")
- }
-
- return nil
-}
-
-func doAnnexRemoteDropTest(remoteRepoPath, repoPath string) (err error) {
- // This test assumes that files are present in repoPath, i.e. it is run after doAnnexDownloadTest.
- // This test drops all files from the remote repository.
- binPath, err := contentLocation(remoteRepoPath, "annexed.bin")
- if err != nil {
- return err
- }
- _, err = os.Stat(binPath)
- if err != nil {
- return err
- }
- tiffPath, err := contentLocation(remoteRepoPath, "annexed.tiff")
- if err != nil {
- return err
- }
- _, err = os.Stat(tiffPath)
- if err != nil {
- return err
- }
- _, _, err = git.NewCommandContextNoGlobals(git.DefaultContext, "annex", "drop", "--from", "origin").RunStdString(&git.RunOpts{Dir: repoPath})
- if err != nil {
- return err
- }
- _, err = os.Stat(binPath)
- if !errors.Is(err, os.ErrNotExist) {
- return fmt.Errorf("annexed.bin wasn't dropped properly: %w", err)
- }
- _, err = os.Stat(tiffPath)
- if !errors.Is(err, os.ErrNotExist) {
- return fmt.Errorf("annexed.tiff wasn't dropped properly: %w", err)
- }
- return nil
-}
-
-// ---- Helpers ----
-
-func generateRandomFile(size int, path string) (err error) {
- // Generate random file
-
- // XXX TODO: maybe this should not be random, but instead a predictable pattern, so that the test is deterministic
- bufSize := 4 * 1024
- if bufSize > size {
- bufSize = size
- }
-
- buffer := make([]byte, bufSize)
-
- f, err := os.Create(path)
- if err != nil {
- return err
- }
- defer f.Close()
-
- written := 0
- for written < size {
- n := size - written
- if n > bufSize {
- n = bufSize
- }
- _, err := rand.Read(buffer[:n])
- if err != nil {
- return err
- }
- n, err = f.Write(buffer[:n])
- if err != nil {
- return err
- }
- written += n
- }
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// ---- Annex-specific helpers ----
-
-/*
-Initialize a repo with some baseline annexed and non-annexed files.
-
- TODO: perhaps this generator could be replaced with a fixture (see
- integrations/gitea-repositories-meta/ and models/fixtures/repository.yml).
- However we reuse this template for -different- repos, so maybe not.
-*/
-func doInitAnnexRepository(repoPath string) error {
- // set up what files should be annexed
- // in this case, all *.bin files will be annexed
- // without this, git-annex's default config annexes every file larger than some number of megabytes
- f, err := os.Create(path.Join(repoPath, ".gitattributes"))
- if err != nil {
- return err
- }
- defer f.Close()
-
- // set up git-annex to store certain filetypes via *annex* pointers
- // (https://git-annex.branchable.com/internals/pointer_file/).
- // but only when run via 'git add' (see git-annex-smudge(1))
- _, err = f.WriteString("* annex.largefiles=anything\n")
- if err != nil {
- return err
- }
- _, err = f.WriteString("*.bin filter=annex\n")
- if err != nil {
- return err
- }
- _, err = f.WriteString("*.rst filter=annex\n")
- if err != nil {
- return err
- }
- _, err = f.WriteString("*.markdown filter=annex\n")
- if err != nil {
- return err
- }
- f.Close()
-
- err = git.AddChanges(repoPath, false, ".")
- if err != nil {
- return err
- }
- err = git.CommitChanges(repoPath, git.CommitChangesOptions{Message: "Configure git-annex settings"})
- if err != nil {
- return err
- }
-
- // 'git annex init'
- err = git.NewCommandContextNoGlobals(git.DefaultContext, "annex", "init", "test-repo").Run(&git.RunOpts{Dir: repoPath})
- if err != nil {
- return err
- }
-
- // add files to the annex, stored via annex symlinks
- // // a binary file
- err = generateRandomFile(1024*1024/4, path.Join(repoPath, "annexed.tiff"))
- if err != nil {
- return err
- }
-
- // // a text file
- err = os.WriteFile(path.Join(repoPath, "annexed.md"), []byte("Overview\n=====\n\n1. Profit\n2. ???\n3. Review Life Activations\n"), 0o777)
- if err != nil {
- return err
- }
-
- // // a markdown file
- err = os.WriteFile(path.Join(repoPath, "annexed.txt"), []byte("We're going to see the wizard\nThe wonderful\nMonkey of\nBoz\n"), 0o777)
- if err != nil {
- return err
- }
-
- err = git.NewCommandContextNoGlobals(git.DefaultContext, "annex", "add", ".").Run(&git.RunOpts{Dir: repoPath})
- if err != nil {
- return err
- }
-
- // add files to the annex, stored via git-annex-smudge
- // // a binary file
- err = generateRandomFile(1024*1024/4, path.Join(repoPath, "annexed.bin"))
- if err != nil {
- return err
- }
-
- // // a text file
- err = os.WriteFile(path.Join(repoPath, "annexed.rst"), []byte("Title\n=====\n\n- this is to test annexing a text file\n- lists are fun\n"), 0o777)
- if err != nil {
- return err
- }
-
- // // a markdown file
- err = os.WriteFile(path.Join(repoPath, "annexed.markdown"), []byte("Overview\n=====\n\n1. Profit\n2. ???\n3. Review Life Activations\n"), 0o777)
- if err != nil {
- return err
- }
-
- err = git.AddChanges(repoPath, false, ".")
- if err != nil {
- return err
- }
-
- // save everything
- err = git.CommitChanges(repoPath, git.CommitChangesOptions{Message: "Annex files"})
- if err != nil {
- return err
- }
-
- return nil
-}
-
-/*
-Initialize a remote repo with some baseline annexed and non-annexed files.
-*/
-func doInitRemoteAnnexRepository(t *testing.T, repoURL *url.URL) error {
- repoPath := path.Join(t.TempDir(), path.Base(repoURL.Path))
- // This clone is immediately thrown away, which
- // helps force the tests to be end-to-end.
- defer util.RemoveAll(repoPath)
-
- doGitClone(repoPath, repoURL)(t) // TODO: this call is the only reason for the testing.T; can it be removed?
-
- err := doInitAnnexRepository(repoPath)
- if err != nil {
- return err
- }
-
- _, _, err = git.NewCommandContextNoGlobals(git.DefaultContext, "annex", "sync", "--content").RunStdString(&git.RunOpts{Dir: repoPath})
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func blobForFile(repoPath, file string) (*git.Blob, error) {
- repo, err := git.OpenRepository(git.DefaultContext, repoPath)
- if err != nil {
- return nil, err
- }
- defer repo.Close()
-
- commitID, err := repo.GetRefCommitID("HEAD") // NB: to examine a *branch*, prefix with "refs/branch/", or call repo.GetBranchCommitID(); ditto for tags
- if err != nil {
- return nil, err
- }
-
- commit, err := repo.GetCommit(commitID)
- if err != nil {
- return nil, err
- }
-
- treeEntry, err := commit.GetTreeEntryByPath(file)
- if err != nil {
- return nil, err
- }
-
- return treeEntry.Blob(), nil
-}
-
-/*
-Find the path in .git/annex/objects/ of the contents for a given annexed file.
-
- repoPath: the git repository to examine
- file: the path (in the repo's current HEAD) of the annex pointer
-
- TODO: pass a parameter to allow examining non-HEAD branches
-*/
-func contentLocation(repoPath, file string) (path string, err error) {
- blob, err := blobForFile(repoPath, file)
- if err != nil {
- return "", err
- }
- return annex.ContentLocation(blob)
-}
-
-/* like withKeyFile(), but automatically sets it the account given in ctx for use by git-annex */
-func withAnnexCtxKeyFile(t *testing.T, ctx APITestContext, callback func()) {
- _gitAnnexUseGitSSH, gitAnnexUseGitSSHExists := os.LookupEnv("GIT_ANNEX_USE_GIT_SSH")
- defer func() {
- // reset
- if gitAnnexUseGitSSHExists {
- t.Setenv("GIT_ANNEX_USE_GIT_SSH", _gitAnnexUseGitSSH)
- }
- }()
-
- t.Setenv("GIT_ANNEX_USE_GIT_SSH", "1") // withKeyFile works by setting GIT_SSH_COMMAND, but git-annex only respects that if this is set
-
- withCtxKeyFile(t, ctx, callback)
-}
-
-/*
-Like withKeyFile(), but sets HTTP credentials instead of SSH credentials.
-
- It does this by temporarily arranging through `git config --global`
- to use git-credential-store(1) with the password written to a tempfile.
-
- This is the only reliable way to pass HTTP credentials non-interactively
- to git-annex. See https://git-annex.branchable.com/bugs/http_remotes_ignore_annex.web-options_--netrc/#comment-b5a299e9826b322f2d85c96d4929a430
- for joeyh's proclamation on the subject.
-
- This **is only effective** when used around git.NewCommandContextNoGlobals() calls.
- git.NewCommand() disables credential.helper as a precaution (see modules/git/git.go).
-
- In contrast, the tests in git_test.go put the password in the remote's URL like
- `git config remote.origin.url http://user2:password@localhost:3003/user2/repo-name.git`,
- writing the password in repoPath+"/.git/config". That would be equally good, except
- that git-annex ignores it!
-*/
-func withAnnexCtxHTTPPassword(t *testing.T, u *url.URL, ctx APITestContext, callback func()) {
- credentialedURL := *u
- credentialedURL.User = url.UserPassword(ctx.Username, userPassword) // NB: all test users use the same password
-
- credentialedAnnexURL := *u
- credentialedAnnexURL.Host = strings.ReplaceAll(credentialedAnnexURL.Host, "127.0.0.1", "localhost")
- credentialedAnnexURL.Scheme = "annex+" + credentialedAnnexURL.Scheme
- credentialedAnnexURL.Path += "git-annex-p2phttp"
- credentialedAnnexURL.User = url.UserPassword(ctx.Username, userPassword) // NB: all test users use the same password
-
- creds := path.Join(t.TempDir(), "creds")
- require.NoError(t, os.WriteFile(creds, []byte(credentialedURL.String()+"\n"+credentialedAnnexURL.String()+"\n"), 0o600))
-
- originalCredentialHelper, _, err := git.NewCommandContextNoGlobals(git.DefaultContext, "config").AddOptionValues("--global", "credential.helper").RunStdString(&git.RunOpts{})
- if err != nil && !git.IsErrorExitCode(err, 1) {
- // ignore the 'error' thrown when credential.helper is unset (when git config returns 1)
- // but catch all others
- require.NoError(t, err)
- }
- hasOriginalCredentialHelper := (err == nil)
-
- _, _, err = git.NewCommandContextNoGlobals(git.DefaultContext, "config").AddOptionValues("--global", "credential.helper", fmt.Sprintf("store --file=%s", creds)).RunStdString(&git.RunOpts{})
- require.NoError(t, err)
-
- defer (func() {
- // reset
- if hasOriginalCredentialHelper {
- _, _, err = git.NewCommandContextNoGlobals(git.DefaultContext, "config").AddOptionValues("--global").AddArguments("credential.helper").AddDynamicArguments(originalCredentialHelper).RunStdString(&git.RunOpts{})
- } else {
- _, _, err = git.NewCommandContextNoGlobals(git.DefaultContext, "config").AddOptionValues("--global").AddOptionValues("--unset").AddArguments("credential.helper").RunStdString(&git.RunOpts{})
- }
- require.NoError(t, err)
- })()
-
- callback()
-}
diff --git a/tests/integration/git_helper_for_declarative_test.go b/tests/integration/git_helper_for_declarative_test.go
index 575f01d..83d8177 100644
--- a/tests/integration/git_helper_for_declarative_test.go
+++ b/tests/integration/git_helper_for_declarative_test.go
@@ -42,28 +42,6 @@ func withKeyFile(t *testing.T, keyname string, callback func(string)) {
"ssh -o \"UserKnownHostsFile=/dev/null\" -o \"StrictHostKeyChecking=no\" -o \"IdentitiesOnly=yes\" -i \""+keyFile+"\" \"$@\""), 0o700)
require.NoError(t, err)
- // reset ssh wrapper afterwards
- _gitSSH, gitSSHExists := os.LookupEnv("GIT_SSH")
- defer func() {
- if gitSSHExists {
- os.Setenv("GIT_SSH", _gitSSH)
- }
- }()
-
- _gitSSHCommand, gitSSHCommandExists := os.LookupEnv("GIT_SSH_COMMAND")
- defer func() {
- if gitSSHCommandExists {
- os.Setenv("GIT_SSH_COMMAND", _gitSSHCommand)
- }
- }()
-
- _gitSSHVariant, gitSSHVariantExists := os.LookupEnv("GIT_SSH_VARIANT")
- defer func() {
- if gitSSHVariantExists {
- os.Setenv("GIT_SSH_VARIANT", _gitSSHVariant)
- }
- }()
-
// Setup ssh wrapper
t.Setenv("GIT_SSH", path.Join(tmpDir, "ssh"))
t.Setenv("GIT_SSH_COMMAND",
@@ -73,13 +51,6 @@ func withKeyFile(t *testing.T, keyname string, callback func(string)) {
callback(keyFile)
}
-func createHTTPUrl(gitPath string, u *url.URL) *url.URL {
- // this assumes u contains the HTTP base URL that Gitea is running on
- u2 := *u
- u2.Path = gitPath
- return &u2
-}
-
func createSSHUrl(gitPath string, u *url.URL) *url.URL {
u2 := *u
u2.Scheme = "ssh"
diff --git a/tests/mysql.ini.tmpl b/tests/mysql.ini.tmpl
index b832026..e15e799 100644
--- a/tests/mysql.ini.tmpl
+++ b/tests/mysql.ini.tmpl
@@ -97,9 +97,6 @@ DISABLE_QUERY_AUTH_TOKEN = true
[lfs]
PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-mysql/data/lfs
-[annex]
-ENABLED = true
-
[packages]
ENABLED = true
diff --git a/tests/pgsql.ini.tmpl b/tests/pgsql.ini.tmpl
index 781508a..340531f 100644
--- a/tests/pgsql.ini.tmpl
+++ b/tests/pgsql.ini.tmpl
@@ -122,9 +122,6 @@ MINIO_LOCATION = us-east-1
MINIO_USE_SSL = false
MINIO_CHECKSUM_ALGORITHM = md5
-[annex]
-ENABLED = true
-
[packages]
ENABLED = true
diff --git a/tests/sqlite.ini.tmpl b/tests/sqlite.ini.tmpl
index 231c0d1..277916a 100644
--- a/tests/sqlite.ini.tmpl
+++ b/tests/sqlite.ini.tmpl
@@ -102,9 +102,6 @@ JWT_SECRET = KZb_QLUd4fYVyxetjxC4eZkrBgWM2SndOOWDNtgUUko
[lfs]
PATH = tests/{{TEST_TYPE}}/gitea-{{TEST_TYPE}}-sqlite/data/lfs
-[annex]
-ENABLED = true
-
[packages]
ENABLED = true
diff --git a/tests/test_utils.go b/tests/test_utils.go
index 6e9374d..b3c03a3 100644
--- a/tests/test_utils.go
+++ b/tests/test_utils.go
@@ -5,11 +5,9 @@
package tests
import (
- "bytes"
"context"
"database/sql"
"fmt"
- "io"
"os"
"path"
"path/filepath"
@@ -490,80 +488,3 @@ func CreateDeclarativeRepo(t *testing.T, owner *user_model.User, name string, en
return CreateDeclarativeRepoWithOptions(t, owner, opts)
}
-
-// Decide if two files have the same contents or not.
-// chunkSize is the size of the blocks to scan by; pass 0 to get a sensible default.
-// *Follows* symlinks.
-//
-// May return an error if something else goes wrong; in this case, you should ignore the value of 'same'.
-//
-// derived from https://stackoverflow.com/a/30038571
-// under CC-BY-SA-4.0 by several contributors
-func FileCmp(file1, file2 string, chunkSize int) (same bool, err error) {
- if chunkSize == 0 {
- chunkSize = 4 * 1024
- }
-
- // shortcuts: check file metadata
- stat1, err := os.Stat(file1)
- if err != nil {
- return false, err
- }
-
- stat2, err := os.Stat(file2)
- if err != nil {
- return false, err
- }
-
- // are inputs are literally the same file?
- if os.SameFile(stat1, stat2) {
- return true, nil
- }
-
- // do inputs at least have the same size?
- if stat1.Size() != stat2.Size() {
- return false, nil
- }
-
- // long way: compare contents
- f1, err := os.Open(file1)
- if err != nil {
- return false, err
- }
- defer f1.Close()
-
- f2, err := os.Open(file2)
- if err != nil {
- return false, err
- }
- defer f2.Close()
-
- b1 := make([]byte, chunkSize)
- b2 := make([]byte, chunkSize)
- for {
- n1, err1 := io.ReadFull(f1, b1)
- n2, err2 := io.ReadFull(f2, b2)
-
- // https://pkg.go.dev/io#Reader
- // > Callers should always process the n > 0 bytes returned
- // > before considering the error err. Doing so correctly
- // > handles I/O errors that happen after reading some bytes
- // > and also both of the allowed EOF behaviors.
-
- if !bytes.Equal(b1[:n1], b2[:n2]) {
- return false, nil
- }
-
- if (err1 == io.EOF && err2 == io.EOF) || (err1 == io.ErrUnexpectedEOF && err2 == io.ErrUnexpectedEOF) {
- return true, nil
- }
-
- // some other error, like a dropped network connection or a bad transfer
- if err1 != nil {
- return false, err1
- }
- if err2 != nil {
- return false, err2
- }
- }
-}
diff --git a/web_src/css/repo.css b/web_src/css/repo.css
index c3f3292..d6faa4b 100644
--- a/web_src/css/repo.css
+++ b/web_src/css/repo.css
@@ -244,7 +244,6 @@ td .commit-summary {
}
.repository.file.list #repo-files-table tbody .svg.octicon-file,
-.repository.file.list #repo-files-table tbody .svg.octicon-file-binary,
.repository.file.list #repo-files-table tbody .svg.octicon-file-symlink-file,
.repository.file.list #repo-files-table tbody .svg.octicon-file-directory-symlink {
color: var(--color-secondary-dark-7);
diff --git a/web_src/js/features/common-global.js b/web_src/js/features/common-global.js
index ded82ad..5a304d9 100644
--- a/web_src/js/features/common-global.js
+++ b/web_src/js/features/common-global.js
@@ -1,19 +1,19 @@
import $ from 'jquery';
import '../vendor/jquery.are-you-sure.js';
-import { clippie } from 'clippie';
-import { createDropzone } from './dropzone.js';
-import { showGlobalErrorMessage } from '../bootstrap.js';
-import { handleGlobalEnterQuickSubmit } from './comp/QuickSubmit.js';
-import { svg } from '../svg.js';
-import { hideElem, showElem, toggleElem, initSubmitEventPolyfill, submitEventSubmitter } from '../utils/dom.js';
-import { htmlEscape } from 'escape-goat';
-import { showTemporaryTooltip } from '../modules/tippy.js';
-import { confirmModal } from './comp/ConfirmModal.js';
-import { showErrorToast } from '../modules/toast.js';
-import { request, POST, GET } from '../modules/fetch.js';
+import {clippie} from 'clippie';
+import {createDropzone} from './dropzone.js';
+import {showGlobalErrorMessage} from '../bootstrap.js';
+import {handleGlobalEnterQuickSubmit} from './comp/QuickSubmit.js';
+import {svg} from '../svg.js';
+import {hideElem, showElem, toggleElem, initSubmitEventPolyfill, submitEventSubmitter} from '../utils/dom.js';
+import {htmlEscape} from 'escape-goat';
+import {showTemporaryTooltip} from '../modules/tippy.js';
+import {confirmModal} from './comp/ConfirmModal.js';
+import {showErrorToast} from '../modules/toast.js';
+import {request, POST, GET} from '../modules/fetch.js';
import '../htmx.js';
-const { appUrl, appSubUrl, csrfToken, i18n } = window.config;
+const {appUrl, appSubUrl, csrfToken, i18n} = window.config;
export function initGlobalFormDirtyLeaveConfirm() {
// Warn users that try to leave a page after entering data into a form.
@@ -82,7 +82,7 @@ async function fetchActionDoRequest(actionElem, url, opt) {
try {
const resp = await request(url, opt);
if (resp.status === 200) {
- let { redirect } = await resp.json();
+ let {redirect} = await resp.json();
redirect = redirect || actionElem.getAttribute('data-redirect');
actionElem.classList.remove('dirty'); // remove the areYouSure check before reloading
if (redirect) {
@@ -96,7 +96,7 @@ async function fetchActionDoRequest(actionElem, url, opt) {
// the code was quite messy, sometimes the backend uses "err", sometimes it uses "error", and even "user_error"
// but at the moment, as a new approach, we only use "errorMessage" here, backend can use JSONError() to respond.
if (data.errorMessage) {
- showErrorToast(data.errorMessage, { useHtmlBody: data.renderFormat === 'html' });
+ showErrorToast(data.errorMessage, {useHtmlBody: data.renderFormat === 'html'});
} else {
showErrorToast(`server error: ${resp.status}`);
}
@@ -134,7 +134,7 @@ async function formFetchAction(e) {
}
let reqUrl = formActionUrl;
- const reqOpt = { method: formMethod.toUpperCase() };
+ const reqOpt = {method: formMethod.toUpperCase()};
if (formMethod.toLowerCase() === 'get') {
const params = new URLSearchParams();
for (const [key, value] of formData) {
@@ -212,7 +212,7 @@ export function initDropzone(el) {
const $dropzone = $(el);
const _promise = createDropzone(el, {
url: $dropzone.data('upload-url'),
- headers: { 'X-Csrf-Token': csrfToken },
+ headers: {'X-Csrf-Token': csrfToken},
maxFiles: $dropzone.data('max-file'),
maxFilesize: $dropzone.data('max-size'),
acceptedFiles: (['*/*', ''].includes($dropzone.data('accepts'))) ? null : $dropzone.data('accepts'),
@@ -229,8 +229,7 @@ export function initDropzone(el) {
this.on('success', (file, data) => {
file.uuid = data.uuid;
const $input = $(`
`).val(data.uuid);
- const $inputPath = $(`
`);
- $dropzone.find('.files').append($input).append($inputPath);
+ $dropzone.find('.files').append($input);
// Create a "Copy Link" element, to conveniently copy the image
// or file link as Markdown to the clipboard
const copyLinkElement = document.createElement('div');
@@ -251,15 +250,10 @@ export function initDropzone(el) {
file.previewTemplate.append(copyLinkElement);
});
this.on('removedfile', (file) => {
- // Remove the hidden input for the file
$(`#${file.uuid}`).remove();
-
- // Remove the hidden input for files_fullpath
- $(`input[name="files_fullpath[${file.uuid}]"]`).remove();
-
if ($dropzone.data('remove-url')) {
POST($dropzone.data('remove-url'), {
- data: new URLSearchParams({ file: file.uuid }),
+ data: new URLSearchParams({file: file.uuid}),
});
}
});
@@ -282,7 +276,7 @@ async function linkAction(e) {
const url = el.getAttribute('data-url');
const doRequest = async () => {
el.disabled = true;
- await fetchActionDoRequest(el, url, { method: 'POST' });
+ await fetchActionDoRequest(el, url, {method: 'POST'});
el.disabled = false;
};
@@ -293,7 +287,7 @@ async function linkAction(e) {
}
const isRisky = el.classList.contains('red') || el.classList.contains('yellow') || el.classList.contains('orange') || el.classList.contains('negative');
- if (await confirmModal({ content: modalConfirmContent, buttonColor: isRisky ? 'orange' : 'primary' })) {
+ if (await confirmModal({content: modalConfirmContent, buttonColor: isRisky ? 'orange' : 'primary'})) {
await doRequest();
}
}
@@ -337,7 +331,7 @@ export function initGlobalLinkActions() {
}
}
- const response = await POST($this.data('url'), { data: postData });
+ const response = await POST($this.data('url'), {data: postData});
if (response.ok) {
const data = await response.json();
window.location.href = data.redirect;
diff --git a/web_src/js/features/imagediff.js b/web_src/js/features/imagediff.js
index 52c9017..d1b139f 100644
--- a/web_src/js/features/imagediff.js
+++ b/web_src/js/features/imagediff.js
@@ -92,17 +92,7 @@ export function initImageDiff() {
return loadElem(img, info.path);
}));
// only the first images is associated with $boundsInfo
- if (!success) {
- const blobContent = await GET(info.path.replace('/media/', '/raw/')).then((response) => response.text());
- if (blobContent.startsWith('.git/annex/objects')) {
- for (const item of document.querySelectorAll('.image-diff .overflow-menu-items .item')) {
- item.style.display = 'none';
- }
- info.$boundsInfo[0].parentElement.textContent = 'annexed file is not present on the server';
- } else {
- info.$boundsInfo.text('(image error)');
- }
- }
+ if (!success) info.$boundsInfo.text('(image error)');
if (info.mime === 'image/svg+xml') {
const resp = await GET(info.path);
const text = await resp.text();