summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@gmail.com>2013-11-06 20:06:33 +0000
committerRichard Maw <richard.maw@gmail.com>2013-11-06 20:37:49 +0000
commit8adc9cb0b220b25692c1bce1733a7383fef062fd (patch)
tree5ea338990cea366477fc6f224c60afd91cdef302
parent2c852a412d923cf71b7747e91696f94ca711ae20 (diff)
downloadtar-clone-8adc9cb0b220b25692c1bce1733a7383fef062fd.tar.bz2
Provide a workspace
-rwxr-xr-xtar-clone7
-rwxr-xr-xtar-clone.lua63
2 files changed, 57 insertions, 13 deletions
diff --git a/tar-clone b/tar-clone
index 7787f96..ebc21b1 100755
--- a/tar-clone
+++ b/tar-clone
@@ -1,8 +1,11 @@
-#!/bin/sh
+#!/bin/bash
# A wrapper to make tar-clone.lua behave like a normal git clone
# and deal with library paths, so lua-archive does not need to be
# installed
+set -o pipefail
+set -e
+
LUA=lua5.1
CURDIR=$(readlink -f "$(dirname "$0")")
LUA_CPATH="$CURDIR/lua-archive/?.so;$($LUA -e'print(package.cpath)')"
@@ -12,4 +15,4 @@ SOURCE="$1"
TARGET="$2"
$LUA "$CURDIR/tar-clone.lua" "$SOURCE" "$TARGET" | tar x
cd "$TARGET"
-git reset --hard HEAD
+git reset HEAD
diff --git a/tar-clone.lua b/tar-clone.lua
index f89ad26..9bd1687 100755
--- a/tar-clone.lua
+++ b/tar-clone.lua
@@ -138,6 +138,55 @@ local function run_git(dir, ...)
return output
end
+local function write_refs(writer, repo, HEAD, localname)
+ for branch, sha1 in run_git(repo, 'git', 'for-each-ref',
+ '--format', '%(refname)%00%(objectname)%00',
+ 'refs/heads')
+ :gmatch"refs/heads/([^%z]+)%z([^%z]+)%z\n" do
+ write_file(writer, localname..'/.git/refs/remotes/origin/'..branch,
+ sha1..'\n')
+ if branch == HEAD then
+ write_file(writer, localname..'/.git/refs/heads/'..branch,
+ sha1..'\n')
+ end
+ end
+end
+
+local function write_workspace(writer, repo, HEAD, localname, bufsize)
+ bufsize = bufsize or 4 * 1024 * 1024 --4MB
+ local proc = sp.spawn_simple{"git", "archive", "--format=tar", HEAD,
+ cwd = repo, stdout = sp.PIPE}
+ local reader = archive.read{
+ compression = "none",
+ format = "tar",
+ reader = function(archive_read)
+ local r = proc.stdout:read(bufsize)
+ if r == -1 then
+ error("Reading git archive output")
+ end
+ if #r == 0 then
+ return nil
+ end
+ return r
+ end,
+ }
+ while true do
+ local header = reader:next_header()
+ if header == nil then
+ break
+ end
+ header:pathname(localname..'/'..header:pathname())
+ writer:header(header)
+ while true do
+ local data = reader:data()
+ if data == nil then
+ break
+ end
+ writer:data(data)
+ end
+ end
+end
+
local writer = archive.write{
format = "pax",
writer = function(archive, string)
@@ -158,14 +207,6 @@ write_file(writer, localname..'/.git/HEAD',
config = get_config('git://git@gitserver/repo', HEAD)
write_file(writer, localname..'/.git/config', config)
-for branch, sha1 in run_git(repo, 'git', 'for-each-ref',
- '--format', '%(refname)%00%(objectname)%00',
- 'refs/heads')
- :gmatch"refs/heads/([^%z]+)%z([^%z]+)%z\n" do
- write_file(writer, localname..'/.git/refs/remotes/origin/'..branch,
- sha1..'\n')
- if branch == HEAD then
- write_file(writer, localname..'/.git/refs/heads/'..branch,
- sha1..'\n')
- end
-end
+write_refs(writer, repo, HEAD, localname)
+
+write_workspace(writer, repo, HEAD, localname)