Skip to content

Commit ae3c338

Browse files
committed
Follow @wxiaoguang's suggestion
1 parent 869f3ae commit ae3c338

File tree

6 files changed

+112
-133
lines changed

6 files changed

+112
-133
lines changed

modules/gitrepo/config.go

Lines changed: 10 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,8 @@ package gitrepo
55

66
import (
77
"context"
8-
"errors"
9-
"io"
10-
"time"
118

129
"code.gitea.io/gitea/modules/git"
13-
giturl "code.gitea.io/gitea/modules/git/url"
1410
"code.gitea.io/gitea/modules/globallock"
1511
)
1612

@@ -33,123 +29,22 @@ func getRepoConfigLockKey(repoStoragePath string) string {
3329

3430
// GitConfigAdd add a git configuration key to a specific value for the given repository.
3531
func GitConfigAdd(ctx context.Context, repo Repository, key, value string) error {
36-
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
37-
if err != nil {
32+
return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error {
33+
_, _, err := git.NewCommand("config", "--add").
34+
AddDynamicArguments(key, value).
35+
RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
3836
return err
39-
}
40-
defer releaser()
41-
42-
_, _, err = git.NewCommand("config", "--add").
43-
AddDynamicArguments(key, value).
44-
RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
45-
return err
37+
})
4638
}
4739

4840
// GitConfigSet updates a git configuration key to a specific value for the given repository.
4941
// If the key does not exist, it will be created.
5042
// If the key exists, it will be updated to the new value.
5143
func GitConfigSet(ctx context.Context, repo Repository, key, value string) error {
52-
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
53-
if err != nil {
54-
return err
55-
}
56-
defer releaser()
57-
58-
_, _, err = git.NewCommand("config").
59-
AddDynamicArguments(key, value).
60-
RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
61-
return err
62-
}
63-
64-
type RemoteOption string
65-
66-
const (
67-
RemoteOptionMirrorPush RemoteOption = "--mirror=push"
68-
RemoteOptionMirrorFetch RemoteOption = "--mirror=fetch"
69-
)
70-
71-
func GitRemoteAdd(ctx context.Context, repo Repository, remoteName, remoteURL string, options ...RemoteOption) error {
72-
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
73-
if err != nil {
74-
return err
75-
}
76-
defer releaser()
77-
78-
cmd := git.NewCommand("remote", "add")
79-
if len(options) > 0 {
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-
}
88-
}
89-
_, _, err = cmd.
90-
AddDynamicArguments(remoteName, remoteURL).
91-
RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
92-
return err
93-
}
94-
95-
func GitRemoteRemove(ctx context.Context, repo Repository, remoteName string) error {
96-
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
97-
if err != nil {
98-
return err
99-
}
100-
defer releaser()
101-
102-
cmd := git.NewCommand("remote", "rm").AddDynamicArguments(remoteName)
103-
_, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
104-
return err
105-
}
106-
107-
// GitRemoteGetURL returns the url of a specific remote of the repository.
108-
func GitRemoteGetURL(ctx context.Context, repo Repository, remoteName string) (*giturl.GitURL, error) {
109-
addr, err := git.GetRemoteAddress(ctx, repoPath(repo), remoteName)
110-
if err != nil {
111-
return nil, err
112-
}
113-
if addr == "" {
114-
return nil, nil
115-
}
116-
return giturl.ParseGitURL(addr)
117-
}
118-
119-
func SetRemoteURL(ctx context.Context, repo Repository, remoteName, remoteURL string) error {
120-
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
121-
if err != nil {
44+
return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error {
45+
_, _, err := git.NewCommand("config").
46+
AddDynamicArguments(key, value).
47+
RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
12248
return err
123-
}
124-
defer releaser()
125-
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-
// GitRemotePrune 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 GitRemotePrune(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
135-
return git.NewCommand("remote", "prune").AddDynamicArguments(remoteName).
136-
Run(ctx, &git.RunOpts{
137-
Timeout: timeout,
138-
Dir: repoPath(repo),
139-
Stdout: stdout,
140-
Stderr: stderr,
141-
})
142-
}
143-
144-
// GitRemoteUpdatePrune 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.
147-
func GitRemoteUpdatePrune(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
148-
return git.NewCommand("remote", "update", "--prune").AddDynamicArguments(remoteName).
149-
Run(ctx, &git.RunOpts{
150-
Timeout: timeout,
151-
Dir: repoPath(repo),
152-
Stdout: stdout,
153-
Stderr: stderr,
154-
})
49+
})
15550
}

