{"thread":{"id":"29851","subject":"What's cooking in git.git (Mar 2012, #03; Mon, 5)","startedAt":"2012-03-06T07:15:12Z","lastAt":"2012-03-07T17:13:37Z","messageCount":13,"participants":["Junio C Hamano","Nguyen Thai Ngoc Duy","Nguyễn Thái Ngọc Duy"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"186174","messageId":"7vmx7uurnj.fsf@alter.siamese.dyndns.org","threadId":"29851","inReplyTo":null,"subject":"What's cooking in git.git (Mar 2012, #03; Mon, 5)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-03-06T07:15:12Z","receivedAt":"2012-03-06T07:15:12Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Here are the topics that have been cooking.  Commits prefixed with '-' are\nonly in 'pu' (proposed updates) while commits prefixed with '+' are in 'next'.\n\nThe tip of 'next' as of tonight is more or less how 1.7.10-rc0 will\nlook like in a few days.  I do not have enough confidence on other\nlarge-ish topics that are not yet in 'next' to include in them in\nthe upcoming release.\n\nSmall, trivially correct topics that have high value/damage ratio\nhowever may have enough time to go in 1.7.10 final even if they are\nstill in 'pu', if the owners put enough effort in them.  Otherwise\nlet's throw them into Stalled category and leave them to the next\ncycle.\n\nYou can find the changes described here in the integration branches of the\nrepositories listed at\n\n    http://git-blame.blogspot.com/p/git-public-repositories.html\n\n--------------------------------------------------\n[New Topics]\n\n* jc/fmt-merge-msg-people (2012-03-05) 1 commit\n  (merged to 'next' on 2012-03-05 at 38de349)\n + fmt-merge-msg: show those involved in a merged series\n\nThe \"fmt-merge-msg\" command learns to list the primary contributors\ninvolved in the side topic you are merging.\n\n* nl/http-proxy-more (2012-03-05) 3 commits\n - http: handle proxy authentication failure (error 407)\n - http: handle proxy proactive authentication\n - http: try http_proxy env var when http.proxy config option is not set\n (this branch uses nl/http-proxy-auth.)\n\nThe code to talk to http proxies learn to use the same credential\nAPI used to talk to the final http destinations.\n\n* nd/stream-more (2012-03-05) 6 commits\n - fsck: use streaming API for writing lost-found blobs\n - show: use streaming API for showing blobs\n - parse_object: avoid putting whole blob in core\n - cat-file: use streaming API to print blobs\n - Add more large blob test cases\n - streaming: make streaming-write-entry to be more reusable\n\nAs I do not think changes in the original larger series that touch\nindex-pack and unpack-objects will be ready for the upcoming 1.7.10,\nI've picked up only bits that deal with \"use streaming API instead\nof reading things in core\" and minimally fixed them up.  These we\nshould be able to polish in time.\n\nThe \"test cases\" patch needs to be trimmed to cover only these, I\nwould think.\n\n--------------------------------------------------\n[Stalled]\n\n* nd/optim-connected (2012-02-29) 1 commit\n - Perform cheaper connectivity check when pack is used as medium\n\nCheats the local connectivity check performed by \"git fetch\"\nslightly to gain some performance. This is a bit iffy.\n\n* jc/diff-ignore-mode (2012-03-01) 1 commit\n - diff --ignore-mode-change\n (this branch uses jc/maint-diff-patch-header.)\n\nWill discard.\n\n* nd/columns (2012-02-28) 10 commits\n - tag: add --column\n - column: support piping stdout to external git-column process\n - status: add --column\n - branch: add --column\n - help: reuse print_columns() for help -a\n - column: add column.ui for default column output settings\n - column: add dense layout support\n - column: add columnar layout\n - Stop starting pager recursively\n - Add git-column for columnar display\n\nRerolled; the configuration handling looked iffy, but otherwise well\nexplained.\n\n* jc/diff-ignore-case (2012-02-28) 6 commits\n - diff: -i is \"--ignore-case\" but means a bit more in \"log\"\n - diff: --ignore-case\n - xdiff: introduce XDF_IGNORE_CASE\n - xdiff: introduce XDF_INEXACT_MATCH\n - xdiff: PATIENCE/HISTOGRAM are not independent option bits\n - xdiff: remove XDL_PATCH_* macros\n\n\"git diff\" learns \"--ignore-case\" option.\nWill discard, as nobody seems to need this.\n\n* hv/submodule-recurse-push (2012-02-13) 3 commits\n - push: teach --recurse-submodules the on-demand option\n - Refactor submodule push check to use string list instead of integer\n - Teach revision walking machinery to walk multiple times sequencially\n\nThe bottom one was not clearly explained and needs a reroll.\n\n* jc/advise-push-default (2011-12-18) 1 commit\n - push: hint to use push.default=upstream when appropriate\n\nPeff had a good suggestion outlining an updated code structure so\nthat somebody new can try to dip his or her toes in the\ndevelopment. Any takers?\n\n* jh/trace-use-startup-info (2012-03-02) 1 commit\n - Use startup_info->prefix rather than prefix.\n\nI tend to agree with the doubt of the author of this patch expressed.\n\n* ss/git-svn-prompt-sans-terminal (2012-01-04) 3 commits\n - fixup! 15eaaf4\n - git-svn, perl/Git.pm: extend Git::prompt helper for querying users\n - perl/Git.pm: \"prompt\" helper to honor GIT_ASKPASS and SSH_ASKPASS\n\nThe bottom one has been replaced with a rewrite based on comments\nfrom Ævar. The second one needs more work, both in perl/Git.pm and\nprompt.c, to give precedence to tty over SSH_ASKPASS when terminal\nis available.\n\n* jc/split-blob (2012-02-23) 7 commits\n - fixup?\n - chunked-object: streaming checkout\n - chunked-object: fallback checkout codepaths\n - bulk-checkin: support chunked-object encoding\n - bulk-checkin: allow the same data to be multiply hashed\n - new representation types in the packstream\n - varint-in-pack: refactor varint encoding/decoding\n\nNot ready.\n\nI finished the streaming checkout codepath, but as explained in\n127b177 (bulk-checkin: support chunked-object encoding, 2011-11-30),\nthese are still early steps of a long and painful journey. At least\npack-objects and fsck need to learn the new encoding for the series\nto be usable locally, and then index-pack/unpack-objects needs to\nlearn it to be used remotely.\n\nGiven that I heard a lot of noise that people want large files, and\nthat I was asked by somebody at GitTogether'11 privately for an\nadvice on how to pay developers (not me) to help adding necessary\nsupport, I am somewhat dissapointed that the original patch series\nthat was sent almost two months ago still remains here without much\ncomments and updates from the developer community. I even made the\ninterface to the logic that decides where to split chunks easily\nreplaceable, and I deliberately made the logic in the original patch\nextremely stupid to entice others, especially the \"bup\" fanboys, to\ncome up with a better logic, thinking that giving people an easy\ntarget to shoot for, they may be encouraged to help out. The plan is\nnot working :-(.\n\n--------------------------------------------------\n[Cooking]\n\n* cn/pull-rebase-message (2012-03-04) 1 commit\n  (merged to 'next' on 2012-03-04 at 5a6cd58)\n + Make git-{pull,rebase} message without tracking information friendlier\n\nThe advise message given when the user didn't give enough clue on what\nto merge was overly long.\nWill merge to 'master'.\n\n* dg/test-from-elsewhere (2012-03-04) 2 commits\n - Support out-of-tree Valgrind tests\n - Allow overriding GIT_BUILD_DIR\n\nBetter support for out-of-tree test scripts.\n\n* jh/threadable-symlink-check (2012-03-02) 1 commit\n  (merged to 'next' on 2012-03-05 at fdd667c)\n + Add threaded versions of functions in symlinks.c.\n\nIt probably is \"threadble\" not \"threaded\" but in any case this\nshould not regress the current callers.\n\n* jn/maint-do-not-match-with-unsanitized-searchtext (2012-03-04) 1 commit\n - gitweb: Fix fixed string (non-regexp) project search\n\n\"gitweb\" did use quotemeta() to prepare search string when asked to\ndo a fixed-string project search, but did not use it by mistake and\nused the user-supplied string instead.\n\nI would love to see this in 1.7.10; what I queued for 'maint' (that\ndoes not have the lazy fill-info stuff), and my conflict resolution\ninto 'pu' to adjust for lazy fill-info, are both correct, I think,\nbut please double check.\n\n* nl/http-proxy-auth (2012-03-02) 1 commit\n  (merged to 'next' on 2012-03-04 at f368669)\n + http: support proxies that require authentication\n (this branch is used by nl/http-proxy-more.)\n\nAllow curl-based transport to use proxies that require authentication.\nWill merge to 'master'.\n\n* sl/modern-t0000 (2012-03-02) 1 commit\n  (merged to 'next' on 2012-03-04 at 2cd1508)\n + t0000: modernise style\n\nWill merge to 'master'.\n\n* th/mergetools-deltawalker (2012-03-05) 1 commit\n  (merged to 'next' on 2012-03-05 at 167c74f)\n + mergetools: add a plug-in to support DeltaWalker\n\nAdd plug-in to support DeltaWalker in difftool/mergetool.  \nWill merge to 'master'.\n\n* jl/maint-submodule-relative (2012-03-04) 4 commits\n - submodules: fix ambiguous absolute paths under Windows\n - submodules: refactor computation of relative gitdir path\n - submodules: always use a relative path from gitdir to work tree\n - submodules: always use a relative path to gitdir\n\nRerolled and resurrected from Stalled category.\n\nI would love to have this in 1.7.10; a couple of Acks from different\nplatforms and success reports would be very helpful.\n\n* nd/threaded-index-pack (2012-03-02) 2 commits\n - index-pack: support multithreaded delta resolving\n - index-pack: split second pass obj handling into own function\n\nRerolled to fix a bug that was discovered with a trivial test, and\nresurrected from Stalled category, but I am reluctant to advance a\ntopic that can easily break many people's repositories at this late\nin the cycle.\n\n* jc/maint-diff-patch-header (2012-03-01) 3 commits\n  (merged to 'next' on 2012-03-02 at 2cd2059)\n + diff -p: squelch \"diff --git\" header for stat-dirty paths\n + t4011: illustrate \"diff-index -p\" on stat-dirty paths\n + t4011: modernise style\n (this branch is used by jc/diff-ignore-mode.)\n\n\"diff-index\" and friends showed \"diff --git\" header and nothing else\nfor a path that is only stat-dirty.\n\nShould be safe, but is not urgent.\n\n* tr/maint-bundle-boundary (2012-03-01) 3 commits\n  (merged to 'next' on 2012-03-02 at c25692f)\n + bundle: keep around names passed to add_pending_object()\n + t5510: ensure we stay in the toplevel test dir\n + t5510: refactor bundle->pack conversion\n\n\"git bundle\" did not record boundary commits correctly when there\nare many of them.\n\nWill merge to 'master'.\n\n* jc/pickaxe-ignore-case (2012-03-04) 3 commits\n  (merged to 'next' on 2012-03-04 at 1ad3a39)\n + ctype.c: Fix a sparse warning\n  (merged to 'next' on 2012-03-02 at 73a632b)\n + pickaxe: allow -i to search in patch case-insensitively\n + grep: use static trans-case table\n\n\"git log -G/-S\" pays attention to the \"-i\" option.\n\nWill merge to 'master'.\n\n* zj/diff-stat-dyncol (2012-03-01) 10 commits\n  (merged to 'next' on 2012-03-01 at 79b4152)\n + diff --stat: add config option to limit graph width\n + diff --stat: enable limiting of the graph part\n + diff --stat: add a test for output with COLUMNS=40\n + diff --stat: use a maximum of 5/8 for the filename part\n + merge --stat: use the full terminal width\n + log --stat: use the full terminal width\n + show --stat: use the full terminal width\n + diff --stat: use the full terminal width\n + diff --stat: tests for long filenames and big change counts\n + Merge branches zj/decimal-width, zj/term-columns and jc/diff-stat-scaler\n\nRerolled again and looking good.\nWill merge to 'master'.\n"},{"id":"186193","messageId":"CACsJy8BRQ63hV5e63yoMVykOMZS3u-VrdCQtvgRGBji4Yzpi4A@mail.gmail.com","threadId":"29851","inReplyTo":"7vmx7uurnj.fsf@alter.siamese.dyndns.org","subject":"Re: What's cooking in git.git (Mar 2012, #03; Mon, 5)","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-03-06T09:40:11Z","receivedAt":"2012-03-06T09:40:11Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Tue, Mar 6, 2012 at 2:15 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> * nd/stream-more (2012-03-05) 6 commits\n>  - fsck: use streaming API for writing lost-found blobs\n>  - show: use streaming API for showing blobs\n>  - parse_object: avoid putting whole blob in core\n>  - cat-file: use streaming API to print blobs\n>  - Add more large blob test cases\n>  - streaming: make streaming-write-entry to be more reusable\n>\n> As I do not think changes in the original larger series that touch\n> index-pack and unpack-objects will be ready for the upcoming 1.7.10,\n> I've picked up only bits that deal with \"use streaming API instead\n> of reading things in core\" and minimally fixed them up.  These we\n> should be able to polish in time.\n\n11/11 should be safe to go too. It simply reads config files so that\nparse_object() respects core.bigfilethreshold.\n\nhttp://mid.gmane.org/1330919028-6611-12-git-send-email-pclouds@gmail.com\n\n> The \"test cases\" patch needs to be trimmed to cover only these, I\n> would think.\n\nI'd rather leave it as is. All new test cases are test_expect_failure,\nthey should not interrupt \"make test\". If I slack off, somebody may be\nannoyed enough with those known breakages to give me a little push.\n-- \nDuy\n"},{"id":"186231","messageId":"7vty21twqc.fsf@alter.siamese.dyndns.org","threadId":"29851","inReplyTo":"CACsJy8BRQ63hV5e63yoMVykOMZS3u-VrdCQtvgRGBji4Yzpi4A@mail.gmail.com","subject":"Re: What's cooking in git.git (Mar 2012, #03; Mon, 5)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-03-06T18:23:07Z","receivedAt":"2012-03-06T18:23:07Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n>> I've picked up only bits that deal with \"use streaming API instead\n>> of reading things in core\" and minimally fixed them up.  These we\n>> should be able to polish in time.\n>\n> 11/11 should be safe to go too. It simply reads config files so that\n> parse_object() respects core.bigfilethreshold.\n\nOk.\n\n> I'd rather leave it as is. All new test cases are test_expect_failure,\n> they should not interrupt \"make test\". If I slack off, somebody may be\n> annoyed enough with those known breakages to give me a little push.\n\nThat requires us to vet and agree that the conditions marked with\nexpect_failure are indeed breakages, which I would want avoid. It is\nfrustrating for people who has to later \"fix\" things and find out\nthat the original \"bug\" was marked without thinking things through.\n"},{"id":"186289","messageId":"7vd38oq5zz.fsf@alter.siamese.dyndns.org","threadId":"29851","inReplyTo":"7vmx7uurnj.fsf@alter.siamese.dyndns.org","subject":"In preparation for 1.7.10-rc0","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-03-07T06:28:48Z","receivedAt":"2012-03-07T06:28:48Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"There are a couple loose ends I would like to tie before we go deep\ninto the pre-release freeze for the upcoming 1.7.10.\n\n* Subsystems\n\nI recall that I received many months worth of accumulated gitk\nupdates during the last round from Paul.\n\nAre there updates for this cycle coming soon?  The same question for\ngit-gui (Pat) and git-svn (Eric)?\n\n* L10N\n\nImmediately after 1.7.10-rc0 gets tagged may be a good time for the\nl10n coordinator to pull from me, run \"make pot\" to update the\npo/git.pot file and propagate the result to the language teams (oh,\nwe would also need to recruit language teams other than Chinese ;-),\nso that the translations can be updated (or added).\n\nThanks.\n"},{"id":"186297","messageId":"1331117661-19378-1-git-send-email-pclouds@gmail.com","threadId":"29851","inReplyTo":"7vty21twqc.fsf@alter.siamese.dyndns.org","subject":"[PATCH 0/7] nd/stream-more updates","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-03-07T10:54:14Z","receivedAt":"2012-03-07T10:54:14Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"As discussed, this series removes test_expect_failure that are still\nnot fixed in the end. It also adds update-server-info patch. I'll hold\noff the rest of the previous series until 1.7.10 comes out.\n\nJunio C Hamano (1):\n  streaming: make streaming-write-entry to be more reusable\n\nNguyễn Thái Ngọc Duy (6):\n  Add more large blob test cases\n  cat-file: use streaming API to print blobs\n  parse_object: avoid putting whole blob in core\n  show: use streaming API for showing blobs\n  fsck: use streaming API for writing lost-found blobs\n  update-server-info: respect core.bigfilethreshold\n\n builtin/cat-file.c           |   25 +++++++++++++++++++\n builtin/fsck.c               |    8 +----\n builtin/log.c                |   34 +++++++++++++++----------\n builtin/update-server-info.c |    1 +\n entry.c                      |   53 ++++------------------------------------\n object.c                     |   11 ++++++++\n sha1_file.c                  |   42 ++++++++++++++++++++++++++++++-\n streaming.c                  |   55 ++++++++++++++++++++++++++++++++++++++++++\n streaming.h                  |    2 +\n t/t1050-large.sh             |   38 +++++++++++++++++++++++++++-\n wrapper.c                    |   27 ++++++++++++++++++--\n 11 files changed, 221 insertions(+), 75 deletions(-)\n\n-- \n1.7.8.36.g69ee2\n"},{"id":"186298","messageId":"1331117661-19378-2-git-send-email-pclouds@gmail.com","threadId":"29851","inReplyTo":"1331117661-19378-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 1/7] streaming: make streaming-write-entry to be more reusable","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-03-07T10:54:15Z","receivedAt":"2012-03-07T10:54:15Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"From: Junio C Hamano <gitster@pobox.com>\n\nThe static function in entry.c takes a cache entry and streams its blob\ncontents to a file in the working tree.  Refactor the logic to a new API\nfunction stream_blob_to_fd() that takes an object name and an open file\ndescriptor, so that it can be reused by other callers.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n entry.c     |   53 +++++------------------------------------------------\n streaming.c |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++\n streaming.h |    2 ++\n 3 files changed, 62 insertions(+), 48 deletions(-)\n\ndiff --git a/entry.c b/entry.c\nindex 852fea1..17a6bcc 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -120,58 +120,15 @@ static int streaming_write_entry(struct cache_entry *ce, char *path,\n \t\t\t\t const struct checkout *state, int to_tempfile,\n \t\t\t\t int *fstat_done, struct stat *statbuf)\n {\n-\tstruct git_istream *st;\n-\tenum object_type type;\n-\tunsigned long sz;\n \tint result = -1;\n-\tssize_t kept = 0;\n-\tint fd = -1;\n-\n-\tst = open_istream(ce->sha1, &type, &sz, filter);\n-\tif (!st)\n-\t\treturn -1;\n-\tif (type != OBJ_BLOB)\n-\t\tgoto close_and_exit;\n+\tint fd;\n \n \tfd = open_output_fd(path, ce, to_tempfile);\n-\tif (fd < 0)\n-\t\tgoto close_and_exit;\n-\n-\tfor (;;) {\n-\t\tchar buf[1024 * 16];\n-\t\tssize_t wrote, holeto;\n-\t\tssize_t readlen = read_istream(st, buf, sizeof(buf));\n-\n-\t\tif (!readlen)\n-\t\t\tbreak;\n-\t\tif (sizeof(buf) == readlen) {\n-\t\t\tfor (holeto = 0; holeto < readlen; holeto++)\n-\t\t\t\tif (buf[holeto])\n-\t\t\t\t\tbreak;\n-\t\t\tif (readlen == holeto) {\n-\t\t\t\tkept += holeto;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t}\n-\n-\t\tif (kept && lseek(fd, kept, SEEK_CUR) == (off_t) -1)\n-\t\t\tgoto close_and_exit;\n-\t\telse\n-\t\t\tkept = 0;\n-\t\twrote = write_in_full(fd, buf, readlen);\n-\n-\t\tif (wrote != readlen)\n-\t\t\tgoto close_and_exit;\n-\t}\n-\tif (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 ||\n-\t\t     write(fd, \"\", 1) != 1))\n-\t\tgoto close_and_exit;\n-\t*fstat_done = fstat_output(fd, state, statbuf);\n-\n-close_and_exit:\n-\tclose_istream(st);\n-\tif (0 <= fd)\n+\tif (0 <= fd) {\n+\t\tresult = stream_blob_to_fd(fd, ce->sha1, filter, 1);\n+\t\t*fstat_done = fstat_output(fd, state, statbuf);\n \t\tresult = close(fd);\n+\t}\n \tif (result && 0 <= fd)\n \t\tunlink(path);\n \treturn result;\ndiff --git a/streaming.c b/streaming.c\nindex 71072e1..7e7ee2b 100644\n--- a/streaming.c\n+++ b/streaming.c\n@@ -489,3 +489,58 @@ static open_method_decl(incore)\n \n \treturn st->u.incore.buf ? 0 : -1;\n }\n+\n+\n+/****************************************************************\n+ * Users of streaming interface\n+ ****************************************************************/\n+\n+int stream_blob_to_fd(int fd, unsigned const char *sha1, struct stream_filter *filter,\n+\t\t      int can_seek)\n+{\n+\tstruct git_istream *st;\n+\tenum object_type type;\n+\tunsigned long sz;\n+\tssize_t kept = 0;\n+\tint result = -1;\n+\n+\tst = open_istream(sha1, &type, &sz, filter);\n+\tif (!st)\n+\t\treturn result;\n+\tif (type != OBJ_BLOB)\n+\t\tgoto close_and_exit;\n+\tfor (;;) {\n+\t\tchar buf[1024 * 16];\n+\t\tssize_t wrote, holeto;\n+\t\tssize_t readlen = read_istream(st, buf, sizeof(buf));\n+\n+\t\tif (!readlen)\n+\t\t\tbreak;\n+\t\tif (can_seek && sizeof(buf) == readlen) {\n+\t\t\tfor (holeto = 0; holeto < readlen; holeto++)\n+\t\t\t\tif (buf[holeto])\n+\t\t\t\t\tbreak;\n+\t\t\tif (readlen == holeto) {\n+\t\t\t\tkept += holeto;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (kept && lseek(fd, kept, SEEK_CUR) == (off_t) -1)\n+\t\t\tgoto close_and_exit;\n+\t\telse\n+\t\t\tkept = 0;\n+\t\twrote = write_in_full(fd, buf, readlen);\n+\n+\t\tif (wrote != readlen)\n+\t\t\tgoto close_and_exit;\n+\t}\n+\tif (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 ||\n+\t\t     write(fd, \"\", 1) != 1))\n+\t\tgoto close_and_exit;\n+\tresult = 0;\n+\n+ close_and_exit:\n+\tclose_istream(st);\n+\treturn result;\n+}\ndiff --git a/streaming.h b/streaming.h\nindex 589e857..3e82770 100644\n--- a/streaming.h\n+++ b/streaming.h\n@@ -12,4 +12,6 @@ extern struct git_istream *open_istream(const unsigned char *, enum object_type\n extern int close_istream(struct git_istream *);\n extern ssize_t read_istream(struct git_istream *, char *, size_t);\n \n+extern int stream_blob_to_fd(int fd, const unsigned char *, struct stream_filter *, int can_seek);\n+\n #endif /* STREAMING_H */\n-- \n1.7.8.36.g69ee2\n"},{"id":"186299","messageId":"1331117661-19378-3-git-send-email-pclouds@gmail.com","threadId":"29851","inReplyTo":"1331117661-19378-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 2/7] Add more large blob test cases","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-03-07T10:54:16Z","receivedAt":"2012-03-07T10:54:16Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"New test cases list commands that should work when memory is\nlimited. All memory allocation functions (*) learn to reject any\nallocation larger than $GIT_ALLOC_LIMIT if set.\n\n(*) Not exactly all. Some places do not use x* functions, but\nmalloc/calloc directly, notably diff-delta. These code path should\nnever be run on large blobs.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n t/t1050-large.sh |   38 ++++++++++++++++++++++++++++++++++++--\n wrapper.c        |   27 ++++++++++++++++++++++++---\n 2 files changed, 60 insertions(+), 5 deletions(-)\n\ndiff --git a/t/t1050-large.sh b/t/t1050-large.sh\nindex 29d6024..ded66b3 100755\n--- a/t/t1050-large.sh\n+++ b/t/t1050-large.sh\n@@ -6,11 +6,15 @@ test_description='adding and checking out large blobs'\n . ./test-lib.sh\n \n test_expect_success setup '\n-\tgit config core.bigfilethreshold 200k &&\n+\t# clone does not allow us to pass core.bigfilethreshold to\n+\t# new repos, so set core.bigfilethreshold globally\n+\tgit config --global core.bigfilethreshold 200k &&\n \techo X | dd of=large1 bs=1k seek=2000 &&\n \techo X | dd of=large2 bs=1k seek=2000 &&\n \techo X | dd of=large3 bs=1k seek=2000 &&\n-\techo Y | dd of=huge bs=1k seek=2500\n+\techo Y | dd of=huge bs=1k seek=2500 &&\n+\tGIT_ALLOC_LIMIT=1500 &&\n+\texport GIT_ALLOC_LIMIT\n '\n \n test_expect_success 'add a large file or two' '\n@@ -100,4 +104,34 @@ test_expect_success 'packsize limit' '\n \t)\n '\n \n+test_expect_success 'diff --raw' '\n+\tgit commit -q -m initial &&\n+\techo modified >>large1 &&\n+\tgit add large1 &&\n+\tgit commit -q -m modified &&\n+\tgit diff --raw HEAD^\n+'\n+\n+test_expect_success 'hash-object' '\n+\tgit hash-object large1\n+'\n+\n+test_expect_failure 'cat-file a large file' '\n+\tgit cat-file blob :large1 >/dev/null\n+'\n+\n+test_expect_failure 'cat-file a large file from a tag' '\n+\tgit tag -m largefile largefiletag :large1 &&\n+\tgit cat-file blob largefiletag >/dev/null\n+'\n+\n+test_expect_failure 'git-show a large file' '\n+\tgit show :large1 >/dev/null\n+\n+'\n+\n+test_expect_failure 'repack' '\n+\tgit repack -ad\n+'\n+\n test_done\ndiff --git a/wrapper.c b/wrapper.c\nindex 85f09df..6ccd059 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -9,6 +9,18 @@ static void do_nothing(size_t size)\n \n static void (*try_to_free_routine)(size_t size) = do_nothing;\n \n+static void memory_limit_check(size_t size)\n+{\n+\tstatic int limit = -1;\n+\tif (limit == -1) {\n+\t\tconst char *env = getenv(\"GIT_ALLOC_LIMIT\");\n+\t\tlimit = env ? atoi(env) * 1024 : 0;\n+\t}\n+\tif (limit && size > limit)\n+\t\tdie(\"attempting to allocate %\"PRIuMAX\" over limit %d\",\n+\t\t    (intmax_t)size, limit);\n+}\n+\n try_to_free_t set_try_to_free_routine(try_to_free_t routine)\n {\n \ttry_to_free_t old = try_to_free_routine;\n@@ -32,7 +44,10 @@ char *xstrdup(const char *str)\n \n void *xmalloc(size_t size)\n {\n-\tvoid *ret = malloc(size);\n+\tvoid *ret;\n+\n+\tmemory_limit_check(size);\n+\tret = malloc(size);\n \tif (!ret && !size)\n \t\tret = malloc(1);\n \tif (!ret) {\n@@ -79,7 +94,10 @@ char *xstrndup(const char *str, size_t len)\n \n void *xrealloc(void *ptr, size_t size)\n {\n-\tvoid *ret = realloc(ptr, size);\n+\tvoid *ret;\n+\n+\tmemory_limit_check(size);\n+\tret = realloc(ptr, size);\n \tif (!ret && !size)\n \t\tret = realloc(ptr, 1);\n \tif (!ret) {\n@@ -95,7 +113,10 @@ void *xrealloc(void *ptr, size_t size)\n \n void *xcalloc(size_t nmemb, size_t size)\n {\n-\tvoid *ret = calloc(nmemb, size);\n+\tvoid *ret;\n+\n+\tmemory_limit_check(size * nmemb);\n+\tret = calloc(nmemb, size);\n \tif (!ret && (!nmemb || !size))\n \t\tret = calloc(1, 1);\n \tif (!ret) {\n-- \n1.7.8.36.g69ee2\n"},{"id":"186304","messageId":"1331117661-19378-4-git-send-email-pclouds@gmail.com","threadId":"29851","inReplyTo":"1331117661-19378-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 3/7] cat-file: use streaming API to print blobs","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-03-07T10:54:17Z","receivedAt":"2012-03-07T10:54:17Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/cat-file.c |   25 +++++++++++++++++++++++++\n t/t1050-large.sh   |    4 ++--\n 2 files changed, 27 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/cat-file.c b/builtin/cat-file.c\nindex 8ed501f..36a9104 100644\n--- a/builtin/cat-file.c\n+++ b/builtin/cat-file.c\n@@ -11,6 +11,7 @@\n #include \"parse-options.h\"\n #include \"diff.h\"\n #include \"userdiff.h\"\n+#include \"streaming.h\"\n \n #define BATCH 1\n #define BATCH_CHECK 2\n@@ -127,6 +128,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)\n \t\t\treturn cmd_ls_tree(2, ls_args, NULL);\n \t\t}\n \n+\t\tif (type == OBJ_BLOB)\n+\t\t\treturn stream_blob_to_fd(1, sha1, NULL, 0);\n \t\tbuf = read_sha1_file(sha1, &type, &size);\n \t\tif (!buf)\n \t\t\tdie(\"Cannot read object %s\", obj_name);\n@@ -149,6 +152,28 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)\n \t\tbreak;\n \n \tcase 0:\n+\t\tif (type_from_string(exp_type) == OBJ_BLOB) {\n+\t\t\tunsigned char blob_sha1[20];\n+\t\t\tif (sha1_object_info(sha1, NULL) == OBJ_TAG) {\n+\t\t\t\tenum object_type type;\n+\t\t\t\tunsigned long size;\n+\t\t\t\tchar *buffer = read_sha1_file(sha1, &type, &size);\n+\t\t\t\tif (memcmp(buffer, \"object \", 7) ||\n+\t\t\t\t    get_sha1_hex(buffer + 7, blob_sha1))\n+\t\t\t\t\tdie(\"%s not a valid tag\", sha1_to_hex(sha1));\n+\t\t\t\tfree(buffer);\n+\t\t\t} else\n+\t\t\t\thashcpy(blob_sha1, sha1);\n+\n+\t\t\tif (sha1_object_info(blob_sha1, NULL) == OBJ_BLOB)\n+\t\t\t\treturn stream_blob_to_fd(1, blob_sha1, NULL, 0);\n+\t\t\t/*\n+\t\t\t * we attempted to dereference a tag to a blob\n+\t\t\t * and failed; there may be new dereference\n+\t\t\t * mechanisms this code is not aware of.\n+\t\t\t * fall-back to the usual case.\n+\t\t\t */\n+\t\t}\n \t\tbuf = read_object_with_reference(sha1, exp_type, &size, NULL);\n \t\tbreak;\n \ndiff --git a/t/t1050-large.sh b/t/t1050-large.sh\nindex ded66b3..f662fef 100755\n--- a/t/t1050-large.sh\n+++ b/t/t1050-large.sh\n@@ -116,11 +116,11 @@ test_expect_success 'hash-object' '\n \tgit hash-object large1\n '\n \n-test_expect_failure 'cat-file a large file' '\n+test_expect_success 'cat-file a large file' '\n \tgit cat-file blob :large1 >/dev/null\n '\n \n-test_expect_failure 'cat-file a large file from a tag' '\n+test_expect_success 'cat-file a large file from a tag' '\n \tgit tag -m largefile largefiletag :large1 &&\n \tgit cat-file blob largefiletag >/dev/null\n '\n-- \n1.7.8.36.g69ee2\n"},{"id":"186300","messageId":"1331117661-19378-5-git-send-email-pclouds@gmail.com","threadId":"29851","inReplyTo":"1331117661-19378-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 4/7] parse_object: avoid putting whole blob in core","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-03-07T10:54:18Z","receivedAt":"2012-03-07T10:54:18Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Traditionally, all the callers of check_sha1_signature() first\ncalled read_sha1_file() to prepare the whole object data in core,\nand called this function.  The function is used to revalidate what\nwe read from the object database actually matches the object name we\nused to ask for the data from the object database.\n\nUpdate the API to allow callers to pass NULL as the object data, and\nhave the function read and hash the object data using streaming API\nto recompute the object name, without having to hold everything in\ncore at the same time.  This is most useful in parse_object() that\nparses a blob object, because this caller does not have to keep the\nactual blob data around in memory after a \"struct blob\" is returned.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n object.c    |   11 +++++++++++\n sha1_file.c |   42 ++++++++++++++++++++++++++++++++++++++++--\n 2 files changed, 51 insertions(+), 2 deletions(-)\n\ndiff --git a/object.c b/object.c\nindex 6b06297..0498b18 100644\n--- a/object.c\n+++ b/object.c\n@@ -198,6 +198,17 @@ struct object *parse_object(const unsigned char *sha1)\n \tif (obj && obj->parsed)\n \t\treturn obj;\n \n+\tif ((obj && obj->type == OBJ_BLOB) ||\n+\t    (!obj && has_sha1_file(sha1) &&\n+\t     sha1_object_info(sha1, NULL) == OBJ_BLOB)) {\n+\t\tif (check_sha1_signature(repl, NULL, 0, NULL) < 0) {\n+\t\t\terror(\"sha1 mismatch %s\\n\", sha1_to_hex(repl));\n+\t\t\treturn NULL;\n+\t\t}\n+\t\tparse_blob_buffer(lookup_blob(sha1), NULL, 0);\n+\t\treturn lookup_object(sha1);\n+\t}\n+\n \tbuffer = read_sha1_file(sha1, &type, &size);\n \tif (buffer) {\n \t\tif (check_sha1_signature(repl, buffer, size, typename(type)) < 0) {\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 4f06a0e..ad314f0 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -19,6 +19,7 @@\n #include \"pack-revindex.h\"\n #include \"sha1-lookup.h\"\n #include \"bulk-checkin.h\"\n+#include \"streaming.h\"\n \n #ifndef O_NOATIME\n #if defined(__linux__) && (defined(__i386__) || defined(__PPC__))\n@@ -1146,10 +1147,47 @@ static const struct packed_git *has_packed_and_bad(const unsigned char *sha1)\n \treturn NULL;\n }\n \n-int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long size, const char *type)\n+/*\n+ * With an in-core object data in \"map\", rehash it to make sure the\n+ * object name actually matches \"sha1\" to detect object corruption.\n+ * With \"map\" == NULL, try reading the object named with \"sha1\" using\n+ * the streaming interface and rehash it to do the same.\n+ */\n+int check_sha1_signature(const unsigned char *sha1, void *map,\n+\t\t\t unsigned long size, const char *type)\n {\n \tunsigned char real_sha1[20];\n-\thash_sha1_file(map, size, type, real_sha1);\n+\tenum object_type obj_type;\n+\tstruct git_istream *st;\n+\tgit_SHA_CTX c;\n+\tchar hdr[32];\n+\tint hdrlen;\n+\n+\tif (map) {\n+\t\thash_sha1_file(map, size, type, real_sha1);\n+\t\treturn hashcmp(sha1, real_sha1) ? -1 : 0;\n+\t}\n+\n+\tst = open_istream(sha1, &obj_type, &size, NULL);\n+\tif (!st)\n+\t\treturn -1;\n+\n+\t/* Generate the header */\n+\thdrlen = sprintf(hdr, \"%s %lu\", typename(obj_type), size) + 1;\n+\n+\t/* Sha1.. */\n+\tgit_SHA1_Init(&c);\n+\tgit_SHA1_Update(&c, hdr, hdrlen);\n+\tfor (;;) {\n+\t\tchar buf[1024 * 16];\n+\t\tssize_t readlen = read_istream(st, buf, sizeof(buf));\n+\n+\t\tif (!readlen)\n+\t\t\tbreak;\n+\t\tgit_SHA1_Update(&c, buf, readlen);\n+\t}\n+\tgit_SHA1_Final(real_sha1, &c);\n+\tclose_istream(st);\n \treturn hashcmp(sha1, real_sha1) ? -1 : 0;\n }\n \n-- \n1.7.8.36.g69ee2\n"},{"id":"186301","messageId":"1331117661-19378-6-git-send-email-pclouds@gmail.com","threadId":"29851","inReplyTo":"1331117661-19378-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 5/7] show: use streaming API for showing blobs","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-03-07T10:54:19Z","receivedAt":"2012-03-07T10:54:19Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/log.c    |   34 ++++++++++++++++++++--------------\n t/t1050-large.sh |    2 +-\n 2 files changed, 21 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 7d1f6f8..d1702e7 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -20,6 +20,7 @@\n #include \"string-list.h\"\n #include \"parse-options.h\"\n #include \"branch.h\"\n+#include \"streaming.h\"\n \n /* Set a default date-time format for git log (\"log.date\" config variable) */\n static const char *default_date_mode = NULL;\n@@ -381,8 +382,13 @@ static void show_tagger(char *buf, int len, struct rev_info *rev)\n \tstrbuf_release(&out);\n }\n \n-static int show_object(const unsigned char *sha1, int show_tag_object,\n-\tstruct rev_info *rev)\n+static int show_blob_object(const unsigned char *sha1, struct rev_info *rev)\n+{\n+\tfflush(stdout);\n+\treturn stream_blob_to_fd(1, sha1, NULL, 0);\n+}\n+\n+static int show_tag_object(const unsigned char *sha1, struct rev_info *rev)\n {\n \tunsigned long size;\n \tenum object_type type;\n@@ -392,16 +398,16 @@ static int show_object(const unsigned char *sha1, int show_tag_object,\n \tif (!buf)\n \t\treturn error(_(\"Could not read object %s\"), sha1_to_hex(sha1));\n \n-\tif (show_tag_object)\n-\t\twhile (offset < size && buf[offset] != '\\n') {\n-\t\t\tint new_offset = offset + 1;\n-\t\t\twhile (new_offset < size && buf[new_offset++] != '\\n')\n-\t\t\t\t; /* do nothing */\n-\t\t\tif (!prefixcmp(buf + offset, \"tagger \"))\n-\t\t\t\tshow_tagger(buf + offset + 7,\n-\t\t\t\t\t    new_offset - offset - 7, rev);\n-\t\t\toffset = new_offset;\n-\t\t}\n+\tassert(type == OBJ_TAG);\n+\twhile (offset < size && buf[offset] != '\\n') {\n+\t\tint new_offset = offset + 1;\n+\t\twhile (new_offset < size && buf[new_offset++] != '\\n')\n+\t\t\t; /* do nothing */\n+\t\tif (!prefixcmp(buf + offset, \"tagger \"))\n+\t\t\tshow_tagger(buf + offset + 7,\n+\t\t\t\t    new_offset - offset - 7, rev);\n+\t\toffset = new_offset;\n+\t}\n \n \tif (offset < size)\n \t\tfwrite(buf + offset, size - offset, 1, stdout);\n@@ -459,7 +465,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)\n \t\tconst char *name = objects[i].name;\n \t\tswitch (o->type) {\n \t\tcase OBJ_BLOB:\n-\t\t\tret = show_object(o->sha1, 0, NULL);\n+\t\t\tret = show_blob_object(o->sha1, NULL);\n \t\t\tbreak;\n \t\tcase OBJ_TAG: {\n \t\t\tstruct tag *t = (struct tag *)o;\n@@ -470,7 +476,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)\n \t\t\t\t\tdiff_get_color_opt(&rev.diffopt, DIFF_COMMIT),\n \t\t\t\t\tt->tag,\n \t\t\t\t\tdiff_get_color_opt(&rev.diffopt, DIFF_RESET));\n-\t\t\tret = show_object(o->sha1, 1, &rev);\n+\t\t\tret = show_tag_object(o->sha1, &rev);\n \t\t\trev.shown_one = 1;\n \t\t\tif (ret)\n \t\t\t\tbreak;\ndiff --git a/t/t1050-large.sh b/t/t1050-large.sh\nindex f662fef..dd1bb84 100755\n--- a/t/t1050-large.sh\n+++ b/t/t1050-large.sh\n@@ -125,7 +125,7 @@ test_expect_success 'cat-file a large file from a tag' '\n \tgit cat-file blob largefiletag >/dev/null\n '\n \n-test_expect_failure 'git-show a large file' '\n+test_expect_success 'git-show a large file' '\n \tgit show :large1 >/dev/null\n \n '\n-- \n1.7.8.36.g69ee2\n"},{"id":"186302","messageId":"1331117661-19378-7-git-send-email-pclouds@gmail.com","threadId":"29851","inReplyTo":"1331117661-19378-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 6/7] fsck: use streaming API for writing lost-found blobs","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-03-07T10:54:20Z","receivedAt":"2012-03-07T10:54:20Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/fsck.c |    8 ++------\n 1 files changed, 2 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/fsck.c b/builtin/fsck.c\nindex 67eb553..a710227 100644\n--- a/builtin/fsck.c\n+++ b/builtin/fsck.c\n@@ -12,6 +12,7 @@\n #include \"parse-options.h\"\n #include \"dir.h\"\n #include \"progress.h\"\n+#include \"streaming.h\"\n \n #define REACHABLE 0x0001\n #define SEEN      0x0002\n@@ -238,13 +239,8 @@ static void check_unreachable_object(struct object *obj)\n \t\t\tif (!(f = fopen(filename, \"w\")))\n \t\t\t\tdie_errno(\"Could not open '%s'\", filename);\n \t\t\tif (obj->type == OBJ_BLOB) {\n-\t\t\t\tenum object_type type;\n-\t\t\t\tunsigned long size;\n-\t\t\t\tchar *buf = read_sha1_file(obj->sha1,\n-\t\t\t\t\t\t&type, &size);\n-\t\t\t\tif (buf && fwrite(buf, 1, size, f) != size)\n+\t\t\t\tif (stream_blob_to_fd(fileno(f), obj->sha1, NULL, 1))\n \t\t\t\t\tdie_errno(\"Could not write '%s'\", filename);\n-\t\t\t\tfree(buf);\n \t\t\t} else\n \t\t\t\tfprintf(f, \"%s\\n\", sha1_to_hex(obj->sha1));\n \t\t\tif (fclose(f))\n-- \n1.7.8.36.g69ee2\n"},{"id":"186303","messageId":"1331117661-19378-8-git-send-email-pclouds@gmail.com","threadId":"29851","inReplyTo":"1331117661-19378-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 7/7] update-server-info: respect core.bigfilethreshold","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2012-03-07T10:54:21Z","receivedAt":"2012-03-07T10:54:21Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This command indirectly calls check_sha1_signature() (add_info_ref ->\nderef_tag -> parse_object -> ..) , which may put whole blob in memory\nif the blob's size is under core.bigfilethreshold. As config is not\nread, the threshold is always 512MB. Respect user settings here.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/update-server-info.c |    1 +\n t/t1050-large.sh             |    2 +-\n 2 files changed, 2 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin/update-server-info.c b/builtin/update-server-info.c\nindex b90dce6..0d63c44 100644\n--- a/builtin/update-server-info.c\n+++ b/builtin/update-server-info.c\n@@ -15,6 +15,7 @@ int cmd_update_server_info(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tgit_config(git_default_config, NULL);\n \targc = parse_options(argc, argv, prefix, options,\n \t\t\t     update_server_info_usage, 0);\n \tif (argc > 0)\ndiff --git a/t/t1050-large.sh b/t/t1050-large.sh\nindex dd1bb84..4d127f1 100755\n--- a/t/t1050-large.sh\n+++ b/t/t1050-large.sh\n@@ -130,7 +130,7 @@ test_expect_success 'git-show a large file' '\n \n '\n \n-test_expect_failure 'repack' '\n+test_expect_success 'repack' '\n \tgit repack -ad\n '\n \n-- \n1.7.8.36.g69ee2\n"},{"id":"186320","messageId":"7vsjhknxku.fsf@alter.siamese.dyndns.org","threadId":"29851","inReplyTo":"1331117661-19378-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 0/7] nd/stream-more updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-03-07T17:13:37Z","receivedAt":"2012-03-07T17:13:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> As discussed, this series removes test_expect_failure that are still\n> not fixed in the end. It also adds update-server-info patch. I'll hold\n> off the rest of the previous series until 1.7.10 comes out.\n\nThanks; all look good.  Will queue and let's aim for 1.7.10-rc1 if\nnot earlier.\n"}]}