Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ You can also list local repositories (+ghq list+).
== SYNOPSIS

[verse]
ghq get [-u] [-p] [--shallow] [--vcs <vcs>] [--look] [--silent] [--branch] [--no-recursive] [--bare] <repository URL>|<host>/<user>/<project>|<user>/<project>|<project>
ghq get [-u] [-p] [--shallow] [--vcs <vcs>] [--look] [--silent] [--branch] [--no-recursive] [--bare] [--partial blobless|treeless] <repository URL>|<host>/<user>/<project>|<user>/<project>|<project>
ghq list [-p] [-e] [<query>]
ghq create [--vcs <vcs>] <repository URL>|<host>/<user>/<project>|<user>/<project>|<project>
ghq rm [--dry-run] <repository URL>|<host>/<user>/<project>|<user>/<project>|<project>
Expand Down Expand Up @@ -44,7 +44,10 @@ get::
The 'ghq' gets the git repository recursively by default. +
We can prevent it with '--no-recursive' option.
With '--bare' option, a "bare clone" will be performed (for Git
repositories only, 'git clone --bare ...' eg.).
repositories only, 'git clone --bare ...' eg.). +
With '--partial' option, a "partial clone" will be performed (for Git
repositories only, in 'blobless' mode, 'git clone --filter=blob:none ...',
in 'treeless' mode, 'git clone --filter=tree:0 ...' eg.).

list::
List locally cloned repositories. If a query argument is given, only
Expand Down
1 change: 1 addition & 0 deletions cmd_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func doGet(c *cli.Context) error {
branch: c.String("branch"),
recursive: !c.Bool("no-recursive"),
bare: c.Bool("bare"),
partial: c.String("partial"),
}
if parallel {
// force silent in parallel import
Expand Down
46 changes: 46 additions & 0 deletions cmd_get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,52 @@ func TestCommandGet(t *testing.T) {
t.Errorf("silent mode should not output any logs, but got: %s", out)
}
},
}, {
name: "[partial] blobless",
scenario: func(t *testing.T, tmpRoot string, cloneArgs *_cloneArgs, updateArgs *_updateArgs) {
localDir := filepath.Join(tmpRoot, "github.com", "motemen", "ghq-test-repo")

app.Run([]string{"", "get", "--partial", "blobless", "motemen/ghq-test-repo"})

expect := "https://github.com/motemen/ghq-test-repo"
if cloneArgs.remote.String() != expect {
t.Errorf("got: %s, expect: %s", cloneArgs.remote, expect)
}
if filepath.ToSlash(cloneArgs.local) != filepath.ToSlash(localDir) {
t.Errorf("got: %s, expect: %s", filepath.ToSlash(cloneArgs.local), filepath.ToSlash(localDir))
}
if cloneArgs.partial != "blobless" {
t.Errorf("cloneArgs.partial should be \"blobless\"")
}
},
}, {
name: "[partial] treeless",
scenario: func(t *testing.T, tmpRoot string, cloneArgs *_cloneArgs, updateArgs *_updateArgs) {
localDir := filepath.Join(tmpRoot, "github.com", "motemen", "ghq-test-repo")

app.Run([]string{"", "get", "--partial", "treeless", "motemen/ghq-test-repo"})

expect := "https://github.com/motemen/ghq-test-repo"
if cloneArgs.remote.String() != expect {
t.Errorf("got: %s, expect: %s", cloneArgs.remote, expect)
}
if filepath.ToSlash(cloneArgs.local) != filepath.ToSlash(localDir) {
t.Errorf("got: %s, expect: %s", filepath.ToSlash(cloneArgs.local), filepath.ToSlash(localDir))
}
if cloneArgs.partial != "treeless" {
t.Errorf("cloneArgs.partial should be \"treeless\"")
}
},
}, {
name: "[partial] unacceptable value",
scenario: func(t *testing.T, tmpRoot string, cloneArgs *_cloneArgs, updateArgs *_updateArgs) {
err := app.Run([]string{"", "get", "--partial", "unacceptable", "motemen/ghq-test-repo"})

expect := "flag partial value \"unacceptable\" is not allowed"
if err.Error() != expect {
t.Errorf("got: %s, expect: %s", err.Error(), expect)
}
},
}}