modules/gitrepo/remote.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package gitrepo
5+
6+
import (
7+
"context"
8+
"errors"
9+
"io"
10+
"time"
11+
12+
"code.gitea.io/gitea/modules/git"
13+
giturl "code.gitea.io/gitea/modules/git/url"
14+
"code.gitea.io/gitea/modules/globallock"
15+
"code.gitea.io/gitea/modules/util"
16+
)
17+
18+
type RemoteOption string
19+
20+
const (
21+
RemoteOptionMirrorPush RemoteOption = "--mirror=push"
22+
RemoteOptionMirrorFetch RemoteOption = "--mirror=fetch"
23+
)
24+
25+
func GitRemoteAdd(ctx context.Context, repo Repository, remoteName, remoteURL string, options ...RemoteOption) error {
26+
return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error {
27+
cmd := git.NewCommand("remote", "add")
28+
if len(options) > 0 {
29+
switch options[0] {
30+
case RemoteOptionMirrorPush:
31+
cmd.AddArguments("--mirror=push")
32+
case RemoteOptionMirrorFetch:
33+
cmd.AddArguments("--mirror=fetch")
34+
default:
35+
return errors.New("unknown remote option: " + string(options[0]))
36+
}
37+
}
38+
_, _, err := cmd.
39+
AddDynamicArguments(remoteName, remoteURL).
40+
RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
41+
return err
42+
})
43+
}
44+
45+
func GitRemoteRemove(ctx context.Context, repo Repository, remoteName string) error {
46+
return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error {
47+
cmd := git.NewCommand("remote", "rm").AddDynamicArguments(remoteName)
48+
_, _, err := cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
49+
return err
50+
})
51+
}
52+
53+
// GitRemoteGetURL returns the url of a specific remote of the repository.
54+
func GitRemoteGetURL(ctx context.Context, repo Repository, remoteName string) (*giturl.GitURL, error) {
55+
addr, err := git.GetRemoteAddress(ctx, repoPath(repo), remoteName)
56+
if err != nil {
57+
return nil, err
58+
}
59+
if addr == "" {
60+
return nil, util.NewNotExistErrorf("remote '%s' does not exist", remoteName)
61+
}
62+
return giturl.ParseGitURL(addr)
63+
}
64+
65+
func SetRemoteURL(ctx context.Context, repo Repository, remoteName, remoteURL string) error {
66+
return globallock.LockAndDo(ctx, getRepoConfigLockKey(repo.RelativePath()), func(ctx context.Context) error {
67+
cmd := git.NewCommand("remote", "set-url").AddDynamicArguments(remoteName, remoteURL)
68+
_, _, err := cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
69+
return err
70+
})
71+
}
72+
73+
// GitRemotePrune prunes the remote branches that no longer exist in the remote repository.
74+
// No lock is needed because the remote remoteName will be checked before invoking this function.
75+
// Then it will not update the remote automatically if the remote does not exist.
76+
func GitRemotePrune(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
77+
return git.NewCommand("remote", "prune").AddDynamicArguments(remoteName).
78+
Run(ctx, &git.RunOpts{
79+
Timeout: timeout,
80+
Dir: repoPath(repo),
81+
Stdout: stdout,
82+
Stderr: stderr,
83+
})
84+
}
85+
86+
// GitRemoteUpdatePrune updates the remote branches and prunes the ones that no longer exist in the remote repository.
87+
// No lock is needed because the remote remoteName will be checked before invoking this function.
88+
// Then it will not update the remote automatically if the remote does not exist.
89+
func GitRemoteUpdatePrune(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
90+
return git.NewCommand("remote", "update", "--prune").AddDynamicArguments(remoteName).
91+
Run(ctx, &git.RunOpts{
92+
Timeout: timeout,
93+
Dir: repoPath(repo),
94+
Stdout: stdout,
95+
Stderr: stderr,
96+
})
97+
}

