{"action":"created","comment":{"url":"https://api.github.com/repos/github/git-lfs/pulls/comments/86699029","pull_request_review_id":7343307,"id":86699029,"diff_hunk":"@@ -138,29 +160,32 @@ func filterCommand(cmd *cobra.Command, args []string) {\n \n Scan:\n \tfor s.Scan() {\n-\t\treq := s.Request()\n-\n-\t\t// TODO:\n-\t\t// clean/smudge should also take a Writer instead of returning []byte\n-\t\tvar outputData []byte\n \t\tvar err error\n+\t\tvar w io.Writer\n \n-\t\tswitch req.Header[\"command\"] {\n+\t\tswitch req := s.Request(); req.Header[\"command\"] {\n \t\tcase \"clean\":\n-\t\t\toutputData, err = clean(req.Payload, req.Header[\"pathname\"])\n+\t\t\tw = git.NewPacketWriter(os.Stdout, cleanFilterBufferCapacity)\n+\t\t\terr = clean(w, req.Payload, req.Header[\"pathname\"])\n \t\tcase \"smudge\":\n-\t\t\toutputData, err = smudge(req.Payload, req.Header[\"pathname\"])\n+\t\t\tw = git.NewPacketWriter(os.Stdout, smudgeFilterBufferCapacity)\n+\t\t\terr = smudge(w, req.Payload, req.Header[\"pathname\"])\n \t\tdefault:\n \t\t\tfmt.Errorf(\"Unknown command %s\", cmd)\n \t\t\tbreak Scan\n \t\t}\n \n+\t\tif err == nil {\n+\t\t\t_, err = w.Write(nil)\n+\t\t}","path":"commands/command_filter.go","position":117,"original_position":117,"commit_id":"055ac4841dd9d3a3359419969d1952ce9ae93528","original_commit_id":"055ac4841dd9d3a3359419969d1952ce9ae93528","user":{"login":"larsxschneider","id":477434,"avatar_url":"https://avatars.githubusercontent.com/u/477434?v=3","gravatar_id":"","url":"https://api.github.com/users/larsxschneider","html_url":"https://github.com/larsxschneider","followers_url":"https://api.github.com/users/larsxschneider/followers","following_url":"https://api.github.com/users/larsxschneider/following{/other_user}","gists_url":"https://api.github.com/users/larsxschneider/gists{/gist_id}","starred_url":"https://api.github.com/users/larsxschneider/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/larsxschneider/subscriptions","organizations_url":"https://api.github.com/users/larsxschneider/orgs","repos_url":"https://api.github.com/users/larsxschneider/repos","events_url":"https://api.github.com/users/larsxschneider/events{/privacy}","received_events_url":"https://api.github.com/users/larsxschneider/received_events","type":"User","site_admin":false},"body":"I assume we flush the content here?","created_at":"2016-11-06T23:02:27Z","updated_at":"2016-11-06T23:56:09Z","html_url":"https://github.com/github/git-lfs/pull/1622#discussion_r86699029","pull_request_url":"https://api.github.com/repos/github/git-lfs/pulls/1622","_links":{"self":{"href":"https://api.github.com/repos/github/git-lfs/pulls/comments/86699029"},"html":{"href":"https://github.com/github/git-lfs/pull/1622#discussion_r86699029"},"pull_request":{"href":"https://api.github.com/repos/github/git-lfs/pulls/1622"}}},"pull_request":{"url":"https://api.github.com/repos/github/git-lfs/pulls/1622","id":92237612,"html_url":"https://github.com/github/git-lfs/pull/1622","diff_url":"https://github.com/github/git-lfs/pull/1622.diff","patch_url":"https://github.com/github/git-lfs/pull/1622.patch","issue_url":"https://api.github.com/repos/github/git-lfs/issues/1622","number":1622,"state":"open","locked":false,"title":"filter_stream: provide io.Writer implementation","user":{"login":"ttaylorr","id":443245,"avatar_url":"https://avatars.githubusercontent.com/u/443245?v=3","gravatar_id":"","url":"https://api.github.com/users/ttaylorr","html_url":"https://github.com/ttaylorr","followers_url":"https://api.github.com/users/ttaylorr/followers","following_url":"https://api.github.com/users/ttaylorr/following{/other_user}","gists_url":"https://api.github.com/users/ttaylorr/gists{/gist_id}","starred_url":"https://api.github.com/users/ttaylorr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ttaylorr/subscriptions","organizations_url":"https://api.github.com/users/ttaylorr/orgs","repos_url":"https://api.github.com/users/ttaylorr/repos","events_url":"https://api.github.com/users/ttaylorr/events{/privacy}","received_events_url":"https://api.github.com/users/ttaylorr/received_events","type":"User","site_admin":true},"body":"This pull-request provides an implementation of the `io.Writer` interface capable of writing packets using the Git \"pktline\" format to an underlying datastream.\r\n\r\nHere's a 🔎  at some the different parts of this PR:\r\n\r\n1. https://github.com/github/git-lfs/commit/5723bb8c016d422fa098fcdaaf1dd15e146c3e42: implement the `PacketWriter` type and add an exhaustive set of unit tests.\r\n2. https://github.com/github/git-lfs/commit/8ab75794997d64c92dc7649abb216ce33e32fbe4: add public constructor `NewPacketWriter` which takes any `io.Writer` and returns a `*PacketWriter` wrapping that underneath. If the given writer is itself already a `*PacketWriter`, it returns that wholesale to avoid re-wrapping.\r\n3. https://github.com/github/git-lfs/commit/a90c16285bc98ae8f7e71fea832494eeabb0caf2: Use the `io.Writer` in the `clean`/`smudge` implementation in `commands/commands_filter.go`.\r\n4. https://github.com/github/git-lfs/commit/5e72db6a3541b21d9bbb1981e09a981a8827f26f: A quick bit of 💅  to use the new `tools.MinInt` func instead of casting `int`s to `float64`s and relying on (potentially) inaccurate results from `math.Min`.\r\n\r\nIn terms of the implementation of the `io.Writer` itself, here's a quick tour:\r\n\r\n- Since the pktline protocol expects us to write as much data as we can in a single packet (as many bytes as we can up to and including `MaxPacketLength`), we have an internal buffer that is written to until we have ingested enough data to fill a single packet. \r\n- To avoid leaving data in the buffer at the end of writing a chunk of data, calling `w.Write(nil)` is a special-case signaling to write the `0000` flush packet.\r\n- `Write(p []byte)` reports only the amount of _data_ (not including the 4-byte headers) _actually_ written to the stream. This means that `Write()` with less data than `MaxPacketLength` will return `(0, nil)`, unless there was enough data in the buffer to cause a packet to be written.\r\n- `Write` is smart enough to write multiple packets if the given buffer \"p\" holds more information than a single packet can hold. It will buffer extra data that does not fit past the first `n` packets.\r\n\r\n---\r\n\r\n/cc @technoweenie @larsxschneider @sinbad @rubyist @sschuberth ","created_at":"2016-11-03T20:51:14Z","updated_at":"2016-11-06T23:56:09Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0b2741e49e54cedf70f6e24a74d6a3063bbefc0f","assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/github/git-lfs/milestones/1","html_url":"https://github.com/github/git-lfs/milestones/Filter%20protocol%20support","labels_url":"https://api.github.com/repos/github/git-lfs/milestones/1/labels","id":2110220,"number":1,"title":"Filter protocol support","description":"","creator":{"login":"ttaylorr","id":443245,"avatar_url":"https://avatars.githubusercontent.com/u/443245?v=3","gravatar_id":"","url":"https://api.github.com/users/ttaylorr","html_url":"https://github.com/ttaylorr","followers_url":"https://api.github.com/users/ttaylorr/followers","following_url":"https://api.github.com/users/ttaylorr/following{/other_user}","gists_url":"https://api.github.com/users/ttaylorr/gists{/gist_id}","starred_url":"https://api.github.com/users/ttaylorr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ttaylorr/subscriptions","organizations_url":"https://api.github.com/users/ttaylorr/orgs","repos_url":"https://api.github.com/users/ttaylorr/repos","events_url":"https://api.github.com/users/ttaylorr/events{/privacy}","received_events_url":"https://api.github.com/users/ttaylorr/received_events","type":"User","site_admin":true},"open_issues":5,"closed_issues":1,"state":"open","created_at":"2016-11-02T17:25:24Z","updated_at":"2016-11-03T20:51:14Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/github/git-lfs/pulls/1622/commits","review_comments_url":"https://api.github.com/repos/github/git-lfs/pulls/1622/comments","review_comment_url":"https://api.github.com/repos/github/git-lfs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/github/git-lfs/issues/1622/comments","statuses_url":"https://api.github.com/repos/github/git-lfs/statuses/055ac4841dd9d3a3359419969d1952ce9ae93528","head":{"label":"github:filter-stream-writer","ref":"filter-stream-writer","sha":"055ac4841dd9d3a3359419969d1952ce9ae93528","user":{"login":"github","id":9919,"avatar_url":"https://avatars.githubusercontent.com/u/9919?v=3","gravatar_id":"","url":"https://api.github.com/users/github","html_url":"https://github.com/github","followers_url":"https://api.github.com/users/github/followers","following_url":"https://api.github.com/users/github/following{/other_user}","gists_url":"https://api.github.com/users/github/gists{/gist_id}","starred_url":"https://api.github.com/users/github/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github/subscriptions","organizations_url":"https://api.github.com/users/github/orgs","repos_url":"https://api.github.com/users/github/repos","events_url":"https://api.github.com/users/github/events{/privacy}","received_events_url":"https://api.github.com/users/github/received_events","type":"Organization","site_admin":false},"repo":{"id":13021798,"name":"git-lfs","full_name":"github/git-lfs","owner":{"login":"github","id":9919,"avatar_url":"https://avatars.githubusercontent.com/u/9919?v=3","gravatar_id":"","url":"https://api.github.com/users/github","html_url":"https://github.com/github","followers_url":"https://api.github.com/users/github/followers","following_url":"https://api.github.com/users/github/following{/other_user}","gists_url":"https://api.github.com/users/github/gists{/gist_id}","starred_url":"https://api.github.com/users/github/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github/subscriptions","organizations_url":"https://api.github.com/users/github/orgs","repos_url":"https://api.github.com/users/github/repos","events_url":"https://api.github.com/users/github/events{/privacy}","received_events_url":"https://api.github.com/users/github/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/github/git-lfs","description":"Git extension for versioning large files","fork":false,"url":"https://api.github.com/repos/github/git-lfs","forks_url":"https://api.github.com/repos/github/git-lfs/forks","keys_url":"https://api.github.com/repos/github/git-lfs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/github/git-lfs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/github/git-lfs/teams","hooks_url":"https://api.github.com/repos/github/git-lfs/hooks","issue_events_url":"https://api.github.com/repos/github/git-lfs/issues/events{/number}","events_url":"https://api.github.com/repos/github/git-lfs/events","assignees_url":"https://api.github.com/repos/github/git-lfs/assignees{/user}","branches_url":"https://api.github.com/repos/github/git-lfs/branches{/branch}","tags_url":"https://api.github.com/repos/github/git-lfs/tags","blobs_url":"https://api.github.com/repos/github/git-lfs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/github/git-lfs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/github/git-lfs/git/refs{/sha}","trees_url":"https://api.github.com/repos/github/git-lfs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/github/git-lfs/statuses/{sha}","languages_url":"https://api.github.com/repos/github/git-lfs/languages","stargazers_url":"https://api.github.com/repos/github/git-lfs/stargazers","contributors_url":"https://api.github.com/repos/github/git-lfs/contributors","subscribers_url":"https://api.github.com/repos/github/git-lfs/subscribers","subscription_url":"https://api.github.com/repos/github/git-lfs/subscription","commits_url":"https://api.github.com/repos/github/git-lfs/commits{/sha}","git_commits_url":"https://api.github.com/repos/github/git-lfs/git/commits{/sha}","comments_url":"https://api.github.com/repos/github/git-lfs/comments{/number}","issue_comment_url":"https://api.github.com/repos/github/git-lfs/issues/comments{/number}","contents_url":"https://api.github.com/repos/github/git-lfs/contents/{+path}","compare_url":"https://api.github.com/repos/github/git-lfs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/github/git-lfs/merges","archive_url":"https://api.github.com/repos/github/git-lfs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/github/git-lfs/downloads","issues_url":"https://api.github.com/repos/github/git-lfs/issues{/number}","pulls_url":"https://api.github.com/repos/github/git-lfs/pulls{/number}","milestones_url":"https://api.github.com/repos/github/git-lfs/milestones{/number}","notifications_url":"https://api.github.com/repos/github/git-lfs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/github/git-lfs/labels{/name}","releases_url":"https://api.github.com/repos/github/git-lfs/releases{/id}","deployments_url":"https://api.github.com/repos/github/git-lfs/deployments","created_at":"2013-09-22T22:03:28Z","updated_at":"2016-11-06T09:17:31Z","pushed_at":"2016-11-04T21:15:36Z","git_url":"git://github.com/github/git-lfs.git","ssh_url":"git@github.com:github/git-lfs.git","clone_url":"https://github.com/github/git-lfs.git","svn_url":"https://github.com/github/git-lfs","homepage":"https://git-lfs.github.com","size":12858,"stargazers_count":4013,"watchers_count":4013,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":579,"mirror_url":null,"open_issues_count":165,"forks":579,"open_issues":165,"watchers":4013,"default_branch":"master"}},"base":{"label":"github:filter-stream-reader","ref":"filter-stream-reader","sha":"0c0cd2ead16377977387acee90f71264bdbe9d9c","user":{"login":"github","id":9919,"avatar_url":"https://avatars.githubusercontent.com/u/9919?v=3","gravatar_id":"","url":"https://api.github.com/users/github","html_url":"https://github.com/github","followers_url":"https://api.github.com/users/github/followers","following_url":"https://api.github.com/users/github/following{/other_user}","gists_url":"https://api.github.com/users/github/gists{/gist_id}","starred_url":"https://api.github.com/users/github/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github/subscriptions","organizations_url":"https://api.github.com/users/github/orgs","repos_url":"https://api.github.com/users/github/repos","events_url":"https://api.github.com/users/github/events{/privacy}","received_events_url":"https://api.github.com/users/github/received_events","type":"Organization","site_admin":false},"repo":{"id":13021798,"name":"git-lfs","full_name":"github/git-lfs","owner":{"login":"github","id":9919,"avatar_url":"https://avatars.githubusercontent.com/u/9919?v=3","gravatar_id":"","url":"https://api.github.com/users/github","html_url":"https://github.com/github","followers_url":"https://api.github.com/users/github/followers","following_url":"https://api.github.com/users/github/following{/other_user}","gists_url":"https://api.github.com/users/github/gists{/gist_id}","starred_url":"https://api.github.com/users/github/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/github/subscriptions","organizations_url":"https://api.github.com/users/github/orgs","repos_url":"https://api.github.com/users/github/repos","events_url":"https://api.github.com/users/github/events{/privacy}","received_events_url":"https://api.github.com/users/github/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/github/git-lfs","description":"Git extension for versioning large files","fork":false,"url":"https://api.github.com/repos/github/git-lfs","forks_url":"https://api.github.com/repos/github/git-lfs/forks","keys_url":"https://api.github.com/repos/github/git-lfs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/github/git-lfs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/github/git-lfs/teams","hooks_url":"https://api.github.com/repos/github/git-lfs/hooks","issue_events_url":"https://api.github.com/repos/github/git-lfs/issues/events{/number}","events_url":"https://api.github.com/repos/github/git-lfs/events","assignees_url":"https://api.github.com/repos/github/git-lfs/assignees{/user}","branches_url":"https://api.github.com/repos/github/git-lfs/branches{/branch}","tags_url":"https://api.github.com/repos/github/git-lfs/tags","blobs_url":"https://api.github.com/repos/github/git-lfs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/github/git-lfs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/github/git-lfs/git/refs{/sha}","trees_url":"https://api.github.com/repos/github/git-lfs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/github/git-lfs/statuses/{sha}","languages_url":"https://api.github.com/repos/github/git-lfs/languages","stargazers_url":"https://api.github.com/repos/github/git-lfs/stargazers","contributors_url":"https://api.github.com/repos/github/git-lfs/contributors","subscribers_url":"https://api.github.com/repos/github/git-lfs/subscribers","subscription_url":"https://api.github.com/repos/github/git-lfs/subscription","commits_url":"https://api.github.com/repos/github/git-lfs/commits{/sha}","git_commits_url":"https://api.github.com/repos/github/git-lfs/git/commits{/sha}","comments_url":"https://api.github.com/repos/github/git-lfs/comments{/number}","issue_comment_url":"https://api.github.com/repos/github/git-lfs/issues/comments{/number}","contents_url":"https://api.github.com/repos/github/git-lfs/contents/{+path}","compare_url":"https://api.github.com/repos/github/git-lfs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/github/git-lfs/merges","archive_url":"https://api.github.com/repos/github/git-lfs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/github/git-lfs/downloads","issues_url":"https://api.github.com/repos/github/git-lfs/issues{/number}","pulls_url":"https://api.github.com/repos/github/git-lfs/pulls{/number}","milestones_url":"https://api.github.com/repos/github/git-lfs/milestones{/number}","notifications_url":"https://api.github.com/repos/github/git-lfs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/github/git-lfs/labels{/name}","releases_url":"https://api.github.com/repos/github/git-lfs/releases{/id}","deployments_url":"https://api.github.com/repos/github/git-lfs/deployments","created_at":"2013-09-22T22:03:28Z","updated_at":"2016-11-06T09:17:31Z","pushed_at":"2016-11-04T21:15:36Z","git_url":"git://github.com/github/git-lfs.git","ssh_url":"git@github.com:github/git-lfs.git","clone_url":"https://github.com/github/git-lfs.git","svn_url":"https://github.com/github/git-lfs","homepage":"https://git-lfs.github.com","size":12858,"stargazers_count":4013,"watchers_count":4013,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":579,"mirror_url":null,"open_issues_count":165,"forks":579,"open_issues":165,"watchers":4013,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/github/git-lfs/pulls/1622"},"html":{"href":"https://github.com/github/git-lfs/pull/1622"},"issue":{"href":"https://api.github.com/repos/github/git-lfs/issues/1622"},"comments":{"href":"https://api.github.com/repos/github/git-lfs/issues/1622/comments"},"review_comments":{"href":"https://api.github.com/repos/github/git-lfs/pulls/1622/comments"},"review_comment":{"href":"https://api.github.com/repos/github/git-lfs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/github/git-lfs/pulls/1622/commits"},"statuses":{"href":"https://api.github.com/repos/github/git-lfs/statuses/055ac4841dd9d3a3359419969d1952ce9ae93528"}}}}
{"actor":{"display_login":"larsxschneider"}}