{"thread":{"id":"3271","subject":"Two crazy proposals for changing git's diff commands","startedAt":"2006-02-09T00:29:44Z","lastAt":"2006-02-13T22:00:14Z","messageCount":30,"participants":["Carl Worth","Linus Torvalds","Junio C Hamano","Tim Larson","Petr Baudis","Mark Wooding","Kent Engstrom","J. Bruce Fields","kent@lysator.liu.se","Catalin Marinas"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"15751","messageId":"87slqtcr2f.wl%cworth@cworth.org","threadId":"3271","inReplyTo":null,"subject":"Two crazy proposals for changing git's diff commands","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2006-02-09T00:29:44Z","receivedAt":"2006-02-09T00:29:44Z","isPatch":false,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"So, here I am as a newly converted index-embracer---no more index\ndenying from me.\n\nHowever, I'm still trying to wrap my brain around the various diff\ncommands that git provides and how they would fit into my workflow,\nJunio and I have touched on this already in a previous thread, but I'm\nstarting here with more fresh and complete analysis of the UI around\ndiff.\n\nThe motivation for the *long* (my apologies) message below is largely\nthe fact that I realized my workflow would use the following command\nvery regularly:\n\n\tgit diff-index --cached HEAD\n\nI would be using this before every \"got commit\" to get a preview, and\nit seems like a painfully long name for such a common operation. Even\nits shortcut form:\n\n\tgit diff --cached HEAD\n\nis among the longest of the \"git diff\" shortcuts.\n\nMy other motivation is that in spite of having what I think is a\nfairly good grasp of the structure of git, (the object database, the\nindex, etc.), I still have one heck of a time trying to remember which\ndiff commands are which.\n\nSo here we go...\n\nBackground\n==========\nAt a conceptual level, there are 4 diff operations each of which acts\non an ordered pair (from->to) of trees. One operation takes two\nexplicit tree objects, while the other three act on 0 or 1 explicit\ntrees and 2 or 1 implicit trees (based on either the index or files in\nthe working directory). Specifically, these are tree->index,\nindex->files, and the composite of the two, tree->files.\n\nTo get at these 4 different operations, git provides 4 commands named\ndiff-tree, diff-index --cached, diff-files, and diff-index. On top of\nthese, git also provides some syntactic sugar in the form of \"diff\"\nshortcuts for a total of 8 different diff commands.\n\nThis is all summarized in the following table:\n\nOperation (from -> to)\tCore command\t\t\tShortcut command\n-----------------------\t------------\t\t\t---------------\ndiff <treeA> -> <treeB>\tdiff-tree <treeA> <treeB>\tdiff <treeA> <treeB>\ndiff <tree>  -> index\tdiff-index --cached <tree>\tdiff --cached <tree>\ndiff index   -> files\tdiff-files\t\t\tdiff\ndiff <tree>  -> files\tdiff-index <tree>\t\tdiff <tree>\n\nI think this background is fairly complete, at least as far as the\nfunctionality exposed by git-diff goes---I am ignoring git-diff-stages\nfor now, and throughout the remainder of this message.\n\nUse cases\n=========\nAfter understanding things that far, I asked myself what each of the\nfour operations are useful for. The tree->tree case is easiest as it\nsimply shows the difference between two trees that exist in the object\nstore.\n\nThe remaining three cases are more interesting because they provide\nmechanisms for querying trees that don't yet (or may never) exist in\nthe object store. Here are the questions I have been able to come up\nwith so far that the operations can help in answering:\n\n<treeA> -> <treeB> (diff-tree <treeA> <treeB>, or diff <treeA> <treeB>)\n  What changed between two trees?\n\n<tree> -> index (diff-index --cached <tree>, diff --cached <tree>)\n  When <tree> is HEAD: What will \"git commit\" do?\n\nindex -> files (diff-files, diff)\n  What work have I done that I haven't updated into the index yet?\n  Or, if not manually updating the index: What will \"git commit -a\" do?\n\n<tree> -> files (diff-index <tree>, diff <tree>)\n  When <tree> is HEAD: What will \"git commit -a\" do?\n\nCan anyone else think of common use cases for these various\noperations that I've missed?\n\nSubjective comments/proposals\n=============================\nEverything above should be pretty much objective descriptions of how\nthings exist. From here on out, I'll start in with my opinions and\nhopefully some useful proposals, (ordered by increasing likelihood of\nbeing controversial).\n\nIt's interesting to me that both variants of diff-index (with and\nwithout --cached) require a tree argument, while at the same time,\nboth variants seem most useful when used with HEAD. So it looks like\nthere's a reasonable default value for that option that is\nmissing. This should be pretty painless to fix, (no user retraining\nrequired):\n\n\tProposal 1: Make diff-index use HEAD if no <tree> is specified\n\n\tWith this proposal, my most-common command now shrinks to:\n\n\t\tgit diff-index --cached\n\n\t(And I was quite surprised to just learn that the shortcut\n\tversion of \"git diff --cached\" already does default to HEAD\n\trather than calling git-diff-files and erroring out on the\n\tunknown --cached argument. That's handy, even if a bit\n\tunexpected from the documentation of \"git diff\".)\n\nSo, my common command is a bit shorter, but I'd like to shrink it\nmore, and I still haven't addressed my which-diff-command-do-I-want\nconfusion.\n\nFirst, I see a potential problem in the use cases table above. The\n\"git diff\" command is taught in the tutorial as a way to preview what\nwill be committed by \"commit -a\". But I think this lays a trap for git\nnewcomers.\n\nIf \"git diff\" is learned as a commit preview, (during a larval\nindex-unaware stage), then this behavior will have to be unlearned\nwhen the user starts using the index. At that point \"git diff\" becomes\na way to examine what will *not* be committed by \"git commit\" rather\nthan what *will* be committed by \"git commit -a\".\n\nThis seems an unkind thing to do to new users. Instead, users of\n\"commit -a\" should be provided with a HEAD->files diff operation for\npreviewing commits. That's what they really want to see, (and not the\nindex->files diff that only happens to match in the case they haven't\nmanually dirtied the index).\n\nSo the 'correct' preview command for \"commit -a\" is currently one of\n\"diff HEAD\" or \"diff-index HEAD\", and under Proposal 1 it would be\n\"diff-index\".\n\nSo, without using the shortcut version, the tutorial's preview command\nis down to a single name \"diff-index\", but it is rather awkward to\nhave a \"-index\" command in the index-avoidance stage of the tutorials.\n\nAnd I think this goes toward my which-diff confusion. Consider the\nthree diff operations that allow for investigating un-committed trees:\n\n\t<tree>  -> index\tdiff-index --cached <tree>\n\tindex   -> files\tdiff-files\n\t<tree>  -> files\tdiff-index <tree>\n\nHere, \"diff-index\" is the only one of the three commands that does not\noperate on the index. One can notice a similar thing in the ASCII\ndiagram from the core tutorial where diff-index is the only one of\nthese three operations that completely bypasses the index (!).\n\nAll that just to say that there's some inconsistent naming in the core\ncommands. This is papered over somewhat by the \"git diff\" shortcuts\nbut at the same time that also adds even _more_ diff commands for\npeople like me to have to learn.\n\nSo, here, finally is a proposal to change the names of some diff\ncommands. I expect this to be more controversial than proposal #1 as\nit is sure to run up against ingrained muscle memory in some cases.\nBut I've tried to minimize that as much as possible, and I hope it\nwill be workable.\n\n\tProposal #2: Provide the following 4 diff commands:\n\nOperation (from -> to)\tProposal\t\t\t   \t\n-----------------------\t--------\t\t\t   \t\ndiff <treeA> -> <treeB>\tdiff <treeA> <treeA>\t\t   \t\ndiff <tree>  -> index\tdiff-index <tree> (default to HEAD)\t\ndiff index   -> files\tdiff\t\t\t\t   \t\ndiff <tree>  -> files\tdiff-files <tree> (default to HEAD)\t\n\nThe goal here is that using diff, diff-index, and diff-files without\nany tree argument and without any options (such as --cached) should\ncover the most common cases. So there's less typing in general.\n\nThese 3 diff commands can be presented as fundamental, and usable\nwithout needing a layer of sugar above. So there is already less to\nlearn.n\n\nAlso, diff-index and diff-files have parallel structure and naming,\neach performing a diff from HEAD or the given tree to either the\ncurrent index or files, respectively. So the names should also be\neasier to learn.\n\nUnder this proposal, my \"git commit\" preview becomes:\n\n\tgit diff-index\n\nand the tutorial's \"git commit -a\" preview becomes:\n\n\tgit diff-files\n\nwhich looks pretty nice to me [*].\n\nLet's examine the impact this proposal would have on the existing core\nand shortcut diff commands. Here's an explanation of the Notes column\nentries below:\n\n\"no change\":\tThe existing command is provided in an identical form\n\t\tunder the proposal.\n\n\"compatible\":\tThe existing command will continue to function\n\t\tidentically for backwards compatibility with muscle\n\t\tmemory. But some things (such as --cached options)\n\t\twill simply be ignored and \"unadvertised\" under the\n\t\tnew proposal\n\nincompatible[*]:The proposal is not compatible with existing usage, so\n\t\tsome amount of retraining will be needed. In each\n\t\tcase, I've made notes on ways that might make this\n\t\tbearable.\n\nCurrent core command\t    After proposal\t  Notes\n--------------------\t    --------------\t  -----\ndiff-tree <treeA> <treeB>   diff <treeA> <treeB>  compatible\ndiff-index --cached <tree>  diff-index <tree>\t  compatible\ndiff-files\t\t    diff\t\t  incompatible[1]\ndiff-index <tree>\t    diff-files <tree>\t  incompatible[2]\n\n[1] Existing \"diff-files\" is index->files while the proposed\n\"diff-files\" would be HEAD->files. Fortunately the retraining here is\nto a simpler command (\"diff\") which already exists. Hopefully, current\nusers already prefer the simpler command anyway.\n\n[2] Existing \"diff-index <tree>\" is <tree>->files while the proposed\n\"diff-index <tree>\" would be <tree>->index. Fortunately the existing\n\"diff-index <tree>\" has an existing shortcut as \"diff <tree>\" which\ncan be maintained compatibly. So hopefully, current users already\nprefer the simpler command anyway. Otherwise, retraining for this\ncommand will involves an index->files substitution, but hopefully the\nconsistent naming under the new proposal will help here.\n\nCurrent shortcut command    After proposal\t  Notes\n------------------------    --------------\t  -----\ndiff <treeA> <treeB>\t    diff <treeA> <treeB>  no change\ndiff --cached <tree>\t    diff-index <tree>\t  compatible [3]\t\t\ndiff\t\t\t    diff\t\t  no change\ndiff <tree>\t\t    diff-files <tree>\t  compatible [3]\n\n[3] The proposal doesn't recommend any version of \"git diff\" with a\nsingle <tree> argument. Fortunately we can continue to provide\ncompatible support for both such existing uses since they differ based\non the presence or absence of the --cached option.\n\nAnyway, that's a proposal for some diff commands if we had the\nopportunity to do it from scratch. I'm not a trained user of git that\nwould be impacted by this change, so I can't make any fair comment on\nwhether the change would be worth making or not. But I would\ndefinitely be interested in hearing what existing users of git think\nof the idea.\n\nAnd of course, I am glad to fix up the implementation and all the\ndocumentation as necessary to implement this proposal if people think\nit's a good idea.\n\n-Carl\n\n[*] It's not the original topic of this post, but now that I've\nfinished this, I realize that if the diff proposal were implemented\nthen \"commit-files\" would make a dandy replacement for \"commit\n-a\". That could lead to finally providing the parallel preview\ncommands I originally wanted:\n\n\tgit diff-index\t# as preview for\n\tgit commit-index\nand:\n\tgit diff-files\t# as preview for\n\tgit commit-files\n\nThen \"git commit\" would just be a shortcut for git commit-index.\n\n(Oh, and that would also lead to a natural \"git ci\" abbreviation too,\nif desired. This would parallel the \"ci == checkin\" abbreviation that\nsome other systems provide.)\n\nI think the separate notions of commit-index and commit-files would do\na good job of allowing for simple tutorials, (eliminates the \"what the\nheck is -a all about?\" questions), that also don't contribute to\ngeneral index-unawareness lead to later index-confusion as the current\n\"git diff; git commit -a\" does.\n\nThis might even lead to a natural distinction between \"git\nstatus-index\" and \"git status files\" too.\n"},{"id":"15754","messageId":"Pine.LNX.4.64.0602081643570.2458@g5.osdl.org","threadId":"3271","inReplyTo":"87slqtcr2f.wl%cworth@cworth.org","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-02-09T01:05:14Z","receivedAt":"2006-02-09T01:05:14Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 8 Feb 2006, Carl Worth wrote:\n> \n> I would be using this before every \"got commit\" to get a preview, and\n> it seems like a painfully long name for such a common operation. Even\n> its shortcut form:\n> \n> \tgit diff --cached HEAD\n> \n> is among the longest of the \"git diff\" shortcuts.\n\n[ snip snip ]\n\nYeah, I agree. The \"git diff\" semantics are incomplete, and the choices \nmay not be (aka \"almost certainly aren't\") the best. The recent \"git show\" \nactually came from a very common use (well, for me, at least) for \n\"git-diff-tree\" that the \"git diff\" command simply didn't support.\n\nI don't think it's really worth changing the low-level command naming: \nnopefully few enough people use them that it doesn't matter, but that's \nalso what scripts out there are likely to have, so the pain factor when \nsomething breaks is high enough.\n\nBut making \"git diff\" itself more often \"Do The Right Thing(tm)\" would \nprobably be a good idea.\n\nIn particular, I think the real culprit is the plain \"git diff\" with no \narguments at all. Right now it ends up showing just a piece of the \npicture, and the piece it shows is incomplete enough to be irritating.\n\nSo I would prefer a slightly different fix from yours: instead of changing \nthe core commands (which hopefully people mainly use in scripts where \nstability is more important than \"intuitive and easy defaults\"), how about \n_just_ changing the meaning of \"git diff\"?\n\nRight now a plain \"git diff\" only shows the differences in the current \ntree against the index. I think that was just the wrong choice. I think \nalmost everybody would actually prefer the default to be to show the \ndifference against HEAD.\n\nThe largest reason for why \"git diff\" defaults to diffing against the \nindex (and not head) is _literally_ that it's faster. Yes, I'm ashamed, \nbut \"git diff HEAD\" takes 0.35 seconds for me, and \"git diff\" takes 0.07\nseconds, and largely based entirely on that (and not \"what would users \nwant\"), I made the bad choice to default to git-diff-files for the \"no \narguments\" case.\n\nI hang my head in shame. I just like the _instantness_ of \"nothing \nchanged\". That's a bad reason for choice of interfaces, though.\n\nOne option is to realize that \"git status\" is actually a much better thing \nto use (because it shows _both_ the \"HEAD to index\" _and_ \"index to \ncurrent tree\" format).\n\nTeaching \"git status\" to take a \"-p\" flag (for \"patch\" - or -v for \n\"verbose\") might actually be a good thing. Then, instead of \"git diff\", \nyou'd use \"git status -p\" and it would show you what the differences are \nin the index, and what they are in the tree, so you'd _really_ know what \n\"git commit\" in all its glory would do.\n\n\t\tLinus\n"},{"id":"15755","messageId":"7vfymtl43b.fsf@assigned-by-dhcp.cox.net","threadId":"3271","inReplyTo":"87slqtcr2f.wl%cworth@cworth.org","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-02-09T01:21:12Z","receivedAt":"2006-02-09T01:21:12Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Carl Worth <cworth@cworth.org> writes:\n\n> Can anyone else think of common use cases for these various\n> operations that I've missed?\n\nIf there is none, then that means we have covered everything.\nBut a more interesting question to ask is \"are there useful\ncomparisons that the existing diff lowlevel does not give me\nwith a single command\".  And the answer is of course yes.\n\nFor example, you cannot preview \"git commit --include paths...\"\nwith a single low-level command.  You would need to run\n\"git-diff-index --cached HEAD\" for paths that are _not_\nspecified, and \"git-diff-index HEAD\" output for paths that you\nwill give to \"--include\" when you make that commit.\n\n> \tProposal 1: Make diff-index use HEAD if no <tree> is specified\n\nNo need.  \"git diff --cached\" does it, as you discovered.  I am\nopen to update the lowlevel if there is a need, but this does\nnot justify it.\n\n> If \"git diff\" is learned as a commit preview, (during a larval\n> index-unaware stage), then this behavior will have to be unlearned\n> when the user starts using the index. At that point \"git diff\" becomes\n> a way to examine what will *not* be committed by \"git commit\" rather\n> than what *will* be committed by \"git commit -a\".\n\nOf course, learning various flags to give \"git diff\" is part of\nunderstanding the index, so if the user understands index, \"git\ndiff\" without arguments will _not_ be the only diff command the\nuser uses for a preview.  And I suspect that depending on what\ndevelopment style you would use, the definition of \"useful\ncomparisons\" would be different.\n\nYou are assuming that the user graduated from \"larval unaware\"\nin this part of the discussion, no?\n\n> And I think this goes toward my which-diff confusion. Consider the\n> three diff operations that allow for investigating un-committed trees:\n>\n> \t<tree>  -> index\tdiff-index --cached <tree>\n> \tindex   -> files\tdiff-files\n> \t<tree>  -> files\tdiff-index <tree>\n>\n> Here, \"diff-index\" is the only one of the three commands that does not\n> operate on the index. One can notice a similar thing in the ASCII\n> diagram from the core tutorial where diff-index is the only one of\n> these three operations that completely bypasses the index (!).\n\nBy the way, diff-index without --cached *does* use index.\nUnindexed paths are not shown.  All this means that there is\nstill inconsistent understanding on your part.\n\n> \tProposal #2: Provide the following 4 diff commands:\n\nForget about renaming the core-level commands.  This is\nUNNEGOTIABLE, at least with something like the reasoning\npresented in your message.  You need to have something stronger\nthan that.\n\nI'm VERY open to give friendlier interface to 'git-diff'\nwrapper, though.  And I appreciate that part of your discussion\nvery much.  The end users, once the improvement proposal like\nyours is done right, should NOT need to use the lowlevel diff\ncommand directly AT ALL, so renaming low-level serves no useful\npurpose other than confusing Porcelain people and me.\n\n> The goal here is that using diff, diff-index, and diff-files without\n> any tree argument and without any options (such as --cached) should\n> cover the most common cases. So there's less typing in general.\n\nNo, the goal should be for normal workflows there should be *no*\nneed to use lowlevel commands by end users day-to-day.  Myself,\nI have not typed lowlevel commands from the command line for\nquite a long time, except when I am debugging, and except when I\nwanted to see \"diff-tree --cc\" output for a single commit, only\nbecause there was no suitable wrapper.  The last reason is now\ngone thanks to \"git-show\" Linus added.  So as far as *MY*\nworkflow is concerned, that goal has already been achieved.\n\nI am not saying there is something wrong with your workflow --\nthe tool may still not give an easier way to get a diff you\nwould want in your workflow.  I've given one example already\nabout the --include commit preview.  So let's concentrate on\nthis question:\n\n\tWhat are the useful workflows, in which during various\n\tphases of that workflow, existing \"git diff\" wrapper\n\tdoes not give us a useful comparison?\n\nThen we can fill what is lacking.  During the course of this\nexercise, it _might_ turn out that the low-level may need to be\nupdated to make generation of such an output easier and/or more\nefficient, but first we need know what we want to add to the end\nresult.  Mucking with the machinery to generate output must come\nafter that.\n\nWhile I suspect what people would want most would be commit\npreviews, I purposely said \"useful comparison\" instead of\n\"commit preview\" in the above.  Reviewing a conflicted merge\nwith \"git diff\" falls into \"useful comparison but not commit\npreview\" category.\n\nCommit preview alone is rather easy.  No matter how your worklow\nis (one extreme being no update-index until you are ready to\ncommit, and say \"git commit -a\" to commit everything --- the\nother extreme being frequent update-index between commit, even\nmultiple update-index on the same paths, and do \"git commit\n--include paths...\"), there are only four ways to make commits:\n\n\t$ git commit\n        => git diff --cached\n\n\t$ git commit -a\n        => git diff HEAD\n\n        $ git commit --only paths...\n\t=> git diff HEAD paths...\n\n\t$ git commit --include paths...\n\t... there is no support in \"git diff\"; it cannot be done\n        ... with a single low-level.\n\nSo we could even implement that with\n\n\t$ git commit --preview [other flags] [paths...]\n\nand three quarters of necessary things are already there.\nThere are obvious two other alternatives:\n\n\t$ git commit-preview [commit flags and paths...]\n\t$ git diff --preview [commit flags and paths...]\n"},{"id":"15756","messageId":"Pine.LNX.4.64.0602081719250.2458@g5.osdl.org","threadId":"3271","inReplyTo":"Pine.LNX.4.64.0602081643570.2458@g5.osdl.org","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-02-09T01:21:49Z","receivedAt":"2006-02-09T01:21:49Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 8 Feb 2006, Linus Torvalds wrote:\n> \n> The largest reason for why \"git diff\" defaults to diffing against the \n> index (and not head) is _literally_ that it's faster. Yes, I'm ashamed, \n> but \"git diff HEAD\" takes 0.35 seconds for me, and \"git diff\" takes 0.07\n> seconds, and largely based entirely on that (and not \"what would users \n> want\"), I made the bad choice to default to git-diff-files for the \"no \n> arguments\" case.\n> \n> I hang my head in shame. I just like the _instantness_ of \"nothing \n> changed\". That's a bad reason for choice of interfaces, though.\n\nBtw, it was kind of luck (but it's definitely true) that the current \"git \ndiff\" semantics happen to also be what you do want during merges when you \ntry to resolve a conflict (while \"git diff HEAD\" is much less useful).\n\nSo making \"git diff\" default to diffing against HEAD is actually the wrong \nthing to do during merging, where the current behaviour is exactly what \nyou'd want.\n\nSo I dunno. \n\n\t\tLinus\n"},{"id":"15757","messageId":"Pine.LNX.4.64.0602081726390.2458@g5.osdl.org","threadId":"3271","inReplyTo":"7vfymtl43b.fsf@assigned-by-dhcp.cox.net","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-02-09T01:30:56Z","receivedAt":"2006-02-09T01:30:56Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 8 Feb 2006, Junio C Hamano wrote:\n> \n> So we could even implement that with\n> \n> \t$ git commit --preview [other flags] [paths...]\n\nMy argument for \"git status\" was that it very much _is_ about \"what would \nI commit\". So I'd much rather extend on \"git status\" than add a \n\"--preview\" flag to \"git commit\".\n\nAt least to me, \"git status\" is very much a \"what is pending\" kind of \ncommand. The fact that you can't con it into giving a diff is actually a \ndownside: I would at times have preferred to have the \"git commit\" message \ncontain an extended status that contained the diffs too.\n\nAnother way of saying that: I think it would make sense to have a verbose \nstatus report, and maybe also have that verbose flag passed into \"git \ncommit\" so that you can see the verbose status when you edit the commit \nmessage.\n\nUnder that logic, \"git status -v\" would show all the diffs (not just \nfilenames) and \"git commit -v ..\" would be the same as \"git commit ..\" but \nthe \"-v\" flag would have been passed down to the \"git status\" call, so the \ncommit message file would be pre-populated with the diff.\n\nFor small commits, it's actually nice to see the diff itself as you write \nthe commit message.\n\n\t\tLinus\n"},{"id":"15758","messageId":"7v3bitl3ey.fsf@assigned-by-dhcp.cox.net","threadId":"3271","inReplyTo":"Pine.LNX.4.64.0602081643570.2458@g5.osdl.org","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-02-09T01:35:49Z","receivedAt":"2006-02-09T01:35:49Z","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> In particular, I think the real culprit is the plain \"git diff\" with no \n> arguments at all. Right now it ends up showing just a piece of the \n> picture, and the piece it shows is incomplete enough to be irritating.\n\nNot necessarily.  Your \"during the merge\" example is a good one,\nand \"so far it looks good and I do not want to see these diffs\nwhile modifying things further -- update-index it!\" workflow\nbenefits immensely from it.\n\n> Right now a plain \"git diff\" only shows the differences in the current \n> tree against the index. I think that was just the wrong choice. I think \n> almost everybody would actually prefer the default to be to show the \n> difference against HEAD.\n\nI somehow suspect this is welding training wheels to your\nbicycle.\n\n> Teaching \"git status\" to take a \"-p\" flag (for \"patch\" - or -v for \n> \"verbose\") might actually be a good thing. Then, instead of \"git diff\", \n> you'd use \"git status -p\" and it would show you what the differences are \n> in the index, and what they are in the tree, so you'd _really_ know what \n> \"git commit\" in all its glory would do.\n\nI think this may not be a bad idea.\n\nWhat we could do is this:\n\n\t$ git status -v [--only | --include] [paths...]\n\nWhen -v is given, it takes the same parameter as \"git commit\",\nand changes its output format from the usual N x \"# useful info lines\"\nto something like:\n\n\t---\n        diff ...\n        --- a/path\n        +++ b/path\n        @@ -N,M +L,K @@\n\nthat shows the commit preview.  At the same time we change \"git\ncommit\" commit log message reader to stop reading the input at\nthe first '---' line, just like we do for e-mailed patches.\n\nThen:\n\n - If you want a commit preview _before_ initiating a commit,\n   you can say:\n\n\t$ git status -v [whatever you planned to give git commit]\n\n - If you want a commit preview _while_ writing the commit log, you can\n   say:\n\n\t$ git commit -v [whatever your parameters are]\n\n   which internally would pass the -v and \"$@\" to git status\n   that seeds the log message\n\n\n - If you want a commit preview after you made a commit, it is\n   too late ;-).\n"},{"id":"15759","messageId":"7vy80ljorh.fsf@assigned-by-dhcp.cox.net","threadId":"3271","inReplyTo":"Pine.LNX.4.64.0602081726390.2458@g5.osdl.org","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-02-09T01:37:38Z","receivedAt":"2006-02-09T01:37:38Z","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 Wed, 8 Feb 2006, Junio C Hamano wrote:\n>> \n>> So we could even implement that with\n>> \n>> \t$ git commit --preview [other flags] [paths...]\n>\n> My argument for \"git status\" was that it very much _is_ about \"what would \n> I commit\". So I'd much rather extend on \"git status\" than add a \n> \"--preview\" flag to \"git commit\".\n\nOur messages crossed.  I'd agree about the reasoning completely,\nas I did in my previous message.\n\nNow we need to find a volunteer to do all that work ;-).\n"},{"id":"15791","messageId":"20060209164420.GD14116@localhost","threadId":"3271","inReplyTo":"87slqtcr2f.wl%cworth@cworth.org","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Tim Larson","fromEmail":"tim@keow.org","sentAt":"2006-02-09T16:44:20Z","receivedAt":"2006-02-09T16:44:20Z","isPatch":false,"sender":{"key":"tim@keow.org","avatar":null},"body":"Reading bits an pieces of your email gives an idea:\n[...given at the end of this email]\nOn Wed, Feb 08, 2006 at 04:29:44PM -0800, Carl Worth wrote:\n> So, here I am as a newly converted index-embracer---no more index\n> denying from me.\n> \n> However, I'm still trying to wrap my brain around the various diff\n> commands that git provides and how they would fit into my workflow,\n> Junio and I have touched on this already in a previous thread, but I'm\n> starting here with more fresh and complete analysis of the UI around\n> diff.\n...\n> [*] It's not the original topic of this post, but now that I've\n> finished this, I realize that if the diff proposal were implemented\n> then \"commit-files\" would make a dandy replacement for \"commit\n> -a\". That could lead to finally providing the parallel preview\n> commands I originally wanted:\n> \n> \tgit diff-index\t# as preview for\n> \tgit commit-index\n> and:\n> \tgit diff-files\t# as preview for\n> \tgit commit-files\n> \n> Then \"git commit\" would just be a shortcut for git commit-index.\n> \n> (Oh, and that would also lead to a natural \"git ci\" abbreviation too,\n> if desired. This would parallel the \"ci == checkin\" abbreviation that\n> some other systems provide.)\n> \n> I think the separate notions of commit-index and commit-files would do\n> a good job of allowing for simple tutorials, (eliminates the \"what the\n> heck is -a all about?\" questions), that also don't contribute to\n> general index-unawareness lead to later index-confusion as the current\n> \"git diff; git commit -a\" does.\n> \n> This might even lead to a natural distinction between \"git\n> status-index\" and \"git status files\" too.\n\n...and now the idea:\nWhat if we leave the normal long commands alone, so scripts and\nmuscle memory are not disturbed, but create some short commands\nthat give intuitive true parallel previews:\n  \"git di\" and \"git ci\" (diff or commit index)\n  \"git df\" and \"git cf\" (diff or commit files)\n  \"git dm\" and \"git cm\" (diff or commit merge)\nand of course any other little bits as needed like:\n  \"git si\", \"git sf\", etc. (status index, status file, etc.)\nThis would give a chance to \"start over\" with clear commands,\nwithout causing a ruckus among existing loyal users.  WDYT?\n\n--Tim Larson\n"},{"id":"15813","messageId":"87d5hwxhb5.wl%cworth@cworth.org","threadId":"3271","inReplyTo":"Pine.LNX.4.64.0602081719250.2458@g5.osdl.org","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2006-02-09T23:07:10Z","receivedAt":"2006-02-09T23:07:10Z","isPatch":false,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Wed, 8 Feb 2006 17:21:49 -0800 (PST), Linus Torvalds wrote:\n> > \n> > The largest reason for why \"git diff\" defaults to diffing against the \n> > index (and not head) is _literally_ that it's faster.\n\nThat's certainly surprising history to learn.\n\n> Btw, it was kind of luck (but it's definitely true) that the current \"git \n> diff\" semantics happen to also be what you do want during merges when you \n> try to resolve a conflict (while \"git diff HEAD\" is much less useful).\n> \n> So making \"git diff\" default to diffing against HEAD is actually the wrong \n> thing to do during merging, where the current behaviour is exactly what \n> you'd want.\n\nI discovered this during the analysis and guess (incorrectly) that it\nwas the motivation for the behavior of \"git diff\". Initially I think I\nwould have made a proposal that had \"git diff\" creating a diff from\nHEAD except that I discovered two different targets that would be\nuseful when diffing from HEAD:\n\n\tHEAD -> index\nand:\tHEAD -> files\n\nso I chose \"index\" and \"files\" as the naming distinction there. In\nlight of those, I couldn't think of any good naming for the remaining:\n\n\tindex -> files\n\noperation, so it seemed just as well to leave it with a bare \"diff\" as\nbefore.\n\nBut, as you've pointed out, my trying to create new high-level\ndiff-index and diff-files operations fails in that it clashes with the\nexisting low-level uses of those names, (which scripts may already be\ndepending on).\n\nI totally neglected to consider the pain of migrating scripts.\n\nI still think the three above operations are the most commonly needed,\nbut I don't yet have good suggestions for names for them.\n\nI think I'll be back with some new proposals after considering your\nsuggestion to expand git status.\n\n-Carl\n\n"},{"id":"15816","messageId":"7vmzh06qzd.fsf@assigned-by-dhcp.cox.net","threadId":"3271","inReplyTo":"87d5hwxhb5.wl%cworth@cworth.org","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-02-09T23:40:22Z","receivedAt":"2006-02-09T23:40:22Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Carl Worth <cworth@cworth.org> writes:\n\n> I still think the three above operations are the most commonly needed,\n> but I don't yet have good suggestions for names for them.\n\nBy \"three\" do you mean these three?\n\n\tHEAD -> index\n        HEAD -> files\n        index -> files\n\nThe reason I am asking is because you already have them.\n\n> I think I'll be back with some new proposals after considering your\n> suggestion to expand git status.\n\nI agree with Linus that \"git status -v\" with commit options to\ngive a commit preview is a very good change.  That is one thing\nI pointed out lacking from the current set of the tools in one\nof the earlier message.  I am not sure if you read what I wrote\nin that message, but one approach I suggested for this thread to\ntake is to come up with a list of \"useful comparisons\" that the\ncurrent set of tools, especially \"git diff\" wrapper, does not\ngive you.\n\nThe three you listed above are not.  They are useful, the\nlow-level natively support them, and \"git diff\" wrapper gives\neasy shortcut for them.  And one known \"useful but not supported\none\" will be tackled soon with \"git status -v\" change.  Are\nthere other useful comparisons you wish you had that we do not\ncurrently give you easily?\n"},{"id":"15818","messageId":"87bqxgxfl7.wl%cworth@cworth.org","threadId":"3271","inReplyTo":"7vfymtl43b.fsf@assigned-by-dhcp.cox.net","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2006-02-09T23:44:20Z","receivedAt":"2006-02-09T23:44:20Z","isPatch":false,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Wed, 08 Feb 2006 17:21:12 -0800, Junio C Hamano wrote:\n> Carl Worth <cworth@cworth.org> writes:\n> > Can anyone else think of common use cases for these various\n> > operations that I've missed?\n> \n> If there is none, then that means we have covered everything.\n> But a more interesting question to ask is \"are there useful\n> comparisons that the existing diff lowlevel does not give me\n> with a single command\".  And the answer is of course yes.\n\nYes, that's a more useful way to ask the question.\n\n> For example, you cannot preview \"git commit --include paths...\"\n> with a single low-level command.  You would need to run\n> \"git-diff-index --cached HEAD\" for paths that are _not_\n> specified, and \"git-diff-index HEAD\" output for paths that you\n> will give to \"--include\" when you make that commit.\n\nPersonally, I see that as an argument against adding the --include\nsemantics. It's a single command that is committing a mix of the index\nand the current files, (which neither \"commit\" nor \"commit -a\"\ndo). Granted, Linus has said that he has relied on these existing\nsemantics, (but he also conceded willingness to retrain to\n\"update-index paths; commit\" instead).\n\nSo there's some food for though there.\n\n> Of course, learning various flags to give \"git diff\" is part of\n> understanding the index, so if the user understands index, \"git\n> diff\" without arguments will _not_ be the only diff command the\n> user uses for a preview.  And I suspect that depending on what\n> development style you would use, the definition of \"useful\n> comparisons\" would be different.\n\nYes, and I think it would be nice if the different workflows could be\ncaptured by different subsets of commands, (rather than a mishmash of\ndifferent options to the same commands).\n\nFor example, I *think* we have consensus that two different, equally\nreasonable, workflows might currently use the following sets of\ncommands (this is for basic work-preview-commit):\n\nIndex-lover:\n\n\tupdate-index\n\tdiff --cached\n\tcommit\n\nIndex-ignorer:\n\n\tdiff HEAD\n\tcommit -a\n\nSo, what I'm trying to work towards is a situtation where those\nworkflows are captured through obviously-correlated command\nsubsets. This is what I was getting at in the PS. of my previous\npost. For example, the above could be, (ignoring the clash with\nexisting core commands), something like:\n\nIndex-lover:\n\n\tupdate-index\n\tdiff-index\n\tcommit-index\n\nIndex-ignorer:\n\n\tdiff-files\n\tcommit-files\n\n[Note that due to the name clash problems, I'm not making a serious\nproposal here---merely showing again the consistent naming I'm\ninterested in.]\n\nThe point of an exercise like that is that people could then settle on\nappropriate workflows by reading a small subset of man pages that link\nto each other, in their entirety. Compare that with the previous\ncommand examples where the workflow is documented in little subsets of\nman pages scattered about.\n\nAnd please pardon me for my current fixation on the learnability of\ngit, but I am in the situation of \"selling\" git to my fellow\nmaintainers, (some of whom are saying \"mercurial looks easier to\nlearn\").\n\n> No, the goal should be for normal workflows there should be *no*\n> need to use lowlevel commands by end users day-to-day.\n\nSure. In that light, try to conceive as my proposed \"diff-files\" and\n\"diff-index\" commands as two new highlevel commands. They would be\nuseful in day-to-day operation, and most commonly without any need for\ncommand-line arguments. Those two operations exist today within the\ngit-diff wrapper already as \"diff HEAD\" and \"diff --cached HEAD\" (or\n\"diff --cached). But as described above, I think it would be better to\nput these operations on separate command names, and get them down to\nnot requiring any command-line arguments in their common usage.\n\n> I have not typed lowlevel commands from the command line for\n> quite a long time, except when I am debugging, and except when I\n> wanted to see \"diff-tree --cc\" output for a single commit, only\n> because there was no suitable wrapper. \n\nIf you compare my above two chunks of example commands, there's nothing\nlike a low-level vs. high-level distinction between them. It's more\nabout separate command names being uses for different use cases and\nconsistent naming used to group related commands within a use case.\n\n>                                        The last reason is now\n> gone thanks to \"git-show\" Linus added.  So as far as *MY*\n> workflow is concerned, that goal has already been achieved.\n\nI confess that prior to reading the replies from you and Linus I had\nnever heard of git-show. I'll go look at that now, as well as consider\nthe suggestion to extend git-status to give me what I'm looking for.\n\nAnyway, thanks for all the patience. I'm really enjoying the\nconversation, and I hope I'm not being a bore.\n\n-Carl\n"},{"id":"15822","messageId":"7vr76c5avd.fsf@assigned-by-dhcp.cox.net","threadId":"3271","inReplyTo":"87bqxgxfl7.wl%cworth@cworth.org","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-02-10T00:13:42Z","receivedAt":"2006-02-10T00:13:42Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Carl Worth <cworth@cworth.org> writes:\n\n> So, what I'm trying to work towards is a situtation where those\n> workflows are captured through obviously-correlated command\n> subsets. This is what I was getting at in the PS. of my previous\n> post. For example, the above could be, (ignoring the clash with\n> existing core commands), something like:\n>\n> Index-lover:\n>\n> \tupdate-index\n> \tdiff-index\n> \tcommit-index\n>\n> Index-ignorer:\n>\n> \tdiff-files\n> \tcommit-files\n\nI see where you are coming from and I personally kind of like\nthis consistency.  But I am hesitant to declare these two\nworkflows as the _only_ ones officially supported by the tool at\nthis moment.  The collective use pattern of git is still young\nand leaving the door open would help us to evolve more useful\nworkflows around the core in the future.  One of our first goals\nwould be to have good set of introductory documentations for\nbest current practices -- if the project you work on fits this\nworkflow, here is a way to do it.  With that workflow, there is\nthis way.  By that time, hopefully many useless workflows (my\n\"constantly rewinding pu branch\" pattern _could_ fall into that\ncategory) would be withered away and it would be a good time to\nstreamline the tool around officially supported workflows.\n\nMy feeling is that it is a bit premature to do that right now; I\ndo not think we are there yet.\n\n> Sure. In that light, try to conceive as my proposed \"diff-files\" and\n> \"diff-index\" commands as two new highlevel commands. They would be\n> useful in day-to-day operation, and most commonly without any need for\n> command-line arguments. Those two operations exist today within the\n> git-diff wrapper already as \"diff HEAD\" and \"diff --cached HEAD\" (or\n> \"diff --cached). But as described above, I think it would be better to\n> put these operations on separate command names, and get them down to\n> not requiring any command-line arguments in their common usage.\n\nSorry, I am not convinced about separate command names, but in\nthe meantime you could have small wrappers around \"git diff\":\n\"cw-diff-files\" and \"cw-diff-index\" would be one liner each,\nwouldn't they?\n\nAnd that is a _good_ thing about git.  If the sample set of\nbarebone Porcelains do not fit your needs, you can mix and match\nusing lowlevel commands to quickly script your customized ones.\nIf that is useful in general, that would become one of the best\ncurrent practices.\n\n> If you compare my above two chunks of example commands, there's nothing\n> like a low-level vs. high-level distinction between them. It's more\n> about separate command names being uses for different use cases and\n> consistent naming used to group related commands within a use case.\n\nI think that is where we differ.  I think even for index-lover\n\"diff HEAD\" is useful in certain cases (obviously index-ignorer\nwould not see much useful output from \"diff --cached\", though).\nIn fact, I fall into \"index-lover\" camp but I use both depending\non occasion.  And as I said, I do not think \"index-lover\" and\n\"index-ignorer\" distinction above would be the only two valid\nworkflows anyway, so I feel partitioning the command set along\nthose lines is at least premature if not wrong.\n"},{"id":"15832","messageId":"87fymst399.wl%cworth@cworth.org","threadId":"3271","inReplyTo":"7vr76c5avd.fsf@assigned-by-dhcp.cox.net","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2006-02-10T01:24:18Z","receivedAt":"2006-02-10T01:24:18Z","isPatch":false,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Thu, 09 Feb 2006 16:13:42 -0800, Junio C Hamano wrote:\n> > Index-lover:\n> >\n> > \tupdate-index\n> > \tdiff-index\n> > \tcommit-index\n> >\n> > Index-ignorer:\n> >\n> > \tdiff-files\n> > \tcommit-files\n> \n> I see where you are coming from and I personally kind of like\n> this consistency.\n\nThanks. I think that means I've described my motivation now. Though I\nstill have to come up with a valid proposal.\n\n>                   But I am hesitant to declare these two\n> workflows as the _only_ ones officially supported by the tool at\n> this moment.\n\nI wouldn't want to do that either. Fortunately, I don't think the\nabove command set would do anything like that. The workflows above\nwith the silly names are just examples, but the commands would still\nbe available in general, and I would expect people to mix and match\nfor whatever fits best.\n\nThe more significant aspect of the above grouping is not \"what\nworkflow is supported\" but whether the commands operate primarily on\nthe index or on the files in the working directory. The distinction is\nsignificant to understanding and taking full advantage of git. And\nthis aspect of git is something that is particularly unique to git\n(and hence some source of confusion to newcomers).\n\nTake a look at how the index vs. files distinction currently plays out\nwith existing commands:\n\ncommit:\tActs on index. Can be made to act on files with -a.\n\ndiff:\tActs between index and files (which is a sort of special case).\n\tCan be made to act on files by passing a tree argument.\n\tCan be made to act on index by passing --cached.\n\nupdate-index:\tActs on index, (as obviously encoded in the name).\n\n>                                           One of our first goals\n> would be to have good set of introductory documentations for\n> best current practices -- if the project you work on fits this\n> workflow, here is a way to do it.  With that workflow, there is\n> this way.\n\nI agree. I think the current 'tutorial introduction to git' does a\ngood job at demonstrating one work flow. I'm picky though, so the two\nchanges I'd like to have in it are: 1) No command-line options\nnecessary (rename \"commit -a\" somehow). 2) Provide an honest\nHEAD->files diff rather than the current \"git diff\" that just\n'accidentally' happens to give the same answer in this case.\n\nFor a taking-advantage-of-the-index workflow, I think the 'short git\ntutorial' does a poor job, (it makes the index notion just seem\npainful and in the way). But Linus' responses to me in the recent\nthreads have helped me understand it better, so there's material for\nan improved tutorial there I think.\n\n> Sorry, I am not convinced about separate command names, but in\n> the meantime you could have small wrappers around \"git diff\":\n> \"cw-diff-files\" and \"cw-diff-index\" would be one liner each,\n> wouldn't they?\n> \n> And that is a _good_ thing about git.\n\nYes, I can do that personally, and I do agree it's a nice benefit of\ngit. (Though some might see it as a defect if such scripting is\nperceived as being necessary before getting comfortable use out of the\ntool.)\n\n>               And as I said, I do not think \"index-lover\" and\n> \"index-ignorer\" distinction above would be the only two valid\n> workflows anyway, so I feel partitioning the command set along\n> those lines is at least premature if not wrong.\n\nYeah, that's a false partition. People will certainly use commands\nfrom both sets. I think the index-focused vs. files-focused\norientation I've presented here is more valid partition.\n\nAnd I think if there were a clean files-focused subset of commands\n(that also didn't \"deny the index\" in any fundamental way), that it\nwould make a good introduction to git, (it would certainly provide a\ncloser fit to what many people will conceive of as they come from\nother systems).\n\n-Carl\n"},{"id":"15835","messageId":"7vfyms0x4p.fsf@assigned-by-dhcp.cox.net","threadId":"3271","inReplyTo":"87fymst399.wl%cworth@cworth.org","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-02-10T02:24:06Z","receivedAt":"2006-02-10T02:24:06Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Carl Worth <cworth@cworth.org> writes:\n\n> The more significant aspect of the above grouping is not \"what\n> workflow is supported\" but whether the commands operate primarily on\n> the index or on the files in the working directory. The distinction is\n> significant to understanding and taking full advantage of git. And\n> this aspect of git is something that is particularly unique to git\n> (and hence some source of confusion to newcomers).\n\nI think that is a wrong place to start from.  There is no such\nthing as \"file focused\" operation in git.  Git _fundamentally_\nworks with index.  The reason \"diff-index\" without --cached is\nthere is to tell you what _would_ happen if you were to run\nupdate-index on the path.  The same thing for \"diff-files\".  It\ntells you what damage you would be inflicting on the index if\nyou were to update-index it with what you have in the working\ntree.  They are simulations of what _would_ happen after you\nplace them in the index, and until you place them in the index\nyou obviously cannot write things out to a tree.\n\nHowever much you want to make git pretend to be \"file focused\",\nyou cannot deny the fact that the interesting things happen only\nafter you place things in the index.\n\nNow, from purely traditional SCM point of view, index may be\nsecondary.  People coming from index-less SCM background would\njust want two entities: the last checkin and what you have in\nthe working tree.  If your goal is you would want to have an\nalternative UI that completely hides index, that is a worthy\ngoal (I think Cogito attempts to do so and does a reasonably\ngood job), but that is something different from what git\nbarebone Porcelains would want to force on its users.\n\nBut I do not think that is what you are aiming for in this round\nof your proposal.\n\n> I agree. I think the current 'tutorial introduction to git' does a\n> good job at demonstrating one work flow. I'm picky though, so the two\n> changes I'd like to have in it are: 1) No command-line options\n> necessary (rename \"commit -a\" somehow). 2) Provide an honest\n> HEAD->files diff rather than the current \"git diff\" that just\n> 'accidentally' happens to give the same answer in this case.\n\nAgain, (2) is \"git status -v\".  Simulation of what would happen\nif I were to commit right now.  For (1), \"git commit\" to mean\n\"git commit -a\" has already been rejected, but you could\nintroduce git-commit-all if you want.  I however do not think\nthat would fly well with general public; after already seeing\n100+ commands adding one more would not be too much but I think\nthat would be an additional confusion, not simplification.\n\n> For a taking-advantage-of-the-index workflow, I think the 'short git\n> tutorial' does a poor job, (it makes the index notion just seem\n> painful and in the way). But Linus' responses to me in the recent\n> threads have helped me understand it better, so there's material for\n> an improved tutorial there I think.\n\nThanks.  I take it to mean I can expect some updates to the\nsection from you ;-).\n\n> Yes, I can do that personally, and I do agree it's a nice benefit of\n> git. (Though some might see it as a defect if such scripting is\n> perceived as being necessary before getting comfortable use out of the\n> tool.)\n\nAs I already said, if enough people share the opinon that that\nparticular wrapper is a good thing, it would become established\nBCP and eventually make it into a new command or a new option,\neven replacing the existing one if the benefit outweighs the\ntransition cost.\n\nI do not, unfortunately, see much merit in what you have said so\nfar, such as renaming \"git diff --cached\" and \"git diff HEAD\".\nRunning --cached and non --cached against something other than\nHEAD _is_ useful [*1*], so you cannot remove the existing \"git\ndiff --cached <commit-id>\" or \"git diff <commit-id>\"; which\nmeans you would need two extra command just for the common cases\nto run \"git diff --cached HEAD\" and \"git diff HEAD\".  Certainly\nthat would be less typing for that particular case, but does\nthat justify two extra commands?  Along with the git-commit-all\nthat would be three extra commands.  I am not convinced.\n\nI really feel I should slow down and stop responding for now,\nand instead start spending some time on doing the git-status\nupdates.\n\nJust so that I do not get misunderstood by the above statement.\nI do not mean I will _ignore_ your arguments; what I mean is I\nwould stop talking, give your thought process time to go all the\nway, and then revisit your proposal after you finished thinking.\n\n\n[Footnote]\n\n*1* Often I find myself doing that while rewriting messy\ndevelopment history.  For example, I start doing some\nwork without knowing exactly where it leads, and end up with a\nhistory like this:\n\n            \"master\"\n        o---o\n             \\                    \"topic\" \n              o---o---o---o---o---o\n\nAt this point, \"topic\" contains something I know I want, but it\ncontains two concepts that turned out to be completely\nindependent.  And often, one topic component is larger than the\nother.  It may contain more than two topics.\n\nIn order to rewrite this mess to be more manageable, I would\nfirst do \"diff master topic\", to extract the changes into a\nsingle patch, start picking pieces from it to get logically\nself-contained units, and start building on top of \"master\":\n\n        $ git diff master..topic >P.diff\n        $ git checkout -b topicA master\n        ... pick and apply pieces from P.diff to build\n        ... commits on topicA branch.\n                      \n              o---o---o\n             /        \"topicA\"\n        o---o\"master\"\n             \\                    \"topic\" \n              o---o---o---o---o---o\n\nBefore doing each commit on \"topicA\" HEAD, I run \"diff HEAD\"\nbefore update-index the affected paths, or \"diff --cached HEAD\"\nafter.  Also I would run \"diff --cached master\" to make sure\nthat the changes are only the ones related to \"topicA\".  Usually\nI do this for smaller topics first.\n\nAfter that, I'd do the remainder of the original \"topic\", but\nfor that, I do not start from the patchfile I extracted by\ncomparing \"master\" and \"topic\" I used initially.  Still on\n\"topicA\", I extract \"diff topic\", and use it to rebuild the\nother topic:\n\n        $ git diff -R topic >P.diff ;# --cached also would work fine\n        $ git checkout -b topicB master\n        ... pick and apply pieces from P.diff to build\n        ... commits on topicB branch.\n\n                                \"topicB\"\n               o---o---o---o---o\n              /\n             /o---o---o\n            |/        \"topicA\"\n        o---o\"master\"\n             \\                    \"topic\" \n              o---o---o---o---o---o\n\nAfter I am done, I'd try a pretend-merge between \"topicA\" and\n\"topicB\" in order to make sure I have not missed anything:\n\n        $ git pull . topicA ;# merge it into current \"topicB\"\n        $ git diff topic\n                                \"topicB\"\n               o---o---o---o---o---* (pretend merge)\n              /                   /\n             /o---o---o----------'\n            |/        \"topicA\"\n        o---o\"master\"\n             \\                    \"topic\" \n              o---o---o---o---o---o\n\nThe last diff better not to show anything other than cleanups\nfor crufts.  Then I can finally clean things up:\n\n        $ git branch -D topic\n        $ git reset --hard HEAD^ ;# nuke pretend merge\n\n                                \"topicB\"\n               o---o---o---o---o\n              / \n             /o---o---o\n            |/        \"topicA\"\n        o---o\"master\"\n"},{"id":"15837","messageId":"87ek2buck3.wl%cworth@cworth.org","threadId":"3271","inReplyTo":"7vfyms0x4p.fsf@assigned-by-dhcp.cox.net","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2006-02-10T03:18:04Z","receivedAt":"2006-02-10T03:18:04Z","isPatch":false,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Thu, 09 Feb 2006 18:24:06 -0800, Junio C Hamano wrote:\n> I do not, unfortunately, see much merit in what you have said so\n> far, such as renaming \"git diff --cached\" and \"git diff HEAD\".\n> Running --cached and non --cached against something other than\n> HEAD _is_ useful [*1*]\n\nYes. Of course. My proposed commands still accept a revision\nargument, (they just defaulted to HEAD when one was not provided).\n\n> I really feel I should slow down and stop responding for now,\n\nYeah, me too. I've made enough noise for now. I'll spend more time\nusing things before proposing anything else, and come back with\nsomething more concrete (== patches) next time instead of just lots of\ntalk.\n\nAnyway, thanks again for the time. And sorry for the distraction.\n\nNo reply necessary from this one. :-)\n\n-Carl\n\nPS. Thanks for the several examples. That's more good training for me,\n(the operations here provide a lot of help for things I've always had\nto do much more manually with things like CVS). And that's also more\ncontent for tutorials, (and yes, I did mean to sound like I would like\nto help generate some of those---I've got some people I'm trying to\nconvince to switch to git right now, and they'll need some training).\n"},{"id":"15846","messageId":"7vmzgzy46f.fsf@assigned-by-dhcp.cox.net","threadId":"3271","inReplyTo":"Pine.LNX.4.64.0602081726390.2458@g5.osdl.org","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-02-10T09:05:28Z","receivedAt":"2006-02-10T09:05: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> Under that logic, \"git status -v\" would show all the diffs (not just \n> filenames) and \"git commit -v ..\" would be the same as \"git commit ..\" but \n> the \"-v\" flag would have been passed down to the \"git status\" call, so the \n> commit message file would be pre-populated with the diff.\n\nNow that is done and sitting at the tip of \"next\".\n\n> For small commits, it's actually nice to see the diff itself as you write \n> the commit message.\n\nYes, that is my experience, and even with fairly big one, it is\npleasant as long as your editor allows you to C-x 2 C-x o around\nthe file you are editing, like \"em\" ;-).\n\ncommit cf7bb589af739563c90dc32b4901bea73aaaa9d0\nAuthor: Junio C Hamano <junkio@cox.net>\nDate:   Fri Feb 10 00:45:59 2006 -0800\n\n    git-status -v\n    \n    This revamps the git-status command to take the same set of\n    parameters as git commit.  It gives a preview of what is being\n    committed with that command.  With -v flag, it shows the diff\n    output between the HEAD commit and the index that would be\n    committed if these flags were given to git-commit command.\n    \n    git-commit also acquires -v flag (it used to mean \"verify\" but\n    that is the default anyway and there is --no-verify to turn it\n    off, so not much is lost), which uses the updated git-status -v\n    to seed the commit log buffer.  This is handy for writing a log\n    message while reviewing the changes one last time.\n    \n    Now, git-commit and git-status internally share the same\n    implementation.\n    \n    Unlike previous git-commit change, this uses a temporary index\n    to prepare the index file that would become the real index file\n    after a successful commit, and moves it to the real index file\n    once the commit is actually made.  This makes it safer than the\n    previous scheme, which stashed away the original index file and\n    restored it after an aborted commit.\n    \n    Signed-off-by: Junio C Hamano <junkio@cox.net>\n"},{"id":"15886","messageId":"slrnduphvr.2i8.mdw@metalzone.distorted.org.uk","threadId":"3271","inReplyTo":"7vfyms0x4p.fsf@assigned-by-dhcp.cox.net","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Mark Wooding","fromEmail":"mdw@distorted.org.uk","sentAt":"2006-02-10T17:06:03Z","receivedAt":"2006-02-10T17:06:03Z","isPatch":false,"sender":{"key":"mdw@distorted.org.uk","avatar":null},"body":"Junio C Hamano <junkio@cox.net> wrote:\n\n> In order to rewrite this mess to be more manageable, I would\n> first do \"diff master topic\", to extract the changes into a\n> single patch, start picking pieces from it to get logically\n> self-contained units, and start building on top of \"master\":\n\n[etc.]\n\nOh, good.  It's not just me, then! ;-)\n\nThis is more or less exactly how I built the various patches I submitted\nhere.  The main difference is that I used StGIT because I'm less\ncompetent than Junio and didn't always manage to get all my changes in\nthe right places to begin with.\n\n(I really look forward to a StGIT which can withstand git-prune.)\n\n-- [mdw]\n"},{"id":"15913","messageId":"m31wybknuv.fsf@athena.unit.liu.se","threadId":"3271","inReplyTo":"7vfyms0x4p.fsf@assigned-by-dhcp.cox.net","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Kent Engstrom","fromEmail":"kent@lysator.liu.se","sentAt":"2006-02-10T19:36:24Z","receivedAt":"2006-02-10T19:36:24Z","isPatch":false,"sender":{"key":"kent@lysator.liu.se","avatar":null},"body":"Junio C Hamano <junkio@cox.net> writes:\n> *1* Often I find myself doing that while rewriting messy\n> development history.  For example, I start doing some\n> work without knowing exactly where it leads, and end up with a\n> history like this:\n\nPerhaps this discussion could be added under Documentation/howto?\n\n/ Kent Engström, Lysator\n"},{"id":"15857","messageId":"87u0b7uf91.wl%cworth@cworth.org","threadId":"3271","inReplyTo":"7vmzgzy46f.fsf@assigned-by-dhcp.cox.net","subject":"Comments on \"status -v\" (was: Two crazy proposals for changing git's diff commands)","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2006-02-10T20:32:10Z","receivedAt":"2006-02-10T20:32:10Z","isPatch":false,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Fri, 10 Feb 2006 01:05:28 -0800, Junio C Hamano wrote:\n> \n> Linus Torvalds <torvalds@osdl.org> writes:\n> \n> > Under that logic, \"git status -v\" would show all the diffs (not just \n> > filenames) and \"git commit -v ..\" would be the same as \"git commit ..\" but \n> > the \"-v\" flag would have been passed down to the \"git status\" call, so the \n> > commit message file would be pre-populated with the diff.\n> \n> Now that is done and sitting at the tip of \"next\".\n\nThanks. This does look quite useful.\n\nA couple of comments, though:\n\n1) I think the patch should come after the traditional status summary,\n   not before. If something is obviously \"wrong\" (non-updated file,\n   etc.) that will be more obvious in the summary, so it's good to\n   present that up front, and not bury it after the patch, (which\n   might make it initially invisible without scrolling).\n\n2) Using the \"^---$\" separator to separate the the edited contents\n   into a commit message and ignored content seems risky to me.\n\n   One risk is that the user might put that magic string in the commit\n   message. Perhaps the risk is low, but it would be a silent\n   destruction of historical data, which seems like a bad trap.\n\n   A second risk is that with the current patch-then-summary order it\n   is actually quite easy to inadvertently clobber the separator while\n   editing the commit message. Particularly because the separator is\n   placed exactly where the user must begin editing. So it would be\n   easy to leave the separator trailing on a line of\n   commit message comments or else introducing some initial\n   whitespace that would break it.\n\n   Moving the patch after the summary (as discussed above) would help\n   greatly in avoiding the clobbered separator, but wouldn't address\n   the separator-appears-in-commit-message problem.\n\n-Carl\n"},{"id":"15861","messageId":"7vaccyx6ne.fsf@assigned-by-dhcp.cox.net","threadId":"3271","inReplyTo":"87u0b7uf91.wl%cworth@cworth.org","subject":"Re: Comments on \"status -v\"","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-02-10T21:09:41Z","receivedAt":"2006-02-10T21:09:41Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Carl Worth <cworth@cworth.org> writes:\n\n> 1) I think the patch should come after the traditional status summary,\n>    not before. If something is obviously \"wrong\" (non-updated file,\n>    etc.) that will be more obvious in the summary, so it's good to\n>    present that up front, and not bury it after the patch, (which\n>    might make it initially invisible without scrolling).\n\nMaybe.  A time for a quick poll.\n\n> 2) Using the \"^---$\" separator to separate the the edited contents\n>    into a commit message and ignored content seems risky to me.\n>\n>    Moving the patch after the summary (as discussed above) would help\n>    greatly in avoiding the clobbered separator, but wouldn't address\n>    the separator-appears-in-commit-message problem.\n\nThat is a good argument for (1).  Since the diff output never\nhas '^---$' in itself, instead of discarding everything after\nthe first '^---$', we could change the log cleanser to discard\nafter the _last_ '^---$'.  But coding this sanely is much\ntrickier with sed ;-).\n"},{"id":"15871","messageId":"Pine.LNX.4.64.0602101333570.19172@g5.osdl.org","threadId":"3271","inReplyTo":"7vaccyx6ne.fsf@assigned-by-dhcp.cox.net","subject":"Re: Comments on \"status -v\"","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-02-10T21:35:05Z","receivedAt":"2006-02-10T21:35:05Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 10 Feb 2006, Junio C Hamano wrote:\n\n> Carl Worth <cworth@cworth.org> writes:\n> \n> > 1) I think the patch should come after the traditional status summary,\n> >    not before. If something is obviously \"wrong\" (non-updated file,\n> >    etc.) that will be more obvious in the summary, so it's good to\n> >    present that up front, and not bury it after the patch, (which\n> >    might make it initially invisible without scrolling).\n> \n> Maybe.  A time for a quick poll.\n\nI think I agree. Especially if doing \"git commit -v\", the _top_ of the \nstatus message is what you'd normally be most aware of. I think. \nEspecially if the patch is large, you'd grow bored looking at it long \nbefore you saw what followed.\n\n\t\t\tLinus\n"},{"id":"15869","messageId":"7v7j82vp6i.fsf@assigned-by-dhcp.cox.net","threadId":"3271","inReplyTo":"Pine.LNX.4.64.0602101333570.19172@g5.osdl.org","subject":"Re: Comments on \"status -v\"","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-02-10T22:12:21Z","receivedAt":"2006-02-10T22:12:21Z","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> I think I agree. Especially if doing \"git commit -v\", the _top_ of the \n> status message is what you'd normally be most aware of. I think. \n\nWell the exactly same reasoning on my part, who keeps tons of\nuntracked files in his repository, left the patch output there.\nOtherwise I have to scroll off a long \"untracked files\" list to\nget to the patch ;-).\n\nBut even with that gripe, I'd agree that patch at the end would\nbe a better choice.  The user asked for a patch so she wouldn't\nfail to see it even if many '#' lines precede the patch.  With\nthe current ordering, '#' lines will most likely be ignored.\n"},{"id":"15870","messageId":"20060210225109.GQ31278@pasky.or.cz","threadId":"3271","inReplyTo":"7vaccyx6ne.fsf@assigned-by-dhcp.cox.net","subject":"Re: Comments on \"status -v\"","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-02-10T22:51:09Z","receivedAt":"2006-02-10T22:51:09Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Fri, Feb 10, 2006 at 10:09:41PM CET, I got a letter\nwhere Junio C Hamano <junkio@cox.net> said that...\n> Carl Worth <cworth@cworth.org> writes:\n> \n> > 1) I think the patch should come after the traditional status summary,\n> >    not before. If something is obviously \"wrong\" (non-updated file,\n> >    etc.) that will be more obvious in the summary, so it's good to\n> >    present that up front, and not bury it after the patch, (which\n> >    might make it initially invisible without scrolling).\n> \n> Maybe.  A time for a quick poll.\n\nIt makes more sense to me. (Not that I'd be ever going to use the\ncommand, though. ;)\n\n> > 2) Using the \"^---$\" separator to separate the the edited contents\n> >    into a commit message and ignored content seems risky to me.\n\nWe do it for the mails (and Cogito for cg-mkpatch output) and it seems\nto work out just fine.\n\n> >    Moving the patch after the summary (as discussed above) would help\n> >    greatly in avoiding the clobbered separator, but wouldn't address\n> >    the separator-appears-in-commit-message problem.\n> \n> That is a good argument for (1).  Since the diff output never\n> has '^---$' in itself,\n\n$ echo -- >a; >b; diff -u a b\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nOf the 3 great composers Mozart tells us what it's like to be human,\nBeethoven tells us what it's like to be Beethoven and Bach tells us\nwhat it's like to be the universe.  -- Douglas Adams\n"},{"id":"15876","messageId":"7v3biqvlqw.fsf@assigned-by-dhcp.cox.net","threadId":"3271","inReplyTo":"20060210225109.GQ31278@pasky.or.cz","subject":"Re: Comments on \"status -v\"","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-02-10T23:26:31Z","receivedAt":"2006-02-10T23:26:31Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Petr Baudis <pasky@suse.cz> writes:\n\n>> That is a good argument for (1).  Since the diff output never\n>> has '^---$' in itself,\n>\n> $ echo -- >a; >b; diff -u a b\n\nThanks.  Good point.  Forget what I said.\n"},{"id":"15938","messageId":"7vmzgxn1dz.fsf@assigned-by-dhcp.cox.net","threadId":"3271","inReplyTo":"m31wybknuv.fsf@athena.unit.liu.se","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-02-11T19:25:44Z","receivedAt":"2006-02-11T19:25:44Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Kent Engstrom <kent@lysator.liu.se> writes:\n\n> Junio C Hamano <junkio@cox.net> writes:\n>> *1* Often I find myself doing that while rewriting messy\n>> development history.  For example, I start doing some\n>> work without knowing exactly where it leads, and end up with a\n>> history like this:\n>\n> Perhaps this discussion could be added under Documentation/howto?\n\nMaybe.\n\nTraditionally, person who feels that way proofreads and\ncopyedits the original posting and submits a patch ;-).\n"},{"id":"15953","messageId":"20060212031527.GA31228@fieldses.org","threadId":"3271","inReplyTo":"7vfymtl43b.fsf@assigned-by-dhcp.cox.net","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"J. Bruce Fields","fromEmail":"bfields@fieldses.org","sentAt":"2006-02-12T03:15:27Z","receivedAt":"2006-02-12T03:15:27Z","isPatch":false,"sender":{"key":"bfields@citi.umich.edu","avatar":null},"body":"On Wed, Feb 08, 2006 at 05:21:12PM -0800, Junio C Hamano wrote:\n> Of course, learning various flags to give \"git diff\" is part of\n> understanding the index\n\nWell, there's understanding the index, and then there's memorizing the\nflags.  I would've thought it'd be a lot easier to remember something\nlike\n\ngit diff HEAD INDEX\ngit diff INDEX WORK\ngit diff HEAD WORK\n\nthan, respectively,\n\ngit diff --cached\ngit diff\ngit diff HEAD\n\nBut maybe that's just me.  (And maybe the namespace in question is\nalready to crowded to allow for INDEX and WORK.)\n\n--b.\n"},{"id":"15955","messageId":"7vr769fd95.fsf@assigned-by-dhcp.cox.net","threadId":"3271","inReplyTo":"20060212031527.GA31228@fieldses.org","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-02-12T03:48:54Z","receivedAt":"2006-02-12T03:48:54Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"J. Bruce Fields\" <bfields@fieldses.org> writes:\n\n> On Wed, Feb 08, 2006 at 05:21:12PM -0800, Junio C Hamano wrote:\n>> Of course, learning various flags to give \"git diff\" is part of\n>> understanding the index\n>\n> Well, there's understanding the index, and then there's memorizing the\n> flags...\n> ...\n> But maybe that's just me.  (And maybe the namespace in question is\n> already to crowded to allow for INDEX and WORK.)\n\nI do not think it is just you.  The real problem, honestly\nspeaking, is that \"git diff\" wrapper cheats and avoids doing its\nown set of flags.\n\nThe low-level is just a mechanism UI is built upon, and as a\nmechanism, except perhaps maybe --cached might be now better\nspelled as --index, has set of options and semantics that are\nconsistent with its world model (index centric way of thinking).\n\nBecause \"git diff\" wrapper cheats, it ends up exposing the\nlow-level flags and arguments to the end user, and to use that\neffectively, obviously you need to understand the world model\nthe low-level is built upon.\n\nIt was OK (it could be argued that it was even better than sugar\ncoating to make it *inconsistent* with the underlying world\nmodel) so far, as long as people who use it are aware of the\nindex centric world model, but that \"consistency with the\nunderlying world model\" makes it harder to approach and causes\nconfusion.\n\nThat is why I these days often mention \"welding training\nwheels\".  Doing half-baked sugarcoating of the UI layer would\nbreak mental model of people who understand the world model\nlow-level builds and tries to make effective use of low-level\nthrough the UI.\n"},{"id":"15968","messageId":"m3accwrdl7.fsf_-_@ceres.unit.liu.se","threadId":"3271","inReplyTo":"7vmzgxn1dz.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] Add howto about separating topics.","fromName":"","fromEmail":"kent@lysator.liu.se","sentAt":"2006-02-12T12:00:52Z","receivedAt":"2006-02-12T12:00:52Z","isPatch":true,"sender":{"key":"kent@lysator.liu.se","avatar":null},"body":"This howto consists of a footnote from an email by JC to the git\nmailing list (<7vfyms0x4p.fsf@assigned-by-dhcp.cox.net>).\n\nSigned-off-by: Kent Engstrom <kent@lysator.liu.se>\n\n---\n\n Documentation/howto/separating-topic-branches.txt |   91 +++++++++++++++++++++\n 1 files changed, 91 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/howto/separating-topic-branches.txt\n\n39f152ae224f45a3d977aa8966a477dbc1df676d\ndiff --git a/Documentation/howto/separating-topic-branches.txt b/Documentation/howto/separating-topic-branches.txt\nnew file mode 100644\nindex 0000000..090e2c9\n--- /dev/null\n+++ b/Documentation/howto/separating-topic-branches.txt\n@@ -0,0 +1,91 @@\n+From: Junio C Hamano <junkio@cox.net>\n+Subject: Separating topic branches\n+Abstract: In this article, JC describes how to separate topic branches.\n+\n+This text was originally a footnote to a discussion about the\n+behaviour of the git diff commands.\n+\n+Often I find myself doing that [running diff against something other\n+than HEAD] while rewriting messy development history.  For example, I\n+start doing some work without knowing exactly where it leads, and end\n+up with a history like this:\n+\n+            \"master\"\n+        o---o\n+             \\                    \"topic\" \n+              o---o---o---o---o---o\n+\n+At this point, \"topic\" contains something I know I want, but it\n+contains two concepts that turned out to be completely independent.\n+And often, one topic component is larger than the other.  It may\n+contain more than two topics.\n+\n+In order to rewrite this mess to be more manageable, I would first do\n+\"diff master..topic\", to extract the changes into a single patch, start\n+picking pieces from it to get logically self-contained units, and\n+start building on top of \"master\":\n+\n+        $ git diff master..topic >P.diff\n+        $ git checkout -b topicA master\n+        ... pick and apply pieces from P.diff to build\n+        ... commits on topicA branch.\n+                      \n+              o---o---o\n+             /        \"topicA\"\n+        o---o\"master\"\n+             \\                    \"topic\" \n+              o---o---o---o---o---o\n+\n+Before doing each commit on \"topicA\" HEAD, I run \"diff HEAD\"\n+before update-index the affected paths, or \"diff --cached HEAD\"\n+after.  Also I would run \"diff --cached master\" to make sure\n+that the changes are only the ones related to \"topicA\".  Usually\n+I do this for smaller topics first.\n+\n+After that, I'd do the remainder of the original \"topic\", but\n+for that, I do not start from the patchfile I extracted by\n+comparing \"master\" and \"topic\" I used initially.  Still on\n+\"topicA\", I extract \"diff topic\", and use it to rebuild the\n+other topic:\n+\n+        $ git diff -R topic >P.diff ;# --cached also would work fine\n+        $ git checkout -b topicB master\n+        ... pick and apply pieces from P.diff to build\n+        ... commits on topicB branch.\n+\n+                                \"topicB\"\n+               o---o---o---o---o\n+              /\n+             /o---o---o\n+            |/        \"topicA\"\n+        o---o\"master\"\n+             \\                    \"topic\" \n+              o---o---o---o---o---o\n+\n+After I am done, I'd try a pretend-merge between \"topicA\" and\n+\"topicB\" in order to make sure I have not missed anything:\n+\n+        $ git pull . topicA ;# merge it into current \"topicB\"\n+        $ git diff topic\n+                                \"topicB\"\n+               o---o---o---o---o---* (pretend merge)\n+              /                   /\n+             /o---o---o----------'\n+            |/        \"topicA\"\n+        o---o\"master\"\n+             \\                    \"topic\" \n+              o---o---o---o---o---o\n+\n+The last diff better not to show anything other than cleanups\n+for crufts.  Then I can finally clean things up:\n+\n+        $ git branch -D topic\n+        $ git reset --hard HEAD^ ;# nuke pretend merge\n+\n+                                \"topicB\"\n+               o---o---o---o---o\n+              / \n+             /o---o---o\n+            |/        \"topicA\"\n+        o---o\"master\"\n+\n-- \n1.1.6.g29e5\n"},{"id":"16032","messageId":"tnxaccvhasa.fsf@arm.com","threadId":"3271","inReplyTo":"slrnduphvr.2i8.mdw@metalzone.distorted.org.uk","subject":"Re: Two crazy proposals for changing git's diff commands","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@arm.com","sentAt":"2006-02-13T09:23:49Z","receivedAt":"2006-02-13T09:23:49Z","isPatch":false,"sender":{"key":"catalin.marinas@arm.com","avatar":null},"body":"Mark Wooding <mdw@distorted.org.uk> wrote:\n> (I really look forward to a StGIT which can withstand git-prune.)\n\nAlmost sure in the next release, probably sometime in March.\n\n-- \nCatalin\n"},{"id":"16059","messageId":"43F1016E.5070203@gmail.com","threadId":"3271","inReplyTo":"slrnduphvr.2i8.mdw@metalzone.distorted.org.uk","subject":"Prune-safe StGIT (was Re: Two crazy proposals for changing git's diff commands)","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2006-02-13T22:00:14Z","receivedAt":"2006-02-13T22:00:14Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"Mark Wooding wrote:\n> (I really look forward to a StGIT which can withstand git-prune.)\n\nSince there were a few requests for this feature, I pushed it to the\npublic repository (and also included it in the latest snapshot).\n\nAs it was discussed a few months ago, the top id of each patch\n(including the popped ones) is added to the\n.git/refs/patches/<branch>/<patch> file. The git-prune command will\npreserve these objects and their referents, making even the unapplied\npatches safe. There is another advantage with this approach - gitk shows\nthe patch name for every corresponding commit.\n\nRunning any command (apart from help) on the current branch would create\nthe initial references. You would need to do the same with all the other\nbranches. Since this is a new feature, make sure you have backups before\npruning (though it worked OK for me).\n\n--\nCatalin\n"}]}