Skip to content

Commit 98bc0df

Browse files
committed
some improvements
1 parent 2f89a04 commit 98bc0df

File tree

4 files changed

+103
-21
lines changed

4 files changed

+103
-21
lines changed

modules/gitrepo/config.go

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package gitrepo
55

66
import (
77
"context"
8+
"errors"
89
"io"
910
"time"
1011

@@ -60,7 +61,14 @@ func UpdateGitConfig(ctx context.Context, repo Repository, key, value string) (s
6061
return value, err1
6162
}
6263

63-
func AddGitRemote(ctx context.Context, repo Repository, remoteName, remoteURL string, options ...string) error {
64+
type RemoteOption string
65+
66+
const (
67+
RemoteOptionMirrorPush RemoteOption = "--mirror=push"
68+
RemoteOptionMirrorFetch RemoteOption = "--mirror=fetch"
69+
)
70+
71+
func AddGitRemote(ctx context.Context, repo Repository, remoteName, remoteURL string, options ...RemoteOption) error {
6472
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
6573
if err != nil {
6674
return err
@@ -69,7 +77,14 @@ func AddGitRemote(ctx context.Context, repo Repository, remoteName, remoteURL st
6977

7078
cmd := git.NewCommand("remote", "add")
7179
if len(options) > 0 {
72-
cmd.AddDynamicArguments(options...)
80+
switch options[0] {
81+
case RemoteOptionMirrorPush:
82+
cmd.AddArguments("--mirror=push")
83+
case RemoteOptionMirrorFetch:
84+
cmd.AddArguments("--mirror=fetch")
85+
default:
86+
return errors.New("unknown remote option: " + string(options[0]))
87+
}
7388
}
7489
_, _, err = cmd.
7590
AddDynamicArguments(remoteName, remoteURL).
@@ -95,17 +110,28 @@ func GetRemoteURL(ctx context.Context, repo Repository, remoteName string) (*git
95110
if err != nil {
96111
return nil, err
97112
}
113+
if addr == "" {
114+
return nil, nil
115+
}
98116
return giturl.ParseGitURL(addr)
99117
}
100118

101-
// PruneRemote prunes the remote branches that no longer exist in the remote repository.
102-
func PruneRemote(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
119+
func SetRemoteURL(ctx context.Context, repo Repository, remoteName, remoteURL string) error {
103120
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
104121
if err != nil {
105122
return err
106123
}
107124
defer releaser()
108125

126+
cmd := git.NewCommand("remote", "set-url").AddDynamicArguments(remoteName, remoteURL)
127+
_, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
128+
return err
129+
}
130+
131+
// PruneRemote prunes the remote branches that no longer exist in the remote repository.
132+
// No lock is needed because the remote remoteName will be checked before invoking this function.
133+
// Then it will not update the remote automatically if the remote does not exist.
134+
func PruneRemote(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
109135
return git.NewCommand("remote", "prune").AddDynamicArguments(remoteName).
110136
Run(ctx, &git.RunOpts{
111137
Timeout: timeout,
@@ -115,13 +141,10 @@ func PruneRemote(ctx context.Context, repo Repository, remoteName string, timeou
115141
})
116142
}
117143

144+
// UpdateRemotePrune updates the remote branches and prunes the ones that no longer exist in the remote repository.
145+
// No lock is needed because the remote remoteName will be checked before invoking this function.
146+
// Then it will not update the remote automatically if the remote does not exist.
118147
func UpdateRemotePrune(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
119-
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
120-
if err != nil {
121-
return err
122-
}
123-
defer releaser()
124-
125148
return git.NewCommand("remote", "update", "--prune").AddDynamicArguments(remoteName).
126149
Run(ctx, &git.RunOpts{
127150
Timeout: timeout,

modules/templates/util_misc.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ import (
1414

1515
activities_model "code.gitea.io/gitea/models/activities"
1616
repo_model "code.gitea.io/gitea/models/repo"
17-
"code.gitea.io/gitea/modules/git"
18-
giturl "code.gitea.io/gitea/modules/git/url"
17+
"code.gitea.io/gitea/modules/gitrepo"
1918
"code.gitea.io/gitea/modules/json"
2019
"code.gitea.io/gitea/modules/log"
2120
"code.gitea.io/gitea/modules/repository"
@@ -145,15 +144,13 @@ type remoteAddress struct {
145144

146145
func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string) remoteAddress {
147146
ret := remoteAddress{}
148-
remoteURL, err := git.GetRemoteAddress(ctx, m.RepoPath(), remoteName)
147+
u, err := gitrepo.GetRemoteURL(ctx, m, remoteName)
149148
if err != nil {
150149
log.Error("GetRemoteURL %v", err)
151150
return ret
152151
}
153-
154-
u, err := giturl.ParseGitURL(remoteURL)
155-
if err != nil {
156-
log.Error("giturl.Parse %v", err)
152+
if u == nil {
153+
log.Error("GetRemoteURL %s returned nil", remoteName)
157154
return ret
158155
}
159156

services/mirror/mirror_pull.go

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,24 @@ func pruneBrokenReferences(ctx context.Context,
208208
stderrBuilder.Reset()
209209
stdoutBuilder.Reset()
210210

211+
// check whether the remote still exists before pruning to avoid prune creating a new remote
212+
// this is needed because prune will not fail if the remote does not exist
213+
u, err := gitrepo.GetRemoteURL(ctx, storageRepo, m.GetRemoteName())
214+
if err != nil {
215+
return err
216+
}
217+
if u == nil {
218+
return fmt.Errorf("remote %s does not exist for %srepository %s", m.GetRemoteName(), wiki, storageRepo.RelativePath())
219+
}
220+
221+
fetchConfig, err := gitrepo.GetGitConfig(ctx, storageRepo, "remote.origin.fetch")
222+
if err != nil {
223+
return err
224+
}
225+
if fetchConfig == "" {
226+
return fmt.Errorf("remote %s has no fetch config for %srepository %s", m.GetRemoteName(), wiki, storageRepo.RelativePath())
227+
}
228+
211229
pruneErr := gitrepo.PruneRemote(ctx, storageRepo, m.GetRemoteName(), timeout, stdoutBuilder, stderrBuilder)
212230
if pruneErr != nil {
213231
stdout := stdoutBuilder.String()
@@ -263,7 +281,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
263281

264282
remoteURL, remoteErr := gitrepo.GetRemoteURL(ctx, m.Repo, m.GetRemoteName())
265283
if remoteErr != nil {
266-
log.Error("SyncMirrors [repo: %-v]: GetRemoteAddress Error %v", m.Repo, remoteErr)
284+
log.Error("SyncMirrors [repo: %-v]: GetRemoteURL Error %v", m.Repo, remoteErr)
267285
return nil, false
268286
}
269287

@@ -365,6 +383,28 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
365383
stderrBuilder.Reset()
366384
stdoutBuilder.Reset()
367385

386+
// check whether the remote still exists before pruning to avoid prune creating a new remote
387+
// this is needed because prune will not fail if the remote does not exist
388+
u, err := gitrepo.GetRemoteURL(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName())
389+
if err != nil {
390+
log.Error("SyncMirrors [repo: %-v Wiki]: GetRemoteURL Error %v", m.Repo, err)
391+
return nil, false
392+
}
393+
if u == nil {
394+
log.Error("remote %s does not exist for repository %s", m.GetRemoteName(), m.Repo.WikiStorageRepo().RelativePath())
395+
return nil, false
396+
}
397+
398+
fetchConfig, err := gitrepo.GetGitConfig(ctx, m.Repo.WikiStorageRepo(), "remote.origin.fetch")
399+
if err != nil {
400+
log.Error("SyncMirrors [repo: %-v Wiki]: GetGitConfig Error %v", m.Repo, err)
401+
return nil, false
402+
}
403+
if fetchConfig == "" {
404+
log.Error("remote %s has no fetch config for repository %s", m.GetRemoteName(), m.Repo.WikiStorageRepo().RelativePath())
405+
return nil, false
406+
}
407+
368408
if err := gitrepo.UpdateRemotePrune(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName(),
369409
timeout, &stdoutBuilder, &stderrBuilder); err != nil {
370410
stdout := stdoutBuilder.String()
@@ -386,6 +426,28 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
386426
stderrBuilder.Reset()
387427
stdoutBuilder.Reset()
388428

429+
// check whether the remote still exists before pruning to avoid prune creating a new remote
430+
// this is needed because prune will not fail if the remote does not exist
431+
u, err := gitrepo.GetRemoteURL(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName())
432+
if err != nil {
433+
log.Error("SyncMirrors [repo: %-v Wiki]: GetRemoteURL Error %v", m.Repo, err)
434+
return nil, false
435+
}
436+
if u == nil {
437+
log.Error("remote %s does not exist for repository %s", m.GetRemoteName(), m.Repo.WikiStorageRepo().RelativePath())
438+
return nil, false
439+
}
440+
441+
fetchConfig, err := gitrepo.GetGitConfig(ctx, m.Repo.WikiStorageRepo(), "remote.origin.fetch")
442+
if err != nil {
443+
log.Error("SyncMirrors [repo: %-v Wiki]: GetGitConfig Error %v", m.Repo, err)
444+
return nil, false
445+
}
446+
if fetchConfig == "" {
447+
log.Error("remote %s has no fetch config for repository %s", m.GetRemoteName(), m.Repo.WikiStorageRepo().RelativePath())
448+
return nil, false
449+
}
450+
389451
if err = gitrepo.UpdateRemotePrune(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName(),
390452
timeout, &stdoutBuilder, &stderrBuilder); err != nil {
391453
stdout := stdoutBuilder.String()

services/mirror/mirror_push.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error {
130130
}
131131
remoteURL, err := gitrepo.GetRemoteURL(ctx, storageRepo, m.RemoteName)
132132
if err != nil {
133-
log.Error("GetRemoteAddress(%s) Error %v", path, err)
133+
log.Error("GetRemoteURL(%s) Error %v", path, err)
134134
return errors.New("Unexpected error")
135135
}
136136

@@ -175,8 +175,8 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error {
175175
}
176176

177177
if m.Repo.HasWiki() {
178-
_, err := git.GetRemoteAddress(ctx, m.Repo.WikiPath(), m.RemoteName)
179-
if err == nil {
178+
u, err := gitrepo.GetRemoteURL(ctx, m.Repo.WikiStorageRepo(), m.RemoteName)
179+
if err == nil && u != nil {
180180
err := performPush(m.Repo, true)
181181
if err != nil {
182182
return err

0 commit comments

Comments
 (0)