summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@gmail.com>2013-11-04 15:38:11 +0000
committerRichard Maw <richard.maw@gmail.com>2013-11-04 15:40:07 +0000
commitc07dc8fa5eb1c080b5ce741e980660be64a1da4e (patch)
tree1921192e9d70da533074f9366ca70aa13df924fc
parent4cb991a303e8826da72244e0ccfb40fea376260d (diff)
downloadgitano-add-stream-tar.tar.bz2
Add stream-tar commandadd-stream-tar
-rw-r--r--lib/gitano/repocommand.lua22
-rw-r--r--lib/gitano/repository.lua11
-rw-r--r--testing/02-commands-stream-tar.yarn30
3 files changed, 63 insertions, 0 deletions
diff --git a/lib/gitano/repocommand.lua b/lib/gitano/repocommand.lua
index 4d70a8b..7df1847 100644
--- a/lib/gitano/repocommand.lua
+++ b/lib/gitano/repocommand.lua
@@ -69,6 +69,24 @@ local function builtin_simple_run(config, repo, cmdline, env)
return proc:wait()
end
+local builtin_stream_tar_short = "Get a tar stream of repository"
+local builtin_stream_tar_helptext = [[
+usage: stream-tar repo
+
+Get the contents of a git repository as a tar stream. This is a faster
+way of cloning, but the receiver has to do extra work to make it appear
+like a normal clone.
+
+You must have read access to the repository to run stream-tar.
+]]
+local function builtin_stream_tar_prep(config, repo, cmdline, context)
+ context.operation = "read"
+ return repo:run_lace(context)
+end
+local function builtin_stream_tar_run(config, repo, cmdline, env)
+ return repo:stream_tar()
+end
+
local function register_repocommand(register_cmd)
assert(register_cmd("gc", builtin_gc_short, builtin_gc_helptext,
builtin_simple_validate, builtin_gc_prep,
@@ -82,6 +100,10 @@ local function register_repocommand(register_cmd)
assert(register_cmd("fsck", builtin_fsck_short, builtin_fsck_helptext,
builtin_simple_validate, builtin_fsck_prep,
builtin_simple_run, true, false))
+ assert(register_cmd("stream-tar", builtin_stream_tar_short,
+ builtin_stream_tar_helptext,
+ builtin_simple_validate, builtin_stream_tar_prep,
+ builtin_stream_tar_run, true, false))
end
return {
diff --git a/lib/gitano/repository.lua b/lib/gitano/repository.lua
index 796e162..a81a9f6 100644
--- a/lib/gitano/repository.lua
+++ b/lib/gitano/repository.lua
@@ -687,6 +687,17 @@ function repo_method:save_admin(reason, username)
return self:run_checks()
end
+function repo_method:stream_tar()
+ local proc = sp.spawn_simple{
+ 'tar', 'c', '-C', self:fs_path(), '.'
+ }
+ local how, why = proc:wait()
+ if how ~= "exit" or why ~= 0 then
+ return false, ("Tar failed: %s: %d"):format(how, why)
+ end
+ return how, why
+end
+
local repo_meta = {
__index = repo_method,
}
diff --git a/testing/02-commands-stream-tar.yarn b/testing/02-commands-stream-tar.yarn
new file mode 100644
index 0000000..3541a4c
--- /dev/null
+++ b/testing/02-commands-stream-tar.yarn
@@ -0,0 +1,30 @@
+<!-- -*- markdown -*- -->
+
+`stream-tar <repo>`
+===================
+
+The `stream-tar` command can be used to clone a repository, but bypass
+the repacking logic of the git server.
+
+This requires extra work on the client to get it into the right
+format. For a mirror, this involves removing any branches that aren't in
+`refs/heads` or `refs/tags`, for non-mirror clones, it needs to be turned
+into a non-bare repository.
+
+Basic operation
+===============
+
+ SCENARIO Basic operation of stream-tar
+ GIVEN a standard instance
+ WHEN testinstance adminkey runs create stoat
+ AND testinstance adminkey runs stream-tar stoat
+ THEN testinstance stdout can be extracted as badger
+ AND testinstance has a clone of badger
+
+Implementations
+===============
+
+ IMPLEMENTS THEN ([a-z][a-z0-9]*) ([^ ]+) can be extracted as ([^ ]+)
+ exdir="$DATADIR/user-home-$MATCH_1/$MATCH_3"
+ mkdir -p "$exdir"
+ tar xf "$DATADIR/$MATCH_2" -C "$exdir"