{"thread":{"id":"4128","subject":"git diff: support \"-U\" and \"--unified\" options properly","startedAt":"2006-05-13T20:23:48Z","lastAt":"2006-05-15T03:49:15Z","messageCount":21,"participants":["Linus Torvalds","Junio C Hamano","Martin Langhoff","Josef Weidendorfer"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"19890","messageId":"Pine.LNX.4.64.0605131317200.3866@g5.osdl.org","threadId":"4128","inReplyTo":null,"subject":"git diff: support \"-U\" and \"--unified\" options properly","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-05-13T20:23:48Z","receivedAt":"2006-05-13T20:23:48Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\nWe used to parse \"-U\" and \"--unified\" as part of the GIT_DIFF_OPTS \nenvironment variable, but strangely enough we would _not_ parse them as \npart of the normal diff command line (where we only accepted \"-u\").\n\nThis adds parsing of -U and --unified, both with an optional numeric \nargument. So now you can just say\n\n\tgit diff --unified=5\n\nto get a unified diff with a five-line context, instead of having to do \nsomething silly like\n\n\tGIT_DIFF_OPTS=\"--unified=5\" git diff -u\n\n(that silly format does continue to still work, of course).\n\nSigned-off-by: Linus Torvalds <torvalds@osdl.org>\n---\n\n[ Maybe this can still hit 1.3.3? ]\n\ndiff --git a/combine-diff.c b/combine-diff.c\nindex 8a8fe38..64b20cc 100644\n--- a/combine-diff.c\n+++ b/combine-diff.c\n@@ -608,6 +608,7 @@ static int show_patch_diff(struct combin\n \tint abbrev = opt->full_index ? 40 : DEFAULT_ABBREV;\n \tmmfile_t result_file;\n \n+\tcontext = opt->context;\n \t/* Read the result of merge first */\n \tif (!working_tree_file)\n \t\tresult = grab_blob(elem->sha1, &result_size);\ndiff --git a/diff.c b/diff.c\nindex 7a7b839..be925a3 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -558,7 +558,7 @@ static void builtin_diff(const char *nam\n \n \t\tecbdata.label_path = lbl;\n \t\txpp.flags = XDF_NEED_MINIMAL;\n-\t\txecfg.ctxlen = 3;\n+\t\txecfg.ctxlen = o->context;\n \t\txecfg.flags = XDL_EMIT_FUNCNAMES;\n \t\tif (!diffopts)\n \t\t\t;\n@@ -1182,6 +1182,7 @@ void diff_setup(struct diff_options *opt\n \toptions->line_termination = '\\n';\n \toptions->break_opt = -1;\n \toptions->rename_limit = -1;\n+\toptions->context = 3;\n \n \toptions->change = diff_change;\n \toptions->add_remove = diff_addremove;\n@@ -1222,11 +1223,60 @@ int diff_setup_done(struct diff_options \n \treturn 0;\n }\n \n+int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)\n+{\n+\tchar c, *eq;\n+\tint len;\n+\n+\tif (*arg != '-')\n+\t\treturn 0;\n+\tc = *++arg;\n+\tif (!c)\n+\t\treturn 0;\n+\tif (c == arg_short) {\n+\t\tc = *++arg;\n+\t\tif (!c)\n+\t\t\treturn 1;\n+\t\tif (val && isdigit(c)) {\n+\t\t\tchar *end;\n+\t\t\tint n = strtoul(arg, &end, 10);\n+\t\t\tif (*end)\n+\t\t\t\treturn 0;\n+\t\t\t*val = n;\n+\t\t\treturn 1;\n+\t\t}\n+\t\treturn 0;\n+\t}\n+\tif (c != '-')\n+\t\treturn 0;\n+\targ++;\n+\teq = strchr(arg, '=');\n+\tif (eq)\n+\t\tlen = eq - arg;\n+\telse\n+\t\tlen = strlen(arg);\n+\tif (!len || strncmp(arg, arg_long, len))\n+\t\treturn 0;\n+\tif (eq) {\n+\t\tint n;\n+\t\tchar *end;\n+\t\tif (!isdigit(*++eq))\n+\t\t\treturn 0;\n+\t\tn = strtoul(eq, &end, 10);\n+\t\tif (*end)\n+\t\t\treturn 0;\n+\t\t*val = n;\n+\t}\n+\treturn 1;\n+}\n+\n int diff_opt_parse(struct diff_options *options, const char **av, int ac)\n {\n \tconst char *arg = av[0];\n \tif (!strcmp(arg, \"-p\") || !strcmp(arg, \"-u\"))\n \t\toptions->output_format = DIFF_FORMAT_PATCH;\n+\telse if (opt_arg(arg, 'U', \"unified\", &options->context))\n+\t\toptions->output_format = DIFF_FORMAT_PATCH;\n \telse if (!strcmp(arg, \"--patch-with-raw\")) {\n \t\toptions->output_format = DIFF_FORMAT_PATCH;\n \t\toptions->with_raw = 1;\ndiff --git a/diff.h b/diff.h\nindex d052608..bef586d 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -32,6 +32,7 @@ struct diff_options {\n \t\t full_index:1,\n \t\t silent_on_remove:1,\n \t\t find_copies_harder:1;\n+\tint context;\n \tint break_opt;\n \tint detect_rename;\n \tint line_termination;\n"},{"id":"19891","messageId":"7v4pztu0p6.fsf@assigned-by-dhcp.cox.net","threadId":"4128","inReplyTo":"Pine.LNX.4.64.0605131317200.3866@g5.osdl.org","subject":"Re: git diff: support \"-U\" and \"--unified\" options properly","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-13T20:30:45Z","receivedAt":"2006-05-13T20:30:45Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> We used to parse \"-U\" and \"--unified\" as part of the GIT_DIFF_OPTS \n> environment variable, but strangely enough we would _not_ parse them as \n> part of the normal diff command line (where we only accepted \"-u\").\n>\n> This adds parsing of -U and --unified, both with an optional numeric \n> argument. So now you can just say\n>\n> \tgit diff --unified=5\n>\n> [ Maybe this can still hit 1.3.3? ]\n\nI think so.\n"},{"id":"19892","messageId":"7vzmhlsksm.fsf@assigned-by-dhcp.cox.net","threadId":"4128","inReplyTo":"Pine.LNX.4.64.0605131317200.3866@g5.osdl.org","subject":"Re: git diff: support \"-U\" and \"--unified\" options properly","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-13T20:59:37Z","receivedAt":"2006-05-13T20:59:37Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> [ Maybe this can still hit 1.3.3? ]\n\nAh, we did not pass the diffopt to the function builtin_diff() in\n1.3.X series, so not really.  We could forward port but I do not\nknow if it is worth the effort of backporting while stripping\nthe updates of the whole chain of diff generation from the post\n1.3.0 \"master\" work.  I have to think a bit.\n"},{"id":"19893","messageId":"Pine.LNX.4.64.0605131404391.3866@g5.osdl.org","threadId":"4128","inReplyTo":"7vzmhlsksm.fsf@assigned-by-dhcp.cox.net","subject":"Re: git diff: support \"-U\" and \"--unified\" options properly","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-05-13T21:05:33Z","receivedAt":"2006-05-13T21:05:33Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sat, 13 May 2006, Junio C Hamano wrote:\n>\n> Linus Torvalds <torvalds@osdl.org> writes:\n> \n> > [ Maybe this can still hit 1.3.3? ]\n> \n> Ah, we did not pass the diffopt to the function builtin_diff() in\n> 1.3.X series, so not really.\n\nAhh, ok. Never mind. It's not like people have been clamoring for it, it \njust seemed to be such a _silly_ thing.\n\nMight as well just go into the curren development tree, and then we'll \nhave it fixed eventually (1.4.0?)\n\n\t\tLinus\n"},{"id":"19895","messageId":"7vpsihsjq6.fsf@assigned-by-dhcp.cox.net","threadId":"4128","inReplyTo":"Pine.LNX.4.64.0605131404391.3866@g5.osdl.org","subject":"Re: git diff: support \"-U\" and \"--unified\" options properly","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-13T21:22:41Z","receivedAt":"2006-05-13T21:22:41Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> On Sat, 13 May 2006, Junio C Hamano wrote:\n>>\n>> Linus Torvalds <torvalds@osdl.org> writes:\n>> \n>> > [ Maybe this can still hit 1.3.3? ]\n>> \n>> Ah, we did not pass the diffopt to the function builtin_diff() in\n>> 1.3.X series, so not really.\n>\n> Ahh, ok. Never mind. It's not like people have been clamoring for it, it \n> just seemed to be such a _silly_ thing.\n>\n> Might as well just go into the curren development tree, and then we'll \n> have it fixed eventually (1.4.0?)\n\nNo question about that part.  I've been meaning to start drawing\nthe line of what to have in 1.4 and what to leave out, but the\nlast week was shot so I haven't got around to.\n\nA rough outline.\n\nI'd like to have the following topics from \"next\":\n\n * cvsserver and cvsexportcommit updates (ml/cvs)\n\n   Ready.\n\n * config syntax (lt/config)\n\n   Ready.\n\n * built-in grep (jc/grep)\n\n   Ready.\n\n * built-in format-patch (js/fmt-patch)\n\n   Some features are still missing compared to the script\n   version.\n\n * remotes/ information from .git/config (js/fetchconfig)\n\n   This by itself is more or less ready, but I would like to\n   further adjust it to the \"per branch configuration\"\n   discussion before pushing it out.\n\n   I'd like to eventually arrange things like this.\n\n   [branch \"master\"]\n\tremote = \"ko-private\"\n\t; prevent \"reset --hard\" from rewinding past this.\n        rewind-barrier = refs/heads/ko-master\n\n   ; my private build areas on the kernel.org machines\n   [remote \"ko-private\"]\n   \turl = \"x86-64-build.kernel.org:git\"\n   \turl = \"i386-build.kernel.org:git\"\n        push = master:origin\n        push = next:next\n        push = +pu:pu\n        push = maint:maint\n\n   ; for publishing and keeping track of what I pushed there last time\n   [remote \"ko\"]\n   \turl = \"kernel.org:/pub/scm/git/git.git\"\n        push = master:master\n        push = next:next\n        push = +pu:pu\n        push = maint:maint\n\tfetch = master:ko-master\n\tfetch = next:ko-next\n        fetch = +pu:ko-pu\n        fetch = maint:ko-maint\n"},{"id":"19897","messageId":"Pine.LNX.4.64.0605131518390.3866@g5.osdl.org","threadId":"4128","inReplyTo":"7vpsihsjq6.fsf@assigned-by-dhcp.cox.net","subject":"Re: git diff: support \"-U\" and \"--unified\" options properly","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-05-13T22:39:29Z","receivedAt":"2006-05-13T22:39:29Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sat, 13 May 2006, Junio C Hamano wrote:\n> \n>  * built-in grep (jc/grep)\n> \n>    Ready.\n\nI'm not entirely convinced.\n\nFor the kernel, I currently can do a \n\n\tgit grep some-random-string\n\nin about half a second.\n\nThe new built-in grep is about ten times slower.\n\nBefore:\n\n   [torvalds@g5 linux]$ /usr/bin/time git grep some-random-string\n   Command exited with non-zero status 123\n   0.29user 0.30system 0:00.52elapsed 113%CPU (0avgtext+0avgdata 0maxresident)k\n   0inputs+0outputs (0major+3206minor)pagefaults 0swaps\n\nAfter:\n\n   [torvalds@g5 linux]$ /usr/bin/time git grep some-random-string\n   Command exited with non-zero status 1\n   4.60user 0.33system 0:04.98elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k\n   0inputs+0outputs (0major+7369minor)pagefaults 0swaps\n\nand that \"half a second\" vs \"five seconds\" difference is really \nnoticeable.\n\nRight now I do \"git grep\" as a random \"ok, where was it\", and it works \nvery well, because it's basically instantaneous. And the difference \nbetween \"instantaneous\" and \"5 seconds\" is very big (the five seconds is \nalso long enough that the CPU fan comes on on my G5, which is my sign of \n\"too much work for the CPU\".\n\nI haven't looked at _why_ the builtin grep is ten times slower. I suspect \nit's just the regexp library being a lot slower than the external \noptimized grep, but it may also be just overhead (it looks, for example, \nlike the builtin grep does all matches just one line at a time. And it \nactually reads the file in, when mmap might be more efficient, I dunno). \n\nRegardless, it's a huge downer.\n\n\t\tLinus\n"},{"id":"19904","messageId":"46a038f90605140000p2b321c15vb09a6ce8830bffd3@mail.gmail.com","threadId":"4128","inReplyTo":"7vpsihsjq6.fsf@assigned-by-dhcp.cox.net","subject":"Re: git diff: support \"-U\" and \"--unified\" options properly","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2006-05-14T07:00:52Z","receivedAt":"2006-05-14T07:00:52Z","isPatch":false,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"On 5/14/06, Junio C Hamano <junkio@cox.net> wrote:\n> I'd like to have the following topics from \"next\":\n>\n>  * cvsserver and cvsexportcommit updates (ml/cvs)\n>\n>    Ready.\n\nYeah! What's the timeline for 1.4.0?\n\ncheers,\n\n\n\nmartin\n"},{"id":"19907","messageId":"200605141457.17314.Josef.Weidendorfer@gmx.de","threadId":"4128","inReplyTo":"7vpsihsjq6.fsf@assigned-by-dhcp.cox.net","subject":"Re: git diff: support \"-U\" and \"--unified\" options properly","fromName":"Josef Weidendorfer","fromEmail":"josef.weidendorfer@gmx.de","sentAt":"2006-05-14T12:57:17Z","receivedAt":"2006-05-14T12:57:17Z","isPatch":false,"sender":{"key":"josef.weidendorfer@gmx.de","avatar":null},"body":"On Saturday 13 May 2006 23:22, you wrote:\n>  * remotes/ information from .git/config (js/fetchconfig)\n> ...\n>    [branch \"master\"]\n> \tremote = \"ko-private\"\n\nWhy is this line needed? In this example, what is the relationship\nof local \"master\" with the remote? I think it is enough to specify\nthe local upstream branch:\n\n [branch \"master\"]\n    origin = \"ko-master\"\n\nFor the default pull action when on \"master\", we would have to look\nup for remotes with a fetch line fetching into \"ko-master\", which\ncould be cumbersome. Besides, the fetch lines specify default actions\nwhen fetching from a given remote, and there is no garantuee that we\nwant fetching into \"ko-master\" as any default action.\n\nSo we need\n\n [branch \"ko-master\"]\n    tracksremote = \"master of ko-private\"\n\nThis also would specify that we are not allowed to commit on \"ko-master\".\n\nIf we do not want to have a local tracking branch at all, we would have\n\n [branch \"master\"]\n    origin = \"master of ko-private\"\n\nor\n\n [branch \"master\"]\n    origin = \"master of kernel.org:/pub/scm/git/git.git\"\n\n\nFor a default push action when on master, I would add\n\n [branch \"master\"]\n    push = \"master of ko-private\"\n\nor alternatively\n\n [branch \"master\"]\n    push = \"master of kernel.org:/pub/scm/git/git.git\"\n\n> ...\n>    [remote \"ko\"]\n>    \turl = \"kernel.org:/pub/scm/git/git.git\"\n>       push = master:master\n> ...\n> \tfetch = master:ko-master\n\nThese specifications more or less are independent from the above,\nas it specifies the defaults when fetching/pushing to the specified remote.\n\nJosef\n\nPS: Patch pending...\n"},{"id":"19917","messageId":"7v7j4o33wc.fsf@assigned-by-dhcp.cox.net","threadId":"4128","inReplyTo":"200605141457.17314.Josef.Weidendorfer@gmx.de","subject":"Re: git diff: support \"-U\" and \"--unified\" options properly","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-14T17:36:03Z","receivedAt":"2006-05-14T17:36:03Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:\n\n> On Saturday 13 May 2006 23:22, you wrote:\n>>  * remotes/ information from .git/config (js/fetchconfig)\n>> ...\n>>    [branch \"master\"]\n>> \tremote = \"ko-private\"\n>\n> Why is this line needed? In this example, what is the relationship\n> of local \"master\" with the remote? I think it is enough to specify\n> the local upstream branch:\n>\n>  [branch \"master\"]\n>     origin = \"ko-master\"\n\nI confused you by not describing the flow. \n\nThere are four repositories involved:\n\n a. siamese:/git (my local development repo)\n b. x86-64.kernel.org:~/git (my kernel.org build repo)\n c. i386.kernel.org:~/git   (ditto but for i386)\n d. kernel.org:/pub/scm/git/git.git (public distribution point)\n\nThe workflow is:\n\n 1. maint/master/next/pu are prepared on a.\n\n 2. maint/master/next/pu are pushed to b. and c. as\n    maint/origin/next/pu.  b. and c. always have their \"master\"\n    checked out.\n\n 3. I go to b. and c., and \"pull . origin\" to start my build\n    there on all four branches.\n\n 4. When things go well, I come back to a.\n\n 5. Then maint/master/next/pu are pushed to d. without renaming.\n\n 6. To keep track of what have been pushed, maint/master/next/pu\n    from d. are fetched to a., with ko- prefixed.  There is no\n    \"when on this branch\" involved in this step.  Regardless of\n    which branch I currently on, the fetch goes fine.  I never\n    check out ko-* branches on a, nor merge from ko-* branches.\n\n 7. Go back to step 1 and start the next cycle.  ko-maint, ko-master\n    and ko-next reminds me not to rewind maint/master/next while I\n    shuffle the changes to discard botched commits beyond them.\n\n> So we need\n>\n>  [branch \"ko-master\"]\n>     tracksremote = \"master of ko-private\"\n>\n> This also would specify that we are not allowed to commit on \"ko-master\".\n\nFor my workflow, it is \"master of ko\"; your notation expresses\nthe same constraints more explicitly by being more special\npurpose: \"This tracks that one so never touch it any way other\nthan fetching into it\" (we may not even allow checking out\n\"ko-master\" -- I dunno).  \n\nOne issue you might want to think about is it is far more\nefficient to fetch multiple branches from the same git://... URL\nis than fetching them one by one.  The push has exactly the same\nproperty.\n\nAnother thing is the above talks only about constraints, and the\nuser has to go all over the config file to find \"xxx to\nko-private\" in order to figure out what happens when he says\n\"pull ko-private\".\n\n>> ...\n>>    [remote \"ko\"]\n>>    \turl = \"kernel.org:/pub/scm/git/git.git\"\n>>       push = master:master\n>> ...\n\n>> \tfetch = master:ko-master\n>\n\n> These specifications more or less are independent from the above,\n> as it specifies the defaults when fetching/pushing to the specified remote.\n\nNot really; and what you introduced can conflict with [remote]\nspecification.  If you have [branch \"ko-master\"] that says it\ntracks remote \"master\" from \"ko\" repository, your [remote \"ko\"]\nshould have not say \"fetch = foobla:ko-master\", so in that sense\nit is redundant and inviting later inconsistency.  The only\ninformation you added with \"tracksremote\" is the branch is used\nto track what is on remote (implying we'd better not touch it\nourselves), so I'd say this would make sense\n\n\t[branch \"ko-master\"]\n        \ttracksremote ; bool!\n\t[remote \"ko\"]\n        \turl = git://git.kernel.org/pub/scm/git/git.git\n        \tfetch = master:ko-master\n\nor alternatively this would:\n\n\t[branch \"ko-master\"]\n\t\ttracksremote = \"master of ko\"\n\t[remote \"ko\"]\n        \turl = git://git.kernel.org/pub/scm/git/git.git\n"},{"id":"19926","messageId":"200605142249.17508.Josef.Weidendorfer@gmx.de","threadId":"4128","inReplyTo":"7v7j4o33wc.fsf@assigned-by-dhcp.cox.net","subject":"Branch relationships (was:Re: git diff: support \"-U\" and \"--unified\" options properly)","fromName":"Josef Weidendorfer","fromEmail":"josef.weidendorfer@gmx.de","sentAt":"2006-05-14T20:49:17Z","receivedAt":"2006-05-14T20:49:17Z","isPatch":false,"sender":{"key":"josef.weidendorfer@gmx.de","avatar":null},"body":"On Sunday 14 May 2006 19:36, Junio C Hamano wrote:\n> Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:\n> \n> > On Saturday 13 May 2006 23:22, you wrote:\n> >>  * remotes/ information from .git/config (js/fetchconfig)\n> >> ...\n> >>    [branch \"master\"]\n> >> \tremote = \"ko-private\"\n\nI still do not understand the semantic of this line.\nIs this supposed to do \"git pull ko-private\" as default pull\naction and \"git push ko-private\" as default push?\n\nSo using\n\n>   ; my private build areas on the kernel.org machines\n>    [remote \"ko-private\"]\n>         url = \"x86-64-build.kernel.org:git\"\n>         url = \"i386-build.kernel.org:git\"\n>         push = master:origin\n> ...\n\nspecifies that \"git push\" should push to both URLs?\nThis is really confusing: Is the remote \"ko-private\" now at\n\"x86-64-build.kernel.org:git\" or at \"i386-build.kernel.org:git\" ?\n\nProbably its better to have\n  [branch \"master\"]\n    push-remote = \"ko-private-x86-64 ko-private-i386\"\nand entries for 2 remotes.\n\nNeverless, I missed the info \"Which branch should be merged in a default\npull after fetching the given branches from remote\". I understand that\nthis is not needed in your workflow, as you have no upstream.\n\n> >  [branch \"ko-master\"]\n> >     tracksremote = \"master of ko-private\"\n> >\n> > This also would specify that we are not allowed to commit on \"ko-master\".\n> \n> For my workflow, it is \"master of ko\"; your notation expresses\n> the same constraints more explicitly by being more special\n> purpose\n\nWhy is this more special purpose?\nIMHO the only difference is that your proposal puts this information into\nthe remote, and I am putting it to the branch as attribute.\n\nI chose it this way because I always thought that the Pull-lines in .git/remotes\nwhere only about giving a default fetch action, ie. they are optionally. But\neven if I do not want to have a remote branch fetched on default, I want to put\nthe information \"XXX of remote RRR is the upstream of local YYY\" into some place\nto be able to do a pull when on that branch. \n\n> : \"This tracks that one so never touch it any way other \n> than fetching into it\" (we may not even allow checking out\n> \"ko-master\" -- I dunno).  \n> \n> One issue you might want to think about is it is far more\n> efficient to fetch multiple branches from the same git://... URL\n> is than fetching them one by one.  The push has exactly the same\n> property.\n\nPerhaps an option \"when pulling into this branch from a remote, also fetch\nall branches tracked from this remote\", or another one \"when fetching/pulling\ninto this branch, update all other branches, too\".\n\n> Another thing is the above talks only about constraints, and the\n> user has to go all over the config file to find \"xxx to\n> ko-private\" in order to figure out what happens when he says\n> \"pull ko-private\".\n\nI wasn't intending to change the current semantics of the remote section,\nwhich specifies what to do when pulling/fetching/pushing from/into this\nremote.\n\nBut you are right; this could get inconsistent. Better find a way to\nnot be able to specify an inconsistent config in the first place.\n\nHowever, such an inconsistent config is already possible today:\n\n [remote \"r1\"]\n    fetch = master:master\n [remote \"r2\"]\n    fetch = master:master\n\nThis is not really better than\n\n [branch \"master\"]\n    tracksremote \"master of r1\"\n [remote \"r1\"]\n    fetch = \"notmaster:master\"\n\nWe already print out a warning when updating a branch tracking a remote\nis not a fast-forward.\nSo I would leave it as it is, and allow both ways.\n\nThis all would be mood if we use refs/remotes consequently: existance of\na branch \"refs/remotes/r1/master\" implicitly specifies that this is\na branch tracking a remote, where the remote is named \"r1\" and the\nremote branch is \"master\". \n\nWith\n\n [core]\n   useSeparateRemote ; bool\n\n [r1]\n   url = ...\n   fetch = master branch2 branch3\n\na \"git fetch r1\" would track given remote branches in \"remotes/r1/<branch>\",\nand a\n\n [branch \"master\"]\n   origin = \"remotes/r1/master\"\n\nwould work even without the \"fetch\" line in the remote section.\nHere, we can allow both ways without getting inconsistent, as we implicitly\nhave\n\n [branch \"remotes/r1/master\"]\n   tracksremote = \"master of r1\"\n\nRegarding syntax: Instead of the \"... of ...\" values I would prefer two keys\n\"remotebranch\"/\"remote\".\n\nJosef\n"},{"id":"19929","messageId":"7vr72w2thu.fsf@assigned-by-dhcp.cox.net","threadId":"4128","inReplyTo":"200605142249.17508.Josef.Weidendorfer@gmx.de","subject":"Re: Branch relationships","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-14T21:20:45Z","receivedAt":"2006-05-14T21:20:45Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:\n\n> On Sunday 14 May 2006 19:36, Junio C Hamano wrote:\n>> Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:\n>> \n>> > On Saturday 13 May 2006 23:22, you wrote:\n>> >>  * remotes/ information from .git/config (js/fetchconfig)\n>> >> ...\n>> >>    [branch \"master\"]\n>> >> \tremote = \"ko-private\"\n>\n> I still do not understand the semantic of this line.\n> Is this supposed to do \"git pull ko-private\" as default pull\n> action and \"git push ko-private\" as default push?\n>\n> So using\n>\n>>   ; my private build areas on the kernel.org machines\n>>    [remote \"ko-private\"]\n>>         url = \"x86-64-build.kernel.org:git\"\n>>         url = \"i386-build.kernel.org:git\"\n>>         push = master:origin\n>> ...\n>\n> specifies that \"git push\" should push to both URLs?\n\nExactly.  I would _want_ to push to both with single action when\nI say \"git push ko-private\".  Actually I have _never_ felt need\nto, but Linus wanted it first and I think it makes sense.\n\n> This is really confusing: Is the remote \"ko-private\" now at\n> \"x86-64-build.kernel.org:git\" or at \"i386-build.kernel.org:git\" ?\n\nNeither.\n\nPerhaps reading my comment on #git log from yesterday or so,\nwhere I talk about \".git/branches is about configuration\nper-local branches, and .git/remotes is about giving a\nshort-hand to remote repositories that are used often\",\nmight be helpful.  \n\n> Neverless, I missed the info \"Which branch should be merged in a default\n> pull after fetching the given branches from remote\". I understand that\n> this is not needed in your workflow, as you have no upstream.\n\nNot with git but in other projects I do.\n\nThat is what \"branch.foo.remote = this-remote\" is about.  When\nworking on foo branch, use what is described in\nremote.\"this-remote\" section for \"git pull\".\nremote.\"this-remote\" would have url and one or more fetch lines,\nand as usual the first fetch line would say \"merge this thing\".\nThis gives the continuity in semantics while migrating from\n.git/remotes/foo to [remote \"foo\"] section of the config file.\n\n>> >  [branch \"ko-master\"]\n>> >     tracksremote = \"master of ko-private\"\n>> >\n>> > This also would specify that we are not allowed to commit on \"ko-master\".\n>> \n>> For my workflow, it is \"master of ko\"; your notation expresses\n>> the same constraints more explicitly by being more special\n>> purpose\n>\n> Why is this more special purpose?\n\nIt is more special purpose than just saying \"do not touch this\nmyself\".  You are saying \"do not touch this myself because it\ntracks a remote\".  I do not think it is necessary to state the\nreason.\n\n> Perhaps an option \"when pulling into this branch from a remote, also fetch\n> all branches tracked from this remote\", or another one \"when fetching/pulling\n> into this branch, update all other branches, too\".\n\nYou already have \"when fetching from this remote, fetch all\nthese branches and store them in the tracking branches\", and\nthat is what .git/remotes/ is about.  The [remote] section in\nthe configuration file has the same semantics.  What problem are\nyou trying to fix by doing things differently?\n"},{"id":"19931","messageId":"200605150001.48548.Josef.Weidendorfer@gmx.de","threadId":"4128","inReplyTo":"7vr72w2thu.fsf@assigned-by-dhcp.cox.net","subject":"Re: Branch relationships","fromName":"Josef Weidendorfer","fromEmail":"josef.weidendorfer@gmx.de","sentAt":"2006-05-14T22:01:48Z","receivedAt":"2006-05-14T22:01:48Z","isPatch":false,"sender":{"key":"josef.weidendorfer@gmx.de","avatar":null},"body":"On Sunday 14 May 2006 23:20, Junio C Hamano wrote:\n> Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:\n> >>   ; my private build areas on the kernel.org machines\n> >>    [remote \"ko-private\"]\n> >>         url = \"x86-64-build.kernel.org:git\"\n> >>         url = \"i386-build.kernel.org:git\"\n> >>         push = master:origin\n> >> ...\n> >\n> > specifies that \"git push\" should push to both URLs?\n> \n> Exactly.  I would _want_ to push to both with single action when\n> I say \"git push ko-private\".  Actually I have _never_ felt need\n> to, but Linus wanted it first and I think it makes sense.\n\nHmmm. Isn't this a solution for a very special use-case?\nYou even can not specify different push lines for the 2 URLs.\nI think you want an alias name for a group of remotes here?\nWhy not\n\n [remotealias \"ko-private\"]\n   remote = \"ko-private-x86-64\"\n   remote = \"ko-private-i386\"\n\nNeverless, this wasn't the thing I was after.\n\n> That is what \"branch.foo.remote = this-remote\" is about.\n\nOK. Sorry, I somehow missed this.\n\n> When \n> working on foo branch, use what is described in\n> remote.\"this-remote\" section for \"git pull\".\n> remote.\"this-remote\" would have url and one or more fetch lines,\n> and as usual the first fetch line would say \"merge this thing\".\n> This gives the continuity in semantics while migrating from\n> .git/remotes/foo to [remote \"foo\"] section of the config file.\n\nThe only thing I wanted to discuss in this thread is exactly the\nlimitation of \"as usual the first fetch line...\" by the branch\nattribute \"origin\", which lead me to the alternative \"tracksremote\"\nattribute. Sorry about any confusion.\n\nI suppose \"branch.<branch name>.origin\" is still the way to go for\nspecifying the upstream?\n\nJosef\n"},{"id":"19933","messageId":"7v8xp4ntbf.fsf@assigned-by-dhcp.cox.net","threadId":"4128","inReplyTo":"200605150001.48548.Josef.Weidendorfer@gmx.de","subject":"Re: Branch relationships","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-14T22:19:00Z","receivedAt":"2006-05-14T22:19:00Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:\n\n>> Exactly.  I would _want_ to push to both with single action when\n>> I say \"git push ko-private\".  Actually I have _never_ felt need\n>> to, but Linus wanted it first and I think it makes sense.\n>\n> Hmmm. Isn't this a solution for a very special use-case?\n> You even can not specify different push lines for the 2 URLs.\n> I think you want an alias name for a group of remotes here?\n\nPerhaps.  \n\nThe \"push to multiple places\" is mostly for Linus backing things\nup, and I tend to agree that your \"alias\" notation makes things\nappear to be more general.  However, I do not think you would\nwant to push to two different places with different branch\nmappings, so I suspect that generality is not buying you much\nwhile making things more easily misconfigured.\n\n> I suppose \"branch.<branch name>.origin\" is still the way to go for\n> specifying the upstream?\n\nProbably \"origin\" is a better name for it; I was assuming\n\"branch.<branch name>.remote = foo\" refers to a [remote \"foo\"]\nsection and means \"when on this branch, pull from foo and merge\nfrom it\".\n"},{"id":"19934","messageId":"200605150104.46762.Josef.Weidendorfer@gmx.de","threadId":"4128","inReplyTo":"7v8xp4ntbf.fsf@assigned-by-dhcp.cox.net","subject":"Re: Branch relationships","fromName":"Josef Weidendorfer","fromEmail":"josef.weidendorfer@gmx.de","sentAt":"2006-05-14T23:04:46Z","receivedAt":"2006-05-14T23:04:46Z","isPatch":false,"sender":{"key":"josef.weidendorfer@gmx.de","avatar":null},"body":"On Monday 15 May 2006 00:19, you wrote:\n> > I suppose \"branch.<branch name>.origin\" is still the way to go for\n> > specifying the upstream?\n> \n> Probably \"origin\" is a better name for it; I was assuming\n> \"branch.<branch name>.remote = foo\" refers to a [remote \"foo\"]\n> section and means \"when on this branch, pull from foo and merge\n> from it\".\n\nMaybe.\n\nBut there is a misunderstanding. I wanted the branch attribute \"origin\"\nto specify the upstream _branch_, not a remote.\nAfter a \"git clone\", we would have\n\n [remote \"origin\"]\n   url = ...\n   fetch = master:origin\n\n [branch \"master\"]\n   origin = \"origin\" ; upstream of master is local branch \"origin\"\n\n [branch \"origin\"]\n   tracksremote ; bool\n\nNow adding a further development branch for remote branch \"topic\", we would add\n\n [remote \"origin\"]\n   ...\n   fetch = topic:tracking-topic\n\n [branch \"local-topic\"]\n   origin = \"tracking-topic\"\n\n [branch \"tracking-topic\"]\n   tracksremote\n\nNow, a \"git pull\" on branch \"local-topic\" does the right thing: it fetches\nfrom remote \"origin\", as \"tracking-topic\" is given in a refspec there, and merges\n\"tracking-topic\" to the current branch \"local-topic\", as given by the origin\nattribute.\n\nThis also extends to local upstreams: a \"git checkout -b topic2 master\" would\nappend\n\n [branch \"topic2\"]\n   origin = \"master\"\n\nand a \"git pull\" on topic2 would merge the upstream \"master\".\n\nJosef\n"},{"id":"19942","messageId":"7vslncyxez.fsf@assigned-by-dhcp.cox.net","threadId":"4128","inReplyTo":"200605150104.46762.Josef.Weidendorfer@gmx.de","subject":"Re: Branch relationships","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-14T23:55:00Z","receivedAt":"2006-05-14T23:55:00Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:\n\n> On Monday 15 May 2006 00:19, you wrote:\n>> > I suppose \"branch.<branch name>.origin\" is still the way to go for\n>> > specifying the upstream?\n>> \n>> Probably \"origin\" is a better name for it; I was assuming\n>> \"branch.<branch name>.remote = foo\" refers to a [remote \"foo\"]\n>> section and means \"when on this branch, pull from foo and merge\n>> from it\".\n>\n> Maybe.\n>\n> But there is a misunderstanding. I wanted the branch attribute \"origin\"\n> to specify the upstream _branch_, not a remote.\n>\n> After a \"git clone\", we would have\n>\n>  [remote \"origin\"]\n>    url = ...\n>    fetch = master:origin\n>\n>  [branch \"master\"]\n>    origin = \"origin\" ; upstream of master is local branch \"origin\"\n\nDoesn't that arrangement force people to use tracking branches?\nIOW, \"git pull somewhere that-head\" fetches that-head, without\nstoring it anywhere in the local repository as a tracking\nbranch, and immediately merges it to the current branch.\n"},{"id":"296150","messageId":"7vbqu0yvda.fsf@assigned-by-dhcp.cox.net","threadId":"4128","inReplyTo":"Pine.LNX.4.64.0605131518390.3866@g5.osdl.org","subject":"Re: git diff: support \"-U\" and \"--unified\" options properly","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-15T00:39:13Z","receivedAt":"2006-05-15T00:39:13Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> On Sat, 13 May 2006, Junio C Hamano wrote:\n>> \n>>  * built-in grep (jc/grep)\n>> \n>>    Ready.\n>\n> I'm not entirely convinced.\n\nI am not either after seeing your numbers and trying them\nmyself.  I was going to look at it myself over the weekend, but\nI ended up spending most of the time migrating my environment,\nso no progress on that front yet.  Sorry.\n\n\n"},{"id":"19946","messageId":"Pine.LNX.4.64.0605141745410.3866@g5.osdl.org","threadId":"4128","inReplyTo":"7vbqu0yvda.fsf@assigned-by-dhcp.cox.net","subject":"Re: git diff: support \"-U\" and \"--unified\" options properly","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-05-15T00:58:39Z","receivedAt":"2006-05-15T00:58:39Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 14 May 2006, Junio C Hamano wrote:\n> \n> I am not either after seeing your numbers and trying them\n> myself.  I was going to look at it myself over the weekend, but\n> I ended up spending most of the time migrating my environment,\n> so no progress on that front yet.  Sorry.\n\nI was looking at it, and I just suspect that \"grep\" is very optimized.\n\nAt the same time, the built-in one had many good features, notably that \nyou could grep the cached copy and from a specific version. So I think it \nmakes sense.\n\nI have this suspicion that the best solution is to just handle the \"grep \nagainst current tree\" separately, and even make that something that only \ngets enabled on UNIX - I assume that trying to execve() grep externally \nwould suck on windows again.\n\nSo I would actually assume that the solution is to simply make \ngrep_cache() have a simple\n\n\t#ifdef __unix__\n\t\tif (!cached) {\n\t\t\thit = external_grep(opt, paths, cached);\n\t\t\tif (hit >= 0)\n\t\t\t\treturn hit;\n\t\t}\n\t#endif\n\nat the top, so that we'd have the best of both worlds.\n\nThe \"external_grep()\" should look something like this:\n\n\t#define MAXARGS 1000\n\n\tstatic int external_grep(struct grep_opt *opt, const char **paths, int cached)\n\t{\n\t\tint nr;\n\t\tchar *argv[MAXARGS];\n\n\t\tread_cache();\n\t\targv[0] = \"grep\";\n\t\targv[1] = \"-e\";\n\t\targv[2] = opt->pattern;\t/* whatever */\n\t\targv[3] = \"--\";\n\t\targc = 4;\n\n\t\tfor (nr = 0; nr < active_nr; nr++) {\n\t\t\tstruct cache_entry *ce = active_cache[nr];\n\t\t\tif (ce_stage(ce) || !S_ISREG(ntohl(ce->ce_mode)))\n\t\t\t\tcontinue;\n\t\t\tif (!pathspec_matches(paths, ce->name))\n\t\t\t\tcontinue;\n\t\t\targv[argc++] = ce->name;\n\t\t\tif (argc < MAXARGS)\n\t\t\t\tcontinue;\n\t\t\thit += exec_grep(argv, argc);\n\t\t\targc = 4;\n\t\t}\n\t\tif (argc > 4)\n\t\t\thit += exec_grep(argv, argc);\n\t\treturn hit;\n\t}\n\nand you're all done. Except for testing, and fixing my stupid bugs, which \nI'm too lazy to do.\n\nThe whole \"exec_grep()\" should basically be the same as \"spawn_prog()\". \nYou get the idea.\n\nAnybody?\n\n\t\tLinus\n"},{"id":"19948","messageId":"200605150348.53879.Josef.Weidendorfer@gmx.de","threadId":"4128","inReplyTo":"7vslncyxez.fsf@assigned-by-dhcp.cox.net","subject":"Re: Branch relationships","fromName":"Josef Weidendorfer","fromEmail":"josef.weidendorfer@gmx.de","sentAt":"2006-05-15T01:48:53Z","receivedAt":"2006-05-15T01:48:53Z","isPatch":false,"sender":{"key":"josef.weidendorfer@gmx.de","avatar":null},"body":"On Monday 15 May 2006 01:55, you wrote:\n> > After a \"git clone\", we would have\n> >\n> >  [remote \"origin\"]\n> >    url = ...\n> >    fetch = master:origin\n> >\n> >  [branch \"master\"]\n> >    origin = \"origin\" ; upstream of master is local branch \"origin\"\n> \n> Doesn't that arrangement force people to use tracking branches?\n\nI think we already had the same discussion some time ago ;-)\nThis asks for support of a way to specify a remote origin branch\nwithout any local tracking, like\n  origin = \"<remotebranch> of <remote>\"\n\nBut not supporting this in a first step should be no problem, as\nyou always can do \"git pull somewhere that-head\" directly.\n\nA side-effect of the origin-arrangement would be that branching\noff a tracking branch would automatically update it on pull from\nthe new branch. I would see this as improvement of usability as\n\"generating a local development branch from a remote one\" does\nnot need any special command.\n"},{"id":"19950","messageId":"7v4pzsys0v.fsf@assigned-by-dhcp.cox.net","threadId":"4128","inReplyTo":"Pine.LNX.4.64.0605141745410.3866@g5.osdl.org","subject":"Re: git diff: support \"-U\" and \"--unified\" options properly","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-15T01:51:28Z","receivedAt":"2006-05-15T01:51:28Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> On Sun, 14 May 2006, Junio C Hamano wrote:\n>> \n>> I am not either after seeing your numbers and trying them\n>> myself.  I was going to look at it myself over the weekend, but\n>> I ended up spending most of the time migrating my environment,\n>> so no progress on that front yet.  Sorry.\n>\n> I was looking at it, and I just suspect that \"grep\" is very optimized.\n>\n> At the same time, the built-in one had many good features, notably that \n> you could grep the cached copy and from a specific version. So I think it \n> makes sense.\n> \n> ... Except for testing, and fixing my stupid bugs, which \n> I'm too lazy to do.\n\nThe command line flags needs to be\nunparsed before feeding the external grep.\n\n> The whole \"exec_grep()\" should basically be the same as \"spawn_prog()\". \n> You get the idea.\n>\n> Anybody?\n\nI think somebody wanted to have his own funky grep spawned off\nfrom his PATH, so I'd leave that to him (or her I do not\nremember which) ;-).\n"},{"id":"19951","messageId":"7vbqu0xcjk.fsf@assigned-by-dhcp.cox.net","threadId":"4128","inReplyTo":"200605150348.53879.Josef.Weidendorfer@gmx.de","subject":"Re: Branch relationships","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-15T02:11:11Z","receivedAt":"2006-05-15T02:11:11Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Josef Weidendorfer <Josef.Weidendorfer@gmx.de> writes:\n\n> But not supporting this in a first step should be no problem, as\n> you always can do \"git pull somewhere that-head\" directly.\n\nThat defeats the point of .git/remotes/ setup, and I suspect is\nunacceptable to people who pull from a given branch of a given\nrepository repeatedly without ever tracking it.  Think of the\nmaintainer pulling from subsystem maintainers.\n"},{"id":"19959","messageId":"Pine.LNX.4.64.0605142044550.3866@g5.osdl.org","threadId":"4128","inReplyTo":"Pine.LNX.4.64.0605141745410.3866@g5.osdl.org","subject":"Re: git diff: support \"-U\" and \"--unified\" options properly","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-05-15T03:49:15Z","receivedAt":"2006-05-15T03:49:15Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 14 May 2006, Linus Torvalds wrote:\n> \n> So I would actually assume that the solution is to simply make \n> grep_cache() have a simple\n> \n> \t#ifdef __unix__\n> \t\tif (!cached) {\n> \t\t\thit = external_grep(opt, paths, cached);\n> \t\t\tif (hit >= 0)\n> \t\t\t\treturn hit;\n> \t\t}\n> \t#endif\n> \n> at the top, so that we'd have the best of both worlds.\n\nOk. Here's a slightly tested version, my out-lined thing from the email \nwas pretty close to working already.\n\nIt's not perfect, but it gets the \"git grep some-random-string\" down to \nthe good old half-a-second range for the kernel.\n\nIt should convert more of the argument flags for \"grep\", that should be \ntrivial to expand (I did a few just as an example). It should also bother \nto try to return the right \"hit\" value (which it doesn't, right now - the \ncode is kind of there, but I didn't actually bother to do it _right_).\n\nAlso, right now it _just_ limits by number of arguments, but it should \nalso strictly speaking limit by total argument size (ie add up the length \nof the filenames, and do the \"exec_grep()\" flush call if it's bigger than \nsome random value like 32kB).\n\nBut I think that it's _conceptually_ doing all the right things, and it \nseems to work. So maybe somebody else can do some of the final polish.\n\n\t\tLinus\n\n----\ndiff --git a/builtin-grep.c b/builtin-grep.c\nindex fead356..14471db 100644\n--- a/builtin-grep.c\n+++ b/builtin-grep.c\n@@ -12,6 +12,7 @@ #include \"tree-walk.h\"\n #include \"builtin.h\"\n #include <regex.h>\n #include <fnmatch.h>\n+#include <sys/wait.h>\n \n /*\n  * git grep pathspecs are somewhat different from diff-tree pathspecs;\n@@ -409,12 +410,90 @@ static int grep_file(struct grep_opt *op\n \treturn i;\n }\n \n+static int exec_grep(int argc, const char **argv)\n+{\n+\tpid_t pid;\n+\tint status;\n+\n+\targv[argc] = NULL;\n+\tpid = fork();\n+\tif (pid < 0)\n+\t\treturn pid;\n+\tif (!pid) {\n+\t\texecvp(\"grep\", (char **) argv);\n+\t\texit(255);\n+\t}\n+\twhile (waitpid(pid, &status, 0) < 0) {\n+\t\tif (errno == EINTR)\n+\t\t\tcontinue;\n+\t\treturn -1;\n+\t}\n+\tif (WIFEXITED(status)) {\n+\t\tif (!WEXITSTATUS(status))\n+\t\t\treturn 1;\n+\t\treturn 0;\n+\t}\n+\treturn -1;\n+}\n+\n+#define MAXARGS 1000\n+\n+static int external_grep(struct grep_opt *opt, const char **paths, int cached)\n+{\n+\tint i, nr, argc, hit;\n+\tconst char *argv[MAXARGS+1];\n+\tstruct grep_pat *p;\n+\n+\tnr = 0;\n+\targv[nr++] = \"grep\";\n+\tif (opt->word_regexp)\n+\t\targv[nr++] = \"-w\";\n+\tif (opt->name_only)\n+\t\targv[nr++] = \"-l\";\n+\tfor (p = opt->pattern_list; p; p = p->next) {\n+\t\targv[nr++] = \"-e\";\n+\t\targv[nr++] = p->pattern;\n+\t}\n+\targv[nr++] = \"--\";\n+\n+\thit = 0;\n+\targc = nr;\n+\tfor (i = 0; i < active_nr; i++) {\n+\t\tstruct cache_entry *ce = active_cache[i];\n+\t\tif (ce_stage(ce) || !S_ISREG(ntohl(ce->ce_mode)))\n+\t\t\tcontinue;\n+\t\tif (!pathspec_matches(paths, ce->name))\n+\t\t\tcontinue;\n+\t\targv[argc++] = ce->name;\n+\t\tif (argc < MAXARGS)\n+\t\t\tcontinue;\n+\t\thit += exec_grep(argc, argv);\n+\t\targc = nr;\n+\t}\n+\tif (argc > nr)\n+\t\thit += exec_grep(argc, argv);\n+\treturn 0;\n+}\n+\n static int grep_cache(struct grep_opt *opt, const char **paths, int cached)\n {\n \tint hit = 0;\n \tint nr;\n \tread_cache();\n \n+#ifdef __unix__\n+\t/*\n+\t * Use the external \"grep\" command for the case where\n+\t * we grep through the checked-out files. It tends to\n+\t * be a lot more optimized\n+\t */\n+\tif (!cached) {\n+\t\thit = external_grep(opt, paths, cached);\n+\t\tif (hit >= 0)\n+\t\t\treturn hit;\n+\t}\n+#endif\n+\n \tfor (nr = 0; nr < active_nr; nr++) {\n \t\tstruct cache_entry *ce = active_cache[nr];\n \t\tif (ce_stage(ce) || !S_ISREG(ntohl(ce->ce_mode)))\n"}]}