{"action":"created","comment":{"url":"https://api.github.com/repos/jbenet/go-ipfs/pulls/comments/26087787","id":26087787,"diff_hunk":"@@ -0,0 +1,464 @@\n+package mod\n+\n+import (\n+\t\"bytes\"\n+\t\"errors\"\n+\t\"io\"\n+\t\"os\"\n+\n+\tproto \"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto\"\n+\tmh \"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash\"\n+\tcontext \"github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context\"\n+\n+\tchunk \"github.com/jbenet/go-ipfs/importer/chunk\"\n+\thelp \"github.com/jbenet/go-ipfs/importer/helpers\"\n+\ttrickle \"github.com/jbenet/go-ipfs/importer/trickle\"\n+\tmdag \"github.com/jbenet/go-ipfs/merkledag\"\n+\tpin \"github.com/jbenet/go-ipfs/pin\"\n+\tft \"github.com/jbenet/go-ipfs/unixfs\"\n+\tuio \"github.com/jbenet/go-ipfs/unixfs/io\"\n+\tu \"github.com/jbenet/go-ipfs/util\"\n+)\n+\n+// 2MB\n+var writebufferSize = 1 << 21\n+\n+var log = u.Logger(\"dagio\")\n+\n+// DagModifier is the only struct licensed and able to correctly\n+// perform surgery on a DAG 'file'\n+// Dear god, please rename this to something more pleasant\n+type DagModifier struct {\n+\tdagserv mdag.DAGService\n+\tcurNode *mdag.Node\n+\tmp      pin.ManualPinner\n+\n+\tsplitter   chunk.BlockSplitter\n+\tctx        context.Context\n+\treadCancel func()\n+\n+\twriteStart uint64\n+\tcurWrOff   uint64\n+\twrBuf      *bytes.Buffer\n+\n+\tread *uio.DagReader\n+}\n+\n+func NewDagModifier(ctx context.Context, from *mdag.Node, serv mdag.DAGService, mp pin.ManualPinner, spl chunk.BlockSplitter) (*DagModifier, error) {\n+\treturn &DagModifier{\n+\t\tcurNode:  from.Copy(),\n+\t\tdagserv:  serv,\n+\t\tsplitter: spl,\n+\t\tctx:      ctx,\n+\t\tmp:       mp,\n+\t}, nil\n+}\n+\n+// WriteAt will modify a dag file in place\n+func (dm *DagModifier) WriteAt(b []byte, offset int64) (int, error) {\n+\t// TODO: this is currently VERY inneficient\n+\t// each write that happens at an offset other than the current one causes a\n+\t// flush to disk, and dag rewrite\n+\tif uint64(offset) != dm.curWrOff {\n+\t\tsize, err := dm.Size()\n+\t\tif err != nil {\n+\t\t\treturn 0, err\n+\t\t}\n+\t\tif offset > size {\n+\t\t\terr := dm.expandSparse(offset - size)\n+\t\t\tif err != nil {\n+\t\t\t\treturn 0, err\n+\t\t\t}\n+\t\t}\n+\n+\t\terr = dm.Flush()\n+\t\tif err != nil {\n+\t\t\treturn 0, err\n+\t\t}\n+\t\tdm.writeStart = uint64(offset)\n+\t}\n+\n+\treturn dm.Write(b)\n+}\n+\n+// A reader that just returns zeros\n+type zeroReader struct{}\n+\n+func (zr zeroReader) Read(b []byte) (int, error) {\n+\tfor i, _ := range b {\n+\t\tb[i] = 0\n+\t}\n+\treturn len(b), nil\n+}\n+\n+// expandSparse grows the file with zero blocks of 4096\n+// A small blocksize is chosen to aid in deduplication\n+func (dm *DagModifier) expandSparse(size int64) error {\n+\tspl := chunk.SizeSplitter{4096}\n+\tr := io.LimitReader(zeroReader{}, size)\n+\tblks := spl.Split(r)\n+\tnnode, err := dm.appendData(dm.curNode, blks)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\t_, err = dm.dagserv.Add(nnode)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\tdm.curNode = nnode\n+\treturn nil\n+}\n+\n+// Write continues writing to the dag at the current offset\n+func (dm *DagModifier) Write(b []byte) (int, error) {\n+\tif dm.read != nil {\n+\t\tdm.read = nil\n+\t}\n+\tif dm.wrBuf == nil {\n+\t\tdm.wrBuf = new(bytes.Buffer)\n+\t}\n+\n+\tn, err := dm.wrBuf.Write(b)\n+\tif err != nil {\n+\t\treturn n, err\n+\t}\n+\tdm.curWrOff += uint64(n)\n+\tif dm.wrBuf.Len() > writebufferSize {\n+\t\terr := dm.Flush()\n+\t\tif err != nil {\n+\t\t\treturn n, err\n+\t\t}\n+\t}\n+\treturn n, nil\n+}\n+\n+func (dm *DagModifier) Size() (int64, error) {\n+\t// TODO: compute size without flushing, should be easy\n+\terr := dm.Flush()\n+\tif err != nil {\n+\t\treturn 0, err\n+\t}\n+\n+\tpbn, err := ft.FromBytes(dm.curNode.Data)\n+\tif err != nil {\n+\t\treturn 0, err\n+\t}\n+\n+\treturn int64(pbn.GetFilesize()), nil\n+}\n+\n+// Flush writes changes to this dag to disk\n+func (dm *DagModifier) Flush() error {\n+\t// No buffer? Nothing to do\n+\tif dm.wrBuf == nil {\n+\t\treturn nil\n+\t}\n+\n+\t// If we have an active reader, kill it\n+\tif dm.read != nil {\n+\t\tdm.read = nil\n+\t\tdm.readCancel()\n+\t}\n+\n+\t// Number of bytes we're going to write\n+\tbuflen := dm.wrBuf.Len()\n+\n+\t// overwrite existing dag nodes\n+\tk, done, err := dm.modifyDag(dm.curNode, dm.writeStart, dm.wrBuf)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\n+\tnd, err := dm.dagserv.Get(k)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\n+\tdm.curNode = nd\n+\n+\t// need to write past end of current dag\n+\tif !done {\n+\t\tblks := dm.splitter.Split(dm.wrBuf)\n+\t\tnd, err = dm.appendData(dm.curNode, blks)\n+\t\tif err != nil {\n+\t\t\treturn err\n+\t\t}\n+\n+\t\t_, err := dm.dagserv.Add(nd)\n+\t\tif err != nil {\n+\t\t\treturn err\n+\t\t}\n+\n+\t\tdm.curNode = nd\n+\t}\n+\n+\tdm.writeStart += uint64(buflen)\n+\n+\tdm.wrBuf = nil\n+\treturn nil\n+}\n+\n+// modifyDag writes the data in 'data' over the data in 'node' starting at 'offset'\n+func (dm *DagModifier) modifyDag(node *mdag.Node, offset uint64, data io.Reader) (u.Key, bool, error) {\n+\tf, err := ft.FromBytes(node.Data)\n+\tif err != nil {\n+\t\treturn \"\", false, err\n+\t}\n+\n+\t// If we've reached a leaf node.\n+\tif len(node.Links) == 0 {\n+\t\tn, err := data.Read(f.Data[offset:])\n+\t\tif err != nil && err != io.EOF {\n+\t\t\treturn \"\", false, err\n+\t\t}\n+\n+\t\t// Update newly written node..\n+\t\tb, err := proto.Marshal(f)\n+\t\tif err != nil {\n+\t\t\treturn \"\", false, err\n+\t\t}\n+\n+\t\tnd := &mdag.Node{Data: b}\n+\t\tk, err := dm.dagserv.Add(nd)\n+\t\tif err != nil {\n+\t\t\treturn \"\", false, err\n+\t\t}\n+\n+\t\t// Hey look! we're done!\n+\t\tvar done bool\n+\t\tif n < len(f.Data) {\n+\t\t\tdone = true\n+\t\t}\n+\n+\t\treturn k, done, nil\n+\t}\n+\n+\tvar cur uint64\n+\tvar done bool\n+\tfor i, bs := range f.GetBlocksizes() {\n+\t\tif cur+bs > offset {\n+\t\t\tchild, err := node.Links[i].GetNode(dm.dagserv)\n+\t\t\tif err != nil {\n+\t\t\t\treturn \"\", false, err\n+\t\t\t}\n+\t\t\tk, sdone, err := dm.modifyDag(child, offset-cur, data)\n+\t\t\tif err != nil {\n+\t\t\t\treturn \"\", false, err\n+\t\t\t}\n+\n+\t\t\toffset += bs\n+\t\t\tnode.Links[i].Hash = mh.Multihash(k)\n+\n+\t\t\tif sdone {\n+\t\t\t\tdone = true\n+\t\t\t\tbreak\n+\t\t\t}\n+\t\t}\n+\t\tcur += bs\n+\t}\n+\n+\tk, err := dm.dagserv.Add(node)\n+\treturn k, done, err\n+}\n+\n+// appendData appends the blocks from the given chan to the end of this dag\n+func (dm *DagModifier) appendData(node *mdag.Node, blks <-chan []byte) (*mdag.Node, error) {\n+\tdbp := &help.DagBuilderParams{\n+\t\tDagserv:  dm.dagserv,\n+\t\tMaxlinks: help.DefaultLinksPerBlock,\n+\t\tPinner:   dm.mp,\n+\t}\n+\n+\treturn trickle.TrickleAppend(node, dbp.New(blks))\n+}\n+\n+// Read data from this dag starting at the current offset\n+func (dm *DagModifier) Read(b []byte) (int, error) {\n+\terr := dm.Flush()\n+\tif err != nil {\n+\t\treturn 0, err\n+\t}\n+\n+\tif dm.read == nil {\n+\t\tdr, err := uio.NewDagReader(dm.ctx, dm.curNode, dm.dagserv)\n+\t\tif err != nil {\n+\t\t\treturn 0, err\n+\t\t}\n+\n+\t\ti, err := dr.Seek(int64(dm.curWrOff), os.SEEK_SET)\n+\t\tif err != nil {\n+\t\t\treturn 0, err\n+\t\t}\n+\n+\t\tif i != int64(dm.curWrOff) {\n+\t\t\treturn 0, errors.New(\"failed to seek properly\")\n+\t\t}\n+\n+\t\tdm.read = dr\n+\t}\n+\n+\tn, err := dm.read.Read(b)\n+\tdm.curWrOff += uint64(n)\n+\treturn n, err\n+}\n+\n+// splitBytes uses a splitterFunc to turn a large array of bytes\n+// into many smaller arrays of bytes\n+func (dm *DagModifier) splitBytes(in io.Reader) ([]u.Key, error) {","path":"unixfs/mod/dagmodifier.go","position":307,"original_position":307,"commit_id":"c9130aed19b0e158e5baed12d20b5fed1dd230dc","original_commit_id":"bc57ad8f2bd927152dcaa9e756a58f9f1fb931d8","user":{"login":"whyrusleeping","id":1243164,"avatar_url":"https://avatars.githubusercontent.com/u/1243164?v=3","gravatar_id":"","url":"https://api.github.com/users/whyrusleeping","html_url":"https://github.com/whyrusleeping","followers_url":"https://api.github.com/users/whyrusleeping/followers","following_url":"https://api.github.com/users/whyrusleeping/following{/other_user}","gists_url":"https://api.github.com/users/whyrusleeping/gists{/gist_id}","starred_url":"https://api.github.com/users/whyrusleeping/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/whyrusleeping/subscriptions","organizations_url":"https://api.github.com/users/whyrusleeping/orgs","repos_url":"https://api.github.com/users/whyrusleeping/repos","events_url":"https://api.github.com/users/whyrusleeping/events{/privacy}","received_events_url":"https://api.github.com/users/whyrusleeping/received_events","type":"User","site_admin":false},"body":"yeap, `0xDEADC0DE`","created_at":"2015-03-09T23:42:46Z","updated_at":"2015-03-09T23:42:46Z","html_url":"https://github.com/jbenet/go-ipfs/pull/889#discussion_r26087787","pull_request_url":"https://api.github.com/repos/jbenet/go-ipfs/pulls/889","_links":{"self":{"href":"https://api.github.com/repos/jbenet/go-ipfs/pulls/comments/26087787"},"html":{"href":"https://github.com/jbenet/go-ipfs/pull/889#discussion_r26087787"},"pull_request":{"href":"https://api.github.com/repos/jbenet/go-ipfs/pulls/889"}}},"pull_request":{"url":"https://api.github.com/repos/jbenet/go-ipfs/pulls/889","id":30710107,"html_url":"https://github.com/jbenet/go-ipfs/pull/889","diff_url":"https://github.com/jbenet/go-ipfs/pull/889.diff","patch_url":"https://github.com/jbenet/go-ipfs/pull/889.patch","issue_url":"https://api.github.com/repos/jbenet/go-ipfs/issues/889","number":889,"state":"open","locked":false,"title":"Ipns/refactor dagmod","user":{"login":"whyrusleeping","id":1243164,"avatar_url":"https://avatars.githubusercontent.com/u/1243164?v=3","gravatar_id":"","url":"https://api.github.com/users/whyrusleeping","html_url":"https://github.com/whyrusleeping","followers_url":"https://api.github.com/users/whyrusleeping/followers","following_url":"https://api.github.com/users/whyrusleeping/following{/other_user}","gists_url":"https://api.github.com/users/whyrusleeping/gists{/gist_id}","starred_url":"https://api.github.com/users/whyrusleeping/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/whyrusleeping/subscriptions","organizations_url":"https://api.github.com/users/whyrusleeping/orgs","repos_url":"https://api.github.com/users/whyrusleeping/repos","events_url":"https://api.github.com/users/whyrusleeping/events{/privacy}","received_events_url":"https://api.github.com/users/whyrusleeping/received_events","type":"User","site_admin":false},"body":"Refactor and fix the dagmodifier \r\n\r\nThis is PR number 4 of the ipns set","created_at":"2015-03-07T21:57:21Z","updated_at":"2015-03-09T23:42:46Z","closed_at":null,"merged_at":null,"merge_commit_sha":"af19886760d0afeb15f1250d6f35a1d649abbac9","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/jbenet/go-ipfs/pulls/889/commits","review_comments_url":"https://api.github.com/repos/jbenet/go-ipfs/pulls/889/comments","review_comment_url":"https://api.github.com/repos/jbenet/go-ipfs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/jbenet/go-ipfs/issues/889/comments","statuses_url":"https://api.github.com/repos/jbenet/go-ipfs/statuses/c9130aed19b0e158e5baed12d20b5fed1dd230dc","head":{"label":"jbenet:ipns/refactor-dagmod","ref":"ipns/refactor-dagmod","sha":"c9130aed19b0e158e5baed12d20b5fed1dd230dc","user":{"login":"jbenet","id":138401,"avatar_url":"https://avatars.githubusercontent.com/u/138401?v=3","gravatar_id":"","url":"https://api.github.com/users/jbenet","html_url":"https://github.com/jbenet","followers_url":"https://api.github.com/users/jbenet/followers","following_url":"https://api.github.com/users/jbenet/following{/other_user}","gists_url":"https://api.github.com/users/jbenet/gists{/gist_id}","starred_url":"https://api.github.com/users/jbenet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbenet/subscriptions","organizations_url":"https://api.github.com/users/jbenet/orgs","repos_url":"https://api.github.com/users/jbenet/repos","events_url":"https://api.github.com/users/jbenet/events{/privacy}","received_events_url":"https://api.github.com/users/jbenet/received_events","type":"User","site_admin":false},"repo":{"id":21233191,"name":"go-ipfs","full_name":"jbenet/go-ipfs","owner":{"login":"jbenet","id":138401,"avatar_url":"https://avatars.githubusercontent.com/u/138401?v=3","gravatar_id":"","url":"https://api.github.com/users/jbenet","html_url":"https://github.com/jbenet","followers_url":"https://api.github.com/users/jbenet/followers","following_url":"https://api.github.com/users/jbenet/following{/other_user}","gists_url":"https://api.github.com/users/jbenet/gists{/gist_id}","starred_url":"https://api.github.com/users/jbenet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbenet/subscriptions","organizations_url":"https://api.github.com/users/jbenet/orgs","repos_url":"https://api.github.com/users/jbenet/repos","events_url":"https://api.github.com/users/jbenet/events{/privacy}","received_events_url":"https://api.github.com/users/jbenet/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jbenet/go-ipfs","description":"ipfs implementation in go","fork":false,"url":"https://api.github.com/repos/jbenet/go-ipfs","forks_url":"https://api.github.com/repos/jbenet/go-ipfs/forks","keys_url":"https://api.github.com/repos/jbenet/go-ipfs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jbenet/go-ipfs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jbenet/go-ipfs/teams","hooks_url":"https://api.github.com/repos/jbenet/go-ipfs/hooks","issue_events_url":"https://api.github.com/repos/jbenet/go-ipfs/issues/events{/number}","events_url":"https://api.github.com/repos/jbenet/go-ipfs/events","assignees_url":"https://api.github.com/repos/jbenet/go-ipfs/assignees{/user}","branches_url":"https://api.github.com/repos/jbenet/go-ipfs/branches{/branch}","tags_url":"https://api.github.com/repos/jbenet/go-ipfs/tags","blobs_url":"https://api.github.com/repos/jbenet/go-ipfs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jbenet/go-ipfs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jbenet/go-ipfs/git/refs{/sha}","trees_url":"https://api.github.com/repos/jbenet/go-ipfs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jbenet/go-ipfs/statuses/{sha}","languages_url":"https://api.github.com/repos/jbenet/go-ipfs/languages","stargazers_url":"https://api.github.com/repos/jbenet/go-ipfs/stargazers","contributors_url":"https://api.github.com/repos/jbenet/go-ipfs/contributors","subscribers_url":"https://api.github.com/repos/jbenet/go-ipfs/subscribers","subscription_url":"https://api.github.com/repos/jbenet/go-ipfs/subscription","commits_url":"https://api.github.com/repos/jbenet/go-ipfs/commits{/sha}","git_commits_url":"https://api.github.com/repos/jbenet/go-ipfs/git/commits{/sha}","comments_url":"https://api.github.com/repos/jbenet/go-ipfs/comments{/number}","issue_comment_url":"https://api.github.com/repos/jbenet/go-ipfs/issues/comments{/number}","contents_url":"https://api.github.com/repos/jbenet/go-ipfs/contents/{+path}","compare_url":"https://api.github.com/repos/jbenet/go-ipfs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jbenet/go-ipfs/merges","archive_url":"https://api.github.com/repos/jbenet/go-ipfs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jbenet/go-ipfs/downloads","issues_url":"https://api.github.com/repos/jbenet/go-ipfs/issues{/number}","pulls_url":"https://api.github.com/repos/jbenet/go-ipfs/pulls{/number}","milestones_url":"https://api.github.com/repos/jbenet/go-ipfs/milestones{/number}","notifications_url":"https://api.github.com/repos/jbenet/go-ipfs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jbenet/go-ipfs/labels{/name}","releases_url":"https://api.github.com/repos/jbenet/go-ipfs/releases{/id}","created_at":"2014-06-26T08:14:34Z","updated_at":"2015-03-09T23:21:26Z","pushed_at":"2015-03-09T23:37:37Z","git_url":"git://github.com/jbenet/go-ipfs.git","ssh_url":"git@github.com:jbenet/go-ipfs.git","clone_url":"https://github.com/jbenet/go-ipfs.git","svn_url":"https://github.com/jbenet/go-ipfs","homepage":"https://github.com/jbenet/ipfs","size":29826,"stargazers_count":338,"watchers_count":338,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":50,"mirror_url":null,"open_issues_count":188,"forks":50,"open_issues":188,"watchers":338,"default_branch":"master"}},"base":{"label":"jbenet:master","ref":"master","sha":"10110674550b46b9427371cfab794f452865248a","user":{"login":"jbenet","id":138401,"avatar_url":"https://avatars.githubusercontent.com/u/138401?v=3","gravatar_id":"","url":"https://api.github.com/users/jbenet","html_url":"https://github.com/jbenet","followers_url":"https://api.github.com/users/jbenet/followers","following_url":"https://api.github.com/users/jbenet/following{/other_user}","gists_url":"https://api.github.com/users/jbenet/gists{/gist_id}","starred_url":"https://api.github.com/users/jbenet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbenet/subscriptions","organizations_url":"https://api.github.com/users/jbenet/orgs","repos_url":"https://api.github.com/users/jbenet/repos","events_url":"https://api.github.com/users/jbenet/events{/privacy}","received_events_url":"https://api.github.com/users/jbenet/received_events","type":"User","site_admin":false},"repo":{"id":21233191,"name":"go-ipfs","full_name":"jbenet/go-ipfs","owner":{"login":"jbenet","id":138401,"avatar_url":"https://avatars.githubusercontent.com/u/138401?v=3","gravatar_id":"","url":"https://api.github.com/users/jbenet","html_url":"https://github.com/jbenet","followers_url":"https://api.github.com/users/jbenet/followers","following_url":"https://api.github.com/users/jbenet/following{/other_user}","gists_url":"https://api.github.com/users/jbenet/gists{/gist_id}","starred_url":"https://api.github.com/users/jbenet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbenet/subscriptions","organizations_url":"https://api.github.com/users/jbenet/orgs","repos_url":"https://api.github.com/users/jbenet/repos","events_url":"https://api.github.com/users/jbenet/events{/privacy}","received_events_url":"https://api.github.com/users/jbenet/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jbenet/go-ipfs","description":"ipfs implementation in go","fork":false,"url":"https://api.github.com/repos/jbenet/go-ipfs","forks_url":"https://api.github.com/repos/jbenet/go-ipfs/forks","keys_url":"https://api.github.com/repos/jbenet/go-ipfs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jbenet/go-ipfs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jbenet/go-ipfs/teams","hooks_url":"https://api.github.com/repos/jbenet/go-ipfs/hooks","issue_events_url":"https://api.github.com/repos/jbenet/go-ipfs/issues/events{/number}","events_url":"https://api.github.com/repos/jbenet/go-ipfs/events","assignees_url":"https://api.github.com/repos/jbenet/go-ipfs/assignees{/user}","branches_url":"https://api.github.com/repos/jbenet/go-ipfs/branches{/branch}","tags_url":"https://api.github.com/repos/jbenet/go-ipfs/tags","blobs_url":"https://api.github.com/repos/jbenet/go-ipfs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jbenet/go-ipfs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jbenet/go-ipfs/git/refs{/sha}","trees_url":"https://api.github.com/repos/jbenet/go-ipfs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jbenet/go-ipfs/statuses/{sha}","languages_url":"https://api.github.com/repos/jbenet/go-ipfs/languages","stargazers_url":"https://api.github.com/repos/jbenet/go-ipfs/stargazers","contributors_url":"https://api.github.com/repos/jbenet/go-ipfs/contributors","subscribers_url":"https://api.github.com/repos/jbenet/go-ipfs/subscribers","subscription_url":"https://api.github.com/repos/jbenet/go-ipfs/subscription","commits_url":"https://api.github.com/repos/jbenet/go-ipfs/commits{/sha}","git_commits_url":"https://api.github.com/repos/jbenet/go-ipfs/git/commits{/sha}","comments_url":"https://api.github.com/repos/jbenet/go-ipfs/comments{/number}","issue_comment_url":"https://api.github.com/repos/jbenet/go-ipfs/issues/comments{/number}","contents_url":"https://api.github.com/repos/jbenet/go-ipfs/contents/{+path}","compare_url":"https://api.github.com/repos/jbenet/go-ipfs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jbenet/go-ipfs/merges","archive_url":"https://api.github.com/repos/jbenet/go-ipfs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jbenet/go-ipfs/downloads","issues_url":"https://api.github.com/repos/jbenet/go-ipfs/issues{/number}","pulls_url":"https://api.github.com/repos/jbenet/go-ipfs/pulls{/number}","milestones_url":"https://api.github.com/repos/jbenet/go-ipfs/milestones{/number}","notifications_url":"https://api.github.com/repos/jbenet/go-ipfs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jbenet/go-ipfs/labels{/name}","releases_url":"https://api.github.com/repos/jbenet/go-ipfs/releases{/id}","created_at":"2014-06-26T08:14:34Z","updated_at":"2015-03-09T23:21:26Z","pushed_at":"2015-03-09T23:37:37Z","git_url":"git://github.com/jbenet/go-ipfs.git","ssh_url":"git@github.com:jbenet/go-ipfs.git","clone_url":"https://github.com/jbenet/go-ipfs.git","svn_url":"https://github.com/jbenet/go-ipfs","homepage":"https://github.com/jbenet/ipfs","size":29826,"stargazers_count":338,"watchers_count":338,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":50,"mirror_url":null,"open_issues_count":188,"forks":50,"open_issues":188,"watchers":338,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/jbenet/go-ipfs/pulls/889"},"html":{"href":"https://github.com/jbenet/go-ipfs/pull/889"},"issue":{"href":"https://api.github.com/repos/jbenet/go-ipfs/issues/889"},"comments":{"href":"https://api.github.com/repos/jbenet/go-ipfs/issues/889/comments"},"review_comments":{"href":"https://api.github.com/repos/jbenet/go-ipfs/pulls/889/comments"},"review_comment":{"href":"https://api.github.com/repos/jbenet/go-ipfs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/jbenet/go-ipfs/pulls/889/commits"},"statuses":{"href":"https://api.github.com/repos/jbenet/go-ipfs/statuses/c9130aed19b0e158e5baed12d20b5fed1dd230dc"}}}}