for _, tc := range testCases {
Expand Down
13 changes: 12 additions & 1 deletion commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"fmt"
"slices"
"strings"

"github.com/urfave/cli/v2"
Expand Down Expand Up @@ -38,6 +39,16 @@ var commandGet = &cli.Command{
Usage: "Specify `branch` name. This flag implies --single-branch on Git"},
&cli.BoolFlag{Name: "parallel", Aliases: []string{"P"}, Usage: "Import parallelly"},
&cli.BoolFlag{Name: "bare", Usage: "Do a bare clone"},
&cli.StringFlag{
Name: "partial",
Usage: "Do a partial clone. Can specify either \"blobless\" or \"treeless\"",
Action: func(ctx *cli.Context, v string) error {
expected := []string{"blobless", "treeless"}
if !slices.Contains(expected, v) {
return fmt.Errorf("flag partial value \"%v\" is not allowed", v)
}
return nil
}},
},
}

Expand Down Expand Up @@ -94,7 +105,7 @@ type commandDoc struct {
}

var commandDocs = map[string]commandDoc{
"get": {"", "[-u] [-p] [--shallow] [--vcs <vcs>] [--look] [--silent] [--branch <branch>] [--no-recursive] [--bare] <repository URL>|<project>|<user>/<project>|<host>/<user>/<project>"},
"get": {"", "[-u] [-p] [--shallow] [--vcs <vcs>] [--look] [--silent] [--branch <branch>] [--no-recursive] [--bare] [--partial blobless|treeless] <repository URL>|<project>|<user>/<project>|<host>/<user>/<project>"},
"list": {"", "[-p] [-e] [<query>]"},
"create": {"", "<project>|<user>/<project>|<host>/<user>/<project>"},
"rm": {"", "<project>|<user>/<project>|<host>/<user>/<project>"},
Expand Down
2 changes: 2 additions & 0 deletions commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type _cloneArgs struct {
recursive bool
bare bool
silent bool
partial string
}

type _updateArgs struct {
Expand All @@ -41,6 +42,7 @@ func withFakeGitBackend(t *testing.T, block func(*testing.T, string, *_cloneArgs
recursive: vg.recursive,
bare: vg.bare,
silent: vg.silent,
partial: vg.partial,
}
return nil
},
Expand Down
3 changes: 2 additions & 1 deletion getter.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type getInfo struct {

type getter struct {
update, shallow, silent, ssh, recursive, bare bool
vcs, branch string
vcs, branch, partial string
}

func (g *getter) get(argURL string) (getInfo, error) {
Expand Down Expand Up @@ -113,6 +113,7 @@ func (g *getter) getRemoteRepository(remote RemoteRepository, branch string) (ge
branch: branch,
recursive: g.recursive,
bare: g.bare,
partial: g.partial,
})
}
return info, nil
Expand Down
6 changes: 6 additions & 0 deletions misc/author/integration_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export GHQ_ROOT=$tmpdir
ghq get https://svn.apache.org/repos/asf/subversion
ghq get --shallow hub.darcs.net/byorgey/split
ghq get --bare x-motemen/gore
ghq get --partial blobless x-motemen/blogsync
ghq get --partial treeless x-motemen/gobump

test -d $tmpdir/github.com/x-motemen/ghq/.git
test -d $tmpdir/www.mercurial-scm.org/repo/hello/.hg
Expand All @@ -34,11 +36,15 @@ export GHQ_ROOT=$tmpdir
test -d $tmpdir/svn.apache.org/repos/asf/subversion/.svn
test -d $tmpdir/hub.darcs.net/byorgey/split/_darcs
test -d $tmpdir/github.com/x-motemen/gore.git/refs
grep --quiet "partialclonefilter = blob:none" $tmpdir/github.com/x-motemen/blogsync/.git/config
grep --quiet "partialclonefilter = tree:0" $tmpdir/github.com/x-motemen/gobump/.git/config

: testing 'ghq list'
cat <<EOF | sort > $tmpdir/expect
chiselapp.com/user/sti/repository/fossil-gui
github.com/x-motemen/blogsync
github.com/x-motemen/ghq
github.com/x-motemen/gobump
github.com/x-motemen/gore.git
www.mercurial-scm.org/repo/hello
launchpad.net/shutter
Expand Down
5 changes: 5 additions & 0 deletions misc/fish/ghq.fish
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ complete -c ghq -n '__fish_seen_subcommand_from get' -l no-recursive -d 'Prevent
complete -c ghq -n '__fish_seen_subcommand_from get' -s b -l branch -d 'Specify branch name. This flag implies --single-branch on Git'
complete -c ghq -n '__fish_seen_subcommand_from get' -s P -l parallel -d 'Import parallelly'
complete -c ghq -n '__fish_seen_subcommand_from get' -l bare -d 'Do a bare clone'
function __complete_get_partial
printf '%s\t%s\n' 'blobless' 'Do a blobless clone'
printf '%s\t%s\n' 'treeless' 'Do a treeless clone'
end
complete -c ghq -n '__fish_seen_subcommand_from get' -l partial -d 'Do a partial clone' -xa '(__complete_get_partial)'

complete -c ghq -n '__fish_seen_subcommand_from list' -s e -l exact -d 'Perform an exact match'
complete -c ghq -n '__fish_seen_subcommand_from list' -l vcs -d 'Specify vcs backend for matching'
Expand Down
1 change: 1 addition & 0 deletions misc/zsh/_ghq
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ function _ghq () {
'--bare[Do a bare clone]' \
'(-b --branch)'{-b,--branch}'[Specify branch name]' \
'(-P --parallel)'{-P,--parallel}'[Import parallelly]' \
'--partial[Do a partial clone]: :(blobless treeless)' \
'(-)*:: :->null_state' \
&& ret=0
;;
Expand Down
7 changes: 6 additions & 1 deletion vcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type vcsGetOption struct {
url *url.URL
dir string
recursive, shallow, silent, bare bool
branch string
branch, partial string
}

// GitBackend is the VCSBackend of git
Expand All @@ -70,6 +70,11 @@ var GitBackend = &VCSBackend{
if vg.bare {
args = append(args, "--bare")
}
if vg.partial == "blobless" {
args = append(args, "--filter=blob:none")
} else if vg.partial == "treeless" {
args = append(args, "--filter=tree:0")
}
args = append(args, vg.url.String(), vg.dir)

return run(vg.silent)("git", args...)
Expand Down
20 changes: 20 additions & 0 deletions vcs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,26 @@ func TestVCSBackend(t *testing.T) {
})
},
expect: []string{"git", "clone", "--bare", remoteDummyURL.String(), localDir},
}, {
name: "[git] (partial) blobless clone",
f: func() error {
return GitBackend.Clone(&vcsGetOption{
url: remoteDummyURL,
dir: localDir,
partial: "blobless",
})
},
expect: []string{"git", "clone", "--filter=blob:none", remoteDummyURL.String(), localDir},
}, {
name: "[git] (partial) treeless clone",
f: func() error {
return GitBackend.Clone(&vcsGetOption{
url: remoteDummyURL,
dir: localDir,
partial: "treeless",
})
},
expect: []string{"git", "clone", "--filter=tree:0", remoteDummyURL.String(), localDir},
}, {
name: "[git] switch git-svn on update",
f: func() error {
Expand Down