mirror of
https://github.com/hanzoai/forge.git
synced 2026-10-30 15:00:39 +00:00
2978 files. The fork is 2026-07-15 (rebrand: gitea.dev -> github.com/hanzoai/git), so 2026 is the year, and "Copyright 2026 Hanzo AI, Inc." was already the form used by the handful of files that had ours. Shape is now: // Copyright 2026 Hanzo AI, Inc. All rights reserved. // Copyright 2015 The Gogs Authors. All rights reserved. // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT Ours on top, theirs retained verbatim. Retained because MIT requires it, and separately because they are true — those authors did write that code. Not renamed to "The Git Authors": Git is a different project under a different license, and putting its name here would attribute this code to people who have nothing to do with it. Adding our line is the fix; overwriting theirs would have been both a licence violation and a false statement. gofmt still reports import-order drift in some of these files. It predates this change (verified against a stash) and is left alone rather than burying a one-line-per-file legal change under 3000 files of unrelated reordering. Build clean. Co-authored-by: Hanzo Dev <[email protected]>
82 lines
2.3 KiB
Go
82 lines
2.3 KiB
Go
// Copyright 2026 Hanzo AI, Inc. All rights reserved.
|
|
// Copyright 2025 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package gitrepo
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"slices"
|
|
"strings"
|
|
|
|
"github.com/hanzoai/git/modules/git/gitcmd"
|
|
"github.com/hanzoai/git/modules/setting"
|
|
)
|
|
|
|
// CreateArchive create archive content to the target path
|
|
func CreateArchive(ctx context.Context, repo Repository, format string, target io.Writer, usePrefix bool, commitID string, paths []string) error {
|
|
if format == "unknown" {
|
|
return fmt.Errorf("unknown format: %v", format)
|
|
}
|
|
|
|
cmd := gitcmd.NewCommand("archive")
|
|
if usePrefix {
|
|
cmd.AddOptionFormat("--prefix=%s", filepath.Base(strings.TrimSuffix(repo.RelativePath(), ".git"))+"/")
|
|
}
|
|
cmd.AddOptionFormat("--format=%s", format)
|
|
cmd.AddDynamicArguments(commitID)
|
|
|
|
paths = slices.Clone(paths)
|
|
for i := range paths {
|
|
// although "git archive" already ensures the paths won't go outside the repo, we still clean them here for safety
|
|
paths[i] = path.Clean(paths[i])
|
|
}
|
|
cmd.AddDynamicArguments(paths...)
|
|
return RunCmdWithStderr(ctx, repo, cmd.WithStdoutCopy(target))
|
|
}
|
|
|
|
// CreateBundle create bundle content to the target path
|
|
func CreateBundle(ctx context.Context, repo Repository, commit string, out io.Writer) error {
|
|
tmp, cleanup, err := setting.AppDataTempDir("git-repo-content").MkdirTempRandom("gitea-bundle")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer cleanup()
|
|
|
|
env := append(os.Environ(), "GIT_OBJECT_DIRECTORY="+filepath.Join(repoPath(repo), "objects"))
|
|
_, _, err = gitcmd.NewCommand("init", "--bare").WithDir(tmp).WithEnv(env).RunStdString(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, _, err = gitcmd.NewCommand("reset", "--soft").AddDynamicArguments(commit).WithDir(tmp).WithEnv(env).RunStdString(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, _, err = gitcmd.NewCommand("branch", "-m", "bundle").WithDir(tmp).WithEnv(env).RunStdString(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tmpFile := filepath.Join(tmp, "bundle")
|
|
_, _, err = gitcmd.NewCommand("bundle", "create").AddDynamicArguments(tmpFile, "bundle", "HEAD").WithDir(tmp).WithEnv(env).RunStdString(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fi, err := os.Open(tmpFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer fi.Close()
|
|
|
|
_, err = io.Copy(out, fi)
|
|
return err
|
|
}
|