mirror of
https://github.com/go-gitea/gitea.git
synced 2025-09-15 15:56:14 +00:00
some improvements
This commit is contained in:
@@ -5,6 +5,7 @@ package gitrepo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -60,7 +61,14 @@ func UpdateGitConfig(ctx context.Context, repo Repository, key, value string) (s
|
|||||||
return value, err1
|
return value, err1
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddGitRemote(ctx context.Context, repo Repository, remoteName, remoteURL string, options ...string) error {
|
type RemoteOption string
|
||||||
|
|
||||||
|
const (
|
||||||
|
RemoteOptionMirrorPush RemoteOption = "--mirror=push"
|
||||||
|
RemoteOptionMirrorFetch RemoteOption = "--mirror=fetch"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddGitRemote(ctx context.Context, repo Repository, remoteName, remoteURL string, options ...RemoteOption) error {
|
||||||
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
|
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -69,7 +77,14 @@ func AddGitRemote(ctx context.Context, repo Repository, remoteName, remoteURL st
|
|||||||
|
|
||||||
cmd := git.NewCommand("remote", "add")
|
cmd := git.NewCommand("remote", "add")
|
||||||
if len(options) > 0 {
|
if len(options) > 0 {
|
||||||
cmd.AddDynamicArguments(options...)
|
switch options[0] {
|
||||||
|
case RemoteOptionMirrorPush:
|
||||||
|
cmd.AddArguments("--mirror=push")
|
||||||
|
case RemoteOptionMirrorFetch:
|
||||||
|
cmd.AddArguments("--mirror=fetch")
|
||||||
|
default:
|
||||||
|
return errors.New("unknown remote option: " + string(options[0]))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_, _, err = cmd.
|
_, _, err = cmd.
|
||||||
AddDynamicArguments(remoteName, remoteURL).
|
AddDynamicArguments(remoteName, remoteURL).
|
||||||
@@ -95,17 +110,28 @@ func GetRemoteURL(ctx context.Context, repo Repository, remoteName string) (*git
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if addr == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
return giturl.ParseGitURL(addr)
|
return giturl.ParseGitURL(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PruneRemote prunes the remote branches that no longer exist in the remote repository.
|
func SetRemoteURL(ctx context.Context, repo Repository, remoteName, remoteURL string) error {
|
||||||
func PruneRemote(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
|
|
||||||
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
|
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer releaser()
|
defer releaser()
|
||||||
|
|
||||||
|
cmd := git.NewCommand("remote", "set-url").AddDynamicArguments(remoteName, remoteURL)
|
||||||
|
_, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PruneRemote prunes the remote branches that no longer exist in the remote repository.
|
||||||
|
// No lock is needed because the remote remoteName will be checked before invoking this function.
|
||||||
|
// Then it will not update the remote automatically if the remote does not exist.
|
||||||
|
func PruneRemote(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
|
||||||
return git.NewCommand("remote", "prune").AddDynamicArguments(remoteName).
|
return git.NewCommand("remote", "prune").AddDynamicArguments(remoteName).
|
||||||
Run(ctx, &git.RunOpts{
|
Run(ctx, &git.RunOpts{
|
||||||
Timeout: timeout,
|
Timeout: timeout,
|
||||||
@@ -115,13 +141,10 @@ func PruneRemote(ctx context.Context, repo Repository, remoteName string, timeou
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateRemotePrune updates the remote branches and prunes the ones that no longer exist in the remote repository.
|
||||||
|
// No lock is needed because the remote remoteName will be checked before invoking this function.
|
||||||
|
// Then it will not update the remote automatically if the remote does not exist.
|
||||||
func UpdateRemotePrune(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
|
func UpdateRemotePrune(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
|
||||||
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer releaser()
|
|
||||||
|
|
||||||
return git.NewCommand("remote", "update", "--prune").AddDynamicArguments(remoteName).
|
return git.NewCommand("remote", "update", "--prune").AddDynamicArguments(remoteName).
|
||||||
Run(ctx, &git.RunOpts{
|
Run(ctx, &git.RunOpts{
|
||||||
Timeout: timeout,
|
Timeout: timeout,
|
||||||
|
@@ -14,8 +14,7 @@ import (
|
|||||||
|
|
||||||
activities_model "code.gitea.io/gitea/models/activities"
|
activities_model "code.gitea.io/gitea/models/activities"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
giturl "code.gitea.io/gitea/modules/git/url"
|
|
||||||
"code.gitea.io/gitea/modules/json"
|
"code.gitea.io/gitea/modules/json"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/repository"
|
"code.gitea.io/gitea/modules/repository"
|
||||||
@@ -145,15 +144,13 @@ type remoteAddress struct {
|
|||||||
|
|
||||||
func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string) remoteAddress {
|
func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string) remoteAddress {
|
||||||
ret := remoteAddress{}
|
ret := remoteAddress{}
|
||||||
remoteURL, err := git.GetRemoteAddress(ctx, m.RepoPath(), remoteName)
|
u, err := gitrepo.GetRemoteURL(ctx, m, remoteName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetRemoteURL %v", err)
|
log.Error("GetRemoteURL %v", err)
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
if u == nil {
|
||||||
u, err := giturl.ParseGitURL(remoteURL)
|
log.Error("GetRemoteURL %s returned nil", remoteName)
|
||||||
if err != nil {
|
|
||||||
log.Error("giturl.Parse %v", err)
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -208,6 +208,24 @@ func pruneBrokenReferences(ctx context.Context,
|
|||||||
stderrBuilder.Reset()
|
stderrBuilder.Reset()
|
||||||
stdoutBuilder.Reset()
|
stdoutBuilder.Reset()
|
||||||
|
|
||||||
|
// check whether the remote still exists before pruning to avoid prune creating a new remote
|
||||||
|
// this is needed because prune will not fail if the remote does not exist
|
||||||
|
u, err := gitrepo.GetRemoteURL(ctx, storageRepo, m.GetRemoteName())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if u == nil {
|
||||||
|
return fmt.Errorf("remote %s does not exist for %srepository %s", m.GetRemoteName(), wiki, storageRepo.RelativePath())
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchConfig, err := gitrepo.GetGitConfig(ctx, storageRepo, "remote.origin.fetch")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if fetchConfig == "" {
|
||||||
|
return fmt.Errorf("remote %s has no fetch config for %srepository %s", m.GetRemoteName(), wiki, storageRepo.RelativePath())
|
||||||
|
}
|
||||||
|
|
||||||
pruneErr := gitrepo.PruneRemote(ctx, storageRepo, m.GetRemoteName(), timeout, stdoutBuilder, stderrBuilder)
|
pruneErr := gitrepo.PruneRemote(ctx, storageRepo, m.GetRemoteName(), timeout, stdoutBuilder, stderrBuilder)
|
||||||
if pruneErr != nil {
|
if pruneErr != nil {
|
||||||
stdout := stdoutBuilder.String()
|
stdout := stdoutBuilder.String()
|
||||||
@@ -263,7 +281,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
|
|||||||
|
|
||||||
remoteURL, remoteErr := gitrepo.GetRemoteURL(ctx, m.Repo, m.GetRemoteName())
|
remoteURL, remoteErr := gitrepo.GetRemoteURL(ctx, m.Repo, m.GetRemoteName())
|
||||||
if remoteErr != nil {
|
if remoteErr != nil {
|
||||||
log.Error("SyncMirrors [repo: %-v]: GetRemoteAddress Error %v", m.Repo, remoteErr)
|
log.Error("SyncMirrors [repo: %-v]: GetRemoteURL Error %v", m.Repo, remoteErr)
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,6 +383,28 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
|
|||||||
stderrBuilder.Reset()
|
stderrBuilder.Reset()
|
||||||
stdoutBuilder.Reset()
|
stdoutBuilder.Reset()
|
||||||
|
|
||||||
|
// check whether the remote still exists before pruning to avoid prune creating a new remote
|
||||||
|
// this is needed because prune will not fail if the remote does not exist
|
||||||
|
u, err := gitrepo.GetRemoteURL(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("SyncMirrors [repo: %-v Wiki]: GetRemoteURL Error %v", m.Repo, err)
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
if u == nil {
|
||||||
|
log.Error("remote %s does not exist for repository %s", m.GetRemoteName(), m.Repo.WikiStorageRepo().RelativePath())
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchConfig, err := gitrepo.GetGitConfig(ctx, m.Repo.WikiStorageRepo(), "remote.origin.fetch")
|
||||||
|
if err != nil {
|
||||||
|
log.Error("SyncMirrors [repo: %-v Wiki]: GetGitConfig Error %v", m.Repo, err)
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
if fetchConfig == "" {
|
||||||
|
log.Error("remote %s has no fetch config for repository %s", m.GetRemoteName(), m.Repo.WikiStorageRepo().RelativePath())
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
if err := gitrepo.UpdateRemotePrune(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName(),
|
if err := gitrepo.UpdateRemotePrune(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName(),
|
||||||
timeout, &stdoutBuilder, &stderrBuilder); err != nil {
|
timeout, &stdoutBuilder, &stderrBuilder); err != nil {
|
||||||
stdout := stdoutBuilder.String()
|
stdout := stdoutBuilder.String()
|
||||||
@@ -386,6 +426,28 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
|
|||||||
stderrBuilder.Reset()
|
stderrBuilder.Reset()
|
||||||
stdoutBuilder.Reset()
|
stdoutBuilder.Reset()
|
||||||
|
|
||||||
|
// check whether the remote still exists before pruning to avoid prune creating a new remote
|
||||||
|
// this is needed because prune will not fail if the remote does not exist
|
||||||
|
u, err := gitrepo.GetRemoteURL(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("SyncMirrors [repo: %-v Wiki]: GetRemoteURL Error %v", m.Repo, err)
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
if u == nil {
|
||||||
|
log.Error("remote %s does not exist for repository %s", m.GetRemoteName(), m.Repo.WikiStorageRepo().RelativePath())
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchConfig, err := gitrepo.GetGitConfig(ctx, m.Repo.WikiStorageRepo(), "remote.origin.fetch")
|
||||||
|
if err != nil {
|
||||||
|
log.Error("SyncMirrors [repo: %-v Wiki]: GetGitConfig Error %v", m.Repo, err)
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
if fetchConfig == "" {
|
||||||
|
log.Error("remote %s has no fetch config for repository %s", m.GetRemoteName(), m.Repo.WikiStorageRepo().RelativePath())
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
if err = gitrepo.UpdateRemotePrune(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName(),
|
if err = gitrepo.UpdateRemotePrune(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName(),
|
||||||
timeout, &stdoutBuilder, &stderrBuilder); err != nil {
|
timeout, &stdoutBuilder, &stderrBuilder); err != nil {
|
||||||
stdout := stdoutBuilder.String()
|
stdout := stdoutBuilder.String()
|
||||||
|
@@ -130,7 +130,7 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error {
|
|||||||
}
|
}
|
||||||
remoteURL, err := gitrepo.GetRemoteURL(ctx, storageRepo, m.RemoteName)
|
remoteURL, err := gitrepo.GetRemoteURL(ctx, storageRepo, m.RemoteName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetRemoteAddress(%s) Error %v", path, err)
|
log.Error("GetRemoteURL(%s) Error %v", path, err)
|
||||||
return errors.New("Unexpected error")
|
return errors.New("Unexpected error")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,8 +175,8 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if m.Repo.HasWiki() {
|
if m.Repo.HasWiki() {
|
||||||
_, err := git.GetRemoteAddress(ctx, m.Repo.WikiPath(), m.RemoteName)
|
u, err := gitrepo.GetRemoteURL(ctx, m.Repo.WikiStorageRepo(), m.RemoteName)
|
||||||
if err == nil {
|
if err == nil && u != nil {
|
||||||
err := performPush(m.Repo, true)
|
err := performPush(m.Repo, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
Reference in New Issue
Block a user