modules/templates/util_misc.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,6 @@ func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteNa
149149
log.Error("GetRemoteURL %v", err)
150150
return ret
151151
}
152-
if u == nil {
153-
log.Error("GetRemoteURL %s returned nil", remoteName)
154-
return ret
155-
}
156152

157153
if u.Scheme != "ssh" && u.Scheme != "file" {
158154
if u.User != nil {

routers/web/repo/setting/setting.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,11 +265,6 @@ func handleSettingsPostMirror(ctx *context.Context) {
265265
handleSettingRemoteAddrError(ctx, err, form)
266266
return
267267
}
268-
if u == nil {
269-
ctx.Data["Err_MirrorAddress"] = true
270-
handleSettingRemoteAddrError(ctx, err, form)
271-
return
272-
}
273268
if u.User != nil && form.MirrorPassword == "" && form.MirrorUsername == u.User.Username() {
274269
form.MirrorPassword, _ = u.User.Password()
275270
}

services/mirror/mirror_pull.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error
4646
return err
4747
}
4848

49-
err = gitrepo.GitRemoteAdd(ctx, repo, remoteName, addr, "--mirror=fetch")
49+
err = gitrepo.GitRemoteAdd(ctx, repo, remoteName, addr, gitrepo.RemoteOptionMirrorFetch)
5050
if err != nil && !git.IsRemoteNotExistError(err) {
5151
return err
5252
}
@@ -59,7 +59,7 @@ func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error
5959
return err
6060
}
6161

62-
err = gitrepo.GitRemoteAdd(ctx, repo.WikiStorageRepo(), remoteName, wikiRemotePath, "--mirror=fetch")
62+
err = gitrepo.GitRemoteAdd(ctx, repo.WikiStorageRepo(), remoteName, wikiRemotePath, gitrepo.RemoteOptionMirrorFetch)
6363
if err != nil && !git.IsRemoteNotExistError(err) {
6464
return err
6565
}
@@ -365,17 +365,13 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
365365
stderrBuilder.Reset()
366366
stdoutBuilder.Reset()
367367

368-
// check whether the remote still exists before pruning to avoid prune creating a new remote
368+
// check whether the remote still exists before remote update prune
369369
// this is needed because prune will not fail if the remote does not exist
370-
u, err := gitrepo.GitRemoteGetURL(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName())
370+
_, err := gitrepo.GitRemoteGetURL(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName())
371371
if err != nil {
372372
log.Error("SyncMirrors [repo: %-v Wiki]: GetRemoteURL Error %v", m.Repo, err)
373373
return nil, false
374374
}
375-
if u == nil {
376-
log.Error("remote %s does not exist for repository %s", m.GetRemoteName(), m.Repo.WikiStorageRepo().RelativePath())
377-
return nil, false
378-
}
379375

380376
fetchConfig, err := gitrepo.GitConfigGet(ctx, m.Repo.WikiStorageRepo(), "remote.origin.fetch")
381377
if err != nil {

services/mirror/mirror_push.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ var stripExitStatus = regexp.MustCompile(`exit status \d+ - `)
3030
// AddPushMirrorRemote registers the push mirror remote.
3131
func AddPushMirrorRemote(ctx context.Context, m *repo_model.PushMirror, addr string) error {
3232
addRemoteAndConfig := func(storageRepo gitrepo.Repository, addr string) error {
33-
if err := gitrepo.GitRemoteAdd(ctx, storageRepo, m.RemoteName, addr, "--mirror=push"); err != nil {
33+
if err := gitrepo.GitRemoteAdd(ctx, storageRepo, m.RemoteName, addr, gitrepo.RemoteOptionMirrorPush); err != nil {
3434
return err
3535
}
3636
if err := gitrepo.GitConfigAdd(ctx, storageRepo, "remote."+m.RemoteName+".push", "+refs/heads/*:refs/heads/*"); err != nil {

0 commit comments

Comments
 (0)