{"thread":{"id":"15063","subject":"Call Me Gitless","startedAt":"2008-08-18T00:02:32Z","lastAt":"2008-08-22T19:10:36Z","messageCount":67,"participants":["Trans","Benjamin Sergeant","Martin Langhoff","Pascal Obry","Jon Loeliger","Daniel Barkalow","Marcus Griep","Junio C Hamano","Tarmigan","Stephen R. van den Berg","Peter Valdemar Mørch (Lists)","Imran M Yousuf","Teemu Likonen","Alexander E Genaud","Matthieu Moy","Mike Hommey","Mark Struberg","Jakub Narebski","Jeff King","Petr Baudis","Sverre Hvammen Johansen","Paolo Bonzini","Jonathan Nieder","Elijah Newren"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"87505","messageId":"4b6f054f0808171702q10d89dfey98afa65634d26e91@mail.gmail.com","threadId":"15063","inReplyTo":null,"subject":"Call Me Gitless","fromName":"Trans","fromEmail":"transfire@gmail.com","sentAt":"2008-08-18T00:02:32Z","receivedAt":"2008-08-18T00:02:32Z","isPatch":false,"sender":{"key":"transfire@gmail.com","avatar":"https://gravatar.com/avatar/f98ccb7e9a9a79b343086463300c72cc330cf53bc5731867b662874c9fe1ccca?d=mp&s=160"},"body":"Well, after a few days of using git, I've decide Linus is too smart to\nbe designing end-user interfaces.\n\nPeace,\n7rans\n"},{"id":"87506","messageId":"1621f9fa0808171728q4f8cf679i7fdd8ab5c3dceaa8@mail.gmail.com","threadId":"15063","inReplyTo":"4b6f054f0808171702q10d89dfey98afa65634d26e91@mail.gmail.com","subject":"Re: Call Me Gitless","fromName":"Benjamin Sergeant","fromEmail":"bsergean@gmail.com","sentAt":"2008-08-18T00:28:08Z","receivedAt":"2008-08-18T00:28:08Z","isPatch":false,"sender":{"key":"bsergean@gmail.com","avatar":null},"body":"Funny to end a mail criticizing git with \"Peace\".\n\nI would think \"War\" would be a better way to end it :)\n\nOn Sun, Aug 17, 2008 at 5:02 PM, Trans <transfire@gmail.com> wrote:\n> Well, after a few days of using git, I've decide Linus is too smart to\n> be designing end-user interfaces.\n>\n> Peace,\n> 7rans\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>\n"},{"id":"87507","messageId":"46a038f90808171740ncfa74fg99c546abc6dd65d0@mail.gmail.com","threadId":"15063","inReplyTo":"4b6f054f0808171702q10d89dfey98afa65634d26e91@mail.gmail.com","subject":"Re: Call Me Gitless","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2008-08-18T00:40:09Z","receivedAt":"2008-08-18T00:40:09Z","isPatch":false,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"On Mon, Aug 18, 2008 at 12:02 PM, Trans <transfire@gmail.com> wrote:\n> Well, after a few days of using git, I've decide Linus is too smart to\n> be designing end-user interfaces.\n\nI think you'll find all the current DSCMs have converged to a similar\ncore set of commands. Commit/diff/log are in the same place as anyone\nwould expect. The main difference from the svn/cvs world is the\npush/pull pair. The only really new thing that git brings to bear is\nthat we have an index and our doco is slightly more jargon-laden (but\nseveral of the intros that abound 'round the net are fantastic).\n\nIn any case, have safe travels. A lot of people have found Hg to be\nalmost the same but simpler, and a good part of them have later come\nback to git. Others have had a similar experience with BazaarNG.\nThings are far from settled.\n\nDSCMs have mostly sane storage models, so it's possible to write\nlossless importers/exporters. So you can transform your git repos into\nhg, and do the reverse trip if/when you want to try git again.\n\nenjoy,\n\n\nm\n-- \n martin.langhoff@gmail.com\n martin@laptop.org -- School Server Architect\n - ask interesting questions\n - don't get distracted with shiny stuff - working code first\n - http://wiki.laptop.org/go/User:Martinlanghoff\n"},{"id":"87521","messageId":"48A937F2.60608@obry.net","threadId":"15063","inReplyTo":"4b6f054f0808171702q10d89dfey98afa65634d26e91@mail.gmail.com","subject":"Re: Call Me Gitless","fromName":"Pascal Obry","fromEmail":"pascal@obry.net","sentAt":"2008-08-18T08:50:58Z","receivedAt":"2008-08-18T08:50:58Z","isPatch":false,"sender":{"key":"pascal@obry.net","avatar":"https://avatars.githubusercontent.com/u/467069?v=4"},"body":"Trans a écrit :\n> Well, after a few days of using git, I've decide Linus is too smart to\n> be designing end-user interfaces.\n\nAnybody can think this way at first. I can tell you that it is worth \nspending time to understand how Git works. It is a wonderful and quite \npowerful tool. After some time you just can't work without it.\n\nJust my 2 cents after a bit more than a year to use Git.\n\n-- \n\n--|------------------------------------------------------\n--| Pascal Obry                           Team-Ada Member\n--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE\n--|------------------------------------------------------\n--|              http://www.obry.net\n--| \"The best way to travel is by means of imagination\"\n--|\n--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595\n"},{"id":"87548","messageId":"1219077801.21513.3.camel@ld0161-tx32","threadId":"15063","inReplyTo":"4b6f054f0808171702q10d89dfey98afa65634d26e91@mail.gmail.com","subject":"Re: Call Me Gitless","fromName":"Jon Loeliger","fromEmail":"jdl@freescale.com","sentAt":"2008-08-18T16:43:21Z","receivedAt":"2008-08-18T16:43:21Z","isPatch":false,"sender":{"key":"jdl@jdl.com","avatar":"https://gravatar.com/avatar/75ce9a10b151acd2c28ec4ab2136dba7b2ff1634530bd04b155981a749d08a64?d=mp&s=160"},"body":"On Sun, 2008-08-17 at 20:02 -0400, Trans wrote:\n> Well, after a few days of using git, I've decide Linus is too smart to\n> be designing end-user interfaces.\n\nHrm.  And luckily, you gave us a hint where your difficulties lie, too.\nThat way we might address your concerns and make improvements.\n\njdl\n"},{"id":"87557","messageId":"alpine.LNX.1.00.0808181512160.19665@iabervon.org","threadId":"15063","inReplyTo":"4b6f054f0808171702q10d89dfey98afa65634d26e91@mail.gmail.com","subject":"Re: Call Me Gitless","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-08-18T19:22:37Z","receivedAt":"2008-08-18T19:22:37Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Sun, 17 Aug 2008, Trans wrote:\n\n> Well, after a few days of using git, I've decide Linus is too smart to\n> be designing end-user interfaces.\n\nThis is true, but hardly relevant. Git's end-user interface was almost \nentirely designed by other people, using Linus's excellent \nscript-developer API.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"87567","messageId":"48A9D8F0.9090309@gmail.com","threadId":"15063","inReplyTo":"alpine.LNX.1.00.0808181512160.19665@iabervon.org","subject":"Re: Call Me Gitless","fromName":"Marcus Griep","fromEmail":"neoeinstein@gmail.com","sentAt":"2008-08-18T20:17:52Z","receivedAt":"2008-08-18T20:17:52Z","isPatch":false,"sender":{"key":"neoeinstein@gmail.com","avatar":"https://gravatar.com/avatar/75d467077b37e56699d408fb97545e9a92a2907ff1feea4ba3a4b861f7cb7af4?d=mp&s=160"},"body":"Daniel Barkalow wrote:\n>> Well, after a few days of using git, I've decide Linus is too smart to\n>> be designing end-user interfaces.\n> \n> This is true, but hardly relevant. Git's end-user interface was almost \n> entirely designed by other people, using Linus's excellent \n> script-developer API.\n\nBlame the plumbers. :-P\n\n-- \nMarcus Griep\nGPG Key ID: 0x5E968152\n——\nhttp://www.boohaunt.net\nאת.ψο´\n"},{"id":"87569","messageId":"7vfxp2m5w8.fsf@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"alpine.LNX.1.00.0808181512160.19665@iabervon.org","subject":"Re: Call Me Gitless","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-18T20:20:55Z","receivedAt":"2008-08-18T20:20:55Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> On Sun, 17 Aug 2008, Trans wrote:\n>\n>> Well, after a few days of using git, I've decide Linus is too smart to\n>> be designing end-user interfaces.\n>\n> This is true, but hardly relevant. Git's end-user interface was almost \n> entirely designed by other people, using Linus's excellent \n> script-developer API.\n\nI'd agree that you cannot judge Linus's ability to design end-user\ninterfaces by observing the UI of git.\n\nI am pleased to see that almost everybody who responded in this thread has\nrefrained from saying meaningless things (aka feeding the troll) to waste\npeople's mental bandwidth.\n\nI think there are three majorly different reasons that new people can get\nconfused.\n\n(1) Some concepts in git are different from what people from other systems\n    are used to.  For example, A new person may be puzzled by the\n    distinction among \"git diff\", \"git diff HEAD\" and \"git diff --cached\"\n    and say \"why do you have these three?\"\n\n    Complaining that we have these three instead of two, claiming that\n    such complexity is a source of UI clunkiness, is an invalid argument\n    made by a new person who does not understand the index.  People who do\n    take advantage of the index need the distinction among these three.\n    We shouldn't be doing anything but educate them against that kind of\n    complaints.\n\n    However, I think it is valid to say, for a person who does not use\n    index very actively (i.e. one who does not incrementally stage), what\n    \"git diff\" does is confusing.  It does not say anything about new\n    files (until it is modified since added) while showing changes for\n    existing files.  CVS does the same thing (\"file foo is a newly added\n    file, no comparison available\"), but that may not be a good excuse.\n\n    If we had a configuration for \"index-free\" people, that changes the\n    semantics of \"git add\" to register object name of an empty blob when a\n    new path is added, makes \"git add\" for existing blobs a no-op, but\n    keeps \"git commit -a\" and \"git commit <paths>\" to operate as they\n    currently do, then people with such configuration could:\n\n\t$ >new-file\n        $ git add new-file\n        $ edit old-file\n        $ edit new-file\n        $ git diff\n\n    to always see what's the difference from the HEAD is with \"git diff\",\n    and any of these three:\n\n\t$ git commit -a\n        $ git commit old-file\n        $ git commit old-file new-file\n\n    would work as expected by them.  We still need to support the three\n    diff variants for normal git people, but people who do not use index\n    do not have to know the two variants (\"git diff\" vs \"git diff HEAD\");\n    such a change could be argued as a \"UI improvement\" [*1*].\n\n(2) Some concepts in git are different from what they are used to, without\n    any good reason.  IOW, the concepts have room for improvement, and our\n    UI is based on these faulty concepts.\n\n(3) Some concepts in git may be exactly the same with other systems, yet\n    our UI may operate differently from them without any good reason.\n\nI'd be surprised if there is _no_ UI element that falls into the latter\ntwo categories, but obviously I would not be able to list examples.  If I\ncould, they instead would have long been fixed already.\n\n\n[Footnote]\n\n*1* I need to stress that this is just an example for example's sake.  I\npersonally do not think such an index-free \"training wheel\" configuration\nis a good idea.\n"},{"id":"87575","messageId":"alpine.LNX.1.00.0808181628420.19665@iabervon.org","threadId":"15063","inReplyTo":"7vfxp2m5w8.fsf@gitster.siamese.dyndns.org","subject":"Re: Call Me Gitless","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-08-18T21:31:21Z","receivedAt":"2008-08-18T21:31:21Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Mon, 18 Aug 2008, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > On Sun, 17 Aug 2008, Trans wrote:\n> >\n> >> Well, after a few days of using git, I've decide Linus is too smart to\n> >> be designing end-user interfaces.\n> >\n> > This is true, but hardly relevant. Git's end-user interface was almost \n> > entirely designed by other people, using Linus's excellent \n> > script-developer API.\n> \n> I'd agree that you cannot judge Linus's ability to design end-user\n> interfaces by observing the UI of git.\n> \n> I am pleased to see that almost everybody who responded in this thread has\n> refrained from saying meaningless things (aka feeding the troll) to waste\n> people's mental bandwidth.\n> \n> I think there are three majorly different reasons that new people can get\n> confused.\n> \n> (1) Some concepts in git are different from what people from other systems\n>     are used to.  For example, A new person may be puzzled by the\n>     distinction among \"git diff\", \"git diff HEAD\" and \"git diff --cached\"\n>     and say \"why do you have these three?\"\n> \n>     Complaining that we have these three instead of two, claiming that\n>     such complexity is a source of UI clunkiness, is an invalid argument\n>     made by a new person who does not understand the index.  People who do\n>     take advantage of the index need the distinction among these three.\n>     We shouldn't be doing anything but educate them against that kind of\n>     complaints.\n> \n>     However, I think it is valid to say, for a person who does not use\n>     index very actively (i.e. one who does not incrementally stage), what\n>     \"git diff\" does is confusing.  It does not say anything about new\n>     files (until it is modified since added) while showing changes for\n>     existing files.  CVS does the same thing (\"file foo is a newly added\n>     file, no comparison available\"), but that may not be a good excuse.\n\nThere's another issue here, I think. It's not clear from an understanding \nof the index, working tree, and commits that the default for \"git diff\" is \nbetween the working tree and the index, as opposed to one of the other \npossibilities. For most systems, \"diff\" without options is a preview of \nwhat would be in the patch if you were to commit; \"git diff\", on the other \nhand, shows what would be left out of the patch. So, even given that \npeople understand the meaning of the index, they can fail to understand \nwhat \"diff\" will tell them. And diff is a bit unhelpful in that it \ngenerates headers as for \"diff -r a b\", regardless of what the things are; \nif you'd get:\n\n--- (index)/foo/bar\n+++ ./foo/bar\n\npeople would at least be clear on what information they were getting, even \nif they didn't know why they were getting that as opposed to a different \ncombination.\n\n>     If we had a configuration for \"index-free\" people, that changes the\n>     semantics of \"git add\" to register object name of an empty blob when a\n>     new path is added, makes \"git add\" for existing blobs a no-op, but\n>     keeps \"git commit -a\" and \"git commit <paths>\" to operate as they\n>     currently do, then people with such configuration could:\n> \n> \t$ >new-file\n>         $ git add new-file\n>         $ edit old-file\n>         $ edit new-file\n>         $ git diff\n> \n>     to always see what's the difference from the HEAD is with \"git diff\",\n>     and any of these three:\n> \n> \t$ git commit -a\n>         $ git commit old-file\n>         $ git commit old-file new-file\n> \n>     would work as expected by them.  We still need to support the three\n>     diff variants for normal git people, but people who do not use index\n>     do not have to know the two variants (\"git diff\" vs \"git diff HEAD\");\n>     such a change could be argued as a \"UI improvement\" [*1*].\n\nI think that having the possibility of adding an empty blob (or maybe a \nmagical \"nothing currently here but git-ls-files includes it\") would be \npreferrable to a no-index mode. That is, the operation that corresponds \nmost directly to \"cvs add <filename>\" is \"git update-index --cacheinfo \n100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 <filename>\", which is not \nexactly easy to do, and just because a user wants to do this doesn't mean \nthe user doesn't want to use the index; a user that makes extensive use of \nthe index is actually more likely to want the state where a file is \ntracked but all of the content has not yet been staged.\n\nBut we've argued this before.\n\n> (2) Some concepts in git are different from what they are used to, without\n>     any good reason.  IOW, the concepts have room for improvement, and our\n>     UI is based on these faulty concepts.\n> \n> (3) Some concepts in git may be exactly the same with other systems, yet\n>     our UI may operate differently from them without any good reason.\n> \n> I'd be surprised if there is _no_ UI element that falls into the latter\n> two categories, but obviously I would not be able to list examples.  If I\n> could, they instead would have long been fixed already.\n\nYou've got to include the class of \"The concepts in git are exactly the \nsame as with other systems (although git also has additional concepts), \nand commands from other systems do not do the same thing in git (with or \nwithout good reason).\"\n\nE.g., git has a working directory, and git has a committed state, and CVS \nhas both of these, and \"cvs diff\" compares the working directory with the \ncommitted state, but \"git diff\" does a different operation.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"87578","messageId":"7vtzdiklbw.fsf@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"alpine.LNX.1.00.0808181628420.19665@iabervon.org","subject":"Re: Call Me Gitless","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-18T22:30:27Z","receivedAt":"2008-08-18T22:30:27Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> if you'd get:\n>\n> --- (index)/foo/bar\n> +++ ./foo/bar\n>\n> people would at least be clear on what information they were getting, even \n> if they didn't know why they were getting that as opposed to a different \n> combination.\n\n[Removed somebody who decided not use git from CC.]\n\nI know you mentioned this as an example of differenciating the output\nbetween the modes, and not as a serious suggestion.  The above may apply\ncleanly because \"(index)\" and \".\" are both one level deep, but they look\nugly and the filenames do not align.\n\nIt does look an interesting approach, though.\n\nI often make a quick patch all inside the work tree, never committing, and\nthen send it out by including \"git diff --stat -p\" output in the mail as a\nsuggested patch.  If we did what you suggest, people could tell such a\npatch and a format-patch output.  I actually do like the fact that we\nconsistently say \"a/\" vs \"b/\", but some people actually may prefer to see\nthe difference.\n"},{"id":"87585","messageId":"alpine.LNX.1.00.0808181839390.19665@iabervon.org","threadId":"15063","inReplyTo":"7vtzdiklbw.fsf@gitster.siamese.dyndns.org","subject":"Re: Call Me Gitless","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-08-18T23:12:43Z","receivedAt":"2008-08-18T23:12:43Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Mon, 18 Aug 2008, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > if you'd get:\n> >\n> > --- (index)/foo/bar\n> > +++ ./foo/bar\n> >\n> > people would at least be clear on what information they were getting, even \n> > if they didn't know why they were getting that as opposed to a different \n> > combination.\n> \n> [Removed somebody who decided not use git from CC.]\n> \n> I know you mentioned this as an example of differenciating the output\n> between the modes, and not as a serious suggestion.  The above may apply\n> cleanly because \"(index)\" and \".\" are both one level deep, but they look\n> ugly and the filenames do not align.\n\nI actually think it would be fine; the filenames don't align, but it \ndoesn't matter much because we practically never have patches where they \naren't the same anyway (unless there are also rename headers), so there's \nno need for it to be easy to compare them visually.\n\n> I often make a quick patch all inside the work tree, never committing, and\n> then send it out by including \"git diff --stat -p\" output in the mail as a\n> suggested patch.  If we did what you suggest, people could tell such a\n> patch and a format-patch output.  I actually do like the fact that we\n> consistently say \"a/\" vs \"b/\", but some people actually may prefer to see\n> the difference.\n\nYou could use --src-prefix and --dest-prefix to put it back to a/ and b/ \n(or whatever else you wanted to make it look like). The opposite isn't \nreally true though; while I can use --src-prefix='(index)/' \n--dest-prefix='./', I'd need to figure out per-command-line what I'm going \nto be getting, which sort of defeats the purpose.\n\nActually, this weekend I was trying to cherry-pick the aggregated changes \nto certain files from one branch onto another, and was repeatedly confused \nby the fact that the only available diffs are backwards and there're no \nclues in the output. (That is, you can't get the difference between (---) \nthe {index,working tree} and (+++) some commit, and when you've done \"git \ndiff messy\", the resulting diff doesn't give any clues that you're \ndeciding whether to add the - lines and remove the + lines.)\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"87592","messageId":"905315640808181624w58918a0ao939a3f0462f9dc9e@mail.gmail.com","threadId":"15063","inReplyTo":"7vfxp2m5w8.fsf@gitster.siamese.dyndns.org","subject":"Re: Call Me Gitless","fromName":"Tarmigan","fromEmail":"tarmigan+git@gmail.com","sentAt":"2008-08-18T23:24:35Z","receivedAt":"2008-08-18T23:24:35Z","isPatch":false,"sender":{"key":"tarmigan+git@gmail.com","avatar":null},"body":"On Mon, Aug 18, 2008 at 1:20 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> (2) Some concepts in git are different from what they are used to, without\n>    any good reason.  IOW, the concepts have room for improvement, and our\n>    UI is based on these faulty concepts.\n>\n> (3) Some concepts in git may be exactly the same with other systems, yet\n>    our UI may operate differently from them without any good reason.\n\nOne confusing part of the porcelain may be the way that git's revert\nis different from other systems' revert.  What would people think\nabout something like this somewhere in git-revert(1)?\n\n+DISCUSSION\n+----------\n+If you are more familiar with another SCM, 'git revert' may not do what you\n+expect.  Specifically, if you want to throw away all changes in your working\n+directory, you should read the man page for 'git reset', particulary the\n+'--hard' option.  If you want to extract specific files as they were in a\n+previous commit, you should read the man page for 'git checkout -- <filename>'.\n+\n\nasciidoc probably won't like that as is, but if people like the idea,\nI can make up a real patch.\n\nThanks,\nTarmigan\n"},{"id":"87626","messageId":"alpine.LNX.1.00.0808182027240.19665@iabervon.org","threadId":"15063","inReplyTo":"905315640808181624w58918a0ao939a3f0462f9dc9e@mail.gmail.com","subject":"Re: Call Me Gitless","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-08-19T00:32:32Z","receivedAt":"2008-08-19T00:32:32Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Mon, 18 Aug 2008, Tarmigan wrote:\n\n> On Mon, Aug 18, 2008 at 1:20 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> > (2) Some concepts in git are different from what they are used to, without\n> >    any good reason.  IOW, the concepts have room for improvement, and our\n> >    UI is based on these faulty concepts.\n> >\n> > (3) Some concepts in git may be exactly the same with other systems, yet\n> >    our UI may operate differently from them without any good reason.\n> \n> One confusing part of the porcelain may be the way that git's revert\n> is different from other systems' revert.  What would people think\n> about something like this somewhere in git-revert(1)?\n> \n> +DISCUSSION\n> +----------\n> +If you are more familiar with another SCM, 'git revert' may not do what you\n> +expect.  Specifically, if you want to throw away all changes in your working\n> +directory, you should read the man page for 'git reset', particulary the\n> +'--hard' option.  If you want to extract specific files as they were in a\n> +previous commit, you should read the man page for 'git checkout -- <filename>'.\n\n\"as they were in a particular commit\"; it works for the current commit as \nwell as older ones. And skip the first sentence; even people who aren't \nfamiliar with another SCM are reasonably likely to be attracted by the \nname \"revert\" as being descriptive of what they want to do.\n\nI think this is a good idea, although clever placement is necessary to \nneither distract people who really do want \"revert\" nor get missed by \npeople who are looking in the wrong place.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"87629","messageId":"905315640808181745n7186aa1bu62f6d454255fd805@mail.gmail.com","threadId":"15063","inReplyTo":"alpine.LNX.1.00.0808182027240.19665@iabervon.org","subject":"Re: Call Me Gitless","fromName":"Tarmigan","fromEmail":"tarmigan+git@gmail.com","sentAt":"2008-08-19T00:45:02Z","receivedAt":"2008-08-19T00:45:02Z","isPatch":false,"sender":{"key":"tarmigan+git@gmail.com","avatar":null},"body":"On Mon, Aug 18, 2008 at 5:32 PM, Daniel Barkalow <barkalow@iabervon.org> wrote:\n> On Mon, 18 Aug 2008, Tarmigan wrote:\n>\n>> On Mon, Aug 18, 2008 at 1:20 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> > (2) Some concepts in git are different from what they are used to, without\n>> >    any good reason.  IOW, the concepts have room for improvement, and our\n>> >    UI is based on these faulty concepts.\n>> >\n>> > (3) Some concepts in git may be exactly the same with other systems, yet\n>> >    our UI may operate differently from them without any good reason.\n>>\n>> One confusing part of the porcelain may be the way that git's revert\n>> is different from other systems' revert.  What would people think\n>> about something like this somewhere in git-revert(1)?\n>>\n>> +DISCUSSION\n>> +----------\n>> +If you are more familiar with another SCM, 'git revert' may not do what you\n>> +expect.  Specifically, if you want to throw away all changes in your working\n>> +directory, you should read the man page for 'git reset', particulary the\n>> +'--hard' option.  If you want to extract specific files as they were in a\n>> +previous commit, you should read the man page for 'git checkout -- <filename>'.\n>\n> \"as they were in a particular commit\"; it works for the current commit as\n> well as older ones. And skip the first sentence; even people who aren't\n> familiar with another SCM are reasonably likely to be attracted by the\n> name \"revert\" as being descriptive of what they want to do.\n\nGood points, thanks.\n\n> I think this is a good idea, although clever placement is necessary to\n> neither distract people who really do want \"revert\" nor get missed by\n> people who are looking in the wrong place.\n\nYes, I actually didn't include any context because I wasn't sure where\nto put it and was hoping for feedback on that front as well.\ngit-revert(1) is very short as it is, so I would be inclined to put\nthe DISCUSSION fairly early, like between the DESCRIPTION and the\nOPTIONS so it is very easy to find.  But it seems incorrect to put it\nbefore the options.  Perhaps that text should just be a note in the\nDESCRIPTION?\n\nThanks,\nTarmigan\n"},{"id":"87639","messageId":"7vy72tit90.fsf@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"alpine.LNX.1.00.0808181839390.19665@iabervon.org","subject":"Re: Call Me Gitless","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-19T03:22:19Z","receivedAt":"2008-08-19T03:22:19Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> Actually, this weekend I was trying to cherry-pick the aggregated changes \n> to certain files from one branch onto another, and was repeatedly confused \n> by the fact that the only available diffs are backwards and there're no \n> clues in the output. (That is, you can't get the difference between (---) \n> the {index,working tree} and (+++) some commit, and when you've done \"git \n> diff messy\", the resulting diff doesn't give any clues that you're \n> deciding whether to add the - lines and remove the + lines.)\n\nI do not know if I like the end result, but here is a patch to make the\ntraditional a/ and b/ prefix more mnemonic.\n\nA lot of existing tests and documentation need to be updated, if we were\nto do this, though.    The first test to fail is t1200-tutorial.sh.\n\nObviously not tested except for creating this patch that pretends to be a\nformat-patch output.  You can tell that I just did this only in the work\ntree now.\n\n-- >8 --\ndiff: vary default prefix depending on what are compared\n\nThis implements Daniel's idea to indicate what are compared by using\nprefix different from the traditional a/ and b/ in the textual diff\nheader:\n\n    \"git diff\" compares the (i)ndex and the (w)ork tree;\n    \"git diff HEAD\" compares a (c)ommit and the (w)ork tree;\n    \"git diff --cached\" compares a (c)ommit and the (i)ndex;\n    \"git diff HEAD:f /tmp/f\" compares an (o)bject and (w)ork tree.\n\nBecause these mnemonics now have meanings, they are swapped when reverse\ndiff is in effect.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-diff.c |    2 ++\n diff-lib.c     |    3 +++\n diff.c         |   38 +++++++++++++++++++++++++++++++-------\n diff.h         |    2 ++\n 4 files changed, 38 insertions(+), 7 deletions(-)\n\ndiff --git i/builtin-diff.c w/builtin-diff.c\nindex 7ffea97..ecec753 100644\n--- i/builtin-diff.c\n+++ w/builtin-diff.c\n@@ -74,6 +74,8 @@ static int builtin_diff_b_f(struct rev_info *revs,\n \tif (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))\n \t\tdie(\"'%s': not a regular file or symlink\", path);\n \n+\tdiff_set_default_prefix(&revs->diffopt, \"o/\", \"w/\");\n+\n \tif (blob[0].mode == S_IFINVALID)\n \t\tblob[0].mode = canon_mode(st.st_mode);\n \ndiff --git i/diff-lib.c w/diff-lib.c\nindex e7eaff9..969f8c1 100644\n--- i/diff-lib.c\n+++ w/diff-lib.c\n@@ -63,6 +63,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option)\n \t\t\t      ? CE_MATCH_RACY_IS_DIRTY : 0);\n \tchar symcache[PATH_MAX];\n \n+\tdiff_set_default_prefix(&revs->diffopt, \"i/\", \"w/\");\n+\n \tif (diff_unmerged_stage < 0)\n \t\tdiff_unmerged_stage = 2;\n \tentries = active_nr;\n@@ -469,6 +471,7 @@ int run_diff_index(struct rev_info *revs, int cached)\n \tif (unpack_trees(1, &t, &opts))\n \t\texit(128);\n \n+\tdiff_set_default_prefix(&revs->diffopt, \"c/\", cached ? \"i/\" : \"w/\");\n \tdiffcore_std(&revs->diffopt);\n \tdiff_flush(&revs->diffopt);\n \treturn 0;\ndiff --git i/diff.c w/diff.c\nindex bf5d5f1..1c518c6 100644\n--- i/diff.c\n+++ w/diff.c\n@@ -305,6 +305,15 @@ static void emit_rewrite_diff(const char *name_a,\n \tconst char *new = diff_get_color(color_diff, DIFF_FILE_NEW);\n \tconst char *reset = diff_get_color(color_diff, DIFF_RESET);\n \tstatic struct strbuf a_name = STRBUF_INIT, b_name = STRBUF_INIT;\n+\tconst char *a_prefix, *b_prefix;\n+\n+\tif (DIFF_OPT_TST(o, REVERSE_DIFF)) {\n+\t\ta_prefix = o->b_prefix;\n+\t\tb_prefix = o->a_prefix;\n+\t} else {\n+\t\ta_prefix = o->a_prefix;\n+\t\tb_prefix = o->b_prefix;\n+\t}\n \n \tname_a += (*name_a == '/');\n \tname_b += (*name_b == '/');\n@@ -313,8 +322,8 @@ static void emit_rewrite_diff(const char *name_a,\n \n \tstrbuf_reset(&a_name);\n \tstrbuf_reset(&b_name);\n-\tquote_two_c_style(&a_name, o->a_prefix, name_a, 0);\n-\tquote_two_c_style(&b_name, o->b_prefix, name_b, 0);\n+\tquote_two_c_style(&a_name, a_prefix, name_a, 0);\n+\tquote_two_c_style(&b_name, b_prefix, name_b, 0);\n \n \tdiff_populate_filespec(one, 0);\n \tdiff_populate_filespec(two, 0);\n@@ -1424,6 +1433,14 @@ static const char *diff_funcname_pattern(struct diff_filespec *one)\n \treturn NULL;\n }\n \n+void diff_set_default_prefix(struct diff_options *options, const char *a, const char *b)\n+{\n+\tif (!options->a_prefix)\n+\t\toptions->a_prefix = a;\n+\tif (!options->b_prefix)\n+\t\toptions->b_prefix = b;\n+}\n+\n static void builtin_diff(const char *name_a,\n \t\t\t const char *name_b,\n \t\t\t struct diff_filespec *one,\n@@ -1437,9 +1454,19 @@ static void builtin_diff(const char *name_a,\n \tchar *a_one, *b_two;\n \tconst char *set = diff_get_color_opt(o, DIFF_METAINFO);\n \tconst char *reset = diff_get_color_opt(o, DIFF_RESET);\n+\tconst char *a_prefix, *b_prefix;\n \n-\ta_one = quote_two(o->a_prefix, name_a + (*name_a == '/'));\n-\tb_two = quote_two(o->b_prefix, name_b + (*name_b == '/'));\n+\tdiff_set_default_prefix(o, \"a/\", \"b/\");\n+\tif (DIFF_OPT_TST(o, REVERSE_DIFF)) {\n+\t\ta_prefix = o->b_prefix;\n+\t\tb_prefix = o->a_prefix;\n+\t} else {\n+\t\ta_prefix = o->a_prefix;\n+\t\tb_prefix = o->b_prefix;\n+\t}\n+\n+\ta_one = quote_two(a_prefix, name_a + (*name_a == '/'));\n+\tb_two = quote_two(b_prefix, name_b + (*name_b == '/'));\n \tlbl[0] = DIFF_FILE_VALID(one) ? a_one : \"/dev/null\";\n \tlbl[1] = DIFF_FILE_VALID(two) ? b_two : \"/dev/null\";\n \tfprintf(o->file, \"%sdiff --git %s %s%s\\n\", set, a_one, b_two, reset);\n@@ -2298,9 +2325,6 @@ void diff_setup(struct diff_options *options)\n \telse\n \t\tDIFF_OPT_CLR(options, COLOR_DIFF);\n \toptions->detect_rename = diff_detect_rename_default;\n-\n-\toptions->a_prefix = \"a/\";\n-\toptions->b_prefix = \"b/\";\n }\n \n int diff_setup_done(struct diff_options *options)\ndiff --git i/diff.h w/diff.h\nindex 50fb5dd..5782fef 100644\n--- i/diff.h\n+++ w/diff.h\n@@ -160,6 +160,8 @@ extern void diff_tree_combined(const unsigned char *sha1, const unsigned char pa\n \n extern void diff_tree_combined_merge(const unsigned char *sha1, int, struct rev_info *);\n \n+void diff_set_default_prefix(struct diff_options *options, const char *a, const char *b);\n+\n extern void diff_addremove(struct diff_options *,\n \t\t\t   int addremove,\n \t\t\t   unsigned mode,\n"},{"id":"87642","messageId":"48AA4430.3060207@gmail.com","threadId":"15063","inReplyTo":"7vy72tit90.fsf@gitster.siamese.dyndns.org","subject":"Re: Call Me Gitless","fromName":"Marcus Griep","fromEmail":"neoeinstein@gmail.com","sentAt":"2008-08-19T03:55:28Z","receivedAt":"2008-08-19T03:55:28Z","isPatch":false,"sender":{"key":"neoeinstein@gmail.com","avatar":"https://gravatar.com/avatar/75d467077b37e56699d408fb97545e9a92a2907ff1feea4ba3a4b861f7cb7af4?d=mp&s=160"},"body":"Junio C Hamano wrote:\n> This implements Daniel's idea to indicate what are compared by using\n> prefix different from the traditional a/ and b/ in the textual diff\n> header:\n> \n>     \"git diff\" compares the (i)ndex and the (w)ork tree;\n>     \"git diff HEAD\" compares a (c)ommit and the (w)ork tree;\n>     \"git diff --cached\" compares a (c)ommit and the (i)ndex;\n>     \"git diff HEAD:f /tmp/f\" compares an (o)bject and (w)ork tree.\n> \n> Because these mnemonics now have meanings, they are swapped when reverse\n> diff is in effect.\n\nI like this proposal-ish; making the prefixes more intuitive could be\nuseful when looking at a bare diff from git too.  I'd put some time in\nto help implement this.\n\n-- \nMarcus Griep\nGPG Key ID: 0x5E968152\n——\nhttp://www.boohaunt.net\nאת.ψο´\n\n"},{"id":"87646","messageId":"20080819062828.GA30750@cuci.nl","threadId":"15063","inReplyTo":"7vy72tit90.fsf@gitster.siamese.dyndns.org","subject":"Re: Call Me Gitless","fromName":"Stephen R. van den Berg","fromEmail":"srb@cuci.nl","sentAt":"2008-08-19T06:28:28Z","receivedAt":"2008-08-19T06:28:28Z","isPatch":false,"sender":{"key":"srb@cuci.nl","avatar":"https://gravatar.com/avatar/f75389059e827634d38e9df2a9b6ecbd50028b5a454442efa1c7205b7ff29c6a?d=mp&s=160"},"body":"Junio C Hamano wrote:\n>I do not know if I like the end result, but here is a patch to make the\n>traditional a/ and b/ prefix more mnemonic.\n\n>diff: vary default prefix depending on what are compared\n\n>diff --git i/builtin-diff.c w/builtin-diff.c\n\n>--- i/builtin-diff.c\n>+++ w/builtin-diff.c\n\nI consider this an improvement.\n-- \nSincerely,\n           Stephen R. van den Berg.\n\"Papers in string theory are published at a rate above the speed of light.\n This is no problem since no information is being transmitted.\" -- H. Kleinert\n"},{"id":"87647","messageId":"7vmyj9h567.fsf@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"48AA4430.3060207@gmail.com","subject":"Re: Call Me Gitless","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-19T06:47:44Z","receivedAt":"2008-08-19T06:47:44Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Marcus Griep <neoeinstein@gmail.com> writes:\n\n> Junio C Hamano wrote:\n>\n>> This implements Daniel's idea to indicate what are compared by using\n>> prefix different from the traditional a/ and b/ in the textual diff\n>> header:\n>> \n>>     \"git diff\" compares the (i)ndex and the (w)ork tree;\n>>     \"git diff HEAD\" compares a (c)ommit and the (w)ork tree;\n>>     \"git diff --cached\" compares a (c)ommit and the (i)ndex;\n>>     \"git diff HEAD:f /tmp/f\" compares an (o)bject and (w)ork tree.\n>> \n>> Because these mnemonics now have meanings, they are swapped when reverse\n>> diff is in effect.\n>\n> I like this proposal-ish; making the prefixes more intuitive could be\n> useful when looking at a bare diff from git too.  I'd put some time in\n> to help implement this.\n\nWhat I did not bother in the patch is --no-index codepath, but with the\nrecent refactoring of it to separate it out from the normal \"index vs work\ntree\" codepath, I would expect it to be trivial to use \"1/\" vs \"2/\" (or\n\"old/\" and \"new/\") prefixes for them.  I didn't actually look, though.\n\nI also left \"-c\" and \"--cc\" unmodified.  Daniel's \"have many patches to\napply, but cannot readily tell in which direction they were generated\"\nuse-case won't involve them, and reverse diff won't make sense with --cc,\nso that should be Ok.\n\nAnd obviously I didn't adjust the test vectors and documentation, which is\nneeded if somebody is serious enough about actually making this part of\nthe official system.\n\nBut be warned that this has two downsides, one minor, and one rather\nmajor:\n\n * Using non-standard prefix affects git-patch-id output.  This would not\n   affect \"git-format-patch --ignore-if-in-upstream\", \"git-cherry\",\n   \"git-rebase\" because they all use internal patch-id generation, but\n   third party scripts that feed patches to \"git-patch-id\" and compare its\n   output with precomputed patch-id database to cull duplicates will be\n   affected.\n\n * Similarly, scripts that assume more about \"git diff\" output than that\n   they are meant to be applied with depth 1 may break.\n\n   I think gitweb would be Ok, because I do not think it would try parsing\n   a textual diff, stripping out a/ (or b/), to figure out the paths being\n   affected.  Even if it did, it would be doing two-tree form (iow, it\n   does not use working tree at all) which I deliberately kept to use a/\n   vs b/ with my patch, so it should be fine.  I do not offhand recall how\n   cvsserver generates its diff output, but it would also be fine as the\n   server side would do two-tree form and nothing else.\n\n   But nobody knows what third-party scripts are assuming.  They may be\n   parsing the pathnames, stripping a/ and b/ away.\n"},{"id":"87648","messageId":"7viqtxh4gt.fsf@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"7vmyj9h567.fsf@gitster.siamese.dyndns.org","subject":"Re: Call Me Gitless","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-19T07:02:58Z","receivedAt":"2008-08-19T07:02:58Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> What I did not bother in the patch is --no-index codepath, but with the\n> recent refactoring of it to separate it out from the normal \"index vs work\n> tree\" codepath, I would expect it to be trivial to use \"1/\" vs \"2/\" (or\n> \"old/\" and \"new/\") prefixes for them.  I didn't actually look, though.\n\nOk, I looked.  It is indeed easy enough ;-)\n\n---\n diff-no-index.c |    1 +\n 1 files changed, 1 insertions(+), 0 deletions(-)\n\ndiff --git i/diff-no-index.c w/diff-no-index.c\nindex 7d68b7f..126ff1c 100644\n--- i/diff-no-index.c\n+++ w/diff-no-index.c\n@@ -252,6 +252,7 @@ void diff_no_index(struct rev_info *revs,\n \tif (queue_diff(&revs->diffopt, revs->diffopt.paths[0],\n \t\t       revs->diffopt.paths[1]))\n \t\texit(1);\n+\tdiff_set_default_prefix(&revs->diffopt, \"1/\", \"2/\");\n \tdiffcore_std(&revs->diffopt);\n \tdiff_flush(&revs->diffopt);\n \n"},{"id":"87652","messageId":"7vbpzph3fx.fsf@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"alpine.LNX.1.00.0808181628420.19665@iabervon.org","subject":"Re: Call Me Gitless","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-19T07:25:06Z","receivedAt":"2008-08-19T07:25:06Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> .... For most systems, \"diff\" without options is a preview of \n> what would be in the patch if you were to commit; \"git diff\", on the other \n> hand, shows what would be left out of the patch.\n\nThat is true, but I also think that is because (1) on other systems, you\ncannot even choose to select changes to \"leave out of the patch\", so they\nhave no option other than showing \"what could be committed\", and (2) by\ndefinition active use of index means that you are staging incrementally,\nand it is natural to expect you to want to view \"changes since the last\nstaging\" much more often than \"what would be committed\" when you are\nstaging incrementally, so the current default is the _right_ one.\n\nSo I'd say the below is a faulty argument:\n\n> ...  So, even given that \n> people understand the meaning of the index, they can fail to understand \n> what \"diff\" will tell them.\n\nIf they understand \"the meaning of the index\", not just as literal reading\nof the manual page \"it is a staging area to prepare for the next commit\",\nbut including the reason why there is a \"staging area\" and how it is to be\nused, they would reach the conclusion that \"diff by default will show the\nleftover from incremental staging and it is the right thing\".\n\n> ... And diff is a bit unhelpful in that it \n> generates headers as for \"diff -r a b\", regardless of what the things are.\n\nWe have a separate thread on this now ;-)\n\n>> (2) Some concepts in git are different from what they are used to, without\n>>     any good reason.  IOW, the concepts have room for improvement, and our\n>>     UI is based on these faulty concepts.\n>> \n>> (3) Some concepts in git may be exactly the same with other systems, yet\n>>     our UI may operate differently from them without any good reason.\n>> \n>> I'd be surprised if there is _no_ UI element that falls into the latter\n>> two categories, but obviously I would not be able to list examples.  If I\n>> could, they instead would have long been fixed already.\n>\n> You've got to include the class of \"The concepts in git are exactly the \n> same as with other systems (although git also has additional concepts), \n> and commands from other systems do not do the same thing in git (with or \n> without good reason).\"\n\nIsn't it the same as (3)?\n\n> E.g., git has a working directory, and git has a committed state, and CVS \n> has both of these, and \"cvs diff\" compares the working directory with the \n> committed state, but \"git diff\" does a different operation.\n\nAh, Ok, that is not the same as (3), but \"although git has more\" makes it\ntotally different.\n\nYour example sounds like comparing a car and a motorcycle.  Yes they both\nshare two tyres, but the former having two more tyres makes the driving\ntechnique of the whole thing quite different, doesn't it?\n"},{"id":"87658","messageId":"48AA7BE9.4040108@sneakemail.com","threadId":"15063","inReplyTo":"905315640808181624w58918a0ao939a3f0462f9dc9e@mail.gmail.com","subject":"Re: Call Me Gitless","fromName":"Peter Valdemar Mørch (Lists)","fromEmail":"4ux6as402@sneakemail.com","sentAt":"2008-08-19T07:53:13Z","receivedAt":"2008-08-19T07:53:13Z","isPatch":false,"sender":{"key":"4ux6as402@sneakemail.com","avatar":null},"body":"Tarmigan tarmigan+git-at-gmail.com |Lists| wrote:\n> One confusing part of the porcelain may be the way that git's revert\n> is different from other systems' revert.  What would people think\n> about something like this somewhere in git-revert(1)?\n> \n> +DISCUSSION\n> +----------\n> +If you are more familiar with another SCM, 'git revert' may not do what you\n> +expect.  Specifically, if you want to throw away all changes in your working\n> +directory, you should read the man page for 'git reset', particulary the\n> +'--hard' option.  If you want to extract specific files as they were in a\n> +previous commit, you should read the man page for 'git checkout -- <filename>'.\n> +\n\nHere, here! That is *exactly* what I was thinking when I started reading \nthis thread: \"Hey, the \"git diff\" stuff was easy enough, it was the \nreverting (and friends) that caused me trouble!\"\n\nAlso, in the same area, I've now understood that to undo a \"git add\" - \nto remove a change from the index and making it show up as a difference \nbetween the working tree and the index - one can use \"git reset\" \n(without --hard). Would've been helpful to me to have a sentense or \nparagraph about that in git-add.txt, or even in git-reset.txt. (I guess \nit is there in some form  in git-reset.txt, but not clearly. The \"Undo \nadd\" example talks about a dirty index and pull) I missed the simple \nrelationship between git-add and git-reset for a long time.\n\nWe've covered this recently in the \" Considering teaching plumbing to \nusers harmful\" thread, but to me, the newbie, the sheer number of \ndifferent commands was also quite bewildering.\n\nPeter\n-- \nPeter Valdemar Mørch\nhttp://www.morch.com\n"},{"id":"87660","messageId":"7vk5edfn6g.fsf@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"48AA7BE9.4040108@sneakemail.com","subject":"Re: Call Me Gitless","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-19T08:01:43Z","receivedAt":"2008-08-19T08:01:43Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Peter Valdemar Mørch (Lists)\"  <4ux6as402@sneakemail.com> writes:\n\n> Here, here! That is *exactly* what I was thinking when I started\n> reading this thread: \"Hey, the \"git diff\" stuff was easy enough, it\n> was the reverting (and friends) that caused me trouble!\"\n>\n> Also, in the same area, I've now understood that to undo a \"git add\" -\n> to remove a change from the index and making it show up as a\n> difference between the working tree and the index - one can use \"git\n> ... Would've been helpful to me to have a\n> sentense or paragraph about that in git-add.txt,...\n\nWonderful.\n\nCan somebody who is relatively (but not extremely) new to git can\nvolunteer to be a documentation secretary to collect these \"Hear, hear, it\nwould have been very helpful if X were documented next to Y\" stories, and\ncoordinate documentation updates after enough such improvement suggestions\nare collected?\n\nPeople who lost git virginity like myself cannot do this sensibly and\nfairly.  For example, as my mind is already contaminated enough that I\ndiscarded the original \"add this as Discussion item to revert\" message\nafter reading it once, judging it to add extra noise without much merit.\n"},{"id":"87661","messageId":"7bfdc29a0808190110nddaf57fw5bf40903f3072bff@mail.gmail.com","threadId":"15063","inReplyTo":"7vk5edfn6g.fsf@gitster.siamese.dyndns.org","subject":"Re: Call Me Gitless","fromName":"Imran M Yousuf","fromEmail":"imyousuf@gmail.com","sentAt":"2008-08-19T08:10:22Z","receivedAt":"2008-08-19T08:10:22Z","isPatch":false,"sender":{"key":"imyousuf@gmail.com","avatar":"https://gravatar.com/avatar/fda3c870262849d03c7b9c4d288842e128d6d80769fa7bc2d22731b7597928be?d=mp&s=160"},"body":"On Tue, Aug 19, 2008 at 2:01 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> \"Peter Valdemar Mørch (Lists)\"  <4ux6as402@sneakemail.com> writes:\n>\n>> Here, here! That is *exactly* what I was thinking when I started\n>> reading this thread: \"Hey, the \"git diff\" stuff was easy enough, it\n>> was the reverting (and friends) that caused me trouble!\"\n>>\n>> Also, in the same area, I've now understood that to undo a \"git add\" -\n>> to remove a change from the index and making it show up as a\n>> difference between the working tree and the index - one can use \"git\n>> ... Would've been helpful to me to have a\n>> sentense or paragraph about that in git-add.txt,...\n>\n> Wonderful.\n>\n> Can somebody who is relatively (but not extremely) new to git can\n> volunteer to be a documentation secretary to collect these \"Hear, hear, it\n> would have been very helpful if X were documented next to Y\" stories, and\n> coordinate documentation updates after enough such improvement suggestions\n> are collected?\n>\n> People who lost git virginity like myself cannot do this sensibly and\n> fairly.  For example, as my mind is already contaminated enough that I\n> discarded the original \"add this as Discussion item to revert\" message\n> after reading it once, judging it to add extra noise without much merit.\n\nI would not agree it to be a part of git-add man page, but rather it\nshould be a part of doc that explains basic git commands and their\nflows. I feel that we need a place where git flows are explained. IMO,\ngitwiki is a great place for it. I would like to volunteer to add\nthese pages to Wiki.\n\nBest regards,\n\nImran\n\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>\n"},{"id":"87663","messageId":"48AA83B4.2080009@sneakemail.com","threadId":"15063","inReplyTo":"7bfdc29a0808190110nddaf57fw5bf40903f3072bff@mail.gmail.com","subject":"Re: Call Me Gitless","fromName":"Peter Valdemar Mørch (Lists)","fromEmail":"4ux6as402@sneakemail.com","sentAt":"2008-08-19T08:26:28Z","receivedAt":"2008-08-19T08:26:28Z","isPatch":false,"sender":{"key":"4ux6as402@sneakemail.com","avatar":null},"body":"Hi,\n\nImran M Yousuf imyousuf-at-gmail.com |Lists| wrote:\n> I would not agree it to be a part of git-add man page, but rather it\n> should be a part of doc that explains basic git commands and their\n> flows. I feel that we need a place where git flows are explained. IMO,\n> gitwiki is a great place for it. I would like to volunteer to add\n> these pages to Wiki.\n\nWhy not? Shouldn't the man pages be a superset of those other docs?\n\nDoes it seem clear to you from reading \"git help reset\" that it is \nrelated to \"git add\" and that one can undo a git add with git reset?\n\nPeter\n-- \nPeter Valdemar Mørch\nhttp://www.morch.com\n"},{"id":"87667","messageId":"7bfdc29a0808190153o3d3b2635v4276ef4fa65fbb8@mail.gmail.com","threadId":"15063","inReplyTo":"48AA83B4.2080009@sneakemail.com","subject":"Re: Call Me Gitless","fromName":"Imran M Yousuf","fromEmail":"imyousuf@gmail.com","sentAt":"2008-08-19T08:53:09Z","receivedAt":"2008-08-19T08:53:09Z","isPatch":false,"sender":{"key":"imyousuf@gmail.com","avatar":"https://gravatar.com/avatar/fda3c870262849d03c7b9c4d288842e128d6d80769fa7bc2d22731b7597928be?d=mp&s=160"},"body":"On Tue, Aug 19, 2008 at 2:26 PM, \"Peter Valdemar Mørch (Lists)\"\n<4ux6as402@sneakemail.com> wrote:\n> Hi,\n>\n> Imran M Yousuf imyousuf-at-gmail.com |Lists| wrote:\n>>\n>> I would not agree it to be a part of git-add man page, but rather it\n>> should be a part of doc that explains basic git commands and their\n>> flows. I feel that we need a place where git flows are explained. IMO,\n>> gitwiki is a great place for it. I would like to volunteer to add\n>> these pages to Wiki.\n>\n> Why not? Shouldn't the man pages be a superset of those other docs?\n>\n> Does it seem clear to you from reading \"git help reset\" that it is related\n> to \"git add\" and that one can undo a git add with git reset?\n\nActually when I learned git I never learned one command after another,\nrather I learned the flows and the most the scenarios mentioned in\nthis thread mostly got covered then in either first or second flow I\nwas trying. What learning flows enabled was, for me to experience how\ncommands are inter-related.\n\nIt basically depends how a person learns the tool. My way of learning\na tool is to learn flows. I have also taken the same steps to teach\nsome of my friends and colleagues git and all seem to understand the\nstuffs :). But hey, that is my opinion :) only.\n\nBest regards,\n\nImran\n\n>\n> Peter\n> --\n> Peter Valdemar Mørch\n> http://www.morch.com\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>\n"},{"id":"87668","messageId":"20080819085622.GA6261@mithlond.arda.local","threadId":"15063","inReplyTo":"48AA7BE9.4040108@sneakemail.com","subject":"Re: Call Me Gitless","fromName":"Teemu Likonen","fromEmail":"tlikonen@iki.fi","sentAt":"2008-08-19T08:56:22Z","receivedAt":"2008-08-19T08:56:22Z","isPatch":false,"sender":{"key":"tlikonen@iki.fi","avatar":null},"body":"\"Peter Valdemar Mørch (Lists)\" wrote (2008-08-19 09:53 +0200):\n\n> Also, in the same area, I've now understood that to undo a \"git add\" - \n> to remove a change from the index and making it show up as a difference \n> between the working tree and the index - one can use \"git reset\" \n> (without --hard). Would've been helpful to me to have a sentense or \n> paragraph about that in git-add.txt, or even in git-reset.txt. (I guess \n> it is there in some form  in git-reset.txt, but not clearly. The \"Undo \n> add\" example talks about a dirty index and pull) I missed the simple \n> relationship between git-add and git-reset for a long time.\n\nI quite agree here. I've used git about six months now and I'm quite \nfamiliar with the porcelain layer. I don't even care about the plumbing \n(even though I've used some plumbing commands in a script).\n\nAnyway, to me the index wasn't difficult. It took about two days to be \n_comfortable_ enough with the idea of staging area for commits but it \nwasn't too hard. I have been a lot more confused with the\n\n    git reset <commit> -- <file>\n    git checkout <commit> -- <file>\n\nbusiness. These commands still aren't completely clear to me but it has \nbeen helpful that \"git status\" prints info about how to get back changes \nfrom the index. I think the info is a good idea because \"git status\" is,  \nto me at least, a general \"give me some clue\" command.\n\nI think the confusion with reset and checkout comes from the fact that \nfirst I learned that \"git checkout\" changes branches and later that it \ncan actually check-out any commits. Checking out a file to overwrite one \nin the working directory is something I'd expect from \"git reset\". \nI don't think that documentation would have helped much; it's more about \nthe double meaning of the commands.\n"},{"id":"87669","messageId":"ee521d6f0808190157s6a676a75t2ba3ef095f608431@mail.gmail.com","threadId":"15063","inReplyTo":"7vk5edfn6g.fsf@gitster.siamese.dyndns.org","subject":"Re: Call Me Gitless","fromName":"Alexander E Genaud","fromEmail":"alex@genaud.net","sentAt":"2008-08-19T08:57:28Z","receivedAt":"2008-08-19T08:57:28Z","isPatch":false,"sender":{"key":"alex@genaud.net","avatar":"https://gravatar.com/avatar/046079bd0c4a3c04a9d0cdca66980d593471a7c3b13bed8c57e2c5b0aa56844b?d=mp&s=160"},"body":"Hi Junio,\n\nI would volunteer as the documentation git-virgin. To prove the hymen\nintact, here are some of my thoughts and stumbling blocks over the\npast two weeks:\n\nThere is no indication in the documentation distinguishing porcelain\nfrom plumbing. Perhaps there is a grey scale, but operations that do\nnot move the HEAD to the latest should indicate that fact (for\nexample, pull vs. push, fetch).\n\nRemote never seems to do what I expect, so I manually edit the\n.git/refs!! Nor is git-reset what I expect and use git checkout (which\ndoes make sense only after a few backup trials). Git-add adds to the\nindex but does not create, however git-rm removes from the index and\ndoes delete (an --index-only or --keep flag might be nice).\n\nA single term for cache and index should be decided upon. git diff\n--cached is not intuitive when 'index' is used throughout the\ndocumentation. Generally the index is a simple and powerful concept\nthat should be more thoroughly explained. Likewise for moving the\nHEAD, though I don't yet grok it (git-reset HEAD^, git push, git\nfetch).\n\nSquashing commits into one is something I do often, and carefully read\nthe manual every time, whether it's merge, rebase -i, etc. I would\nexpect all merge-like functions to have an option to squash all new\ncommits into a new single commit (rather than upon the latest commit).\nI'd also expect an abort option at all times during the git rebase -i.\nFor example, when asked to create a single squash commit message, I\nmight get cold feet.\n\nI'd expect most commands to accept a branch argument without having to\ncheck it out first, such as git-log and git-status. Git diff might\nallow flags before branch, directories, etc to avoid ambiguity (such\nas when a branch and directory have the same name)\n\nCheers,\nAlex\n\n-- \n[ alex@genaud.net ][ http://genaud.net ]\n[ B068 ED90 F47B 0965 2953 9FC3 EE9C C4D5 3E51 A207 ]\n"},{"id":"87674","messageId":"vpqk5edid2y.fsf@bauges.imag.fr","threadId":"15063","inReplyTo":"ee521d6f0808190157s6a676a75t2ba3ef095f608431@mail.gmail.com","subject":"Re: Call Me Gitless","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2008-08-19T09:11:33Z","receivedAt":"2008-08-19T09:11:33Z","isPatch":false,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"\"Alexander E Genaud\" <alex@genaud.net> writes:\n\n> There is no indication in the documentation distinguishing porcelain\n> from plumbing.\n\nWell, there is somehow one: \"git\" and \"git help\" show just the\nporcelain. Still, I agree with you: marking plumbing as such more\nexplicitely could help newbies not to bother with it. For example,\n\"man git-update-index\" could say right after the synopsys something\nlike \"This command is meant for scripting purpose. See git-add and\ngit-rm for a user-friendly interface\".\n\n> Git-add adds to the index but does not create, however git-rm\n> removes from the index and does delete (an --index-only or --keep\n> flag might be nice).\n\ngit rm actually had a documented --cached flag now, and git rm\ngives an error message pointing to it in the case where it would lose\ndata and --force is not provided.\n\n> A single term for cache and index should be decided upon.\n\n+1 on this.\n\nI find \"staging area\" the most explicit wording for users, but I say\nthat as a non-native english speaker.\n\nUnfortunately, it's not only a matter of documentation. Renaming \"git\ndiff --cached\" to \"git diff --staged\" would cause backward\ncompatibility problems for example.\n\n-- \nMatthieu\n"},{"id":"87675","messageId":"20080819093646.GA17123@glandium.org","threadId":"15063","inReplyTo":"vpqk5edid2y.fsf@bauges.imag.fr","subject":"Re: Call Me Gitless","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2008-08-19T09:36:46Z","receivedAt":"2008-08-19T09:36:46Z","isPatch":false,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Tue, Aug 19, 2008 at 11:11:33AM +0200, Matthieu Moy <Matthieu.Moy@imag.fr> wrote:\n> \"Alexander E Genaud\" <alex@genaud.net> writes:\n> \n> > There is no indication in the documentation distinguishing porcelain\n> > from plumbing.\n> \n> Well, there is somehow one: \"git\" and \"git help\" show just the\n> porcelain. Still, I agree with you: marking plumbing as such more\n> explicitely could help newbies not to bother with it. For example,\n> \"man git-update-index\" could say right after the synopsys something\n> like \"This command is meant for scripting purpose. See git-add and\n> git-rm for a user-friendly interface\".\n> \n> > Git-add adds to the index but does not create, however git-rm\n> > removes from the index and does delete (an --index-only or --keep\n> > flag might be nice).\n> \n> git rm actually had a documented --cached flag now, and git rm\n> gives an error message pointing to it in the case where it would lose\n> data and --force is not provided.\n> \n> > A single term for cache and index should be decided upon.\n> \n> +1 on this.\n> \n> I find \"staging area\" the most explicit wording for users, but I say\n> that as a non-native english speaker.\n> \n> Unfortunately, it's not only a matter of documentation. Renaming \"git\n> diff --cached\" to \"git diff --staged\" would cause backward\n> compatibility problems for example.\n\nNot only that, but also, it would hide the fact that --cached and\n--index have a different meaning.\n\nSee http://marc.info/?l=git&m=121201719116766&w=2\n\nMike\n"},{"id":"87676","messageId":"ee521d6f0808190309n7f0114a6q2e8113238cb2142b@mail.gmail.com","threadId":"15063","inReplyTo":"vpqk5edid2y.fsf@bauges.imag.fr","subject":"Re: Call Me Gitless","fromName":"Alexander E Genaud","fromEmail":"alex@genaud.net","sentAt":"2008-08-19T10:09:44Z","receivedAt":"2008-08-19T10:09:44Z","isPatch":false,"sender":{"key":"alex@genaud.net","avatar":"https://gravatar.com/avatar/046079bd0c4a3c04a9d0cdca66980d593471a7c3b13bed8c57e2c5b0aa56844b?d=mp&s=160"},"body":">> A single term for cache and index should be decided upon.\n>\n> +1 on this.\n>\n> I find \"staging area\" the most explicit wording for users, but I say\n> that as a non-native english speaker.\n>\n> Unfortunately, it's not only a matter of documentation. Renaming \"git\n> diff --cached\" to \"git diff --staged\" would cause backward\n> compatibility problems for example.\n\nActually, I don't even think of the --cached argument as a flag but as\na reference. Consider INDEX and WORKSPACE as references:\n\ngit diff INDEX HEAD --name-status\n  -- display staged files (git diff --cached)\n\ngit diff INDEX WORKSPACE --name-status\n  -- display unstaged changes (git diff)\n\ngit diff HEAD WORKSPACE --name-status\n  -- display changes since last commit (git diff HEAD)\n\nOf course, --cached is not synonymous with INDEX in my example above,\nthus despite getting use to it, default behavior seems chaotic to me.\nGit-diff HEAD assumes the unspecified reference is WORKSPACE, while\ngit-diff --cached assumes the unspecified reference is HEAD. Git-diff\nwith no argument assumes the unspecified references as INDEX and\nWORKSPACE. If I'm mistaken, it might just prove the point. ;-)\n\nCheers,\nAlex\n\n\n-- \n[ alex@genaud.net ][ http://genaud.net ]\n[ B068 ED90 F47B 0965 2953 9FC3 EE9C C4D5 3E51 A207 ]\n"},{"id":"87677","messageId":"48AA9D90.6050408@sneakemail.com","threadId":"15063","inReplyTo":"vpqk5edid2y.fsf@bauges.imag.fr","subject":"Re: Call Me Gitless","fromName":"Peter Valdemar Mørch (Lists)","fromEmail":"4ux6as402@sneakemail.com","sentAt":"2008-08-19T10:16:48Z","receivedAt":"2008-08-19T10:16:48Z","isPatch":false,"sender":{"key":"4ux6as402@sneakemail.com","avatar":null},"body":"Matthieu Moy Matthieu.Moy-at-imag.fr |Lists| wrote:\n>> There is no indication in the documentation distinguishing porcelain\n>> from plumbing.\n> \n> Well, there is somehow one: \"git\" and \"git help\" show just the\n> porcelain. Still, I agree with you: marking plumbing as such more\n> explicitely could help newbies not to bother with it.\n\nTheodore Tso was helpful to point out to me in\nhttp://thread.gmane.org/gmane.comp.version-control.git/88698/focus=88844\nwhen I said the same thing:\n\n> The top-level man page has a listing of what is porcelain and what is\n> plumbing --- although there is some disagreement.\n\nTake a look at \"git help git\" it has a _different_ (and longer) list of \nwhat is porcelain. But that there isn't an exact concensus on the matter.\n\nPeter\n\n-- \nPeter Valdemar Mørch\nhttp://www.morch.com\n"},{"id":"87679","messageId":"48AAAE17.1070800@obry.net","threadId":"15063","inReplyTo":"ee521d6f0808190309n7f0114a6q2e8113238cb2142b@mail.gmail.com","subject":"Re: Call Me Gitless","fromName":"Pascal Obry","fromEmail":"pascal@obry.net","sentAt":"2008-08-19T11:27:19Z","receivedAt":"2008-08-19T11:27:19Z","isPatch":false,"sender":{"key":"pascal@obry.net","avatar":"https://avatars.githubusercontent.com/u/467069?v=4"},"body":"\nFor what it's worth, I have added this since I've been working with Git \non my aliases:\n\n[alias]\n  staged = diff --cached\n\nSince then I'm always running:\n\n    $ git staged\n\nThis looks more intuitive to me and faster than typing:\n\n    $ git diff --cached\n\nI agree that \"stage\", \"staging area\" is a clean term to use.\n\n-- \n\n--|------------------------------------------------------\n--| Pascal Obry                           Team-Ada Member\n--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE\n--|------------------------------------------------------\n--|              http://www.obry.net\n--| \"The best way to travel is by means of imagination\"\n--|\n--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595\n"},{"id":"87680","messageId":"660749.49882.qm@web27803.mail.ukl.yahoo.com","threadId":"15063","inReplyTo":"ee521d6f0808190157s6a676a75t2ba3ef095f608431@mail.gmail.com","subject":"Re: Call Me Gitless","fromName":"Mark Struberg","fromEmail":"struberg@yahoo.de","sentAt":"2008-08-19T11:31:35Z","receivedAt":"2008-08-19T11:31:35Z","isPatch":false,"sender":{"key":"struberg@yahoo.de","avatar":"https://gravatar.com/avatar/119742c3e8dbc8db35a92bdff0581aec8d364d415f770e60431cba262daa974f?d=mp&s=160"},"body":"Hi Alex!\n\n--- Alexander E Genaud <alex@genaud.net> schrieb am Di, 19.8.2008:\n\n> Von: Alexander E Genaud <alex@genaud.net>\n> Betreff: Re: Call Me Gitless\n> An: \"Junio C Hamano\" <gitster@pobox.com>\n> CC: \"Peter Valdemar Mørch (Lists)\" <4ux6as402@sneakemail.com>, git@vger.kernel.org\n> Datum: Dienstag, 19. August 2008, 10:57\n> ...\n> Remote never seems to do what I expect, so I manually edit\n> the .git/refs!! \n> Nor is git-reset what I expect and use git\n> checkout (which\n> does make sense only after a few backup trials). Git-add\n> adds to the\n> index but does not create, however git-rm removes from the\n> index and\n> does delete (an --index-only or --keep flag might be nice).\n\nThis is explicitely stated in the git-rm manpages: --cached:  Use this option to unstage and remove paths only from the index. Working tree files, whether modified or not, will be left alone.\n\n\n> A single term for cache and index should be decided upon.\n> git diff --cached is not intuitive when 'index' is used\n> throughout the documentation. \n\nThe changes are \"cached\" in the \"Index\". But I wouldn't name the \"Index\" really a \"Cache\" because it is a lot more. All comments for --cached in the manpages mention the Index mechanism. \nAdditionally there is a more detailed introduction to the Index in section 7 (Git concepts) of the Git User's Manual \n\nLieGrue,\nstrub\n\n__________________________________________________\nDo You Yahoo!?\nSie sind Spam leid? Yahoo! Mail verfügt über einen herausragenden Schutz gegen Massenmails. \nhttp://mail.yahoo.com \n"},{"id":"87681","messageId":"m3od3ps02b.fsf@localhost.localdomain","threadId":"15063","inReplyTo":"7vy72tit90.fsf@gitster.siamese.dyndns.org","subject":"Re: Call Me Gitless","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-08-19T11:42:42Z","receivedAt":"2008-08-19T11:42:42Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > Actually, this weekend I was trying to cherry-pick the aggregated changes \n> > to certain files from one branch onto another, and was repeatedly confused \n> > by the fact that the only available diffs are backwards and there're no \n> > clues in the output. (That is, you can't get the difference between (---) \n> > the {index,working tree} and (+++) some commit, and when you've done \"git \n> > diff messy\", the resulting diff doesn't give any clues that you're \n> > deciding whether to add the - lines and remove the + lines.)\n> \n> I do not know if I like the end result, but here is a patch to make the\n> traditional a/ and b/ prefix more mnemonic.\n> \n> A lot of existing tests and documentation need to be updated, if we were\n> to do this, though.    The first test to fail is t1200-tutorial.sh.\n> \n> Obviously not tested except for creating this patch that pretends to be a\n> format-patch output.  You can tell that I just did this only in the work\n> tree now.\n> \n> -- >8 --\n> diff: vary default prefix depending on what are compared\n> \n> This implements Daniel's idea to indicate what are compared by using\n> prefix different from the traditional a/ and b/ in the textual diff\n> header:\n> \n>     \"git diff\" compares the (i)ndex and the (w)ork tree;\n>     \"git diff HEAD\" compares a (c)ommit and the (w)ork tree;\n>     \"git diff --cached\" compares a (c)ommit and the (i)ndex;\n>     \"git diff HEAD:f /tmp/f\" compares an (o)bject and (w)ork tree.\n> \n> Because these mnemonics now have meanings, they are swapped when reverse\n> diff is in effect.\n\n> diff --git i/builtin-diff.c w/builtin-diff.c\n> index 7ffea97..ecec753 100644\n> --- i/builtin-diff.c\n> +++ w/builtin-diff.c\n> @@ -74,6 +74,8 @@ static int builtin_diff_b_f(struct rev_info *revs,\n>  \tif (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))\n>  \t\tdie(\"'%s': not a regular file or symlink\", path);\n>  \n> +\tdiff_set_default_prefix(&revs->diffopt, \"o/\", \"w/\");\n> +\n>  \tif (blob[0].mode == S_IFINVALID)\n>  \t\tblob[0].mode = canon_mode(st.st_mode);\n\nI was thinking about reusing estended SHA1 syntax in the form\nof :0:a/file or ::a/file for index, a/file for working directory,\nand HEAD:a/file for a tree version.  But your way is I think better;\nof course if you remember mnemonics (and they are documented, aren't\nthey?).\n\nBTW. I wonder why in above patch, which I guess is result of running\ngit-format-patch and should be between TWO TREES, doesn't use standard\n'a/' and 'b/' (git-show should also use standard, default prefixes).\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"87682","messageId":"ee521d6f0808190504u12be6195o71eb2f3a38f73a5f@mail.gmail.com","threadId":"15063","inReplyTo":"660749.49882.qm@web27803.mail.ukl.yahoo.com","subject":"Re: Call Me Gitless","fromName":"Alexander E Genaud","fromEmail":"alex@genaud.net","sentAt":"2008-08-19T12:04:42Z","receivedAt":"2008-08-19T12:04:42Z","isPatch":false,"sender":{"key":"alex@genaud.net","avatar":"https://gravatar.com/avatar/046079bd0c4a3c04a9d0cdca66980d593471a7c3b13bed8c57e2c5b0aa56844b?d=mp&s=160"},"body":"Hi Mark,\n\nThanks for pointing me to 'git-rm --cached'.\n\n> The changes are \"cached\" in the \"Index\". But I wouldn't name\n> the \"Index\" really a \"Cache\" because it is a lot more. All\n> comments for --cached in the manpages mention the Index\n> mechanism. Additionally there is a more detailed introduction\n> to the Index in section 7 (Git concepts) of the Git User's\n> Manual\n\nFunny the first example shows the contents of the index using a '--stage' flag.\n\n$ git ls-files --stage\n...\nNote that in older documentation you may see the index called the\n\"current directory cache\" or just the \"cache\".\n\nhttp://www.kernel.org/pub/software/scm/git/docs/user-manual.html#the-index\n\nTo my ear, the term cache is a volatile space used for optimization,\nwhile an index is a pointer or reference within a data structure.\nNeither are obvious concerns of an end user and using both terms is\nplain confusing. Staging implies something more tangible and useful to\nthe end user.\n\nCheers,\nAlex\n\n-- \n[ alex@genaud.net ][ http://genaud.net ]\n[ B068 ED90 F47B 0965 2953 9FC3 EE9C C4D5 3E51 A207 ]\n"},{"id":"87686","messageId":"m3skt1s0c6.fsf@localhost.localdomain","threadId":"15063","inReplyTo":"4b6f054f0808171702q10d89dfey98afa65634d26e91@mail.gmail.com","subject":"Re: Call Me Gitless","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-08-19T13:15:38Z","receivedAt":"2008-08-19T13:15:38Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Trans <transfire@gmail.com> writes:\n\n> Well, after a few days of using git, I've decide Linus is too smart to\n> be designing end-user interfaces.\n\nActually git was developed and designed in bottoms-up fashion,\nin the \"worse is better\" way that is quite characteristic for\nUNIX tools.  And the mantle of being git maintainer passed\nto Junio Hamano before git acquired truly end-user interface\n(as opposed to power-user interface).\n\nAs I can see even if you didn't provide any details about _what_\ndo you find difficult in git end-user interface (you are using\ncurrent git version, and reading up-to-date git documentation?),\ngit UI continues improving, even in this thread...\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"87719","messageId":"20080819175220.GA10142@coredump.intra.peff.net","threadId":"15063","inReplyTo":"7vy72tit90.fsf@gitster.siamese.dyndns.org","subject":"Re: Call Me Gitless","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-08-19T17:52:20Z","receivedAt":"2008-08-19T17:52:20Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Aug 18, 2008 at 08:22:19PM -0700, Junio C Hamano wrote:\n\n> I do not know if I like the end result, but here is a patch to make the\n> traditional a/ and b/ prefix more mnemonic.\n\nHmm. Something deep in my gut doesn't like this, just because I like the\nfact that no matter how I prepare a diff (and I do tend to do it\ndifferent ways and post to the mailing list) it always ends up the same.\nFor example, I sometimes \"hand-generate\" patch messages meant to be\napplied by git-am by doing a diff between the working tree and index and\npasting the result into an email. It just feels a bit wrong for it not\nto be the exact output I would get from commiting and running\nformat-patch.\n\nAnd yes, obviously the prefix should be thrown away by am (and any sane\ntools), so it shouldn't matter. So I don't think there is a technical\nreason not to do so.  But one of the things I have always liked about\ngit is that no matter how I prepare content, the output is always the\nsame.\n\nBut maybe this is just me being a curmudgeonly old-timer. Feel free to\nignore.\n\n-Peff\n"},{"id":"87723","messageId":"7v4p5gdg6c.fsf@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"ee521d6f0808190504u12be6195o71eb2f3a38f73a5f@mail.gmail.com","subject":"Re: Call Me Gitless","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-19T18:15:55Z","receivedAt":"2008-08-19T18:15:55Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Alexander E Genaud\" <alex@genaud.net> writes:\n\n> Thanks for pointing me to 'git-rm --cached'.\n>\n>> The changes are \"cached\" in the \"Index\". But I wouldn't name\n>> the \"Index\" really a \"Cache\" because it is a lot more. All\n>> comments for --cached in the manpages mention the Index\n>> mechanism. Additionally there is a more detailed introduction\n>> to the Index in section 7 (Git concepts) of the Git User's\n>> Manual\n>\n> Funny the first example shows the contents of the index using a '--stage' flag.\n>\n> $ git ls-files --stage\n\nFor ls-files, --cached mode is the default so you did not even have to say\nit in your example.\n\nWith the option --stage, you are specifying how that --cached state is\nshown.  Normally we do not show the object name nor their merge stages,\nbut we do when you give the --stage option.\n\nAlso look at the end of gitcli(7) documentation.\n"},{"id":"87724","messageId":"7vzln8c1ia.fsf@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"m3od3ps02b.fsf@localhost.localdomain","subject":"Re: Call Me Gitless","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-19T18:18:05Z","receivedAt":"2008-08-19T18:18:05Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> BTW. I wonder why in above patch, which I guess is result of running\n> git-format-patch and should be between TWO TREES, doesn't use standard\n> 'a/' and 'b/' (git-show should also use standard, default prefixes).\n\nYou apparently did not read the other messages in the thread (hint: look\nfor places where I describe what I often do, and pay attention to the\nkeyword \"pretends to be a format-patch output\").\n"},{"id":"87728","messageId":"alpine.LNX.1.00.0808191407160.19665@iabervon.org","threadId":"15063","inReplyTo":"20080819175220.GA10142@coredump.intra.peff.net","subject":"Re: Call Me Gitless","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-08-19T18:39:22Z","receivedAt":"2008-08-19T18:39:22Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Tue, 19 Aug 2008, Jeff King wrote:\n\n> On Mon, Aug 18, 2008 at 08:22:19PM -0700, Junio C Hamano wrote:\n> \n> > I do not know if I like the end result, but here is a patch to make the\n> > traditional a/ and b/ prefix more mnemonic.\n> \n> Hmm. Something deep in my gut doesn't like this, just because I like the\n> fact that no matter how I prepare a diff (and I do tend to do it\n> different ways and post to the mailing list) it always ends up the same.\n> For example, I sometimes \"hand-generate\" patch messages meant to be\n> applied by git-am by doing a diff between the working tree and index and\n> pasting the result into an email. It just feels a bit wrong for it not\n> to be the exact output I would get from commiting and running\n> format-patch.\n\nHmm... everybody who doesn't like it is concerned about scripts and \nsending it places, while the people who like it seem to be interested in \nlooking at the output. Maybe there should be an option that controls it, \nwith the default being to use -a+b for pipelines and informational stuff \nfor pager?\n\nIt seems to me like, in output for user consumption, the information is \nuseful, while in output for non-user consumption, the information is \noverly personal. But that's easy enough to detect...\n\n(For that matter, maybe format-patch should be able to handle uncommitted \nchanges, and should hide what it did? What's with all these people faking \nformat-patch output with other commands, rather than having format-patch \nactually generate suitable output in their situations?)\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"87729","messageId":"20080819184525.GA17691@coredump.intra.peff.net","threadId":"15063","inReplyTo":"alpine.LNX.1.00.0808191407160.19665@iabervon.org","subject":"Re: Call Me Gitless","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-08-19T18:45:25Z","receivedAt":"2008-08-19T18:45:25Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Aug 19, 2008 at 02:39:22PM -0400, Daniel Barkalow wrote:\n\n> Hmm... everybody who doesn't like it is concerned about scripts and \n> sending it places, while the people who like it seem to be interested in \n> looking at the output. Maybe there should be an option that controls it, \n> with the default being to use -a+b for pipelines and informational stuff \n> for pager?\n\nTo clarify my statement: no, I'm concerned about looking at it. That is,\nI don't think it will break scripts, but I think the output is\npotentially confusing to humans.\n\nBut like I said before, it's just my intuition; I don't have real facts\nto back it up, so feel free to ignore.\n\n> (For that matter, maybe format-patch should be able to handle uncommitted \n> changes, and should hide what it did? What's with all these people faking \n> format-patch output with other commands, rather than having format-patch \n> actually generate suitable output in their situations?)\n\nI do it because I haven't actually committed the content.  I dump the\ndiff right into an email I'm already writing.\n\n-Peff\n"},{"id":"87734","messageId":"alpine.LNX.1.00.0808191448530.19665@iabervon.org","threadId":"15063","inReplyTo":"20080819184525.GA17691@coredump.intra.peff.net","subject":"Re: Call Me Gitless","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-08-19T18:57:04Z","receivedAt":"2008-08-19T18:57:04Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Tue, 19 Aug 2008, Jeff King wrote:\n\n> On Tue, Aug 19, 2008 at 02:39:22PM -0400, Daniel Barkalow wrote:\n> \n> > Hmm... everybody who doesn't like it is concerned about scripts and \n> > sending it places, while the people who like it seem to be interested in \n> > looking at the output. Maybe there should be an option that controls it, \n> > with the default being to use -a+b for pipelines and informational stuff \n> > for pager?\n> \n> To clarify my statement: no, I'm concerned about looking at it. That is,\n> I don't think it will break scripts, but I think the output is\n> potentially confusing to humans.\n\nHumans being recipients of emails, or humans being the users who typed the \ncommand? Unless you're cut-and-pasting out of a pager (which never works \nwell for me if it's long enough to include diff headers, context, and some \nchange), recipients of emails would get what scripts get. (I personnaly do \nthat as \"git diff > temp.patch\" and read temp.patch into my mailer; this \ndoesn't trigger starting a pager, and wouldn't trigger the default to be \ninformative prefixes.)\n\n> But like I said before, it's just my intuition; I don't have real facts\n> to back it up, so feel free to ignore.\n> \n> > (For that matter, maybe format-patch should be able to handle uncommitted \n> > changes, and should hide what it did? What's with all these people faking \n> > format-patch output with other commands, rather than having format-patch \n> > actually generate suitable output in their situations?)\n> \n> I do it because I haven't actually committed the content.  I dump the\n> diff right into an email I'm already writing.\n\nYeah, that's why I think that format-patch should work on content that you \nhaven't committed, generating something you can dump right into an email \n(with the --- and diffstat that you'd get if you actually did commit and \nuse format-patch now).\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"87737","messageId":"20080819190159.GB17943@coredump.intra.peff.net","threadId":"15063","inReplyTo":"alpine.LNX.1.00.0808191448530.19665@iabervon.org","subject":"Re: Call Me Gitless","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-08-19T19:01:59Z","receivedAt":"2008-08-19T19:01:59Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Aug 19, 2008 at 02:57:04PM -0400, Daniel Barkalow wrote:\n\n> Humans being recipients of emails, or humans being the users who typed the \n> command? Unless you're cut-and-pasting out of a pager (which never works \n\nI meant the recipients of the emails.\n\n> well for me if it's long enough to include diff headers, context, and some \n> change), recipients of emails would get what scripts get. (I personnaly do \n> that as \"git diff > temp.patch\" and read temp.patch into my mailer; this \n> doesn't trigger starting a pager, and wouldn't trigger the default to be \n> informative prefixes.)\n\nOK, I didn't read your mail carefully enough. Yes, I do the same thing,\nso the \"do this only if pager\" rule would meet my requirement. OTOH, I\ndon't know if that would satisfy the people who want this feature (but I\nwill let them speak for themselves).\n\n> Yeah, that's why I think that format-patch should work on content that you \n> haven't committed, generating something you can dump right into an email \n> (with the --- and diffstat that you'd get if you actually did commit and \n> use format-patch now).\n\nIt's not clear to me:\n\n  - how you would tell format-patch that's what you wanted to dump\n\n  - what parts would be included. There's no commit message or author.\n    We could guess at the author as if you were about to commit this.\n\n  - how this would be any real improvement over \"git diff --stat -p\". In\n    fact, I like the fact that I get _just_ the diff, which I then\n    paste. The headers would just be clutter I would have to delete.\n\n-Peff\n"},{"id":"87743","messageId":"alpine.LNX.1.00.0808191143040.19665@iabervon.org","threadId":"15063","inReplyTo":"7vbpzph3fx.fsf@gitster.siamese.dyndns.org","subject":"Re: Call Me Gitless","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-08-19T19:22:30Z","receivedAt":"2008-08-19T19:22:30Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Tue, 19 Aug 2008, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > .... For most systems, \"diff\" without options is a preview of \n> > what would be in the patch if you were to commit; \"git diff\", on the other \n> > hand, shows what would be left out of the patch.\n> \n> That is true, but I also think that is because (1) on other systems, you\n> cannot even choose to select changes to \"leave out of the patch\", so they\n> have no option other than showing \"what could be committed\", and (2) by\n> definition active use of index means that you are staging incrementally,\n> and it is natural to expect you to want to view \"changes since the last\n> staging\" much more often than \"what would be committed\" when you are\n> staging incrementally, so the current default is the _right_ one.\n\nWow, that's a completely different idea of how to use the index than I \nthink of. When I think of staging things incrementally, I'm taking a \nworking tree with a ton of changes, and triaging them into: (a) things \nthat go into this commit; (b) things that I want to hang onto but not put \nin yet; and (c) things I want to get rid of. This is after I've got a \nworking version of the change, and I'm just cleaning it up and debugging. \nThis, of course, is essentially the same as using the index for merging, \nwhere you start using the index when you've got all the content available \n(including stuff you don't want), and you finish with the state you'll \nwant to commit.\n\nWhen I want to do what you're doing, I just do a commit and then use \n--amend when I've done more work (or I work on a temporary branch). I \nthink the real benefit of the index is that it doesn't have to match a \ncomplete-working-tree state you've actually had, so you can use it to \ncommit the correct version of API A without user B when you really wrote a \nbuggy version of A, then wrote B, then fixed A.\n\n> So I'd say the below is a faulty argument:\n> \n> > ...  So, even given that \n> > people understand the meaning of the index, they can fail to understand \n> > what \"diff\" will tell them.\n> \n> If they understand \"the meaning of the index\", not just as literal reading\n> of the manual page \"it is a staging area to prepare for the next commit\",\n> but including the reason why there is a \"staging area\" and how it is to be\n> used, they would reach the conclusion that \"diff by default will show the\n> leftover from incremental staging and it is the right thing\".\n\nI think you may be overly limited in \"how the index is to be used\". One of \nthe major advantages, in my view, of git over other systems is that you \ncan incrementally decide what of the changes persent in your working tree \nwill be included in the next commit, and the index stores what you've \ndecided to include. That is, you can not only checkpoint your work on \nchanging the content, you can even checkpoint your work on forming the \ncontent change into commits, and you can checkpoint your work on resolving \nmerge conflicts.\n\nSimply checkpointing content changes is, IMHO, better done in ways other \nthan the index (git stash, throw-away development branches) that allow you \nto recover to earlier checkpoints; having private commits satisfies this \nneed admirably, while the index allows incremental work on preparing a \ncommit out of changes you've written, which is an area where nothing but \nthe index works nearly so well.\n\n> > ... And diff is a bit unhelpful in that it \n> > generates headers as for \"diff -r a b\", regardless of what the things are.\n> \n> We have a separate thread on this now ;-)\n\nRight.\n\n> >> (2) Some concepts in git are different from what they are used to, without\n> >>     any good reason.  IOW, the concepts have room for improvement, and our\n> >>     UI is based on these faulty concepts.\n> >> \n> >> (3) Some concepts in git may be exactly the same with other systems, yet\n> >>     our UI may operate differently from them without any good reason.\n> >> \n> >> I'd be surprised if there is _no_ UI element that falls into the latter\n> >> two categories, but obviously I would not be able to list examples.  If I\n> >> could, they instead would have long been fixed already.\n> >\n> > You've got to include the class of \"The concepts in git are exactly the \n> > same as with other systems (although git also has additional concepts), \n> > and commands from other systems do not do the same thing in git (with or \n> > without good reason).\"\n> \n> Isn't it the same as (3)?\n\nWell there may be a good reason, which (3) excludes. \n\n> > E.g., git has a working directory, and git has a committed state, and CVS \n> > has both of these, and \"cvs diff\" compares the working directory with the \n> > committed state, but \"git diff\" does a different operation.\n> \n> Ah, Ok, that is not the same as (3), but \"although git has more\" makes it\n> totally different.\n> \n> Your example sounds like comparing a car and a motorcycle.  Yes they both\n> share two tyres, but the former having two more tyres makes the driving\n> technique of the whole thing quite different, doesn't it?\n\nAh, but a motorcycle has handlebars and a car has a steering wheel. That \nis, they somewhat arbitrarily have different user interfaces, \ncorresponding to the difference in driving technique. That would be like \nhaving \"git diff\" not exist, but \"git cmp\" serve the same goal as \"cvs \ndiff\", because git can do a different and more useful operation than cvs \ncan do, but we'd name it differently because it's not the same operation.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"87746","messageId":"alpine.LNX.1.00.0808191523050.19665@iabervon.org","threadId":"15063","inReplyTo":"20080819190159.GB17943@coredump.intra.peff.net","subject":"Re: Call Me Gitless","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-08-19T19:42:01Z","receivedAt":"2008-08-19T19:42:01Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Tue, 19 Aug 2008, Jeff King wrote:\n\n> On Tue, Aug 19, 2008 at 02:57:04PM -0400, Daniel Barkalow wrote:\n> \n> > Humans being recipients of emails, or humans being the users who typed the \n> > command? Unless you're cut-and-pasting out of a pager (which never works \n> \n> I meant the recipients of the emails.\n> \n> > well for me if it's long enough to include diff headers, context, and some \n> > change), recipients of emails would get what scripts get. (I personnaly do \n> > that as \"git diff > temp.patch\" and read temp.patch into my mailer; this \n> > doesn't trigger starting a pager, and wouldn't trigger the default to be \n> > informative prefixes.)\n> \n> OK, I didn't read your mail carefully enough. Yes, I do the same thing,\n> so the \"do this only if pager\" rule would meet my requirement. OTOH, I\n> don't know if that would satisfy the people who want this feature (but I\n> will let them speak for themselves).\n\nAh, okay. I feel like the main application for this is \"I typed some git \ndiff command, started looking at it, my phone rang, I took the call, and \nnow I don't know what I'm looking at, and the pager hides the command \nline, but quitting the pager loses my place.\" At least, that's the \nsituation I'm often in.\n\n> > Yeah, that's why I think that format-patch should work on content that you \n> > haven't committed, generating something you can dump right into an email \n> > (with the --- and diffstat that you'd get if you actually did commit and \n> > use format-patch now).\n> \n> It's not clear to me:\n> \n>   - how you would tell format-patch that's what you wanted to dump\n\nMaybe an option? Maybe it should include it if the working tree is dirty?\n\n>   - what parts would be included. There's no commit message or author.\n>     We could guess at the author as if you were about to commit this.\n\nProbably it should start just after the message, since that's what you've \npresumably got elsewhere.\n\n>   - how this would be any real improvement over \"git diff --stat -p\". In\n>     fact, I like the fact that I get _just_ the diff, which I then\n>     paste. The headers would just be clutter I would have to delete.\n\nThat all-important \"---\" line? But I think the real advantage is that \npeople who don't know that \"git diff --stat -p\" is the standard info for a \npatch email would be able to run the same command as usual.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"87747","messageId":"7v1w0k3i5g.fsf@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"20080819175220.GA10142@coredump.intra.peff.net","subject":"Re: Call Me Gitless","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-19T19:43:23Z","receivedAt":"2008-08-19T19:43:23Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Mon, Aug 18, 2008 at 08:22:19PM -0700, Junio C Hamano wrote:\n>\n>> I do not know if I like the end result, but here is a patch to make the\n>> traditional a/ and b/ prefix more mnemonic.\n>\n> Hmm. Something deep in my gut doesn't like this, just because I like the\n> fact that no matter how I prepare a diff (and I do tend to do it\n> different ways and post to the mailing list) it always ends up the same.\n\nI had the exact same reaction when I prepared and sent the patch with i/\nand w/ prefixes.  I'm trying to see if that \"deep in my gut\" feeling is\nmerely coming from my being very used to see a/ vs b/ or something more\nfundamental, even though my working hypothesis is that I'll get used to\nit.\n"},{"id":"87753","messageId":"20080819203353.GG10544@machine.or.cz","threadId":"15063","inReplyTo":"alpine.LNX.1.00.0808191523050.19665@iabervon.org","subject":"Re: Call Me Gitless","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2008-08-19T20:33:53Z","receivedAt":"2008-08-19T20:33:53Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Tue, Aug 19, 2008 at 03:42:01PM -0400, Daniel Barkalow wrote:\n> On Tue, 19 Aug 2008, Jeff King wrote:\n> Ah, okay. I feel like the main application for this is \"I typed some git \n> diff command, started looking at it, my phone rang, I took the call, and \n> now I don't know what I'm looking at, and the pager hides the command \n> line, but quitting the pager loses my place.\" At least, that's the \n> situation I'm often in.\n\nPress ctrl-z. ;-)\n\n> > > Yeah, that's why I think that format-patch should work on content that you \n> > > haven't committed, generating something you can dump right into an email \n> > > (with the --- and diffstat that you'd get if you actually did commit and \n> > > use format-patch now).\n\nHmm, and why don't you actually do the commit after all? You can compose\nall the details within the commit and you can do the commit on a\nseparate branch or git reset HEAD^ afterwards if you don't want to keep\nit around.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nThe next generation of interesting software will be done\non the Macintosh, not the IBM PC.  -- Bill Gates\n"},{"id":"87758","messageId":"alpine.LNX.1.00.0808191647320.19665@iabervon.org","threadId":"15063","inReplyTo":"20080819203353.GG10544@machine.or.cz","subject":"Re: Call Me Gitless","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-08-19T21:49:04Z","receivedAt":"2008-08-19T21:49:04Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Tue, 19 Aug 2008, Petr Baudis wrote:\n\n> On Tue, Aug 19, 2008 at 03:42:01PM -0400, Daniel Barkalow wrote:\n> > On Tue, 19 Aug 2008, Jeff King wrote:\n> > Ah, okay. I feel like the main application for this is \"I typed some git \n> > diff command, started looking at it, my phone rang, I took the call, and \n> > now I don't know what I'm looking at, and the pager hides the command \n> > line, but quitting the pager loses my place.\" At least, that's the \n> > situation I'm often in.\n> \n> Press ctrl-z. ;-)\n> \n> > > > Yeah, that's why I think that format-patch should work on content that you \n> > > > haven't committed, generating something you can dump right into an email \n> > > > (with the --- and diffstat that you'd get if you actually did commit and \n> > > > use format-patch now).\n> \n> Hmm, and why don't you actually do the commit after all? You can compose\n> all the details within the commit and you can do the commit on a\n> separate branch or git reset HEAD^ afterwards if you don't want to keep\n> it around.\n\nI personally almost always do something like:\n\n$ git checkout -b informational-diff-prefixes\n$ git commit -a\n$ git show HEAD > temp.patch\n$ git checkout master\n\nBut then I tend to use \"checkout -b; commit -a; checkout\" instead of \n\"reset --hard\" to get rid of unwanted local changes anyway these days.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"87802","messageId":"7vljysru9b.fsf_-_@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"7viqtxh4gt.fsf@gitster.siamese.dyndns.org","subject":"[PATCH v2] diff: vary default prefix depending on what are compared","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-20T08:00:16Z","receivedAt":"2008-08-20T08:00:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"With a new configuration \"diff.mnemonicprefix\", \"git diff\" shows the\ndifferences between various combinations of preimage and postimage trees\nwith prefixes different from the standard \"a/\" and \"b/\".  Hopefully this\nwill make the distinction stand out for some people.\n\n    \"git diff\" compares the (i)ndex and the (w)ork tree;\n    \"git diff HEAD\" compares a (c)ommit and the (w)ork tree;\n    \"git diff --cached\" compares a (c)ommit and the (i)ndex;\n    \"git diff --no-index a b\" compares two non-git things (1) and (2).\n\nBecause these mnemonics now have meanings, they are swapped when reverse\ndiff is in effect and this feature is enabled.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\n * This is much low impact mainly because it only affects \"git diff\" and\n   Porcelains that use diff_ui_config().  As an added bonus, tests do not\n   have to get fixed ;-)  I did have to fix --cc codepath, by the way.\n\n   I'll run my git life with this enabled for two weeks to see if the \"gut\n   feeling\" we discussed earlier changes in some way.\n\n   Another thing we may want to do is to explicitly disable this for\n   format-patch, as we may want to change the default for this\n   configuration to true in some future.\n\n Documentation/config.txt |   14 ++++++++++++++\n builtin-diff.c           |    2 ++\n combine-diff.c           |    8 ++++++--\n diff-lib.c               |    3 +++\n diff-no-index.c          |    1 +\n diff.c                   |   46 ++++++++++++++++++++++++++++++++++++++++------\n diff.h                   |    2 ++\n 7 files changed, 68 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 676c39b..b125bf5 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -576,6 +576,20 @@ diff.external::\n \tyou want to use an external diff program only on a subset of\n \tyour files, you\tmight want to use linkgit:gitattributes[5] instead.\n \n+diff.mnemonicprefix::\n+\tIf set, 'git-diff' uses a prefix pair that is different from the\n+\tstandard \"a/\" and \"b/\" depending on what is being compared.  When\n+\tthis configuration is in effect, reverse diff output also swaps\n+\tthe order of the prefixes:\n+'git-diff';;\n+\tcompares the (i)ndex and the (w)ork tree;\n+'git-diff HEAD';;\n+\t compares a (c)ommit and the (w)ork tree;\n+'git diff --cached';;\n+\tcompares a (c)ommit and the (i)ndex;\n+'git diff --no-index a b';;\n+\tcompares two non-git things (1) and (2).\n+\n diff.renameLimit::\n \tThe number of files to consider when performing the copy/rename\n \tdetection; equivalent to the 'git-diff' option '-l'.\ndiff --git a/builtin-diff.c b/builtin-diff.c\nindex 7ffea97..266337b 100644\n--- a/builtin-diff.c\n+++ b/builtin-diff.c\n@@ -74,6 +74,8 @@ static int builtin_diff_b_f(struct rev_info *revs,\n \tif (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))\n \t\tdie(\"'%s': not a regular file or symlink\", path);\n \n+\tdiff_set_mnemonic_prefix(&revs->diffopt, \"o/\", \"w/\");\n+\n \tif (blob[0].mode == S_IFINVALID)\n \t\tblob[0].mode = canon_mode(st.st_mode);\n \ndiff --git a/combine-diff.c b/combine-diff.c\nindex 9f80a1c..fe1970e 100644\n--- a/combine-diff.c\n+++ b/combine-diff.c\n@@ -675,9 +675,13 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,\n \tint i, show_hunks;\n \tint working_tree_file = is_null_sha1(elem->sha1);\n \tint abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? 40 : DEFAULT_ABBREV;\n+\tconst char *a_prefix, *b_prefix;\n \tmmfile_t result_file;\n \n \tcontext = opt->context;\n+\ta_prefix = opt->a_prefix ? opt->a_prefix : \"a/\";\n+\tb_prefix = opt->b_prefix ? opt->b_prefix : \"b/\";\n+\n \t/* Read the result of merge first */\n \tif (!working_tree_file)\n \t\tresult = grab_blob(elem->sha1, &result_size);\n@@ -841,13 +845,13 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,\n \t\t\tdump_quoted_path(\"--- \", \"\", \"/dev/null\",\n \t\t\t\t\t c_meta, c_reset);\n \t\telse\n-\t\t\tdump_quoted_path(\"--- \", opt->a_prefix, elem->path,\n+\t\t\tdump_quoted_path(\"--- \", a_prefix, elem->path,\n \t\t\t\t\t c_meta, c_reset);\n \t\tif (deleted)\n \t\t\tdump_quoted_path(\"+++ \", \"\", \"/dev/null\",\n \t\t\t\t\t c_meta, c_reset);\n \t\telse\n-\t\t\tdump_quoted_path(\"+++ \", opt->b_prefix, elem->path,\n+\t\t\tdump_quoted_path(\"+++ \", b_prefix, elem->path,\n \t\t\t\t\t c_meta, c_reset);\n \t\tdump_sline(sline, cnt, num_parent,\n \t\t\t   DIFF_OPT_TST(opt, COLOR_DIFF));\ndiff --git a/diff-lib.c b/diff-lib.c\nindex e7eaff9..ae96c64 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -63,6 +63,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option)\n \t\t\t      ? CE_MATCH_RACY_IS_DIRTY : 0);\n \tchar symcache[PATH_MAX];\n \n+\tdiff_set_mnemonic_prefix(&revs->diffopt, \"i/\", \"w/\");\n+\n \tif (diff_unmerged_stage < 0)\n \t\tdiff_unmerged_stage = 2;\n \tentries = active_nr;\n@@ -469,6 +471,7 @@ int run_diff_index(struct rev_info *revs, int cached)\n \tif (unpack_trees(1, &t, &opts))\n \t\texit(128);\n \n+\tdiff_set_mnemonic_prefix(&revs->diffopt, \"c/\", cached ? \"i/\" : \"w/\");\n \tdiffcore_std(&revs->diffopt);\n \tdiff_flush(&revs->diffopt);\n \treturn 0;\ndiff --git a/diff-no-index.c b/diff-no-index.c\nindex 7d68b7f..b60d345 100644\n--- a/diff-no-index.c\n+++ b/diff-no-index.c\n@@ -252,6 +252,7 @@ void diff_no_index(struct rev_info *revs,\n \tif (queue_diff(&revs->diffopt, revs->diffopt.paths[0],\n \t\t       revs->diffopt.paths[1]))\n \t\texit(1);\n+\tdiff_set_mnemonic_prefix(&revs->diffopt, \"1/\", \"2/\");\n \tdiffcore_std(&revs->diffopt);\n \tdiff_flush(&revs->diffopt);\n \ndiff --git a/diff.c b/diff.c\nindex bf5d5f1..2768bbb 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -23,6 +23,7 @@ static int diff_rename_limit_default = 200;\n int diff_use_color_default = -1;\n static const char *external_diff_cmd_cfg;\n int diff_auto_refresh_index = 1;\n+static int diff_mnemonic_prefix;\n \n static char diff_colors[][COLOR_MAXLEN] = {\n \t\"\\033[m\",\t/* reset */\n@@ -149,6 +150,10 @@ int git_diff_ui_config(const char *var, const char *value, void *cb)\n \t\tdiff_auto_refresh_index = git_config_bool(var, value);\n \t\treturn 0;\n \t}\n+\tif (!strcmp(var, \"diff.mnemonicprefix\")) {\n+\t\tdiff_mnemonic_prefix = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n \tif (!strcmp(var, \"diff.external\"))\n \t\treturn git_config_string(&external_diff_cmd_cfg, var, value);\n \tif (!prefixcmp(var, \"diff.\")) {\n@@ -305,6 +310,15 @@ static void emit_rewrite_diff(const char *name_a,\n \tconst char *new = diff_get_color(color_diff, DIFF_FILE_NEW);\n \tconst char *reset = diff_get_color(color_diff, DIFF_RESET);\n \tstatic struct strbuf a_name = STRBUF_INIT, b_name = STRBUF_INIT;\n+\tconst char *a_prefix, *b_prefix;\n+\n+\tif (diff_mnemonic_prefix && DIFF_OPT_TST(o, REVERSE_DIFF)) {\n+\t\ta_prefix = o->b_prefix;\n+\t\tb_prefix = o->a_prefix;\n+\t} else {\n+\t\ta_prefix = o->a_prefix;\n+\t\tb_prefix = o->b_prefix;\n+\t}\n \n \tname_a += (*name_a == '/');\n \tname_b += (*name_b == '/');\n@@ -313,8 +327,8 @@ static void emit_rewrite_diff(const char *name_a,\n \n \tstrbuf_reset(&a_name);\n \tstrbuf_reset(&b_name);\n-\tquote_two_c_style(&a_name, o->a_prefix, name_a, 0);\n-\tquote_two_c_style(&b_name, o->b_prefix, name_b, 0);\n+\tquote_two_c_style(&a_name, a_prefix, name_a, 0);\n+\tquote_two_c_style(&b_name, b_prefix, name_b, 0);\n \n \tdiff_populate_filespec(one, 0);\n \tdiff_populate_filespec(two, 0);\n@@ -1424,6 +1438,14 @@ static const char *diff_funcname_pattern(struct diff_filespec *one)\n \treturn NULL;\n }\n \n+void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b)\n+{\n+\tif (!options->a_prefix)\n+\t\toptions->a_prefix = a;\n+\tif (!options->b_prefix)\n+\t\toptions->b_prefix = b;\n+}\n+\n static void builtin_diff(const char *name_a,\n \t\t\t const char *name_b,\n \t\t\t struct diff_filespec *one,\n@@ -1437,9 +1459,19 @@ static void builtin_diff(const char *name_a,\n \tchar *a_one, *b_two;\n \tconst char *set = diff_get_color_opt(o, DIFF_METAINFO);\n \tconst char *reset = diff_get_color_opt(o, DIFF_RESET);\n+\tconst char *a_prefix, *b_prefix;\n+\n+\tdiff_set_mnemonic_prefix(o, \"a/\", \"b/\");\n+\tif (DIFF_OPT_TST(o, REVERSE_DIFF)) {\n+\t\ta_prefix = o->b_prefix;\n+\t\tb_prefix = o->a_prefix;\n+\t} else {\n+\t\ta_prefix = o->a_prefix;\n+\t\tb_prefix = o->b_prefix;\n+\t}\n \n-\ta_one = quote_two(o->a_prefix, name_a + (*name_a == '/'));\n-\tb_two = quote_two(o->b_prefix, name_b + (*name_b == '/'));\n+\ta_one = quote_two(a_prefix, name_a + (*name_a == '/'));\n+\tb_two = quote_two(b_prefix, name_b + (*name_b == '/'));\n \tlbl[0] = DIFF_FILE_VALID(one) ? a_one : \"/dev/null\";\n \tlbl[1] = DIFF_FILE_VALID(two) ? b_two : \"/dev/null\";\n \tfprintf(o->file, \"%sdiff --git %s %s%s\\n\", set, a_one, b_two, reset);\n@@ -2299,8 +2331,10 @@ void diff_setup(struct diff_options *options)\n \t\tDIFF_OPT_CLR(options, COLOR_DIFF);\n \toptions->detect_rename = diff_detect_rename_default;\n \n-\toptions->a_prefix = \"a/\";\n-\toptions->b_prefix = \"b/\";\n+\tif (!diff_mnemonic_prefix) {\n+\t\toptions->a_prefix = \"a/\";\n+\t\toptions->b_prefix = \"b/\";\n+\t}\n }\n \n int diff_setup_done(struct diff_options *options)\ndiff --git a/diff.h b/diff.h\nindex 50fb5dd..9a679f5 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -160,6 +160,8 @@ extern void diff_tree_combined(const unsigned char *sha1, const unsigned char pa\n \n extern void diff_tree_combined_merge(const unsigned char *sha1, int, struct rev_info *);\n \n+void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b);\n+\n extern void diff_addremove(struct diff_options *,\n \t\t\t   int addremove,\n \t\t\t   unsigned mode,\n-- \n1.6.0.38.g002c7\n"},{"id":"87805","messageId":"m3k5ecrr6j.fsf@localhost.localdomain","threadId":"15063","inReplyTo":"7vljysru9b.fsf_-_@gitster.siamese.dyndns.org","subject":"Re: [PATCH v2] diff: vary default prefix depending on what are compared","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-08-20T09:06:50Z","receivedAt":"2008-08-20T09:06:50Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> With a new configuration \"diff.mnemonicprefix\", \"git diff\" shows the\n> differences between various combinations of preimage and postimage trees\n> with prefixes different from the standard \"a/\" and \"b/\".  Hopefully this\n> will make the distinction stand out for some people.\n> \n>     \"git diff\" compares the (i)ndex and the (w)ork tree;\n>     \"git diff HEAD\" compares a (c)ommit and the (w)ork tree;\n>     \"git diff --cached\" compares a (c)ommit and the (i)ndex;\n>     \"git diff --no-index a b\" compares two non-git things (1) and (2).\n> \n> Because these mnemonics now have meanings, they are swapped when reverse\n> diff is in effect and this feature is enabled.\n\n>  \n> +\tdiff_set_mnemonic_prefix(&revs->diffopt, \"o/\", \"w/\");\n> +\n\nSomehow you lost in the commit description and in the added\ndocumentation the (o)bject prefix (explicitely naming 'blob' object,\nfor example HEAD:a, or :2:b, or 7a7ff130a34942506e6068105ac5946c9404bf18)\n\nIt is also not obvious IMVHO that when comparing two trees (two\ncommits) git uses default 'a/'..'b/' prefixes.\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"87941","messageId":"loom.20080821T031647-276@post.gmane.org","threadId":"15063","inReplyTo":"alpine.LNX.1.00.0808181628420.19665@iabervon.org","subject":"Re: Call Me Gitless","fromName":"Sverre Hvammen Johansen","fromEmail":"hvammen@gmail.com","sentAt":"2008-08-21T03:40:52Z","receivedAt":"2008-08-21T03:40:52Z","isPatch":false,"sender":{"key":"hvammen@gmail.com","avatar":"https://gravatar.com/avatar/d1fc25ec327eea135af60fe7b56b2a2e21f711aa32167e7f505014ec88aa24bc?d=mp&s=160"},"body":"Daniel Barkalow <barkalow <at> iabervon.org> writes:\n> I think that having the possibility of adding an empty blob (or maybe a \n> magical \"nothing currently here but git-ls-files includes it\") would be \n> preferrable to a no-index mode. That is, the operation that corresponds \n> most directly to \"cvs add <filename>\" is \"git update-index --cacheinfo \n> 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 <filename>\", which is not \n> exactly easy to do, and just because a user wants to do this doesn't mean \n> the user doesn't want to use the index; a user that makes extensive use of \n> the index is actually more likely to want the state where a file is \n> tracked but all of the content has not yet been staged.\n\nI think it would be more natural if we had two commands for this; 'add' and\n'keep/cache/stage'.  The add command would add the file not the content to the\nindex and the keep command would add the content.  We could then have an\nauto-keep option for the add command and an auto-add option for the keep\ncommand.  By setting both of these options they would give current behaviour for\nadd.\n\n-- \nSverre Hvammen Johansen\n"},{"id":"87952","messageId":"7viqtukbec.fsf@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"alpine.LNX.1.00.0808181628420.19665@iabervon.org","subject":"Re: Call Me Gitless","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-21T08:41:47Z","receivedAt":"2008-08-21T08:41:47Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> On Mon, 18 Aug 2008, Junio C Hamano wrote:\n> ...\n>>     If we had a configuration for \"index-free\" people, that changes the\n>>     semantics of \"git add\" to register object name of an empty blob when a\n>>     new path is added, makes \"git add\" for existing blobs a no-op, but\n>>     keeps \"git commit -a\" and \"git commit <paths>\" to operate as they\n>>     currently do, then people with such configuration could:\n>> \n>> \t$ >new-file\n>>         $ git add new-file\n>>         $ edit old-file\n>>         $ edit new-file\n>>         $ git diff\n>> \n>>     to always see what's the difference from the HEAD is with \"git diff\",\n>>     and any of these three:\n>> \n>> \t$ git commit -a\n>>         $ git commit old-file\n>>         $ git commit old-file new-file\n>> \n>>     would work as expected by them.  We still need to support the three\n>>     diff variants for normal git people, but people who do not use index\n>>     do not have to know the two variants (\"git diff\" vs \"git diff HEAD\");\n>>     such a change could be argued as a \"UI improvement\" [*1*].\n>\n> I think that having the possibility of adding an empty blob (or maybe a \n> magical \"nothing currently here but git-ls-files includes it\") would be \n> preferrable to a no-index mode.\n\nI am not sure if you are really saying something different from what I am\nsaying.  We'll see after this three patch series.  The first one is an\nunrelated bugfix (but the bug won't trigger with existing callers -- only\ntriggered with the added codepath).\n"},{"id":"87953","messageId":"7vej4ikbc2.fsf_-_@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"7viqtukbec.fsf@gitster.siamese.dyndns.org","subject":"[PATCH 1/3] sha1_object_info(): pay attention to cached objects","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-21T08:43:09Z","receivedAt":"2008-08-21T08:43:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"We have some hardcoded objects (e.g. \"empty tree\") and also an interface\nto pretend we have objects in-core without ever writing them out to the\ndisk.  read_sha1_file() are aware of these cached objects.  However,\nsome codepaths use sha1_object_info() to find out the availability and\nsize of the object without reading the object data, without using\nread_sha1_file().\n\nThis teaches sha1_object_info() about these cached objects.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n sha1_file.c |   22 ++++++++++++++++------\n 1 files changed, 16 insertions(+), 6 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 2aff59b..d9e342e 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1926,10 +1926,25 @@ static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *size\n \treturn status;\n }\n \n+struct cached_object {\n+\tunsigned char sha1[20];\n+\tenum object_type type;\n+\tvoid *buf;\n+\tunsigned long size;\n+};\n+static struct cached_object *find_cached_object(const unsigned char *sha1);\n+\n int sha1_object_info(const unsigned char *sha1, unsigned long *sizep)\n {\n \tstruct pack_entry e;\n \tint status;\n+\tstruct cached_object *co;\n+\n+\tco = find_cached_object(sha1);\n+\tif (co) {\n+\t\t*sizep = co->size;\n+\t\treturn co->type;\n+\t}\n \n \tif (!find_pack_entry(sha1, &e, NULL)) {\n \t\t/* Most likely it's a loose object. */\n@@ -1975,12 +1990,7 @@ static void *read_packed_sha1(const unsigned char *sha1,\n  * to write them into the object store (e.g. a browse-only\n  * application).\n  */\n-static struct cached_object {\n-\tunsigned char sha1[20];\n-\tenum object_type type;\n-\tvoid *buf;\n-\tunsigned long size;\n-} *cached_objects;\n+static struct cached_object *cached_objects;\n static int cached_object_nr, cached_object_alloc;\n \n static struct cached_object empty_tree = {\n-- \n1.6.0.51.g078ae\n"},{"id":"87954","messageId":"7v8wuqkbb3.fsf_-_@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"7viqtukbec.fsf@gitster.siamese.dyndns.org","subject":"[PATCH 2/3] cached_object: learn empty blob","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-21T08:43:44Z","receivedAt":"2008-08-21T08:43:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"We have hardcoded an empty tree for a long time.  This teaches the code\nabout an empty blob object.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n sha1_file.c |   11 +++++++++++\n 1 files changed, 11 insertions(+), 0 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex d9e342e..1e5de12 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -2002,6 +2002,15 @@ static struct cached_object empty_tree = {\n \t0\n };\n \n+static struct cached_object empty_blob = {\n+\t/* empty blob sha1: e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 */\n+\t\"\\xe6\\x9d\\xe2\\x9b\\xb2\\xd1\\xd6\\x43\\x4b\\x8b\"\n+\t\"\\x29\\xae\\x77\\x5a\\xd8\\xc2\\xe4\\x8c\\x53\\x91\",\n+\tOBJ_BLOB,\n+\t\"\",\n+\t0\n+};\n+\n static struct cached_object *find_cached_object(const unsigned char *sha1)\n {\n \tint i;\n@@ -2013,6 +2022,8 @@ static struct cached_object *find_cached_object(const unsigned char *sha1)\n \t}\n \tif (!hashcmp(sha1, empty_tree.sha1))\n \t\treturn &empty_tree;\n+\tif (!hashcmp(sha1, empty_blob.sha1))\n+\t\treturn &empty_blob;\n \treturn NULL;\n }\n \n-- \n1.6.0.51.g078ae\n"},{"id":"87955","messageId":"7v3akykb96.fsf_-_@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"7viqtukbec.fsf@gitster.siamese.dyndns.org","subject":"[PATCH 3/3] git-add --intent-to-add (-N)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-21T08:44:53Z","receivedAt":"2008-08-21T08:44:53Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This adds \"--intent-to-add\" option to \"git add\".  This is to let the\nsystem know that you will tell it the final contents to be staged later,\niow, just be aware of the presense of the path with the type of the blob\nfor now.\n\nWith this sequence:\n\n    $ git reset --hard\n    $ edit newfile\n    $ git add -N newfile\n    $ edit newfile oldfile\n    $ git diff\n\nthe diff will show all changes relative to the current commit.  Then you\ncan do:\n\n    $ git commit -a ;# commit everything\n\nor\n\n    $ git commit oldfile ;# only oldfile, newfile not yet added\n\nto pretend you are working with an index-free system like CVS.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-add.c         |    4 +++-\n cache.h               |    2 ++\n read-cache.c          |   30 ++++++++++++++++++++----------\n t/t2203-add-intent.sh |   36 ++++++++++++++++++++++++++++++++++++\n 4 files changed, 61 insertions(+), 11 deletions(-)\n create mode 100755 t/t2203-add-intent.sh\n\ndiff --git a/builtin-add.c b/builtin-add.c\nindex fc3f96e..a08d50d 100644\n--- a/builtin-add.c\n+++ b/builtin-add.c\n@@ -191,7 +191,7 @@ static const char ignore_error[] =\n \"The following paths are ignored by one of your .gitignore files:\\n\";\n \n static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0;\n-static int ignore_add_errors, addremove;\n+static int ignore_add_errors, addremove, intent_to_add;\n \n static struct option builtin_add_options[] = {\n \tOPT__DRY_RUN(&show_only),\n@@ -201,6 +201,7 @@ static struct option builtin_add_options[] = {\n \tOPT_BOOLEAN('p', \"patch\", &patch_interactive, \"interactive patching\"),\n \tOPT_BOOLEAN('f', \"force\", &ignored_too, \"allow adding otherwise ignored files\"),\n \tOPT_BOOLEAN('u', \"update\", &take_worktree_changes, \"update tracked files\"),\n+\tOPT_BOOLEAN('N', \"intent-to-add\", &intent_to_add, \"record only the fact that the path will be added later\"),\n \tOPT_BOOLEAN('A', \"all\", &addremove, \"add all, noticing removal of tracked files\"),\n \tOPT_BOOLEAN( 0 , \"refresh\", &refresh_only, \"don't add, only refresh the index\"),\n \tOPT_BOOLEAN( 0 , \"ignore-errors\", &ignore_add_errors, \"just skip files which cannot be added because of errors\"),\n@@ -271,6 +272,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \n \tflags = ((verbose ? ADD_CACHE_VERBOSE : 0) |\n \t\t (show_only ? ADD_CACHE_PRETEND : 0) |\n+\t\t (intent_to_add ? ADD_CACHE_INTENT : 0) |\n \t\t (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0));\n \n \tif (require_pathspec && argc == 0) {\ndiff --git a/cache.h b/cache.h\nindex 68ce6e6..5948bcc 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -369,6 +369,7 @@ extern int index_name_pos(const struct index_state *, const char *name, int name\n #define ADD_CACHE_OK_TO_REPLACE 2\t/* Ok to replace file/directory */\n #define ADD_CACHE_SKIP_DFCHECK 4\t/* Ok to skip DF conflict checks */\n #define ADD_CACHE_JUST_APPEND 8\t\t/* Append only; tree.c::read_tree() */\n+#define ADD_CACHE_NEW_ONLY 16\t\t/* Do not replace existing ones */\n extern int add_index_entry(struct index_state *, struct cache_entry *ce, int option);\n extern struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really);\n extern void rename_index_entry_at(struct index_state *, int pos, const char *new_name);\n@@ -377,6 +378,7 @@ extern int remove_file_from_index(struct index_state *, const char *path);\n #define ADD_CACHE_VERBOSE 1\n #define ADD_CACHE_PRETEND 2\n #define ADD_CACHE_IGNORE_ERRORS\t4\n+#define ADD_CACHE_INTENT 8\n extern int add_to_index(struct index_state *, const char *path, struct stat *, int flags);\n extern int add_file_to_index(struct index_state *, const char *path, int flags);\n extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh);\ndiff --git a/read-cache.c b/read-cache.c\nindex 2c03ec3..1592045 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -154,13 +154,13 @@ static int ce_modified_check_fs(struct cache_entry *ce, struct stat *st)\n \treturn 0;\n }\n \n+static const unsigned char empty_blob_sha1[20] = {\n+\t0xe6,0x9d,0xe2,0x9b,0xb2,0xd1,0xd6,0x43,0x4b,0x8b,\n+\t0x29,0xae,0x77,0x5a,0xd8,0xc2,0xe4,0x8c,0x53,0x91\n+};\n+\n static int is_empty_blob_sha1(const unsigned char *sha1)\n {\n-\tstatic const unsigned char empty_blob_sha1[20] = {\n-\t\t0xe6,0x9d,0xe2,0x9b,0xb2,0xd1,0xd6,0x43,0x4b,0x8b,\n-\t\t0x29,0xae,0x77,0x5a,0xd8,0xc2,0xe4,0x8c,0x53,0x91\n-\t};\n-\n \treturn !hashcmp(sha1, empty_blob_sha1);\n }\n \n@@ -514,6 +514,9 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,\n \tunsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_RACY_IS_DIRTY;\n \tint verbose = flags & (ADD_CACHE_VERBOSE | ADD_CACHE_PRETEND);\n \tint pretend = flags & ADD_CACHE_PRETEND;\n+\tint intent_only = flags & ADD_CACHE_INTENT;\n+\tint add_option = (ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE|\n+\t\t\t  (intent_only ? ADD_CACHE_NEW_ONLY : 0));\n \n \tif (!S_ISREG(st_mode) && !S_ISLNK(st_mode) && !S_ISDIR(st_mode))\n \t\treturn error(\"%s: can only add regular files, symbolic links or git-directories\", path);\n@@ -527,7 +530,8 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,\n \tce = xcalloc(1, size);\n \tmemcpy(ce->name, path, namelen);\n \tce->ce_flags = namelen;\n-\tfill_stat_cache_info(ce, st);\n+\tif (!intent_only)\n+\t\tfill_stat_cache_info(ce, st);\n \n \tif (trust_executable_bit && has_symlinks)\n \t\tce->ce_mode = create_ce_mode(st_mode);\n@@ -550,8 +554,12 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,\n \t\talias->ce_flags |= CE_ADDED;\n \t\treturn 0;\n \t}\n-\tif (index_path(ce->sha1, path, st, 1))\n-\t\treturn error(\"unable to index file %s\", path);\n+\tif (!intent_only) {\n+\t\tif (index_path(ce->sha1, path, st, 1))\n+\t\t\treturn error(\"unable to index file %s\", path);\n+\t} else\n+\t\thashcpy(ce->sha1, empty_blob_sha1);\n+\n \tif (ignore_case && alias && different_name(ce, alias))\n \t\tce = create_alias_ce(ce, alias);\n \tce->ce_flags |= CE_ADDED;\n@@ -564,7 +572,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,\n \n \tif (pretend)\n \t\t;\n-\telse if (add_index_entry(istate, ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE))\n+\telse if (add_index_entry(istate, ce, add_option))\n \t\treturn error(\"unable to add %s to index\",path);\n \tif (verbose && !was_same)\n \t\tprintf(\"add '%s'\\n\", path);\n@@ -843,13 +851,15 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e\n \tint ok_to_add = option & ADD_CACHE_OK_TO_ADD;\n \tint ok_to_replace = option & ADD_CACHE_OK_TO_REPLACE;\n \tint skip_df_check = option & ADD_CACHE_SKIP_DFCHECK;\n+\tint new_only = option & ADD_CACHE_NEW_ONLY;\n \n \tcache_tree_invalidate_path(istate->cache_tree, ce->name);\n \tpos = index_name_pos(istate, ce->name, ce->ce_flags);\n \n \t/* existing match? Just replace it. */\n \tif (pos >= 0) {\n-\t\treplace_index_entry(istate, pos, ce);\n+\t\tif (!new_only)\n+\t\t\treplace_index_entry(istate, pos, ce);\n \t\treturn 0;\n \t}\n \tpos = -pos-1;\ndiff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh\nnew file mode 100755\nindex 0000000..d4de35e\n--- /dev/null\n+++ b/t/t2203-add-intent.sh\n@@ -0,0 +1,36 @@\n+#!/bin/sh\n+\n+test_description='Intent to add'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'intent to add' '\n+\techo hello >file &&\n+\techo hello >elif &&\n+\tgit add -N file &&\n+\tgit add elif\n+'\n+\n+test_expect_success 'check result of \"add -N\"' '\n+\tgit ls-files -s file >actual &&\n+\tempty=$(git hash-object --stdin </dev/null) &&\n+\techo \"100644 $empty 0\tfile\" >expect &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'intent to add is just an ordinary empty blob' '\n+\tgit add -u &&\n+\tgit ls-files -s file >actual &&\n+\tgit ls-files -s elif | sed -e \"s/elif/file/\" >expect &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'intent to add does not clobber existing paths' '\n+\tgit add -N file elif &&\n+\tempty=$(git hash-object --stdin </dev/null) &&\n+\tgit ls-files -s >actual &&\n+\t! grep \"$empty\" actual\n+'\n+\n+test_done\n+\n-- \n1.6.0.51.g078ae\n"},{"id":"87981","messageId":"alpine.LNX.1.00.0808210928010.19665@iabervon.org","threadId":"15063","inReplyTo":"7viqtukbec.fsf@gitster.siamese.dyndns.org","subject":"Re: Call Me Gitless","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-08-21T13:58:52Z","receivedAt":"2008-08-21T13:58:52Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Thu, 21 Aug 2008, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > On Mon, 18 Aug 2008, Junio C Hamano wrote:\n> > ...\n> >>     If we had a configuration for \"index-free\" people, that changes the\n> >>     semantics of \"git add\" to register object name of an empty blob when a\n> >>     new path is added, makes \"git add\" for existing blobs a no-op, but\n> >>     keeps \"git commit -a\" and \"git commit <paths>\" to operate as they\n> >>     currently do, then people with such configuration could:\n> >> \n> >> \t$ >new-file\n> >>         $ git add new-file\n> >>         $ edit old-file\n> >>         $ edit new-file\n> >>         $ git diff\n> >> \n> >>     to always see what's the difference from the HEAD is with \"git diff\",\n> >>     and any of these three:\n> >> \n> >> \t$ git commit -a\n> >>         $ git commit old-file\n> >>         $ git commit old-file new-file\n> >> \n> >>     would work as expected by them.  We still need to support the three\n> >>     diff variants for normal git people, but people who do not use index\n> >>     do not have to know the two variants (\"git diff\" vs \"git diff HEAD\");\n> >>     such a change could be argued as a \"UI improvement\" [*1*].\n> >\n> > I think that having the possibility of adding an empty blob (or maybe a \n> > magical \"nothing currently here but git-ls-files includes it\") would be \n> > preferrable to a no-index mode.\n> \n> I am not sure if you are really saying something different from what I am\n> saying.  We'll see after this three patch series.  The first one is an\n> unrelated bugfix (but the bug won't trigger with existing callers -- only\n> triggered with the added codepath).\n\nI see this primarily as something you can use if you're worried about \nleaving files out of commits. When you create the file, you can use \"git \nadd -N\" to make sure that it won't get overlooked when you're adding \nthings. If you weren't using the index for anything important, you could \njust use a normal add, but that would get confusing if you're adding \ncompleted changes as well as some half-written version of any file that \nhappens to be new. That is, it'll let you cause \"git diff\" to report the \ncontents as unstaged changes in your working tree, rather than not \nreporting it (either because it's not tracked at all, or because the \nchanges are now staged). Then you can decide to stage them.\n\n(The thing that I'd ideally like to have different is for:\n\n$ echo \"content\" > new-name\n$ git add -N new-name\n$ git commit\n\nSay:\n\n# On branch master\n# Changed but not updated:\n#   (use \"git add <file>...\" to update what will be committed)\n#\n#          added:   new-name\n#\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\n\nrather than committing the empty blob. But that's tricky to implement \nand keep from breaking other stuff and really minor; and the \ndocumentation doesn't exclude that being what happens with -N)\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"87985","messageId":"48AD7895.5010707@gnu.org","threadId":"15063","inReplyTo":"48AAAE17.1070800@obry.net","subject":"Re: Call Me Gitless","fromName":"Paolo Bonzini","fromEmail":"bonzini@gnu.org","sentAt":"2008-08-21T14:15:49Z","receivedAt":"2008-08-21T14:15:49Z","isPatch":false,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"Pascal Obry wrote:\n> \n> For what it's worth, I have added this since I've been working with Git \n> on my aliases:\n> \n> [alias]\n>  staged = diff --cached\n> \n> Since then I'm always running:\n> \n>    $ git staged\n> \n> This looks more intuitive to me and faster than typing:\n> \n>    $ git diff --cached\n\nYou're probably right, but it means that basically you cannot have other \n\"diff\" aliases without having an exploding number of combinations.  For \nexample I have\n\n[alias]\n         changes=diff --name-status -r\n\nand I don't want to have staged-changes too. :-)\n\nI used to think that the proposal I saw in another git frontend, which is:\n\n\tgit diff --cached -->\tgit diff --staged\n\tgit diff -->\t\tgit diff --unstaged\n\tgit diff HEAD -->\tgit diff\n\nwas a good one, but it is actually not when you start thinking about \nwhat to do during a large merge with few conflicts.  In fact, even \nthough I use the index almost exclusively when merging (*), I don't mind \nthe few extra keystrokes.\n\n(*) When not merging, I use \"git commit -a\" preceded by \"git changes\" \n(see above).  In all situations where I might get confused between what \nis in the index and what is not (for example when adding new files) I \nuse \"git citool\".\n\nPaolo\n"},{"id":"87987","messageId":"48AD7A78.2020907@gnu.org","threadId":"15063","inReplyTo":"7v3akykb96.fsf_-_@gitster.siamese.dyndns.org","subject":"Re: [PATCH 3/3] git-add --intent-to-add (-N)","fromName":"Paolo Bonzini","fromEmail":"bonzini@gnu.org","sentAt":"2008-08-21T14:23:52Z","receivedAt":"2008-08-21T14:23:52Z","isPatch":true,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"Junio C Hamano wrote:\n> This adds \"--intent-to-add\" option to \"git add\".  This is to let the\n> system know that you will tell it the final contents to be staged later,\n> iow, just be aware of the presense of the path with the type of the blob\n> for now.\n\nWhile I like intent_* in the variables, what about \"git add --path FILE\" \nfor the user interface?  Also, I wonder if it would be good to restrict \n\"git add --path\" to paths not already in the index, and give an error \notherwise.\n\nAs I said elsewhere in the thread, I wouldn't use this feature (I keep a \n\"git citool\" window open to review my own changes, when I have to deal \nwith new files), but I applaud its introduction.\n\n> Then you can do:\n> \n>     $ git commit -a ;# commit everything\n> \n> or\n> \n>     $ git commit oldfile ;# only oldfile, newfile not yet added\n\nDid you mean \"git commit\" for the second use case?\n\nPaolo\n"},{"id":"88041","messageId":"Pine.GSO.4.62.0808211608020.26161@harper.uchicago.edu","threadId":"15063","inReplyTo":"7v3akykb96.fsf_-_@gitster.siamese.dyndns.org","subject":"Re: [PATCH 3/3] git-add --intent-to-add (-N)","fromName":"Jonathan Nieder","fromEmail":"jrnieder@uchicago.edu","sentAt":"2008-08-21T21:14:32Z","receivedAt":"2008-08-21T21:14:32Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nJunio C Hamano wrote:\n\n> This adds \"--intent-to-add\" option to \"git add\".\n\nI quite like the idea of this patch series.  When I try to test it with\n\"git merge jc/ita; make test\", t0020-crlf setup fails with\n\n\terror: invalid object e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\n\terror: Error building trees\n\t* FAIL 1: setup\n\nThis could be me doing something wrong, but I thought you'd like to\nknow, anyway.  I'll try to diagnose it tonight.\n\nRegards,\nJonathan\n"},{"id":"88081","messageId":"Pine.GSO.4.62.0808212304200.9108@harper.uchicago.edu","threadId":"15063","inReplyTo":"Pine.GSO.4.62.0808211608020.26161@harper.uchicago.edu","subject":"Re: [PATCH 3/3] git-add --intent-to-add (-N)","fromName":"Jonathan Nieder","fromEmail":"jrnieder@uchicago.edu","sentAt":"2008-08-22T04:10:54Z","receivedAt":"2008-08-22T04:10:54Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nJonathan Nieder wrote:\n\n> I quite like the idea of this patch series.  When I try to test it with\n> \"git merge jc/ita; make test\", t0020-crlf setup fails\n[...]\n> This could be me doing something [stupid]\n\nand it was.  In a sleepy daze, I resolved a conflict\n\n<<<<<<<\n#define ADD_CACHE_IGNORE_REMOVAL 8\n=======\n#define ADD_CACHE_INTENT 8\n>>>>>>>\n\nby using the same bit for both.  Sorry for the noise.\n\nOthers can experience that unpleasant error message for themselves\nwith next + jc/add-ita merged properly:\n\n\t$ mkdir test-repo && cd test-repo\n\t$ git init\n\tInitialized empty Git repository in /var/tmp/jrnieder/test-repo/.git/\n\t$ : >a\n\t$ git add -N a\n\t$ git commit\n\terror: invalid object e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\n\terror: Error building trees\n\nI think the first error comes from update_one, which creates a tree\nobject from the index.  It is complaining, because after all, that\nobject is not in any sha1 file.\n\nIf the empty blob happened to be in our object database, the user's\nmistake would be hidden:\n\n\t$ git add a && git commit\n\terror: invalid object e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\n\terror: Error building trees\n\t$ git rm -f --cached a\n\trm 'a'\n\t$ git add a\n\t$ git commit -m initial\n\t$ echo hi >b\n\t$ git add -N b\n\t$ git commit && echo ok\n\tCreated commit 91325db: some commit message\n\t 0 files changed, 0 insertions(+), 0 deletions(-)\n\t create mode 100644 b\n\tok\n\nMaybe it would be better to use some other magic blob (or a bit\nsomewhere) to remember that the file has not been added yet.\n\nThoughts?\n\nRegards,\nJonathan\n"},{"id":"88083","messageId":"alpine.LNX.1.00.0808220023170.19665@iabervon.org","threadId":"15063","inReplyTo":"Pine.GSO.4.62.0808212304200.9108@harper.uchicago.edu","subject":"Re: [PATCH 3/3] git-add --intent-to-add (-N)","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-08-22T04:34:13Z","receivedAt":"2008-08-22T04:34:13Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Thu, 21 Aug 2008, Jonathan Nieder wrote:\n\n> Hi,\n> \n> Jonathan Nieder wrote:\n> \n> > I quite like the idea of this patch series.  When I try to test it with\n> > \"git merge jc/ita; make test\", t0020-crlf setup fails\n> [...]\n> > This could be me doing something [stupid]\n> \n> and it was.  In a sleepy daze, I resolved a conflict\n> \n> <<<<<<<\n> #define ADD_CACHE_IGNORE_REMOVAL 8\n> =======\n> #define ADD_CACHE_INTENT 8\n> >>>>>>>\n> \n> by using the same bit for both.  Sorry for the noise.\n> \n> Others can experience that unpleasant error message for themselves\n> with next + jc/add-ita merged properly:\n> \n> \t$ mkdir test-repo && cd test-repo\n> \t$ git init\n> \tInitialized empty Git repository in /var/tmp/jrnieder/test-repo/.git/\n> \t$ : >a\n> \t$ git add -N a\n> \t$ git commit\n> \terror: invalid object e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\n> \terror: Error building trees\n> \n> I think the first error comes from update_one, which creates a tree\n> object from the index.  It is complaining, because after all, that\n> object is not in any sha1 file.\n\nI think [1/3] was supposed to make this not an issue, with that particular \nobject being implicitly in all objects databases.\n\n> If the empty blob happened to be in our object database, the user's\n> mistake would be hidden:\n> \n> \t$ git add a && git commit\n> \terror: invalid object e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\n> \terror: Error building trees\n> \t$ git rm -f --cached a\n> \trm 'a'\n> \t$ git add a\n> \t$ git commit -m initial\n> \t$ echo hi >b\n> \t$ git add -N b\n> \t$ git commit && echo ok\n> \tCreated commit 91325db: some commit message\n> \t 0 files changed, 0 insertions(+), 0 deletions(-)\n> \t create mode 100644 b\n> \tok\n> \n> Maybe it would be better to use some other magic blob (or a bit\n> somewhere) to remember that the file has not been added yet.\n\nAn actual magic value (maybe the all-zeros hash) would make it an actual \nerror for the file to not have been added; the current code behaves as if \nyou did:\n\n$ touch b\n$ git add b\n\nright before putting anything in b. Aside, perhaps, from retrieval bugs, \nit's just like you actually added an empty blob.\n\nLast time I tried something along these lines, using the all-zeros hash \nactually came pretty close to working, except that diff uses this value \nfor \"look at the working tree\" in its representation, and stuff gets \nconfused by it; these are actually distinguishable, IIRC, by whether the \nmode bits are set or not, but current code doesn't check that.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"88085","messageId":"7vr68hejca.fsf@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"alpine.LNX.1.00.0808220023170.19665@iabervon.org","subject":"Re: [PATCH 3/3] git-add --intent-to-add (-N)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-22T04:59:01Z","receivedAt":"2008-08-22T04:59:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> ... these are actually distinguishable, IIRC, by whether the \n> mode bits are set or not, but current code doesn't check that.\n\nIIRC, mode bits all zero means something different, so I do not think that\nwould fly.  If we really wanted to do this \"intent-to-add\" properly, we\nprobably should give one of the flag bits in the in-core index structure.\nUnlike on-disk flag bits, they are not scarce resources anymore these\ndays.\n"},{"id":"88086","messageId":"Pine.GSO.4.62.0808220015190.11259@harper.uchicago.edu","threadId":"15063","inReplyTo":"alpine.LNX.1.00.0808220023170.19665@iabervon.org","subject":"Re: [PATCH 3/3] git-add --intent-to-add (-N)","fromName":"Jonathan Nieder","fromEmail":"jrnieder@uchicago.edu","sentAt":"2008-08-22T05:32:01Z","receivedAt":"2008-08-22T05:32:01Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Daniel Barkalow wrote:\n\n> On Thu, 21 Aug 2008, Jonathan Nieder wrote:\n[...]\n> > \t$ git add -N a\n> > \t$ git commit\n> > \terror: invalid object e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\n> > \terror: Error building trees\n> > \n> > I think the first error comes from update_one, which creates a tree\n> > object from the index.  It is complaining, because after all, that\n> > object is not in any sha1 file.\n> \n> I think [1/3] was supposed to make this not an issue, with that particular \n> object being implicitly in all objects databases.\n\nWait, is [1/3] meant to create that strong of an illusion?  That is,\nshould has_sha1_file pretend the object is present, too?\n\nJonathan\n"},{"id":"88088","messageId":"7vtzddd1z5.fsf@gitster.siamese.dyndns.org","threadId":"15063","inReplyTo":"Pine.GSO.4.62.0808220015190.11259@harper.uchicago.edu","subject":"Re: [PATCH 3/3] git-add --intent-to-add (-N)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-08-22T05:59:26Z","receivedAt":"2008-08-22T05:59:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jonathan Nieder <jrnieder@uchicago.edu> writes:\n\n> Wait, is [1/3] meant to create that strong of an illusion?  That is,\n> should has_sha1_file pretend the object is present, too?\n\nAFAIR has_sha1_file() is actually used to write out the object for real\nafter you have been pretending it exists, so no.\n\nDidn't I already tell you that you seem to have picked only one out of _three_\npatch series?\n"},{"id":"88093","messageId":"Pine.GSO.4.62.0808220119250.12851@harper.uchicago.edu","threadId":"15063","inReplyTo":"7vtzddd1z5.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 3/3] git-add --intent-to-add (-N)","fromName":"Jonathan Nieder","fromEmail":"jrnieder@uchicago.edu","sentAt":"2008-08-22T06:38:02Z","receivedAt":"2008-08-22T06:38:02Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nJunio C Hamano wrote:\n\n> Didn't I already tell you that you seem to have picked only one out of\n> _three_ patch series?\n\nI am using all three patches.  If you try \">a && git add -N a && git\ncommit\" in an empty repo, you should get the same behavior (I checked\nwith commit 038a213^2, which is three commits ahead of master).  And\nyes, I do understand where your suspicion came from.\n\nBut the reason for the behavior is that update_one in cache-tree.c\ncontains the test\n\n\tif (mode != S_IFGITLINK && !missing_ok && !has_sha1_file(sha1))\n\nwhich fails for the empty blob in a new repo because, as I said, we\ndon't have that sha1 file.\n\nI still wonder, do we want to pretend we have that object on disk\nand proceed with the commit, or are the hardcoded objects only\nsupposed to be sufficient for in-core use?  If the former, I will\nhave to make some tests to be comfortable: are the objects properly\ntransfered to older clients without the hardcoded objects, etc.  But\nI don't want to bother if that is not the intent.\n\nHoping that is clearer,\nJonathan\n"},{"id":"88099","messageId":"Pine.GSO.4.62.0808220150410.13589@harper.uchicago.edu","threadId":"15063","inReplyTo":"Pine.GSO.4.62.0808220119250.12851@harper.uchicago.edu","subject":"Re: [PATCH 3/3] git-add --intent-to-add (-N)","fromName":"Jonathan Nieder","fromEmail":"jrnieder@uchicago.edu","sentAt":"2008-08-22T07:52:39Z","receivedAt":"2008-08-22T07:52:39Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Jonathan Nieder wrote:\n[...]\n> I still wonder, do we want to pretend we have that object on disk\n> and proceed with the commit, or are the hardcoded objects only\n> supposed to be sufficient for in-core use?\n\nSorry, I responded in haste.  The objects are supposed to be used in\ncore and then written out as needed, so I had been describing a bug.\n\nHow about this (in the spirit of patch 1/3)?  If the approach is\nright, I can add tests tomorrow.\n\n-- snipsnip --\nSubject: update_one(): write out cached objects as needed\n\nAlthough we can always pretend to have hardcoded objects such as\nthe empty tree in core, in the on-disk repository, if they are\nreferred to, they should be present.  Currently, if we try to\nwrite a tree that uses a hardcoded object, we can notice that the\nobject is missing and fail with \"error: invalid object\".\n\nWith this patch, the objects are written to disk as needed\ninstead.\n\nSigned-off-by: Jonathan Nieder <jrnieder@uchicago.edu>\n---\n cache-tree.c |   11 +++++++++--\n cache.h      |    1 +\n sha1_file.c  |   16 ++++++++++++++++\n 3 files changed, 26 insertions(+), 2 deletions(-)\n\ndiff --git a/cache-tree.c b/cache-tree.c\nindex 5f8ee87..b17f34f 100644\n--- a/cache-tree.c\n+++ b/cache-tree.c\n@@ -323,8 +323,15 @@ static int update_one(struct cache_tree *it,\n \t\t\tmode = ce->ce_mode;\n \t\t\tentlen = pathlen - baselen;\n \t\t}\n-\t\tif (mode != S_IFGITLINK && !missing_ok && !has_sha1_file(sha1))\n-\t\t\treturn error(\"invalid object %s\", sha1_to_hex(sha1));\n+\t\tif (mode != S_IFGITLINK && !missing_ok &&\n+\t\t\t\t!has_sha1_file(sha1)) {\n+\t\t\t/* Hopefully it's a cached object.  Make sure. */\n+\t\t\tif (dryrun)\n+\t\t\t\t(void) sha1_object_info(sha1, NULL);\n+\t\t\telse if (write_cached_object_sha1_file(sha1))\n+\t\t\t\treturn error(\"invalid object %s\",\n+\t\t\t\t\tsha1_to_hex(sha1));\n+\t\t}\n \n \t\tif (ce->ce_flags & CE_REMOVE)\n \t\t\tcontinue; /* entry being removed */\ndiff --git a/cache.h b/cache.h\nindex c443df4..83dbdf7 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -546,6 +546,7 @@ extern int hash_sha1_file(const void *buf, unsigned long len, const char *type,\n extern int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *return_sha1);\n extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);\n extern int force_object_loose(const unsigned char *sha1, time_t mtime);\n+extern int write_cached_object_sha1_file(const unsigned char *sha1);\n \n /* just like read_sha1_file(), but non fatal in presence of bad objects */\n extern void *read_object(const unsigned char *sha1, enum object_type *type, unsigned long *size);\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 7d86d76..8584a33 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -2028,6 +2028,22 @@ static struct cached_object *find_cached_object(const unsigned char *sha1)\n \treturn NULL;\n }\n \n+int write_cached_object_sha1_file(const unsigned char *sha1)\n+{\n+\tstruct cached_object *co = find_cached_object(sha1);\n+\tunsigned char sha1_compare[20];\n+\tint result;\n+\n+\tif (co == NULL)\n+\t\treturn -1;\n+\tresult = write_sha1_file(co->buf, co->size, typename(co->type),\n+\t\t\tsha1_compare);\n+\tif (memcmp(sha1, sha1_compare, 20))\n+\t\treturn error(\"corrupt cached object %s\",\n+\t\t\t\tsha1_to_hex(sha1));\n+\treturn result;\n+}\n+\n int pretend_sha1_file(void *buf, unsigned long len, enum object_type type,\n \t\t      unsigned char *sha1)\n {\n-- \n1.6.0.481.gabe4\n"},{"id":"88175","messageId":"51419b2c0808221210k6e7defdcw3ba9e4ef89e054e7@mail.gmail.com","threadId":"15063","inReplyTo":"48AD7895.5010707@gnu.org","subject":"Re: Call Me Gitless","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2008-08-22T19:10:36Z","receivedAt":"2008-08-22T19:10:36Z","isPatch":false,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Aug 21, 2008 at 8:15 AM, Paolo Bonzini <bonzini@gnu.org> wrote:\n> I used to think that the proposal I saw in another git frontend, which is:\n>\n>        git diff --cached -->   git diff --staged\n>        git diff -->            git diff --unstaged\n>        git diff HEAD -->       git diff\n>\n> was a good one, but it is actually not when you start thinking about what to\n> do during a large merge with few conflicts.  In fact, even though I use the\n> index almost exclusively when merging (*), I don't mind the few extra\n> keystrokes.\n\nIf you look a little closer, you'll note that the three lines of this\nproposal has an exception specifically for the conflict during merge\ncase.   :-)\n\nElijah\n"}]}