mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 19:11:25 +01:00
fix(repo): add the upstream remote when cloning a pull mirror
Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
2 files changed
+40
-3
No files matched your search
@@ -150,6 +150,35 @@ func TestSSHCloneTrustsAPIEndpointUnlessSSHHostIsConfigured(t *testing.T) {
|
|||||||
require.Empty(t, runner.calls)
|
require.Empty(t, runner.calls)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCloneAddsSourceRemoteForMirrors(t *testing.T) {
|
||||||
|
original := ""
|
||||||
|
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
_, _ = fmt.Fprintf(w, `{"id":9,"name":"project","full_name":"alice/project","mirror":true,"clone_url":"http://%s/alice/project.git","original_url":%q}`, r.Host, original)
|
||||||
|
}))
|
||||||
|
defer server.Close()
|
||||||
|
deps, out, diagnostics := repoTTYDeps(t, server.URL)
|
||||||
|
clone := credentialCall(t, deps, server.URL, "alice", "clone", "--", server.URL+"/alice/project.git", "destination")
|
||||||
|
original = "https://github.com/upstream/project.git"
|
||||||
|
runner := &fakeGit{results: map[string]string{clone: "", "remote add -- source " + original: ""}}
|
||||||
|
deps.Git = runner
|
||||||
|
args := []string{"repo", "clone", "alice/project", "destination"}
|
||||||
|
require.NoError(t, Execute(context.Background(), deps, args))
|
||||||
|
require.Equal(t, []string{clone, "remote add -- source " + original}, runner.calls)
|
||||||
|
require.Equal(t, "✓ Cloned alice/project into destination\n✓ Added remote source for "+original+"\n", diagnostics.String())
|
||||||
|
runner.calls = nil
|
||||||
|
require.NoError(t, Execute(context.Background(), deps, append(args, "--json")))
|
||||||
|
require.Equal(t, []string{clone, "remote add -- source " + original}, runner.calls)
|
||||||
|
require.NotContains(t, out.String(), "github.com")
|
||||||
|
runner.calls = nil
|
||||||
|
require.NoError(t, Execute(context.Background(), deps, append(args, "--no-upstream")))
|
||||||
|
require.Equal(t, []string{clone}, runner.calls)
|
||||||
|
for _, unsafe := range []string{"https://user:secret@github.com/upstream/project.git", "file:///srv/project.git", "ext::sh -c touch% /tmp/pwned"} {
|
||||||
|
original, runner.calls = unsafe, nil
|
||||||
|
require.NoError(t, Execute(context.Background(), deps, args), unsafe)
|
||||||
|
require.Equal(t, []string{clone}, runner.calls, unsafe)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestClonePassesGitFlagsAndNamesTheUpstreamRemote(t *testing.T) {
|
func TestClonePassesGitFlagsAndNamesTheUpstreamRemote(t *testing.T) {
|
||||||
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
_, _ = fmt.Fprintf(w, `{"name":"project","full_name":"bob/project","fork":true,"clone_url":"http://%[1]s/bob/project.git","parent":{"full_name":"alice/project","default_branch":"main","clone_url":"http://%[1]s/alice/project.git"}}`, r.Host)
|
_, _ = fmt.Fprintf(w, `{"name":"project","full_name":"bob/project","fork":true,"clone_url":"http://%[1]s/bob/project.git","parent":{"full_name":"alice/project","default_branch":"main","clone_url":"http://%[1]s/alice/project.git"}}`, r.Host)
|
||||||
|
|||||||
@@ -241,7 +241,8 @@ func (a *application) repoCloneCommand() *cobra.Command {
|
|||||||
Short: "Clone a repository locally",
|
Short: "Clone a repository locally",
|
||||||
Long: `Clone a repository with the configured Git protocol and tea's credentials. Git flags can
|
Long: `Clone a repository with the configured Git protocol and tea's credentials. Git flags can
|
||||||
follow --. A fork's parent is added as the "upstream" remote, and tea commands in the clone then
|
follow --. A fork's parent is added as the "upstream" remote, and tea commands in the clone then
|
||||||
target the parent.`,
|
target the parent. A pull mirror's source is added as the "source" remote; tea commands keep
|
||||||
|
targeting the mirror.`,
|
||||||
Example: `# Clone a repository into ./project
|
Example: `# Clone a repository into ./project
|
||||||
$ tea repo clone alice/project
|
$ tea repo clone alice/project
|
||||||
|
|
||||||
@@ -287,7 +288,7 @@ $ tea repo clone alice/project -- --branch develop --recurse-submodules`,
|
|||||||
}
|
}
|
||||||
command.Flags().IntVarP(&opts.depth, "depth", "d", 0, "Number of commits to fetch (0: full history)")
|
command.Flags().IntVarP(&opts.depth, "depth", "d", 0, "Number of commits to fetch (0: full history)")
|
||||||
command.Flags().StringVarP(&opts.upstream, "upstream-remote-name", "u", "upstream", "Remote name for the parent of a fork")
|
command.Flags().StringVarP(&opts.upstream, "upstream-remote-name", "u", "upstream", "Remote name for the parent of a fork")
|
||||||
command.Flags().BoolVar(&noUpstream, "no-upstream", false, "Do not add a remote for the parent of a fork")
|
command.Flags().BoolVar(&noUpstream, "no-upstream", false, "Do not add a remote for the parent of a fork or the source of a mirror")
|
||||||
command.ValidArgsFunction = pathArgs(1, false, completeDirectories, a.completeRepos())
|
command.ValidArgsFunction = pathArgs(1, false, completeDirectories, a.completeRepos())
|
||||||
return command
|
return command
|
||||||
}
|
}
|
||||||
@@ -419,7 +420,7 @@ type cloneOptions struct {
|
|||||||
directory string
|
directory string
|
||||||
depth int
|
depth int
|
||||||
gitFlags []string
|
gitFlags []string
|
||||||
// upstream names the remote of a fork's parent; empty adds none.
|
// upstream names the remote of a fork's parent; empty adds neither it nor a mirror's source.
|
||||||
upstream string
|
upstream string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,6 +488,13 @@ func (a *application) cloneRepository(cmd *cobra.Command, t target, item service
|
|||||||
}
|
}
|
||||||
a.done(cmd, "Added remote %s for %s; tea commands in the clone target it (change with tea repo set-default)", opts.upstream, item.Parent.FullName)
|
a.done(cmd, "Added remote %s for %s; tea commands in the clone target it (change with tea repo set-default)", opts.upstream, item.Parent.FullName)
|
||||||
}
|
}
|
||||||
|
// The remote is named source because repository discovery prefers a remote named upstream.
|
||||||
|
if source := mirrorSourceURL(item); source != "" && opts.upstream != "" {
|
||||||
|
if _, err := a.gitIn(cmd.Context(), clone, "remote", "add", "--", "source", source); err != nil {
|
||||||
|
return clone, fmt.Errorf("cloned the mirror, but could not add the source remote: %w", err)
|
||||||
|
}
|
||||||
|
a.done(cmd, "Added remote source for %s", source)
|
||||||
|
}
|
||||||
return clone, nil
|
return clone, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user