{"thread":{"id":"43230","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","startedAt":"2006-12-01T20:06:20Z","lastAt":"2006-12-03T09:16:04Z","messageCount":21,"participants":["Junio C Hamano","Nicolas Pitre","Jakub Narebski","Carl Worth","Han-Wen Nienhuys","Alan Chandler"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"297844","messageId":"Pine.LNX.4.64.0612011444310.9647@xanadu.home","threadId":"43230","inReplyTo":null,"subject":"[PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2006-12-01T20:06:20Z","receivedAt":"2006-12-01T20:06:20Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"I personally think this is going to make the GIT experience lot more \nenjoyable for everybody.  This brings the power of the index up front \nusing a proper mental model without talking about the index at all. See \nfor example how all the technical discussion has been evacuated from the \ngit-add man page.\n\nAny content to be committed must be added together.  Whether that \ncontent comes from new files or modified files doesn't matter.  You just \nneed to \"add\" it, either with git-add, or by providing git-commit with \n-a (for already known files only of course). No need for a separate \ncommand to distinguish new vs modified files please.  That would only \nscrew the mental model everybody should have when using GIT.\n\nSigned-off-by: Nicolas Pitre <nico@cam.org>\n\n---\n\nTODO:\n\nmaybe add a -f/--force argument to allow for adding ignored files \ninstead of going through git-update-index.\n\nmaybe add --new-only and --known-only arguments if there is a real need \nto discriminate between new vs updated files.  I would not suggest \nagainst it though, because if someone really has such fancy and uncommon \nrequirements he might just use git-update-index directly at that point.\n\ndiff --git a/Documentation/git-add.txt b/Documentation/git-add.txt\nindex 6342ea3..ffa8446 100644\n--- a/Documentation/git-add.txt\n+++ b/Documentation/git-add.txt\n@@ -3,7 +3,7 @@ git-add(1)\n \n NAME\n ----\n-git-add - Add files to the index file\n+git-add - Add file content to the changeset to be committed next\n \n SYNOPSIS\n --------\n@@ -11,16 +11,31 @@ SYNOPSIS\n \n DESCRIPTION\n -----------\n-A simple wrapper for git-update-index to add files to the index,\n-for people used to do \"cvs add\".\n-\n-It only adds non-ignored files, to add ignored files use\n+Contrary to other SCMs, with GIT you have to explicitly \"add\" all the\n+changed file content you want to commit together to form a changeset\n+with the 'add' command before using the 'commit' command.\n+\n+This is not only for adding new files.  Even modified files must be\n+added to the set of changes about to be committed. This command can\n+be performed multiple times before a commit. The 'git status' command\n+will give you a summary of what is included for the next commit.\n+\n+Note: don't forget to 'add' a file again if you modified it after the\n+first 'add' and before 'commit'. Otherwise only the previous added\n+state of that file will be committed. This is because git tracks\n+content, so what you're really 'add'ing to the commit is the *content*\n+of the file in the state it is in when you 'add' it. Of course there are\n+legitimate usage cases for not updating an already added file content\n+in order to commit a previous file state, but in this case you better\n+know what you're doing.\n+\n+This command only adds non-ignored files, to add ignored files use\n \"git update-index --add\".\n \n OPTIONS\n -------\n <file>...::\n-\tFiles to add to the index (see gitlink:git-ls-files[1]).\n+\tFiles to add content from.\n \n -n::\n         Don't actually add the file(s), just show if they exist.\n@@ -34,27 +49,12 @@ OPTIONS\n \tfor command-line options).\n \n \n-DISCUSSION\n-----------\n-\n-The list of <file> given to the command is fed to `git-ls-files`\n-command to list files that are not registered in the index and\n-are not ignored/excluded by `$GIT_DIR/info/exclude` file or\n-`.gitignore` file in each directory.  This means two things:\n-\n-. You can put the name of a directory on the command line, and\n-  the command will add all files in it and its subdirectories;\n-\n-. Giving the name of a file that is already in index does not\n-  run `git-update-index` on that path.\n-\n-\n EXAMPLES\n --------\n git-add Documentation/\\\\*.txt::\n \n-\tAdds all `\\*.txt` files that are not in the index under\n-\t`Documentation` directory and its subdirectories.\n+\tAdds content from all `\\*.txt` files under `Documentation`\n+\tdirectory and its subdirectories.\n +\n Note that the asterisk `\\*` is quoted from the shell in this\n example; this lets the command to include the files from\n@@ -62,15 +62,17 @@ subdirectories of `Documentation/` directory.\n \n git-add git-*.sh::\n \n-\tAdds all git-*.sh scripts that are not in the index.\n+\tConsiders adding content from all git-*.sh scripts.\n \tBecause this example lets shell expand the asterisk\n \t(i.e. you are listing the files explicitly), it does not\n-\tadd `subdir/git-foo.sh` to the index.\n+\tconsider `subdir/git-foo.sh`.\n \n See Also\n --------\n gitlink:git-rm[1]\n-gitlink:git-ls-files[1]\n+gitlink:git-mv[1]\n+gitlink:git-commit[1]\n+gitlink:git-update-index[1]\n \n Author\n ------\ndiff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt\nindex fe4491d..8113d79 100644\n--- a/Documentation/tutorial.txt\n+++ b/Documentation/tutorial.txt\n@@ -87,14 +87,54 @@ thorough description.  Tools that turn commits into email, for\n example, use the first line on the Subject line and the rest of the\n commit in the body.\n \n-To add a new file, first create the file, then\n-\n-------------------------------------------------\n-$ git add path/to/new/file\n-------------------------------------------------\n-\n-then commit as usual.  No special command is required when removing a\n-file; just remove it, then tell `commit` about the file as usual.\n+GIt tracks content not files\n+----------------------------\n+\n+Contrary to other SCMs, with GIT you have to explicitly \"add\" all\n+the changed _content_ you want to commit together to form a changeset.\n+This can be done in a few different ways:\n+\n+1) By using 'git add <file_spec>...'\n+ \n+   This can be performed multiple times before a commit.  Note that this\n+   is not only for adding new files.  Even modified files must be\n+   added to the set of changes about to be committed.  The \"git status\"\n+   command gives you a summary of what is included so far for the\n+   next commit.  When done you should use the 'git commit' command to\n+   make it real.\n+\n+   Note: don't forget to 'add' a file again if you modified it after the\n+   first 'add' and before 'commit'. Otherwise only the previous added\n+   state of that file will be committed. This is because git tracks\n+   content, so what you're really 'add'ing to the commit is the *content*\n+   of the file in the state it is in when you 'add' it.\n+\n+2) By using 'git commit -a' directly\n+\n+   This is a quick way to automatically 'add' the content from all files\n+   that were modified since the previous commit, and perform the actual\n+   commit without having to separately 'add' them beforehand.  This will\n+   not add content from new files i.e. files that were never added before.\n+   Those files still have to be added explicitly before performing a\n+   commit.\n+\n+But here's a twist. If you do 'git commit <file1> <file2> ...' then only\n+the  changes belonging to those explicitly specified files will be\n+committed, entirely bypassing the current \"added\" changes. Those \"added\"\n+changes will still remain available for a subsequent commit though.\n+\n+There is a twist about that twist: if you do 'git commit -i <file>...'\n+then the commit will consider changes to those specified files _including_\n+all \"added\" changes so far.\n+\n+But for instance it is best to only remember 'git add' + 'git commit'\n+and/or 'git commit -a'.\n+\n+No special command is required when removing a file; just remove it,\n+then tell `commit` about the file as usual.\n+\n+Viewing the changelog\n+---------------------\n \n At any point you can view the history of your changes using\n \ndiff --git a/builtin-add.c b/builtin-add.c\nindex febb75e..b3f9206 100644\n--- a/builtin-add.c\n+++ b/builtin-add.c\n@@ -94,9 +94,6 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \n \tnewfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1);\n \n-\tif (read_cache() < 0)\n-\t\tdie(\"index file corrupt\");\n-\n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n \n@@ -131,6 +128,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\treturn 0;\n \t}\n \n+\tif (read_cache() < 0)\n+\t\tdie(\"index file corrupt\");\n+\n \tfor (i = 0; i < dir.nr; i++)\n \t\tadd_file_to_index(dir.entries[i]->name, verbose);\n \ndiff --git a/wt-status.c b/wt-status.c\nindex de1be5b..4b8b570 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -163,7 +163,7 @@ static void wt_status_print_changed_cb(struct diff_queue_struct *q,\n \tint i;\n \tif (q->nr)\n \t\twt_status_print_header(\"Changed but not updated\",\n-\t\t\t\t\"use git-update-index to mark for commit\");\n+\t\t\t\t\"use git-add on files to include for commit\");\n \tfor (i = 0; i < q->nr; i++)\n \t\twt_status_print_filepair(WT_STATUS_CHANGED, q->queue[i]);\n"},{"id":"294089","messageId":"7vpsb36yem.fsf@assigned-by-dhcp.cox.net","threadId":"43230","inReplyTo":"Pine.LNX.4.64.0612011444310.9647@xanadu.home","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-12-01T22:31:45Z","receivedAt":"2006-12-01T22:31:45Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nicolas Pitre <nico@cam.org> writes:\n\n> I personally think this is going to make the GIT experience lot more \n> enjoyable for everybody.  This brings the power of the index up front \n> using a proper mental model without talking about the index at all. See \n> for example how all the technical discussion has been evacuated from the \n> git-add man page.\n\nI like the direction this is taking us.\n\nThe documentation update is in the same spirit with the sample\nrewrite of 'git diff' manpage.  We might want to tweak the\nwording to make this round of documentation updates consistent.\n\nMy preferences:\n\n - You used the word \"changeset\"; I am not sure that is a good\n   wording.  The recent explanation I saw on the list and liked\n   were \"you _stage_ your changes to prepare for the next\n   commit (footnote: the staging area is called 'the index')\".\n   My impression was that both extremes (Linus and Carl) are\n   also Ok with this wording.\n\n - We keep the word \"index\", and not reword it to \"stage\" in the\n   names of commands and options.  \"to stage\" is very good verb\n   to explain the _concept_, but there is no need to use\n   inconsistent wording Porcelain-ish and plumbing use to\n   describe the entity used for staging.\n\n   (1) New people need to learn the new concept anyway, and they\n       are intelligent enough to learn what that new concept has\n       been called for a long time in git-land at the same time.\n\n       \"The index\" is the receiver of new contents to be staged;\n       conversely, \"to stage\" is the act of registering contents\n       to the index.\n\n   (2) Majority of git old timers do not follow git mailing list\n       discussion closely.  They already know the concept of\n       \"registering thing in the index\".  We on the list are\n       just about to agree to give a good short name, \"to\n       stage\", for that action they have known about, in order\n       for us to make it easier to explain to new people.  That\n       should not affect the terminology the old timers are\n       accustomed to and and trained their fingers with\n       (\"update-index\", \"diff --cached\", \"apply --index\").\n\n   (3) I hope nobody proposes to rename \"update-index\" to\n       \"update-stage\" nor \"diff-index\" to \"diff-stage\"; that\n       would break countless number of existing third party\n       scripts old timers rely on and even new people would find\n       on the web and tempted to try out, so plumbing level\n       commands and options have to keep using the word 'index'.\n       The option to 'git diff --cached' may need a new synonym\n       to make things consistent, but the new synonym should be\n       --index, not --staged.\n\n   (4) New people will not stay newbies forever.  Using a\n       consistent word for the entity used for staging for the\n       next commit across Porcelain and plumbing is important.\n\n> maybe add a -f/--force argument to allow for adding ignored files \n> instead of going through git-update-index.\n\nYup.\n\n> maybe add --new-only and --known-only arguments if there is a real need \n> to discriminate between new vs updated files.  I would not suggest \n> against it though, because if someone really has such fancy and uncommon \n> requirements he might just use git-update-index directly at that point.\n\nBorrow from \"update-index --again\", perhaps?\n\n> +Contrary to other SCMs, with GIT you have to explicitly \"add\" all the\n> +changed file content you want to commit together to form a changeset\n> +with the 'add' command before using the 'commit' command.\n\n... \"before a new commit is made\"; it is not an offence to leave\nlocal changes outside the index.  Staging such changes to all\nfiles is done using the \"-a\" flag and that is done \"before a new\ncommit is made\", but not \"before using the 'commit' command\" --\nit is done at the same time.\n\n> +This is not only for adding new files.  Even modified files must be\n> +added to the set of changes about to be committed. This command can\n> +be performed multiple times before a commit. The 'git status' command\n> +will give you a summary of what is included for the next commit.\n> +\n> +Note: don't forget to 'add' a file again if you modified it after the\n> +first 'add' and before 'commit'. Otherwise only the previous added\n> +state of that file will be committed. This is because git tracks\n> +content, so what you're really 'add'ing to the commit is the *content*\n> +of the file in the state it is in when you 'add' it. Of course there are\n> +legitimate usage cases for not updating an already added file content\n> +in order to commit a previous file state, but in this case you better\n> +know what you're doing.\n\nMay be we could hint the reader that a faster-to-type\nalternative exists here.  Perhaps...\n\n        Note: instead of doing 'git add' to stage the modified contents,\n        you can ask 'git commit' to take all the modified contents in\n        the working tree and stage them all before creating a commit\n        with 'git commit -a'.\n\n> +GIt tracks content not files\n\ns/I/i/\n\n> +But here's a twist. If you do 'git commit <file1> <file2> ...' then only\n> +the  changes belonging to those explicitly specified files will be\n> +committed, entirely bypassing the current \"added\" changes. Those \"added\"\n> +changes will still remain available for a subsequent commit though.\n> +\n> +There is a twist about that twist: if you do 'git commit -i <file>...'\n> +then the commit will consider changes to those specified files _including_\n> +all \"added\" changes so far.\n> +\n\nI think there is another twist more deserving of mention than -i twist.\nIf you jump the index using --only, what is committed with that\ncommit becomes part of what is staged for the commit after that,\nand in order to prevent data loss, we disallow this sequence:\n\n\t$ git checkout\n\t$ edit foo\n        $ git add foo ;# your new add to update the existing entry.\n\t$ edit foo\n        $ git commit foo\n\nIf we did not have the second edit (the behaviour is the same if\nwe did not have \"git add foo\" there), this commit:\n\n * commits the changes to 'foo' (not because you staged it\n   earlier with 'git add', but only because you said \"commit\n   foo\" to invoke the '--only' semantics), obviously;\n\n * updates 'foo' in the index to what was committed.\n\nSo if we allowed the above sequence to succeed, we would commit\nthe result of the second edit, and after the commit, the index\nwould have the result of the second edit.  We would lose the\nstate the user wanted to keep in the index while this commit\njumped the index, and that is why we disallow it.\n\n> +But for instance it is best to only remember 'git add' + 'git commit'\n> +and/or 'git commit -a'.\n> +\n> +No special command is required when removing a file; just remove it,\n> +then tell `commit` about the file as usual.\n\nI wonder if this sequence should do the same as \"git rm -f foo\":\n\n\t$ /bin/rm foo\n        $ git add foo\n\nThat's one of the reasons I suggested 'checkin' instead of\n'resolve', 'resolved', etc.  You check-in the removal of the\ncontent from that path to the staging area, to go as a part of\nthe next commit.\n\n> diff --git a/builtin-add.c b/builtin-add.c\n> index febb75e..b3f9206 100644\n> --- a/builtin-add.c\n> +++ b/builtin-add.c\n> @@ -94,9 +94,6 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n>  \n>  \tnewfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1);\n>  \n> -\tif (read_cache() < 0)\n> -\t\tdie(\"index file corrupt\");\n> -\n>  \tfor (i = 1; i < argc; i++) {\n>  \t\tconst char *arg = argv[i];\n>  \n> @@ -131,6 +128,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n>  \t\treturn 0;\n>  \t}\n>  \n> +\tif (read_cache() < 0)\n> +\t\tdie(\"index file corrupt\");\n> +\n>  \tfor (i = 0; i < dir.nr; i++)\n>  \t\tadd_file_to_index(dir.entries[i]->name, verbose);\n>  \n\nHmph.  Fair enough.\n\n> diff --git a/wt-status.c b/wt-status.c\n> index de1be5b..4b8b570 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -163,7 +163,7 @@ static void wt_status_print_changed_cb(struct diff_queue_struct *q,\n>  \tint i;\n>  \tif (q->nr)\n>  \t\twt_status_print_header(\"Changed but not updated\",\n> -\t\t\t\t\"use git-update-index to mark for commit\");\n> +\t\t\t\t\"use git-add on files to include for commit\");\n>  \tfor (i = 0; i < q->nr; i++)\n>  \t\twt_status_print_filepair(WT_STATUS_CHANGED, q->queue[i]);\n>  \tif (q->nr)\n\n\"use git-add to mark for commit, or use commit -a\"?\n\nI think the one source of confusion is \"update-index\" sounds as\nif it is a command to \"update the index\" and as if you can leave\nout \"with what?\" part to complete the order to the command.\n\nWe can use the word \"add\", thanks to your patch that enhances\nthe user level command, and I do not think the word \"add\" would\nnot induce that confusion.  It is more obvious that you have to\nsay \"what to add\".\n\n"},{"id":"297385","messageId":"200612020018.32672.alan@chandlerfamily.org.uk","threadId":"43230","inReplyTo":"7vpsb36yem.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Alan Chandler","fromEmail":"alan@chandlerfamily.org.uk","sentAt":"2006-12-02T00:18:32Z","receivedAt":"2006-12-02T00:18:32Z","isPatch":true,"sender":{"key":"alan@chandlerfamily.org.uk","avatar":"https://gravatar.com/avatar/1862247e5ea8eac114c842f9dc3a5db6253754e24ef7171757cf97eedce48b8c?d=mp&s=160"},"body":"On Friday 01 December 2006 22:31, Junio C Hamano wrote:\n> Nicolas Pitre <nico@cam.org> writes:\n...\n>\n> > +Contrary to other SCMs, with GIT you have to explicitly \"add\" all the\n> > +changed file content you want to commit together to form a changeset\n> > +with the 'add' command before using the 'commit' command.\n>\n> ... \"before a new commit is made\"; it is not an offence to leave\n> local changes outside the index.  Staging such changes to all\n> files is done using the \"-a\" flag and that is done \"before a new\n> commit is made\", but not \"before using the 'commit' command\" --\n> it is done at the same time.\n\nHow about\n\nContrary to other SCM's, with GIT you have to explicitly \"add\" the content \nthat you want to commit before it is made; it is not an offence to leave \nchanges outside the index if you want to leave them to a later commit.  \nHowever if you do want all changes from your working tree to be added to the \ncommit before it is made use the \"-a\" flag with the commit command and the \ncontent will be added just before the commit is made.\n\n\n-- \nAlan Chandler\n"},{"id":"294099","messageId":"Pine.LNX.4.64.0612012056420.9647@xanadu.home","threadId":"43230","inReplyTo":"200612020018.32672.alan@chandlerfamily.org.uk","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2006-12-02T02:01:04Z","receivedAt":"2006-12-02T02:01:04Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Sat, 2 Dec 2006, Alan Chandler wrote:\n\n> On Friday 01 December 2006 22:31, Junio C Hamano wrote:\n> > Nicolas Pitre <nico@cam.org> writes:\n> ...\n> >\n> > > +Contrary to other SCMs, with GIT you have to explicitly \"add\" all the\n> > > +changed file content you want to commit together to form a changeset\n> > > +with the 'add' command before using the 'commit' command.\n> >\n> > ... \"before a new commit is made\"; it is not an offence to leave\n> > local changes outside the index.  Staging such changes to all\n> > files is done using the \"-a\" flag and that is done \"before a new\n> > commit is made\", but not \"before using the 'commit' command\" --\n> > it is done at the same time.\n\nBleamphfff...  Nah.  There is certainly another way to formulate that.\n\n> How about\n> \n> Contrary to other SCM's, with GIT you have to explicitly \"add\" the content \n> that you want to commit before it is made; it is not an offence to leave \n\nBefore what is made?\n\n> changes outside the index if you want to leave them to a later commit.  \n> However if you do want all changes from your working tree to be added to the \n> commit before it is made use the \"-a\" flag with the commit command and the \n> content will be added just before the commit is made.\n\nNah.  Too many concepts in the same paragraph.\n\n\n"},{"id":"298067","messageId":"Pine.LNX.4.64.0612012101230.9647@xanadu.home","threadId":"43230","inReplyTo":"7vpsb36yem.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2006-12-02T03:05:39Z","receivedAt":"2006-12-02T03:05:39Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 1 Dec 2006, Junio C Hamano wrote:\n\n> Nicolas Pitre <nico@cam.org> writes:\n> \n> > I personally think this is going to make the GIT experience lot more \n> > enjoyable for everybody.  This brings the power of the index up front \n> > using a proper mental model without talking about the index at all. See \n> > for example how all the technical discussion has been evacuated from the \n> > git-add man page.\n> \n> I like the direction this is taking us.\n> \n> The documentation update is in the same spirit with the sample\n> rewrite of 'git diff' manpage.  We might want to tweak the\n> wording to make this round of documentation updates consistent.\n> \n> My preferences:\n> \n>  - You used the word \"changeset\"; I am not sure that is a good\n>    wording.  \n\nWhy not?  It is a well defined word in the SCM context, and I really \nthink what is built in the index before a commit is a changeset.\n\nBut actually I'd prefer \"set of changes\" even better as it is more \nindependent of any definition \"changeset\" might have.\n\n>    The recent explanation I saw on the list and liked\n>    were \"you _stage_ your changes to prepare for the next\n>    commit (footnote: the staging area is called 'the index')\".\n>    My impression was that both extremes (Linus and Carl) are\n>    also Ok with this wording.\n\nWell... dunno.\n\n>  - We keep the word \"index\", and not reword it to \"stage\" in the\n>    names of commands and options.  \"to stage\" is very good verb\n>    to explain the _concept_, but there is no need to use\n>    inconsistent wording Porcelain-ish and plumbing use to\n>    describe the entity used for staging.\n\nFirst I don't know if \"to stage\" is such a good verb.  According to \nhttp://dictionary.reference.com/search?q=stage I think \"stage\" has just \ntoo many definitions already, and none of which really make me think of \nGIT's index.\n\n>    (1) New people need to learn the new concept anyway, and they\n>        are intelligent enough to learn what that new concept has\n>        been called for a long time in git-land at the same time.\n> \n>        \"The index\" is the receiver of new contents to be staged;\n>        conversely, \"to stage\" is the act of registering contents\n>        to the index.\n\nIn technical docs maybe.  But I don't see the need for this wording in \nthe tutorial, not even in the \"add\" man page.\n\nThe best way not to confuse people and making the thing look \nnot too complicated is to avoid making too many explanations especially \nwhen they're not necessary to operate the thing.  In my \nopinion the above quote fails that test.\n\nThere are two level of languages we must be aware of.  First there is \nlanguage to explain how to use the thing.  Next there is language to \nexplain how the thing works.  And _most_ people just want to know how to \nuse the thing at first.  They don't care how it works under the hood \nuntil they have more confidence in their own ability to use the thing \nfirst.  So it is really important not to mix both levels of language.\n\nIn my opinion git-add man page and the tutorial should be about how to \nuse the thing, not about how the thing works.  the git-update-index is \nwhere to talk about how the thing works.\n\nAnd even on the technical level, the quote above is wrong.  Because if \nwe talk about the actual index, it doesn't contain new content only.  \nThe index really contains everything, including current unmodified \ncontent.  So on a technical level (on the \"how it works\" level) we \nreally \"update\" the index to reflect a different state, and in that \ncontext the git-update-index could not have a better name.  It really \nsays what it does.\n\nIt's just that GIT users are simply not interested to know about it.  Of \ncourse all subscribers of this mailing list are, but not users.  What \nusers want to know is how to use the tool and the best way IMHO is to \nsimply create a mental model where \"all changes always have to be added \ntogether explicitly before they are committed with git-add.\"  All the \nrest are shortcuts and variants derived from that fundamental user \nmodel.\n\nAnd eventually the more intripid users will discover that what they were \ndoing without knowing initially was \"updating the index\".\n\nWhat we really want is for users to make use of the index.  This is our \ngoal.  This is how GIT is superior.\n\nBut we don't need to force users to know about how it all works.  Not \nbefore they are confortable with using GIT first.\n\n>    (2) Majority of git old timers do not follow git mailing list\n>        discussion closely.  They already know the concept of\n>        \"registering thing in the index\".  We on the list are\n>        just about to agree to give a good short name, \"to\n>        stage\", for that action they have known about, in order\n>        for us to make it easier to explain to new people.  That\n>        should not affect the terminology the old timers are\n>        accustomed to and and trained their fingers with\n>        (\"update-index\", \"diff --cached\", \"apply --index\").\n\nI don't see the point.  Old timers are already familiar with GIT and \nwith how it works so they don't really need the tutorial nor the basic \ncommand's man pages.  They won't be affected at all by any change of \n\"how to use\" model and terminology since they obviously don't have to \nlearn how to use GIT.\n\n>    (3) I hope nobody proposes to rename \"update-index\" to\n>        \"update-stage\" nor \"diff-index\" to \"diff-stage\"; that\n>        would break countless number of existing third party\n>        scripts old timers rely on and even new people would find\n>        on the web and tempted to try out, so plumbing level\n>        commands and options have to keep using the word 'index'.\n\nAbsolutely not!  Doing that would be an horrible mistake.  First because \nof the reasons you mention above, and because IMHO \"stage\" isn't it at \nall.  The \"how it works\" model is perfectly sane and it is really about \n\"updating the index\".  Always was, always should.\n\n>        The option to 'git diff --cached' may need a new synonym\n>        to make things consistent, but the new synonym should be\n>        --index, not --staged.\n\nIt should be --index, and it should also be --commit in my opinion.  The \nfirst for the \"how it works\" model, and the second for the \"how to use\" \nmodel.  Because what _users_ want is a diff of what is going to be \ncommitted if they type \"git commit\".  Therefore I think --commit is \nreally the best it could be.  Let's avoid proxy meanings like \"stage\" or \nwhatever and get to the point.  It is --index for obvious reasons, and \nit is --commit for another but as obvious reason.\n\n>    (4) New people will not stay newbies forever.  Using a\n>        consistent word for the entity used for staging for the\n>        next commit across Porcelain and plumbing is important.\n\nI disagree.  Porcelain is about usage. Plumbing is about programming.  \nIt is perfectly normal that they have different concepts and words.\n\n> > maybe add a -f/--force argument to allow for adding ignored files \n> > instead of going through git-update-index.\n> \n> Yup.\n> \n> > maybe add --new-only and --known-only arguments if there is a real need \n> > to discriminate between new vs updated files.  I would not suggest \n> > against it though, because if someone really has such fancy and uncommon \n\nSorry, \"I would suggest against\" is what I meant.\n\n\n"},{"id":"298294","messageId":"87veku3i0j.wl%cworth@cworth.org","threadId":"43230","inReplyTo":"7vpsb36yem.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2006-12-02T06:54:04Z","receivedAt":"2006-12-02T06:54:04Z","isPatch":true,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Fri, 01 Dec 2006 14:31:45 -0800, Junio C Hamano wrote:\n>        \"registering thing in the index\".  We on the list are\n>        just about to agree to give a good short name, \"to\n>        stage\", for that action they have known about, in order\n>        for us to make it easier to explain to new people.  That\n>        should not affect the terminology the old timers are\n>        accustomed to and and trained their fingers with\n>        (\"update-index\", \"diff --cached\", \"apply --index\").\n\nYou can adopt a new, short name, and use it in both documentation\n_and_ commands without breaking any habits. Just leave the\nimplementation of the old commands alone. You can even remove things\nfrom the documentation, (or squirrel chunks away to \"deprecated\"\nsections), if you're leaving things only for old-timers.\n\nI've been _trying_ to make git easier to learn, and when there are two\ncommands, (update-index and \"diff --cached\"), that use different\nterminology for the same concept, that's a road bump to learning.\n\nYes, _we_ all know that it's talking about the same thing. And we are\nall an existence proof that people _can_ learn git as it is without\nany changes. But I contend that more people could learn git more\neasily if we worked to smooth things out like this.\n\nBut almost none of what I proposed should really make things harder on\nexperienced users. If we make the terminology of the command-set\nconsistent with the way we explain things in the tutorials and\ndocumentation, then we're being that much nicer. I came up with\n\"stage\" and \"--staged\" because over and over again I saw Linus and\nother say things like \"the index is easy to understand if you think of\nit as a staging area.\"\n\nSomeone didn't like the use of \"stage\" as a verb. I'd be happy with\nsomething else that's a nice, short verb that has a consistent\nadjective to match. Currently, we have an unshort, non-verb\n\"update-index\", a mismatched adjective \"--cached\" and a misplaced noun\n\"--index\".\n\nThe proposal in the current thread of using \"add\" is an improvement on\nthe shortness side, and I am _delighted_ to see documentation\nappearing that is focused on what the user wants to achieve and what\nthe user should expect to happen. So, Junio, please go ahead with\nNico's stuff here. It is an improvement over the current\nsituation. (And thanks, Nico, for fighting against having technical\ndetails getting added to user-oriented documentation).\n\nBut I do still think it's a mistake to muddle the concepts of \"adding\"\na file and \"staging edited content\" for a file. In index terms, the\ndistinction is between adding a new path (and contents, of course) to\nthe index vs. just updating the contents for an existing path.\n\nBut it's not the index distinction that's interesting. It's that users\nthink of those operations differently. An \"add\" operation takes a\nfiles out of the \"untracked file\" state as reported by git\nstatus. That's a very different thing conceptually than updating the\ncontents of a file that is already being tracked by git. And if the\nuser thinks of an operation as being different, the command should\nreflect that. There is a sense in which the user is always right here,\n(since if the tool doesn't do what the user wants, the user just goes\nsomewhere else).\n\n>        The option to 'git diff --cached' may need a new synonym\n>        to make things consistent, but the new synonym should be\n>        --index, not --staged.\n\nI like consistency, so I agree that \"diff --index\" is an improvement\nover \"diff --cached\", (and of course you can leave \"diff --cached\"\naround forever).\n\nThe \"--staged\" thing only came up as I looked for a replacement for\n\"update-index\" as a verb. We can just use \"add\" to, but it is a bit\nawkward for the reasons I explained above.\n\n> > maybe add a -f/--force argument to allow for adding ignored files\n> > instead of going through git-update-index.\n>\n> Yup.\n\nYes, very nice.\n\n> > maybe add --new-only and --known-only arguments if there is a real need\n> > to discriminate between new vs updated files.  I would not suggest\n> > against it though, because if someone really has such fancy and uncommon\n> > requirements he might just use git-update-index directly at that point.\n\nPlease don't add --new-only and --known-only options to git add. The\nfewer the options, the easier the command is for humans to learn.\n\nThe only place I can imagine --new-only or --known-only being useful\nwould be in a scripting situation, not manually typed on the command\nline. And as you say, update-index already exists for that.\n\nPlease keep user-oriented commands focused on things that _users_\nactually want to do.\n\n> > +Contrary to other SCMs, with GIT you have to explicitly \"add\" all the\n> > +changed file content you want to commit together to form a changeset\n> > +with the 'add' command before using the 'commit' command.\n\nI think we can explain the git model in positive terms that stand on\nits own. People will learn the differences and appreciate how git is\nbetter. So I'd just drop \"Contrary to other SCMs\". It's a really weak\nform of pride to compare ourselves to other systems. We can do much\nbetter by having the hubris to pretend no other systems exists.\n\n> > +This is not only for adding new files.\n\nI think this sentence shows the failing of the \"add\" naming. We having\nto explicitly say here. Oh, and when we say \"add\" we don't mean what\nyou think of as \"add\", we mean something else. If we mean something\nelse, why don't we just call it something else?\n\n> I think there is another twist more deserving of mention than -i twist.\n> If you jump the index using --only, what is committed with that\n> commit becomes part of what is staged for the commit after that,\n> and in order to prevent data loss, we disallow this sequence:\n[...]\n> So if we allowed the above sequence to succeed, we would commit\n> the result of the second edit, and after the commit, the index\n> would have the result of the second edit.  We would lose the\n> state the user wanted to keep in the index while this commit\n> jumped the index, and that is why we disallow it.\n\nWow, this index stuff sure takes a lot of explaining. Why are users\nbetter off having to grasp all of that stuff before they can\nsuccessfully add; edit; #oops, add again; and commit their files?\n\n> I wonder if this sequence should do the same as \"git rm -f foo\":\n>\n> \t$ /bin/rm foo\n>         $ git add foo\n\nArgh. Please no. Update-index already exists. Let's not push all of\nits semantics onto \"add\". Let's use \"add\" for when the user _actually_\nwants to _add_ a file. Please? please?\n\n> That's one of the reasons I suggested 'checkin' instead of\n> 'resolve', 'resolved', etc.  You check-in the removal of the\n> content from that path to the staging area, to go as a part of\n> the next commit.\n\nI think having \"checkin\" as a non-synonym for \"commit\" would be a big\nmistake for new users. Different systems out there use those terms\ninterchangeably. Since git has something unique in its \"index\" or\n\"staging area\" we're much better off sticking to unique terms for\ndescribing it.\n\n> \"use git-add to mark for commit, or use commit -a\"?\n>\n> I think the one source of confusion is \"update-index\" sounds as\n> if it is a command to \"update the index\" and as if you can leave\n> out \"with what?\" part to complete the order to the command.\n\nYes. Jesse Keating, for example, read the \"use update-index\"\nsuggestion from git-commit and was very confused why he didn't succeed\nwhen he thought he was following instructions with:\n\n\tgit update-index\n\tgit commit\n\nMaybe the above could be:\n\n\tUse \"git add <files...>\" then \"git commit\",\n\tor \"git commit -a\" to add and commit all tracked files.\n\nBut why are we even directing to \"git add\" here instead of just:\n\n\tWhat would you like to commit?\n\n\tUse \"git commit <files..>\" to commit some files\n\tor \"git commit -a\" to commit all files.\n\nThis doesn't teach the two-part, staged commit to the user at this\npoint, but that's perhaps OK.\n\nExcept it does still leave open the user confusion of:\n\n\tgit add file1\n\tgit commit\n\t\"cool, that works\"\n\n\tedit file1\n\tgit add file2\n\tgit commit\n\t\"hmm, why didn't file1 get commited that time?!\"\n\nAnd the only answer we can give to the poor user is:\n\n\tOh, \"git add\", (and \"git commit\" for that matter) don't do\n\twhat you think they do. Go read the documentation and try\n\tagain.\n\nAt least, with this latest round of updates, the \"git add\"\ndocumentation will actually explain this stuff, (and not just say\n\"this is a wrapper for update-index\"). But there are still a lot of\nusers that will say \"I have to add the file over and over again?\nThat's bizarre.\" They won't be saying, \"Oh, the git designers were so\nbrilliant to implement a system based entirely on file contents and\nnever treating filenames as an interesting entity separate from\ncontent. Thank you so much!\"\n\nSo, git still isn't \"usable\" by just picking up the commands and\nrunning with them, learning more as they go along. Some potential\nusers get lost here. And that's too bad, because nothing in git's\nmodel, (or even in functionality already existing in the command set),\nis missing compared to what the user wants. They just didn't find it\nby default.\n\nGit _will_ be more learnable from the documentation, but it will still\nleave a lot of users thinking it makes some simple things harder than\nthey should be. So other potential users get lost here. And that's too\nbad too, because if they would stick with it a little, they could\nlearn things later on where git would make complex things simple,\n(like conflict resolution).\n\nIf add really were uniquely about _adding_ files to be tracked,\n(rather than just a short synonym for update-index), and if we tweaked\nthe default behavior of git-commit, we could fix these things. And\nall the model and power of git would still exist and be ready to be\nlearned by anyone that wants it, (rather than only by those who manage\nto get past snags like these).\n\n-Carl\n\nPS. Is there a twelve-steps program for people who can't let a thread\ndie? I really want to stop, and I keep telling myself I can stop\nanytime I want.\n"},{"id":"296700","messageId":"7vlklq20n5.fsf@assigned-by-dhcp.cox.net","threadId":"43230","inReplyTo":"87veku3i0j.wl%cworth@cworth.org","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-12-02T07:54:38Z","receivedAt":"2006-12-02T07:54:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Carl Worth <cworth@cworth.org> writes:\n\n>> > +Contrary to other SCMs, with GIT you have to explicitly \"add\" all the\n>> > +changed file content you want to commit together to form a changeset\n>> > +with the 'add' command before using the 'commit' command.\n>\n> I think we can explain the git model in positive terms that stand on\n> its own. People will learn the differences and appreciate how git is\n> better. So I'd just drop \"Contrary to other SCMs\".\n\nI already committed Nico's on 'master', because all he said in\nhis response made sense, but this comment made me rewind it.  I\nagree that we do not have to start with a \"we are harder to\nlearn, we are different from what you know, you have been\nwarned.\"  I'll queue it for 'next'.\n\n> Wow, this index stuff sure takes a lot of explaining. Why are users\n> better off having to grasp all of that stuff before they can\n> successfully add; edit; #oops, add again; and commit their files?\n\nJumping the index is not about that sequence.  It is about being\ninterrupted while doing something else, and committing a smaller\ntrivial change first that is independent from what you have been\ndoing.  Beginners do not have to do that \"interrupted work\"\nsequence.\n\n>> I wonder if this sequence should do the same as \"git rm -f foo\":\n>>\n>> \t$ /bin/rm foo\n>>      $ git add foo\n>\n> Argh. Please no. Update-index already exists. Let's not push all of\n> its semantics onto \"add\". Let's use \"add\" for when the user _actually_\n> wants to _add_ a file. Please? please?\n\nI do agree \"adding the deletion\" is a funny terminology.  But\nthis is a illustration that this part of proposed update to the\ntutorial could be further improved:\n\n+But for instance it is best to only remember 'git add' + 'git commit'\n+and/or 'git commit -a'.\n+\n+No special command is required when removing a file; just remove it,\n+then tell `commit` about the file as usual.\n\nWe say \"you should add modified state again if you edit it again\nafter you added it\" in a section before these sentences, and\nencourage users to consistently say 'git add'.  Since we supply\n\"git rm\" and \"git mv\" to make it convenient to remove/rename\nfiles and index entries at the same time, I think it would be\nbetter to say \"Use add/rm/mv\", not \"don't worry about rm\".\n\nBy the way, aren't people disturbed that \"git rm\" does not\ndefault to \"-f\" -- I rarely use the command myself but that\nmakes it feel even more awkward that \"git rm foo\" does not\nremove the file \"foo\".\n\n> PS. Is there a twelve-steps program for people who can't let a thread\n> die? I really want to stop, and I keep telling myself I can stop\n> anytime I want.\n\nWell, I think at least we are converging.\n\n"},{"id":"296963","messageId":"200612020828.57989.alan@chandlerfamily.org.uk","threadId":"43230","inReplyTo":"87veku3i0j.wl%cworth@cworth.org","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Alan Chandler","fromEmail":"alan@chandlerfamily.org.uk","sentAt":"2006-12-02T08:28:57Z","receivedAt":"2006-12-02T08:28:57Z","isPatch":true,"sender":{"key":"alan@chandlerfamily.org.uk","avatar":"https://gravatar.com/avatar/1862247e5ea8eac114c842f9dc3a5db6253754e24ef7171757cf97eedce48b8c?d=mp&s=160"},"body":"On Saturday 02 December 2006 06:54, Carl Worth wrote:\n...\n> The proposal in the current thread of using \"add\" is an improvement on\n> the shortness side, and I am _delighted_ to see documentation\n> appearing that is focused on what the user wants to achieve and what\n> the user should expect to happen. So, Junio, please go ahead with\n> Nico's stuff here. It is an improvement over the current\n> situation. (And thanks, Nico, for fighting against having technical\n> details getting added to user-oriented documentation).\n>\n> But I do still think it's a mistake to muddle the concepts of \"adding\"\n> a file and \"staging edited content\" for a file. In index terms, the\n> distinction is between adding a new path (and contents, of course) to\n> the index vs. just updating the contents for an existing path.\n>\n> But it's not the index distinction that's interesting. It's that users\n> think of those operations differently. An \"add\" operation takes a\n> files out of the \"untracked file\" state as reported by git\n> status. That's a very different thing conceptually than updating the\n> contents of a file that is already being tracked by git. And if the\n> user thinks of an operation as being different, the command should\n> reflect that. There is a sense in which the user is always right here,\n> (since if the tool doesn't do what the user wants, the user just goes\n> somewhere else).\n>\n...\n \n> \n> Except it does still leave open the user confusion of:\n>\n> \tgit add file1\n> \tgit commit\n> \t\"cool, that works\"\n>\n> \tedit file1\n> \tgit add file2\n> \tgit commit\n> \t\"hmm, why didn't file1 get commited that time?!\"\n>\n> And the only answer we can give to the poor user is:\n>\n> \tOh, \"git add\", (and \"git commit\" for that matter) don't do\n> \twhat you think they do. Go read the documentation and try\n> \tagain.\n>\n...\n> If add really were uniquely about _adding_ files to be tracked,\n> (rather than just a short synonym for update-index), and if we tweaked\n> the default behavior of git-commit, we could fix these things. And\n> all the model and power of git would still exist and be ready to be\n> learned by anyone that wants it, (rather than only by those who manage\n> to get past snags like these).\n\nThere is a conceptual difference between thinking that git-add is about adding \na file and git-add adding the current state of a files content.  If your \nconceptual model is the first of these - then I can see why you see a problem \nwith git-add being used to say a files contents have changed. \n\nHowever, if you regard the git-add command is \"adding the current content of \nthe file to a staging area\" , and you say this is an SCM which by definition \nkeeps the history of things once its been told about them I don't see why \nthere is a need for a different name for the operation the first time and for \nthe operation later.\n\nTrying to put myself in the shoes of a newbie - if taught to use add in both \nways up front - is to ask why git isn't clever enough to notice that I have \nchanged the content of something it already knows about rather than having it \nto manually add it again.  \n\nSo I am with you that we need to effective teach\n\ngit add <filename>   #add content of filename to the SCM\n#edit <filename>\ngit commit -a\t\t#commit current state of all tracked content\n\nfirst, and then move on to teach selective commiting\n\nThe benefit of one name rather than two is that its less to remember\n\n\n\n-- \nAlan Chandler\n"},{"id":"295053","messageId":"87u00e3bv2.wl%cworth@cworth.org","threadId":"43230","inReplyTo":"7vlklq20n5.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2006-12-02T09:06:57Z","receivedAt":"2006-12-02T09:06:57Z","isPatch":true,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Fri, 01 Dec 2006 23:54:38 -0800, Junio C Hamano wrote:\n> > Wow, this index stuff sure takes a lot of explaining. Why are users\n> > better off having to grasp all of that stuff before they can\n> > successfully add; edit; #oops, add again; and commit their files?\n>\n> Jumping the index is not about that sequence.  It is about being\n> interrupted while doing something else, and committing a smaller\n> trivial change first that is independent from what you have been\n> doing.  Beginners do not have to do that \"interrupted work\"\n> sequence.\n\nI guess my point is, the only arguments I've heard against changing the\ndefault behavior of \"git commit\" are:\n\n1. It's always been the way it is\n\n  This is a legitimate concern, yes. It might justify a big bump to\n  git's version number, or a new configuration option that the\n  old-timers would set, or maybe the \"default\" I want could be a a new\n  configuration option that would be set by default for new clones.\n\n  Whatever. There's an inertia problem here, but that hasn't been the\n  strong push-back I've been getting.\n\n2. Doing anything other than the way it is would \"deny the index\"\n\n  This argument has been made forcefully, and again and again.\n\n  But I don't think it stands at all. The current behavior of\n  \"git-commit files...\" denies the index just as much. Just look at\n  the documentation for git-commit. It starts out with a technical,\n  index-based description:\n\n\tUpdates the index file for given paths, or all modified files\n\tif -a is specified, and makes a commit object.\n\n  Now, that description doesn't explicitly say from _what_ the commit\n  object is created, but a natural reading would be \"from the updated\n  index\". And historically, that is exactly what \"git commit files...\"\n  did. I'm sure this wording is fairly old.\n\n  However, today what \"git commit files...\" does today is very\n  different. It's a bit hard to track it down in the man page, but\n  eventually you end up with:\n\n\t\"Commit only the files specified on the command line.\"\n\n  What does that even mean in terms of the index? I don't even know\n  the precise details. And I don't think there's even a very clean way\n  to describe it. (The documentation already starts to get a bit messy\n  where it has to describe that certain index states will make \"git\n  commit files...\" balk completely).\n\n  So \"git commit files...\" already \"denies the index\" just as much as\n  my proposed default behavior for \"git commit\". Why? Because it's\n  _useful_, that's why. The old \"git commit files...\" behavior was\n  much more consistent in terms of index manipulation, but Junio got a\n  scalding email from Linus when he suggested reverting that behavior.\n\n  If you try to think about all the index manipulations of \"git commit\n  files...\" you'll actually get fairly confused. But has there been\n  some problem with people failing to be able to learn the index as a\n  result? Has anyone ever even run into this confusion?  No. Because,\n  \"git commit files...\" does exactly what you actually _want_ to do,\n  and that operation is really easy to describe without any confusion:\n\n\t\"Commit only the files specified on the command line.\"\n\nSo, we can come up with just as short descriptions for the other\nuseful git commands:\n\n\tcommit -a\tCommit all files tracked by git\n\n\tcommit\t\tCommit all files as they exist in the index\n\nThink about when the behavior of these commands is the same, and think\nabout when they are different. If they're different, think about what\nsituations make that difference _useful_, what does the user _want_ to\ndo? And finally, what did the user have to do to arrive at that\nsituation?\n\n * The commands are the same when resolving a merge.\n\n * The commands are different when explicitly staging a commit. This\n   difference is useful---a point which has also been made forcefully,\n   again and again. This situation arises when a user explicitly\n   executes a command to stage something into the index, (historically\n   with \"update-index\" and now proposed for \"add\").\n\n * The commands are different after adding a new file to be tracked by\n   git for the first time. This difference is not useful. This\n   situation arises whenever a file is added and subsequently\n   edited. It's not necessarily the case that the user is _trying_ to\n   do any staged commit, (and most commonly the user is not).\n\nThe recent \"git add\" conversation conflates these last two use cases,\nwhich is a bit problematic because one is useful to the user while the\nother is not.\n\n> We say \"you should add modified state again if you edit it again\n> after you added it\" in a section before these sentences, and\n> encourage users to consistently say 'git add'.\n\nI think this is a mistake for documentation that will be encountered\nearly by new users, (as git-add is one of the first things a user must\nuse if starting with git from scratch as opposed to through a\nclone). The problem is that all the talk of \"git add + git commit\"\neasily leads to the impression that there's more work to do in git\nthan in any other system that anyone may have ever encountered.\n\nNow, there isn't actually more work, and we can explain that later,\n\"you will most commonly not use the sequence explained above, but will\ninstead use 'git commit -a' which will perform both steps for you\".\n\nThis is the kind of sentence in documentation which just screams that\nthere's a user-interface problem. Why do we explain how to do\nsomething only to say a moment later that user's won't do that? The\nreason is because we _have_ to explain git-add that way or else the\ncurrent semantics of git-add + git-commit can be very confusing.\n\nLet's just eliminate that confusion, drop the stuff from the\ndocs. that make git seem like it's harder to use than anything else on\nthe planet, and save the discussion of the index for a section in the\ndocumentation that deals with something the user is wanting to do that\nactually _benefits_ from the index.\n\n> By the way, aren't people disturbed that \"git rm\" does not\n> default to \"-f\" -- I rarely use the command myself but that\n> makes it feel even more awkward that \"git rm foo\" does not\n> remove the file \"foo\".\n\nYes, it's usually a bug that it doesn't delete the file by\ndefault. This one's my doing, but I was thinking of an actual\nsituation that I had been in, that of wanting to undo an \"add\". For\nexample:\n\n\tgit add file1\n\tgit add file2\n\t# Oh, wait, I should commit these independently\n\tgit rm file2\n\tgit commit -m \"add file1\"\n\tgit add file2\n\tgit commit -m \"add file2\"\n\nSo one way to fix this would be to make \"git rm\" delete the file if it\nis consistent in working-tree and HEAD and to leave it there\notherwise. The message could be something like:\n\n\tNote: file <foo> has uncommitted changes, leaving it in\n\tthe working tree as an untracked file.\n\nThen, -f could still be useful as a way to force file deletion even in\nthis case.\n\n> Well, I think at least we are converging.\n\nI'm glad you feel that way. I know I've been something of a pest\nrecently, (and yes, Linus, I do often get weary of pests that want to\nthrow out the fundamental strengths of a system like X).\n\nMaybe think of it this way: I've been arguing on behalf of\nbrain-damaged users. Git's got the cure for them, but they're not\nready to sign up for that kind of brain surgery when they can see it\ncoming. If we can subdue them with a more gentle introduction, (\"start\ncounting the everyday git commands backwards from 10 to 1\"), then\nwe'll have their brains and can do everything we want to them.\n\nAnd I really think the re-training can be painless---I don't think the\nproposals I'm making will setup any nasty surprises down the road.\n\n-Carl\n"},{"id":"296374","messageId":"ekri99$7gh$1@sea.gmane.org","threadId":"43230","inReplyTo":"7vpsb36yem.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-12-02T09:52:33Z","receivedAt":"2006-12-02T09:52:33Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n\n>  - We keep the word \"index\", and not reword it to \"stage\" in the\n>    names of commands and options.  \"to stage\" is very good verb\n>    to explain the _concept_, but there is no need to use\n>    inconsistent wording Porcelain-ish and plumbing use to\n>    describe the entity used for staging.\n> \n>    (1) New people need to learn the new concept anyway, and they\n>        are intelligent enough to learn what that new concept has\n>        been called for a long time in git-land at the same time.\n> \n>        \"The index\" is the receiver of new contents to be staged;\n>        conversely, \"to stage\" is the act of registering contents\n>        to the index.\n\nI think we should refer to \"the index\" as \"the staging area [for commits]\",\nat least the first time (it is a bit longish to use it later).\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n"},{"id":"294806","messageId":"ekrjc9$8uc$1@sea.gmane.org","threadId":"43230","inReplyTo":"7vlklq20n5.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-12-02T10:11:14Z","receivedAt":"2006-12-02T10:11:14Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n\n> By the way, aren't people disturbed that \"git rm\" does not\n> default to \"-f\" -- I rarely use the command myself but that\n> makes it feel even more awkward that \"git rm foo\" does not\n> remove the file \"foo\".\n\nBut _only_ if file is unmodified. I think that \"git rm\" meaning\n\"remove this file from version control, but not from working area\"\nis a good thing; if you want to remove file, just /usr/bin/rm it.\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n"},{"id":"295331","messageId":"457192D5.8090209@xs4all.nl","threadId":"43230","inReplyTo":"ekrjc9$8uc$1@sea.gmane.org","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Han-Wen Nienhuys","fromEmail":"hanwen@xs4all.nl","sentAt":"2006-12-02T14:51:01Z","receivedAt":"2006-12-02T14:51:01Z","isPatch":true,"sender":{"key":"hanwen@google.com","avatar":"https://avatars.githubusercontent.com/u/31547?v=4"},"body":"Jakub Narebski escreveu:\n> Junio C Hamano wrote:\n> \n>> By the way, aren't people disturbed that \"git rm\" does not\n>> default to \"-f\" -- I rarely use the command myself but that\n>> makes it feel even more awkward that \"git rm foo\" does not\n>> remove the file \"foo\".\n> \n> But _only_ if file is unmodified. I think that \"git rm\" meaning\n> \"remove this file from version control, but not from working area\"\n> is a good thing; if you want to remove file, just /usr/bin/rm it.\n\nIn my workflow,  I regularly get bitten by this: \n\nI do \n\n  git checkout devel\n  git rm src/foo.cc\n  git commit src/foo.cc    # or whatever -a -i --difficult option is necessary\n\n  git checkout stable\n\n     ...barf: trying to overwrite untracked src/foo.cc file..\n\n\nI think for the default to remove from the working area is better. \n\nFWIW, I consider it annoyance with CVS as well \n\n-- \n Han-Wen Nienhuys - hanwen@xs4all.nl - http://www.xs4all.nl/~hanwen\n"},{"id":"296221","messageId":"87psb22qgu.wl%cworth@cworth.org","threadId":"43230","inReplyTo":"200612020828.57989.alan@chandlerfamily.org.uk","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2006-12-02T16:49:05Z","receivedAt":"2006-12-02T16:49:05Z","isPatch":true,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Sat, 2 Dec 2006 08:28:57 +0000, Alan Chandler wrote:\n> There is a conceptual difference between thinking that git-add is about adding\n> a file and git-add adding the current state of a files content.\n\nYes, there is.\n\n>                                                                 If your\n> conceptual model is the first of these - then I can see why you see a problem\n> with git-add being used to say a files contents have changed.\n\nYes. (And of course, I personally understand the second conceptual\nmodel. But there are a lot of \"brain-damaged\" people out there.)\n\n> However, if you regard the git-add command is \"adding the current content of\n> the file to a staging area\" , and you say this is an SCM which by definition\n> keeps the history of things once its been told about them I don't see why\n> there is a need for a different name for the operation the first time and for\n> the operation later.\n\nYes, that's also true. Once you know the model then you wouldn't need\ntwo different commands. One can certainly get by with just the\nfunctionality of \"update-index\" for everything.\n\n> Trying to put myself in the shoes of a newbie - if taught to use add in both\n> ways up front - is to ask why git isn't clever enough to notice that I have\n> changed the content of something it already knows about rather than having it\n> to manually add it again.\n\nYes, and \"put myself in the shoes of a newbie\" is what I've been doing\nthrough the whole conversation. That's why I keep coming across as so\nstubbornly stupid in these threads, (\"why can't Carl just understand\nhow git works?!\").\n\n> So I am with you that we need to effective teach\n>\n> git add <filename>   #add content of filename to the SCM\n> #edit <filename>\n> git commit -a\t\t#commit current state of all tracked content\n>\n> first, and then move on to teach selective commiting\n\nYes. That's the only way to avoid this confusion.\n\nSo all of the conditions above, (\"if your conceptual model is\", \"if\nyou regard the git-add command\", \"if taught to use git-add up front\",\n\"if we effectively teach 'commit -a' first\"), are barriers to learning\ngit. We can't guarantee these are all met for new users, and when\nthey're not, the users can get confused.\n\nIf git's model imposes the requirement, \"we should first teach one\nthing, then move on to teach a subsequent thing\", it would be just\nthat much nicer if the commands themselves could help us do that,\n(because the default would do the thing they would need first, and\nthen the user has to explicitly do _something_ else to get the\nsubsequent thing).\n\nSee? I'm just trying to make the command set more naturally provide\nthe same flow of learning that we've been proposing for the tutorial.\n\n-Carl\n"},{"id":"297800","messageId":"eksc35$fji$1@sea.gmane.org","threadId":"43230","inReplyTo":"87psb22qgu.wl%cworth@cworth.org","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-12-02T17:12:55Z","receivedAt":"2006-12-02T17:12:55Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Carl Worth wrote:\n\n> If git's model imposes the requirement, \"we should first teach one\n> thing, then move on to teach a subsequent thing\", it would be just\n> that much nicer if the commands themselves could help us do that,\n> (because the default would do the thing they would need first, and\n> then the user has to explicitly do _something_ else to get the\n> subsequent thing).\n> \n> See? I'm just trying to make the command set more naturally provide\n> the same flow of learning that we've been proposing for the tutorial.\n\nNot exactly. For example more user-friendly is \"mv -i\" than \"mv\",\nbut noone proposes to make \"mv -i\" default (well, you can alias\n\"mv\" to \"mv -i\" in shell, while you cannot alias \"commit\" to \"commit -a\"\nin git).\n\nSo i think having the default geared towards advanced users and not\nnewbie users is O.K.\n\nBy the way, I find it a bit annoying that \"git commit\" outputs\ngit-status output (possibly multi-line if you have many untracked\nbut unignored files in working area) before \"nothing to commit\".\n\nP.S. Is there a difference between \"git commit .\" and \"git commit -a\"?\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n\n"},{"id":"295749","messageId":"200612021805.09143.alan@chandlerfamily.org.uk","threadId":"43230","inReplyTo":"87psb22qgu.wl%cworth@cworth.org","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Alan Chandler","fromEmail":"alan@chandlerfamily.org.uk","sentAt":"2006-12-02T18:05:08Z","receivedAt":"2006-12-02T18:05:08Z","isPatch":true,"sender":{"key":"alan@chandlerfamily.org.uk","avatar":"https://gravatar.com/avatar/1862247e5ea8eac114c842f9dc3a5db6253754e24ef7171757cf97eedce48b8c?d=mp&s=160"},"body":"On Saturday 02 December 2006 16:49, Carl Worth wrote:\n> On Sat, 2 Dec 2006 08:28:57 +0000, Alan Chandler wrote:\n> > There is a conceptual difference between thinking that git-add is about\n> > adding a file and git-add adding the current state of a files content.\n>\n> Yes, there is.\n>\n> >                                                                 If your\n> > conceptual model is the first of these - then I can see why you see a\n> > problem with git-add being used to say a files contents have changed.\n>\n> Yes. (And of course, I personally understand the second conceptual\n> model. But there are a lot of \"brain-damaged\" people out there.)\n>\n> > However, if you regard the git-add command is \"adding the current content\n> > of the file to a staging area\" , and you say this is an SCM which by\n> > definition keeps the history of things once its been told about them I\n> > don't see why there is a need for a different name for the operation the\n> > first time and for the operation later.\n>\n> Yes, that's also true. Once you know the model then you wouldn't need\n> two different commands. One can certainly get by with just the\n> functionality of \"update-index\" for everything.\n...\n> So all of the conditions above, (\"if your conceptual model is\", \"if\n> you regard the git-add command\", \"if taught to use git-add up front\",\n> \"if we effectively teach 'commit -a' first\"), are barriers to learning\n> git. We can't guarantee these are all met for new users, and when\n> they're not, the users can get confused.\n>\n\nThe argument I was _trying_ to make was that we should teach the second \nconceptual model not the first one AND stick with just the git add command \n(in response to your (Carl's) statement earlier in the thread that there \nneeds to be two separate commands) .  My if statements were to illustrate \nthat there are two fundamental ways of looking at this, not lots of ifs that \nnewbies would have to consider.  We should up-front (in the tutorial, in \nappropriate man pages) use the one conceptual model (and I also like Junio's \nargument that git should take an aggressive stance of this is how the \nconceptual model is rather than the \"contrary to ...\" approach).\n\n\n\n-- \nAlan Chandler\n"},{"id":"297521","messageId":"Pine.LNX.4.64.0612022302540.2630@xanadu.home","threadId":"43230","inReplyTo":"200612021805.09143.alan@chandlerfamily.org.uk","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2006-12-03T04:04:28Z","receivedAt":"2006-12-03T04:04:28Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Sat, 2 Dec 2006, Alan Chandler wrote:\n\n> The argument I was _trying_ to make was that we should teach the second \n> conceptual model not the first one AND stick with just the git add command \n> (in response to your (Carl's) statement earlier in the thread that there \n> needs to be two separate commands) .  My if statements were to illustrate \n> that there are two fundamental ways of looking at this, not lots of ifs that \n> newbies would have to consider.  We should up-front (in the tutorial, in \n> appropriate man pages) use the one conceptual model (and I also like Junio's \n> argument that git should take an aggressive stance of this is how the \n> conceptual model is rather than the \"contrary to ...\" approach).\n\nAgreed.\n\n\n"},{"id":"297312","messageId":"Pine.LNX.4.64.0612022305100.2630@xanadu.home","threadId":"43230","inReplyTo":"87psb22qgu.wl%cworth@cworth.org","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2006-12-03T04:22:11Z","receivedAt":"2006-12-03T04:22:11Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Sat, 2 Dec 2006, Carl Worth wrote:\n\n> If git's model imposes the requirement, \"we should first teach one\n> thing, then move on to teach a subsequent thing\", it would be just\n> that much nicer if the commands themselves could help us do that,\n> (because the default would do the thing they would need first, and\n> then the user has to explicitly do _something_ else to get the\n> subsequent thing).\n\nSince I've been thinking about this issue I've come to the conclusion \nthat making commit -a the default for commit is not a good thing.\n\nWhy? Because we really want newbies to be tricked into using the index.\n\nAnd teaching about the different ways to update the index in the \ntutorial right after the first commit example is IMHO the best thing to \ndo.\n\nMaking commit -a the default would make it possible for newbies to \nget along for a long while ignoring the usage model of git and that is \nbad.\n\nI think the idea is really to make \"git commit\" with a clean index more \nclueful to the user.  Right now it only says \"use git-update-index to \nmark for commit\" which is really not that helpful, and actually the \npoint of failure with the example newbie problem you pointed out.\n\nThere is a compromise to reach.  Sure the _user_ needs a proper model to \nuse the tool without being bothered with technical implementation or \narchitecture details.  But we still need newbies to get into the git \nmodel nevertheless, and having a default for git-commit geared towards \nmaking it bump free for new users is not the way to go I think.  The \n\"nothing to commit\" message needs to be way more helpful with better \nguidance and the git-commit default behavior should be overcome.\n\n\n"},{"id":"296161","messageId":"Pine.LNX.4.64.0612022323330.2630@xanadu.home","threadId":"43230","inReplyTo":"200612020828.57989.alan@chandlerfamily.org.uk","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2006-12-03T04:34:18Z","receivedAt":"2006-12-03T04:34:18Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Sat, 2 Dec 2006, Alan Chandler wrote:\n\n> So I am with you that we need to effective teach\n> \n> git add <filename>   #add content of filename to the SCM\n> #edit <filename>\n> git commit -a\t\t#commit current state of all tracked content\n> \n> first, and then move on to teach selective commiting\n\nI think that's pretty much what my patch to the tutorial does.\n\nThe tutorial talks about:\n\n\t1) git init-db\n\n\t2) git add .\n\n\t3) git commit\n\n\t4) modifying some files then git diff\n\n\t5) git commit file1 file2, or git commit -a\n\nThen goes the discussion about what git add does and why.  It is quite \nearly in the tutorial and making it earlier would be a bit premature.  \nLet's have the user make his first simple commit while blindly \nfollowing the instructions before going with the \nactual usage model.  At that point,since we just mentioned \"git commit \nfile1 file2\" or \"git commit -a\" will the user be in the proper mindset \nto wonder why not using plain \"git commit\"... and incidentally the whole \nexplanation is there to follow immediately.\n\nI'm reworking my patch with suggestions that have been posted so let's \nhope it'll be even clearer.\n\n\n"},{"id":"294342","messageId":"Pine.LNX.4.64.0612022335350.2630@xanadu.home","threadId":"43230","inReplyTo":"7vpsb36yem.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] make 'git add' a first class user friendly interface to the index","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2006-12-03T05:03:56Z","receivedAt":"2006-12-03T05:03:56Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 1 Dec 2006, Junio C Hamano wrote:\n\n> > +Contrary to other SCMs, with GIT you have to explicitly \"add\" all the\n> > +changed file content you want to commit together to form a changeset\n> > +with the 'add' command before using the 'commit' command.\n> \n> ... \"before a new commit is made\"; it is not an offence to leave\n> local changes outside the index.  Staging such changes to all\n> files is done using the \"-a\" flag and that is done \"before a new\n> commit is made\", but not \"before using the 'commit' command\" --\n> it is done at the same time.\n\nSorry but I don't think this is a good idea to tell that.  At least not \nhere.  Opening all the possibilities too fast at once is a good way to \ncreate distrust.  Let's focus on what the user needs to know about the \nadd command only.  \n\nThe newbie that becomes not so newbie aftera while will deduce that he \nactually _can_ leave local changes outside the index and he'll go \"wow, \nthat is cool!\" especially if he deduce this by himself.  And that \ndeduction will happen in time while using the tool when the opportunity \nfor leaving local changes outside the index arises which is a much \nbetter way to grasp the power of the index than by just being told about \nit.\n\nAS to the commit -a ... I think it is better to refer to the commit man \npage once it has been refactored with the writeup you posted yourself \nand simply direct the user with \"You may also have a look at the \ngit-commit documentation for alternative ways to add content to a \ncommit.\"\n\n> > +This is not only for adding new files.  Even modified files must be\n> > +added to the set of changes about to be committed. This command can\n> > +be performed multiple times before a commit. The 'git status' command\n> > +will give you a summary of what is included for the next commit.\n> > +\n> > +Note: don't forget to 'add' a file again if you modified it after the\n> > +first 'add' and before 'commit'. Otherwise only the previous added\n> > +state of that file will be committed. This is because git tracks\n> > +content, so what you're really 'add'ing to the commit is the *content*\n> > +of the file in the state it is in when you 'add' it. Of course there are\n> > +legitimate usage cases for not updating an already added file content\n> > +in order to commit a previous file state, but in this case you better\n> > +know what you're doing.\n> \n> May be we could hint the reader that a faster-to-type\n> alternative exists here.  Perhaps...\n\nPerhaps not.\n\n> > +GIt tracks content not files\n> \n> s/I/i/\n\nYup\n\n> > +But here's a twist. If you do 'git commit <file1> <file2> ...' then only\n> > +the  changes belonging to those explicitly specified files will be\n> > +committed, entirely bypassing the current \"added\" changes. Those \"added\"\n> > +changes will still remain available for a subsequent commit though.\n> > +\n> > +There is a twist about that twist: if you do 'git commit -i <file>...'\n> > +then the commit will consider changes to those specified files _including_\n> > +all \"added\" changes so far.\n> > +\n> \n> I think there is another twist more deserving of mention than -i twist.\n\nActually I removed the -i twist entirely.  It is simply too much for the \ncontext of the tutorial and it is of no advantage for a newbie to even \nknow that -i exists just yet.\n\n> If you jump the index using --only, what is committed with that\n> commit becomes part of what is staged for the commit after that,\n> and in order to prevent data loss, we disallow this sequence:\n> \n> \t$ git checkout\n> \t$ edit foo\n>         $ git add foo ;# your new add to update the existing entry.\n> \t$ edit foo\n>         $ git commit foo\n> \n> If we did not have the second edit (the behaviour is the same if\n> we did not have \"git add foo\" there), this commit:\n> \n>  * commits the changes to 'foo' (not because you staged it\n>    earlier with 'git add', but only because you said \"commit\n>    foo\" to invoke the '--only' semantics), obviously;\n> \n>  * updates 'foo' in the index to what was committed.\n> \n> So if we allowed the above sequence to succeed, we would commit\n> the result of the second edit, and after the commit, the index\n> would have the result of the second edit.  We would lose the\n> state the user wanted to keep in the index while this commit\n> jumped the index, and that is why we disallow it.\n\nGreat.  This is perfectly fine behavior.  But I think this definitely \ndoesn't belong in the tutorial.  the probability for a newbie to perform \nthe above sequence is rather low, and even then the explanation belongs \nin the failure message not in the tutorial.  It can be as short as \n\"Please see git-commit man page and look for xyz for explanation about \nthis failure\" if the inline explanation would be too long.\n\n> > +But for instance it is best to only remember 'git add' + 'git commit'\n> > +and/or 'git commit -a'.\n> > +\n> > +No special command is required when removing a file; just remove it,\n> > +then tell `commit` about the file as usual.\n> \n> I wonder if this sequence should do the same as \"git rm -f foo\":\n> \n> \t$ /bin/rm foo\n>         $ git add foo\n\nWell I think Linus' suggestions about git-rm are really sane.  When \ngit-rm has been updated then it could be mentioned here, along with \ngit-mv.  In the mean time I simply removed that paragraph.\n\n\n"},{"id":"297697","messageId":"Pine.LNX.4.64.0612030028290.2630@xanadu.home","threadId":"43230","inReplyTo":"Pine.LNX.4.64.0612011444310.9647@xanadu.home","subject":"[PATCH v2] make 'git add' a first class user friendly interface to the index","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2006-12-03T05:33:04Z","receivedAt":"2006-12-03T05:33:04Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"I personally think this is going to make the GIT experience lot more\nenjoyable for everybody.  This brings the power of the index up front\nusing a proper mental model without talking about the index at all. See\nfor example how all the technical discussion has been evacuated from the\ngit-add man page.\n\nAny content to be committed must be added together.  Whether that\ncontent comes from new files or modified files doesn't matter.  You just\nneed to \"add\" it, either with git-add, or by providing git-commit with\n-a (for already known files only of course). No need for a separate\ncommand to distinguish new vs modified files please.  That would only\nscrew the mental model everybody should have when using GIT.\n\nSigned-off-by: Nicolas Pitre <nico@cam.org>\n---\n Documentation/git-add.txt  |   55 +++++++++++++++++++++++--------------------\n Documentation/tutorial.txt |   46 ++++++++++++++++++++++++++++++++----\n builtin-add.c              |    6 ++--\n wt-status.c                |    2 +-\n 4 files changed, 73 insertions(+), 36 deletions(-)\n\ndiff --git a/Documentation/git-add.txt b/Documentation/git-add.txt\nindex 6342ea3..411adad 100644\n--- a/Documentation/git-add.txt\n+++ b/Documentation/git-add.txt\n@@ -3,7 +3,7 @@ git-add(1)\n \n NAME\n ----\n-git-add - Add files to the index file\n+git-add - Add file content to the changeset to be committed next\n \n SYNOPSIS\n --------\n@@ -11,16 +11,32 @@ SYNOPSIS\n \n DESCRIPTION\n -----------\n-A simple wrapper for git-update-index to add files to the index,\n-for people used to do \"cvs add\".\n-\n-It only adds non-ignored files, to add ignored files use\n+All the changed file content to be committed together in a single set\n+of changes must be \"added\" together with the 'add' command before using\n+the 'commit' command.\n+\n+This is not only for adding new files.  Even modified files must be\n+added to the set of changes about to be committed. This command can\n+be performed multiple times before a commit. The 'git status' command\n+can be used to obtain a summary of what is included for the next commit.\n+\n+Note: don't forget to 'add' a file again if you modified it after the\n+first 'add' and before 'commit'. Otherwise only the previous added\n+state of that file will be committed. This is because git tracks\n+content, so what you're really 'add'ing to the commit is the *content*\n+of the file in the state it is in when you 'add' it. Of course there are\n+legitimate usage cases for not updating an already added file content\n+in order to commit a previous file state if you really know what\n+you're doing.\n+\n+This command only adds non-ignored files, to add ignored files use\n \"git update-index --add\".\n \n+\n OPTIONS\n -------\n <file>...::\n-\tFiles to add to the index (see gitlink:git-ls-files[1]).\n+\tFiles to add content from.\n \n -n::\n         Don't actually add the file(s), just show if they exist.\n@@ -34,27 +50,12 @@ OPTIONS\n \tfor command-line options).\n \n \n-DISCUSSION\n-----------\n-\n-The list of <file> given to the command is fed to `git-ls-files`\n-command to list files that are not registered in the index and\n-are not ignored/excluded by `$GIT_DIR/info/exclude` file or\n-`.gitignore` file in each directory.  This means two things:\n-\n-. You can put the name of a directory on the command line, and\n-  the command will add all files in it and its subdirectories;\n-\n-. Giving the name of a file that is already in index does not\n-  run `git-update-index` on that path.\n-\n-\n EXAMPLES\n --------\n git-add Documentation/\\\\*.txt::\n \n-\tAdds all `\\*.txt` files that are not in the index under\n-\t`Documentation` directory and its subdirectories.\n+\tAdds content from all `\\*.txt` files under `Documentation`\n+\tdirectory and its subdirectories.\n +\n Note that the asterisk `\\*` is quoted from the shell in this\n example; this lets the command to include the files from\n@@ -62,15 +63,17 @@ subdirectories of `Documentation/` directory.\n \n git-add git-*.sh::\n \n-\tAdds all git-*.sh scripts that are not in the index.\n+\tConsiders adding content from all git-*.sh scripts.\n \tBecause this example lets shell expand the asterisk\n \t(i.e. you are listing the files explicitly), it does not\n-\tadd `subdir/git-foo.sh` to the index.\n+\tconsider `subdir/git-foo.sh`.\n \n See Also\n --------\n gitlink:git-rm[1]\n-gitlink:git-ls-files[1]\n+gitlink:git-mv[1]\n+gitlink:git-commit[1]\n+gitlink:git-update-index[1]\n \n Author\n ------\ndiff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt\nindex fe4491d..0069fc3 100644\n--- a/Documentation/tutorial.txt\n+++ b/Documentation/tutorial.txt\n@@ -87,14 +87,48 @@ thorough description.  Tools that turn commits into email, for\n example, use the first line on the Subject line and the rest of the\n commit in the body.\n \n-To add a new file, first create the file, then\n \n-------------------------------------------------\n-$ git add path/to/new/file\n-------------------------------------------------\n+Git tracks content not files\n+----------------------------\n+\n+With git you have to explicitly \"add\" all the changed _content_ you\n+want to commit together. This can be done in a few different ways:\n+\n+1) By using 'git add <file_spec>...'\n+ \n+   This can be performed multiple times before a commit.  Note that this\n+   is not only for adding new files.  Even modified files must be\n+   added to the set of changes about to be committed.  The \"git status\"\n+   command gives you a summary of what is included so far for the\n+   next commit.  When done you should use the 'git commit' command to\n+   make it real.\n+\n+   Note: don't forget to 'add' a file again if you modified it after the\n+   first 'add' and before 'commit'. Otherwise only the previous added\n+   state of that file will be committed. This is because git tracks\n+   content, so what you're really 'add'ing to the commit is the *content*\n+   of the file in the state it is in when you 'add' it.\n+\n+2) By using 'git commit -a' directly\n+\n+   This is a quick way to automatically 'add' the content from all files\n+   that were modified since the previous commit, and perform the actual\n+   commit without having to separately 'add' them beforehand.  This will\n+   not add content from new files i.e. files that were never added before.\n+   Those files still have to be added explicitly before performing a\n+   commit.\n+\n+But here's a twist. If you do 'git commit <file1> <file2> ...' then only\n+the  changes belonging to those explicitly specified files will be\n+committed, entirely bypassing the current \"added\" changes. Those \"added\"\n+changes will still remain available for a subsequent commit though.\n+\n+But for instance it is best to only remember 'git add' + 'git commit'\n+and/or 'git commit -a'.\n+\n \n-then commit as usual.  No special command is required when removing a\n-file; just remove it, then tell `commit` about the file as usual.\n+Viewing the changelog\n+---------------------\n \n At any point you can view the history of your changes using\n \ndiff --git a/builtin-add.c b/builtin-add.c\nindex febb75e..b3f9206 100644\n--- a/builtin-add.c\n+++ b/builtin-add.c\n@@ -94,9 +94,6 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \n \tnewfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1);\n \n-\tif (read_cache() < 0)\n-\t\tdie(\"index file corrupt\");\n-\n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n \n@@ -131,6 +128,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\treturn 0;\n \t}\n \n+\tif (read_cache() < 0)\n+\t\tdie(\"index file corrupt\");\n+\n \tfor (i = 0; i < dir.nr; i++)\n \t\tadd_file_to_index(dir.entries[i]->name, verbose);\n \ndiff --git a/wt-status.c b/wt-status.c\nindex de1be5b..4b8b570 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -163,7 +163,7 @@ static void wt_status_print_changed_cb(struct diff_queue_struct *q,\n \tint i;\n \tif (q->nr)\n \t\twt_status_print_header(\"Changed but not updated\",\n-\t\t\t\t\"use git-update-index to mark for commit\");\n+\t\t\t\t\"use git-add on files to include for commit\");\n \tfor (i = 0; i < q->nr; i++)\n \t\twt_status_print_filepair(WT_STATUS_CHANGED, q->queue[i]);\n \tif (q->nr)\n-- \n1.4.4.1.gc419-dirty\n"},{"id":"297165","messageId":"200612030916.04791.alan@chandlerfamily.org.uk","threadId":"43230","inReplyTo":"Pine.LNX.4.64.0612030028290.2630@xanadu.home","subject":"Re: [PATCH v2] make 'git add' a first class user friendly interface to the index","fromName":"Alan Chandler","fromEmail":"alan@chandlerfamily.org.uk","sentAt":"2006-12-03T09:16:04Z","receivedAt":"2006-12-03T09:16:04Z","isPatch":true,"sender":{"key":"alan@chandlerfamily.org.uk","avatar":"https://gravatar.com/avatar/1862247e5ea8eac114c842f9dc3a5db6253754e24ef7171757cf97eedce48b8c?d=mp&s=160"},"body":"On Sunday 03 December 2006 05:33, Nicolas Pitre wrote:\n...\n> +But here's a twist. If you do 'git commit <file1> <file2> ...' then only\n> +the  changes belonging to those explicitly specified files will be\n> +committed, entirely bypassing the current \"added\" changes. Those \"added\"\n> +changes will still remain available for a subsequent commit though.\n> +\n> +But for instance it is best to only remember 'git add' + 'git commit'\n> +and/or 'git commit -a'.\n> +\n\nThe \"But for instance\" seems a strange way of saying that.\n\nHow about\n\nHowever, for normal usage you only have to remember 'git add' + 'git commit' \nand/or 'git commit -a'.\n\n\n-- \nAlan Chandler\n"}]}