{"action":"created","comment":{"url":"https://api.github.com/repos/flynn/flynn/pulls/comments/24966728","id":24966728,"diff_hunk":"@@ -307,14 +313,134 @@ func ensureCacheRepo(path string) error {\n \tdefer cacheMtx.Unlock()\n \n \tcachePath := *repoPath + \"/\" + path\n-\tif _, err := os.Stat(cachePath); os.IsNotExist(err) {\n-\t\tos.MkdirAll(cachePath, 0755)\n+\n+\t// remove old copy\n+\tif _, err := os.Stat(cachePath); err == nil {\n+\t\tos.RemoveAll(cachePath)\n+\t}\n+\tos.MkdirAll(cachePath, 0755)\n+\n+\tres, err := http.Get(\"http://blobstore.discoverd/cache/\" + path + \".tar\")\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\tdefer res.Body.Close()\n+\n+\tif res.StatusCode == 200 {\n+\t\t// cache hit\n+\t\tr := tar.NewReader(res.Body)\n+\t\tfor {\n+\t\t\theader, err := r.Next()\n+\t\t\tif err != nil {\n+\t\t\t\tif err == io.EOF {\n+\t\t\t\t\tbreak\n+\t\t\t\t}\n+\t\t\t\treturn err\n+\t\t\t}\n+\n+\t\t\tfilename := cachePath + \"/\" + header.Name\n+\n+\t\t\tswitch header.Typeflag {\n+\t\t\tcase tar.TypeDir:\n+\t\t\t\tif _, err := os.Stat(filename); os.IsNotExist(err) {\n+\t\t\t\t\tif err := os.MkdirAll(filename, os.FileMode(header.Mode)); err != nil {\n+\t\t\t\t\t\treturn err\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t\tif err := os.Chmod(filename, os.FileMode(header.Mode)); err != nil {\n+\t\t\t\t\treturn err\n+\t\t\t\t}\n+\t\t\tcase tar.TypeReg, tar.TypeRegA:\n+\t\t\t\t// if the files are out of order, the dir might not exist yet\n+\t\t\t\tif _, err := os.Stat(filepath.Dir(filename)); os.IsNotExist(err) {\n+\t\t\t\t\tif err := os.MkdirAll(filepath.Dir(filename), os.FileMode(header.Mode)); err != nil {\n+\t\t\t\t\t\treturn err\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t\twriter, err := os.Create(filename)\n+\t\t\t\tif err != nil {\n+\t\t\t\t\treturn err\n+\t\t\t\t}\n+\t\t\t\tdefer writer.Close()\n+\n+\t\t\t\tio.Copy(writer, r)\n+\n+\t\t\t\tif err := os.Chmod(filename, os.FileMode(header.Mode)); err != nil {\n+\t\t\t\t\treturn err\n+\t\t\t\t}\n+\t\t\tdefault:\n+\t\t\t}\n+\t\t}\n+\t} else {\n \t\tcmd := exec.Command(\"git\", \"init\", \"--bare\")\n \t\tcmd.Dir = cachePath\n \t\terr = cmd.Run()\n \t\tif err != nil {\n \t\t\treturn err\n \t\t}\n+\t\treturn ioutil.WriteFile(cachePath+\"/hooks/pre-receive\", prereceiveHook, 0755)\n+\t}\n+\treturn nil\n+}\n+\n+func uploadCache(path string) error {\n+\tcacheMtx.Lock()\n+\tdefer cacheMtx.Unlock()\n+\n+\tcachePath := *repoPath + \"/\" + path\n+\n+\tbuf := new(bytes.Buffer)\n+\ttw := tar.NewWriter(buf)\n+\n+\tif err := filepath.Walk(cachePath, func(path string, file os.FileInfo, err error) error {\n+\t\tif err != nil {\n+\t\t\treturn err\n+\t\t}\n+\t\tif file.IsDir() {\n+\t\t\treturn nil\n+\t\t}\n+\n+\t\tf, err := os.Open(path)\n+\t\tif err != nil {\n+\t\t\treturn err\n+\t\t}\n+\t\tdefer f.Close()\n+\n+\t\tfpath, err := filepath.Rel(cachePath, path)\n+\t\tif err != nil {\n+\t\t\treturn err\n+\t\t}\n+\t\thdr := &tar.Header{\n+\t\t\tName:    fpath,\n+\t\t\tSize:    file.Size(),\n+\t\t\tMode:    int64(file.Mode()),\n+\t\t\tModTime: file.ModTime(),\n+\t\t}\n+\n+\t\tif err := tw.WriteHeader(hdr); err != nil {\n+\t\t\treturn err\n+\t\t}\n+\n+\t\tif _, err = io.Copy(tw, f); err != nil {\n+\t\t\treturn err\n+\t\t}\n+\t\treturn nil\n+\t}); err != nil {\n+\t\treturn err\n+\t}\n+\tif err := tw.Close(); err != nil {\n+\t\treturn err\n \t}\n-\treturn ioutil.WriteFile(cachePath+\"/hooks/pre-receive\", prereceiveHook, 0755)\n+\n+\t// upload the tarball to the blobstore\n+\treq, err := http.NewRequest(\"PUT\", \"http://blobstore.discoverd/cache/\"+path+\".tar\", buf)\n+\n+\tclient := &http.Client{}","path":"gitreceived/gitreceived.go","position":158,"original_position":158,"commit_id":"f85f9ed421af3a6f17c9a89b388100a739c4072e","original_commit_id":"f85f9ed421af3a6f17c9a89b388100a739c4072e","user":{"login":"titanous","id":13026,"avatar_url":"https://avatars.githubusercontent.com/u/13026?v=3","gravatar_id":"","url":"https://api.github.com/users/titanous","html_url":"https://github.com/titanous","followers_url":"https://api.github.com/users/titanous/followers","following_url":"https://api.github.com/users/titanous/following{/other_user}","gists_url":"https://api.github.com/users/titanous/gists{/gist_id}","starred_url":"https://api.github.com/users/titanous/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/titanous/subscriptions","organizations_url":"https://api.github.com/users/titanous/orgs","repos_url":"https://api.github.com/users/titanous/repos","events_url":"https://api.github.com/users/titanous/events{/privacy}","received_events_url":"https://api.github.com/users/titanous/received_events","type":"User","site_admin":false},"body":"Use `http.DefaultClient`","created_at":"2015-02-19T05:27:20Z","updated_at":"2015-02-19T05:27:20Z","html_url":"https://github.com/flynn/flynn/pull/1035#discussion_r24966728","pull_request_url":"https://api.github.com/repos/flynn/flynn/pulls/1035","_links":{"self":{"href":"https://api.github.com/repos/flynn/flynn/pulls/comments/24966728"},"html":{"href":"https://github.com/flynn/flynn/pull/1035#discussion_r24966728"},"pull_request":{"href":"https://api.github.com/repos/flynn/flynn/pulls/1035"}}},"pull_request":{"url":"https://api.github.com/repos/flynn/flynn/pulls/1035","id":29587698,"html_url":"https://github.com/flynn/flynn/pull/1035","diff_url":"https://github.com/flynn/flynn/pull/1035.diff","patch_url":"https://github.com/flynn/flynn/pull/1035.patch","issue_url":"https://api.github.com/repos/flynn/flynn/issues/1035","number":1035,"state":"open","locked":false,"title":"gitreceived: Cache repos in blobstore.","user":{"login":"archSeer","id":1372918,"avatar_url":"https://avatars.githubusercontent.com/u/1372918?v=3","gravatar_id":"","url":"https://api.github.com/users/archSeer","html_url":"https://github.com/archSeer","followers_url":"https://api.github.com/users/archSeer/followers","following_url":"https://api.github.com/users/archSeer/following{/other_user}","gists_url":"https://api.github.com/users/archSeer/gists{/gist_id}","starred_url":"https://api.github.com/users/archSeer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/archSeer/subscriptions","organizations_url":"https://api.github.com/users/archSeer/orgs","repos_url":"https://api.github.com/users/archSeer/repos","events_url":"https://api.github.com/users/archSeer/events{/privacy}","received_events_url":"https://api.github.com/users/archSeer/received_events","type":"User","site_admin":false},"body":"Allows us to consistently cache repos across different gitreceived instances.\r\n\r\nSigned-off-by: Blaž Hrastnik <blaz.hrast@gmail.com>","created_at":"2015-02-19T05:13:53Z","updated_at":"2015-02-19T05:27:20Z","closed_at":null,"merged_at":null,"merge_commit_sha":"715b437a6a9353bb08a041e55afd073d4cd5570b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/flynn/flynn/pulls/1035/commits","review_comments_url":"https://api.github.com/repos/flynn/flynn/pulls/1035/comments","review_comment_url":"https://api.github.com/repos/flynn/flynn/pulls/comments/{number}","comments_url":"https://api.github.com/repos/flynn/flynn/issues/1035/comments","statuses_url":"https://api.github.com/repos/flynn/flynn/statuses/f85f9ed421af3a6f17c9a89b388100a739c4072e","head":{"label":"cache-gitreceived","ref":"cache-gitreceived","sha":"f85f9ed421af3a6f17c9a89b388100a739c4072e","user":{"login":"flynn","id":4973613,"avatar_url":"https://avatars.githubusercontent.com/u/4973613?v=3","gravatar_id":"","url":"https://api.github.com/users/flynn","html_url":"https://github.com/flynn","followers_url":"https://api.github.com/users/flynn/followers","following_url":"https://api.github.com/users/flynn/following{/other_user}","gists_url":"https://api.github.com/users/flynn/gists{/gist_id}","starred_url":"https://api.github.com/users/flynn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flynn/subscriptions","organizations_url":"https://api.github.com/users/flynn/orgs","repos_url":"https://api.github.com/users/flynn/repos","events_url":"https://api.github.com/users/flynn/events{/privacy}","received_events_url":"https://api.github.com/users/flynn/received_events","type":"Organization","site_admin":false},"repo":{"id":11290232,"name":"flynn","full_name":"flynn/flynn","owner":{"login":"flynn","id":4973613,"avatar_url":"https://avatars.githubusercontent.com/u/4973613?v=3","gravatar_id":"","url":"https://api.github.com/users/flynn","html_url":"https://github.com/flynn","followers_url":"https://api.github.com/users/flynn/followers","following_url":"https://api.github.com/users/flynn/following{/other_user}","gists_url":"https://api.github.com/users/flynn/gists{/gist_id}","starred_url":"https://api.github.com/users/flynn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flynn/subscriptions","organizations_url":"https://api.github.com/users/flynn/orgs","repos_url":"https://api.github.com/users/flynn/repos","events_url":"https://api.github.com/users/flynn/events{/privacy}","received_events_url":"https://api.github.com/users/flynn/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/flynn/flynn","description":"A next generation open source platform as a service (PaaS)","fork":false,"url":"https://api.github.com/repos/flynn/flynn","forks_url":"https://api.github.com/repos/flynn/flynn/forks","keys_url":"https://api.github.com/repos/flynn/flynn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/flynn/flynn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/flynn/flynn/teams","hooks_url":"https://api.github.com/repos/flynn/flynn/hooks","issue_events_url":"https://api.github.com/repos/flynn/flynn/issues/events{/number}","events_url":"https://api.github.com/repos/flynn/flynn/events","assignees_url":"https://api.github.com/repos/flynn/flynn/assignees{/user}","branches_url":"https://api.github.com/repos/flynn/flynn/branches{/branch}","tags_url":"https://api.github.com/repos/flynn/flynn/tags","blobs_url":"https://api.github.com/repos/flynn/flynn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/flynn/flynn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/flynn/flynn/git/refs{/sha}","trees_url":"https://api.github.com/repos/flynn/flynn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/flynn/flynn/statuses/{sha}","languages_url":"https://api.github.com/repos/flynn/flynn/languages","stargazers_url":"https://api.github.com/repos/flynn/flynn/stargazers","contributors_url":"https://api.github.com/repos/flynn/flynn/contributors","subscribers_url":"https://api.github.com/repos/flynn/flynn/subscribers","subscription_url":"https://api.github.com/repos/flynn/flynn/subscription","commits_url":"https://api.github.com/repos/flynn/flynn/commits{/sha}","git_commits_url":"https://api.github.com/repos/flynn/flynn/git/commits{/sha}","comments_url":"https://api.github.com/repos/flynn/flynn/comments{/number}","issue_comment_url":"https://api.github.com/repos/flynn/flynn/issues/comments/{number}","contents_url":"https://api.github.com/repos/flynn/flynn/contents/{+path}","compare_url":"https://api.github.com/repos/flynn/flynn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/flynn/flynn/merges","archive_url":"https://api.github.com/repos/flynn/flynn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/flynn/flynn/downloads","issues_url":"https://api.github.com/repos/flynn/flynn/issues{/number}","pulls_url":"https://api.github.com/repos/flynn/flynn/pulls{/number}","milestones_url":"https://api.github.com/repos/flynn/flynn/milestones{/number}","notifications_url":"https://api.github.com/repos/flynn/flynn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/flynn/flynn/labels{/name}","releases_url":"https://api.github.com/repos/flynn/flynn/releases{/id}","created_at":"2013-07-09T18:22:06Z","updated_at":"2015-02-18T23:22:19Z","pushed_at":"2015-02-19T05:16:01Z","git_url":"git://github.com/flynn/flynn.git","ssh_url":"git@github.com:flynn/flynn.git","clone_url":"https://github.com/flynn/flynn.git","svn_url":"https://github.com/flynn/flynn","homepage":"https://flynn.io","size":38947,"stargazers_count":3251,"watchers_count":3251,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":211,"mirror_url":null,"open_issues_count":129,"forks":211,"open_issues":129,"watchers":3251,"default_branch":"master"}},"base":{"label":"master","ref":"master","sha":"6b262dc945576f413f94753742266b292a4ae288","user":{"login":"flynn","id":4973613,"avatar_url":"https://avatars.githubusercontent.com/u/4973613?v=3","gravatar_id":"","url":"https://api.github.com/users/flynn","html_url":"https://github.com/flynn","followers_url":"https://api.github.com/users/flynn/followers","following_url":"https://api.github.com/users/flynn/following{/other_user}","gists_url":"https://api.github.com/users/flynn/gists{/gist_id}","starred_url":"https://api.github.com/users/flynn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flynn/subscriptions","organizations_url":"https://api.github.com/users/flynn/orgs","repos_url":"https://api.github.com/users/flynn/repos","events_url":"https://api.github.com/users/flynn/events{/privacy}","received_events_url":"https://api.github.com/users/flynn/received_events","type":"Organization","site_admin":false},"repo":{"id":11290232,"name":"flynn","full_name":"flynn/flynn","owner":{"login":"flynn","id":4973613,"avatar_url":"https://avatars.githubusercontent.com/u/4973613?v=3","gravatar_id":"","url":"https://api.github.com/users/flynn","html_url":"https://github.com/flynn","followers_url":"https://api.github.com/users/flynn/followers","following_url":"https://api.github.com/users/flynn/following{/other_user}","gists_url":"https://api.github.com/users/flynn/gists{/gist_id}","starred_url":"https://api.github.com/users/flynn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flynn/subscriptions","organizations_url":"https://api.github.com/users/flynn/orgs","repos_url":"https://api.github.com/users/flynn/repos","events_url":"https://api.github.com/users/flynn/events{/privacy}","received_events_url":"https://api.github.com/users/flynn/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/flynn/flynn","description":"A next generation open source platform as a service (PaaS)","fork":false,"url":"https://api.github.com/repos/flynn/flynn","forks_url":"https://api.github.com/repos/flynn/flynn/forks","keys_url":"https://api.github.com/repos/flynn/flynn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/flynn/flynn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/flynn/flynn/teams","hooks_url":"https://api.github.com/repos/flynn/flynn/hooks","issue_events_url":"https://api.github.com/repos/flynn/flynn/issues/events{/number}","events_url":"https://api.github.com/repos/flynn/flynn/events","assignees_url":"https://api.github.com/repos/flynn/flynn/assignees{/user}","branches_url":"https://api.github.com/repos/flynn/flynn/branches{/branch}","tags_url":"https://api.github.com/repos/flynn/flynn/tags","blobs_url":"https://api.github.com/repos/flynn/flynn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/flynn/flynn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/flynn/flynn/git/refs{/sha}","trees_url":"https://api.github.com/repos/flynn/flynn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/flynn/flynn/statuses/{sha}","languages_url":"https://api.github.com/repos/flynn/flynn/languages","stargazers_url":"https://api.github.com/repos/flynn/flynn/stargazers","contributors_url":"https://api.github.com/repos/flynn/flynn/contributors","subscribers_url":"https://api.github.com/repos/flynn/flynn/subscribers","subscription_url":"https://api.github.com/repos/flynn/flynn/subscription","commits_url":"https://api.github.com/repos/flynn/flynn/commits{/sha}","git_commits_url":"https://api.github.com/repos/flynn/flynn/git/commits{/sha}","comments_url":"https://api.github.com/repos/flynn/flynn/comments{/number}","issue_comment_url":"https://api.github.com/repos/flynn/flynn/issues/comments/{number}","contents_url":"https://api.github.com/repos/flynn/flynn/contents/{+path}","compare_url":"https://api.github.com/repos/flynn/flynn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/flynn/flynn/merges","archive_url":"https://api.github.com/repos/flynn/flynn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/flynn/flynn/downloads","issues_url":"https://api.github.com/repos/flynn/flynn/issues{/number}","pulls_url":"https://api.github.com/repos/flynn/flynn/pulls{/number}","milestones_url":"https://api.github.com/repos/flynn/flynn/milestones{/number}","notifications_url":"https://api.github.com/repos/flynn/flynn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/flynn/flynn/labels{/name}","releases_url":"https://api.github.com/repos/flynn/flynn/releases{/id}","created_at":"2013-07-09T18:22:06Z","updated_at":"2015-02-18T23:22:19Z","pushed_at":"2015-02-19T05:16:01Z","git_url":"git://github.com/flynn/flynn.git","ssh_url":"git@github.com:flynn/flynn.git","clone_url":"https://github.com/flynn/flynn.git","svn_url":"https://github.com/flynn/flynn","homepage":"https://flynn.io","size":38947,"stargazers_count":3251,"watchers_count":3251,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":211,"mirror_url":null,"open_issues_count":129,"forks":211,"open_issues":129,"watchers":3251,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/flynn/flynn/pulls/1035"},"html":{"href":"https://github.com/flynn/flynn/pull/1035"},"issue":{"href":"https://api.github.com/repos/flynn/flynn/issues/1035"},"comments":{"href":"https://api.github.com/repos/flynn/flynn/issues/1035/comments"},"review_comments":{"href":"https://api.github.com/repos/flynn/flynn/pulls/1035/comments"},"review_comment":{"href":"https://api.github.com/repos/flynn/flynn/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/flynn/flynn/pulls/1035/commits"},"statuses":{"href":"https://api.github.com/repos/flynn/flynn/statuses/f85f9ed421af3a6f17c9a89b388100a739c4072e"}}}}