{"thread":{"id":"22832","subject":"Meta-variable naming convention in documentation","startedAt":"2010-02-26T04:55:08Z","lastAt":"2010-02-27T02:41:22Z","messageCount":4,"participants":["Mark Lodato","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"135729","messageId":"ca433831002252055l37292cf6v868cc407f0be7250@mail.gmail.com","threadId":"22832","inReplyTo":null,"subject":"Meta-variable naming convention in documentation","fromName":"Mark Lodato","fromEmail":"lodatom@gmail.com","sentAt":"2010-02-26T04:55:08Z","receivedAt":"2010-02-26T04:55:08Z","isPatch":false,"sender":{"key":"lodatom@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58860?v=4"},"body":"Currently, git's documentation and usage statements are inconsistent in\nthe meta-variables (e.g., <path>) used to described positional arguments\nthat denote a path.  This post is an attempt to document the existing\nissues and to propose a potential solution.\n\nTo begin, I ran each of the git sub-commands in git 1.7.0 and documented\nits behavior.  Each row contains the program, the meta-variables, and\nthe type.  If the man page and the '-h' usage statement differ, I list\nboth.  For example, git-annotate uses \"file\" in both the man page and\nthe usage statement, while git-blame uses \"<file>\" in the man page but\n\"file\" in the usage statement.\n\nThe following accept exact filenames.  No directory recursion or\nglobing is applied.  The first group die if the file does not exist,\nwhile the second group \"filters\" (f) -- they silently ignore\nnon-matching files.\n\n\tprogram\t\t\tman[/usage]\t\ttype\n\t-------\t\t\t-----------\t\t----\n\tgit-annotate\t\tfile\t\t\tfile\n\tgit-blame\t\t<file>/file\t\tfile\n\tgit-checkout-index\t<file>\t\t\tfile\n\tgit-hash-object\t\t<file>\t\t\tfile\n\tgit-mailsplit\t\t<mbox>|<Maildir>\tfile\n\tgit-merge-file\t\t<current-file> ...\tfile\n\tgit-merge-index\t\t<file>/<filename>\tfile\n\tgit-merge-one-file\t<path>\t\t\tfile\n\tgit-mergetool\t\t<file>/file to merge\tfile\n\tgit-mv\t\t\t<args>/<source>\t\tfile\n\tgit-pack-redundant\t.pack filename/<...>\tfile\n\tgit-send-email\t\t<file>\t\t\tfile\n\tgit-update-index\t<file>\t\t\tfile\n\tgit-am\t\t\t<dir>\t\t\tdir\n\tgit-clone\t\t<directory>\t\tdir\n\tgit-cvsserver\t\t<directory>\t\tdir\n\tgit-daemon\t\t<directory>\t\tdir\n\tgit-fetch-pack\t\t<directory>\t\tdir\n\tgit-filter-branch\t<directory>\t\tdir\n\tgit-format-patch\t<dir>\t\t\tdir\n\tgit-fsck\t\t<dir>\t\t\tdir\n\tgit-mailsplit\t\t<directory>\t\tdir\n\tgit-peek-remote\t\t<directory>\t\tdir\n\tgit-quiltimport\t\t<dir>\t\t\tdir\n\tgit-receive-pack\t<directory>\t\tdir\n\tgit-relink\t\t<dir>\t\t\tdir\n\tgit-send-pack\t\t<directory>\t\tdir\n\tgit-submodule\t\t<path>\t\t\tdir\n\tgit-upload-archive\t<directory>\t\tdir\n\tgit-upload-pack\t\t<directory>\t\tdir\n\tgit-bundle\t\t<file>\t\t\toutfile\n\tgit-mailinfo\t\t<patch>\t\t\toutfile\n\tgit-pack-objects\tbase-name\t\toutfile\n\n\tgit-diff-tree\t\t<path>\t\t\tfile\t(f)\n\tgit-ls-tree\t\tpaths/path\t\tfile\t(f)\n\nThe following accept exact filenames or directories.  If a directory,\nthis matches all files within that directory recursively.\n\n\tgit-archive\t\tpath\t\t\tfdir\n\n\tgit-bisect\t\t<paths>/<pathspec>\tfdir\t(f)\n\tgit-diff\t\t<path>\t\t\tfdir\t(f)\n\tgit-diff-files\t\t<path>\t\t\tfdir\t(f)\n\tgit-diff-index\t\t<path>\t\t\tfdir\t(f)\n\tgit-difftool\t\t<path>/(nothing)\tfdir\t(f)\n\tgit-log\t\t\t<path>\t\t\tfdir\t(f)\n\tgit-reset\t\t<paths>\t\t\tfdir\t(f)\n\tgit-rev-list\t\t<paths>/paths\t\tfdir\t(f)\n\tgit-show\t\t(undoc)/<path>\t\tfdir\t(f)\n\tgit-whatchanged\t\t(undocumented)\t\tfdir\t(f)\n\tgitk\t\t\t<path>\t\t\tfdir\t(f)\n\nThe following accept recursive directory matches or path globs.\n\n\tgit-add\t\t\t<filepattern>\t\tglob\n\tgit-checkout\t\t<paths>/<file>\t\tglob\n\tgit-commit\t\t<file>/<filepattern>\tglob\n\tgit-rm\t\t\t<file>\t\t\tglob\n\n\tgit-clean\t\t<path>/<paths>\t\tglob\t(f)\n\tgit-grep\t\t<path>/path\t\tglob\t(f)\n\tgit-ls-files\t\t<file>\t\t\tglob\t(f)\n\tgit-status\t<pathspec>/<filepattern>\tglob?\t(f)\n\n* git-rm has --ignore-unmatch, which causes it to \"filter\"\n* git-status only accepts globs for untracked files (currently a bug?)\n\nHere are some examples showing what I mean by \"type\".  (May be useful to\nhave something like this in the documentation.)\n\n    pattern            file  fdir  glob\n    -------            ----  ----  ----\n    path/to/base.ext   yes   yes   yes\n    path                -    yes   yes\n    *xt                 -     -    yes\n    p*t                 -     -    yes\n    base.ext            -     -     -\n    b*                  -     -     -\n    to                  -     -     -\n\n>From the above, it appears that there are four major groups:\n* 'file' or 'dir'\n* 'fdir' (f)\n* 'glob'\n* 'glob' (f)\n\n(The only exceptions are git-diff-tree, git-ls-tree, and git-archive.)\n\nTherefore, I suggest that we stick to a consistent naming convention for\nthese four groups, and document them in git(1).  Here's is a proposal,\nbut I'm not tied to these names.\n* <file> for 'file'\n* <dir> for 'dir'\n* <path> for 'fdir' (f)\n* <filepattern> for 'glob'\n* <pathspec> for 'glob' (f)\n\nWe would have to come up with something for the three exceptions above,\nand some commands would benefit from more detailed meta-vars, such as\n\"<source>... <destination>\" for git-mv.\n\nAdditionally, it would be nice if all non-filtering commands had\n--ignore-unmatch, and all filtering commands had an option to die/warn\nif any arguments did not match.  But, this is much more work than\na simple documentation change.\n\nAnyway, what do you think of this proposal?  I am not sure that I have\nmy partitioning correct, but I would like to see some sort of\nconsistency in the documentation.  I would be happy to implement\nwhatever is decided.\n"},{"id":"135732","messageId":"7vfx4oeeol.fsf@alter.siamese.dyndns.org","threadId":"22832","inReplyTo":"ca433831002252055l37292cf6v868cc407f0be7250@mail.gmail.com","subject":"Re: Meta-variable naming convention in documentation","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-26T05:42:02Z","receivedAt":"2010-02-26T05:42:02Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Mark Lodato <lodatom@gmail.com> writes:\n\n> The following accept exact filenames or directories.  If a directory,\n> this matches all files within that directory recursively.\n>\n> \tgit-archive\t\tpath\t\t\tfdir\n>\n> \tgit-bisect\t\t<paths>/<pathspec>\tfdir\t(f)\n\nWhat does the gap between these two mean?  Do you mean \"bisect and later\nare not in the 'exact filenames or directories' group\"?\n\nIn general, unless the command takes only one filesystem entity (e.g. in\n\"format-patch -o <dir>\", <dir> cannot be anything but a single directory;\nin \"blame <file>\", <file> cannot be anything but a single file), you never\ngive a single \"filename\" to git command.  Even when you say \"git add\nMakefile\", you are _not_ giving a filename that is \"M' \"a\" \"k\" \"e\" ...;\nyou are giving a _pattern_ to be matched with files git would find by\ntraversing the filesystem.  In the case of \"Makefile\", it may happen to\nmatch only one single file.\n\nThis pattern is called \"pathspec\", and commands that can take one pathspec\ncan always take more than one.\n\nUnfortunately, for historical reasons, there are two semantics of\npathspec, and at least three implementations of pathspec logic.\n\n - diff family (diff, log, show, rev-list) does not support glob.  The\n   pattern is matched either as a leading directory path, or exact name.\n\n - ls-files family (I think \"clean\" also uses the logic internally) does\n   support glob.  The pattern is matched either as a leading directory\n   path, exact name, or a glob.\n\n - grep implements the same logic as ls-files but uses a newer\n   implementation better suited for optimized tree traversal.\n\nAnd there are higher level commands that internally use logic from either\ndiff family or ls-files family.  You can guess which pathspec is used if\nyou think about how you would implement what they do.  For example:\n\n - \"add <pathspec>\" traverses the work tree using ls-files logic and adds\n   found files to the index.\n\n - \"add -u <pathspec>\" compares the index and the work tree using\n   diff-files logic and adds paths with differences to the index.\n\n - \"status\" uses \"diff-index --cached\" logic to come up with 'Changed to\n   be committed' list, \"diff-files\" logic to come up with 'Changed but not\n   updated' list, and \"ls-files\" logic to list 'Untracked' files.\n\nUnifying the two different semantics of pathspecs is one of the suggested\ntopics for GSoC, by the way.\n\nI think it would make sense to document which ones are concrete paths\n(e.g. \"blame takes a filename\" vs \"diff takes zero or more pathspecs\"),\nbut it would not make much sense to document the two different pathspecs.\nThe effort is better spent at fixing the difference --- obviously we would\neventually want to be able to say \"git diff 'lib/*.h'\".\n"},{"id":"135784","messageId":"ca433831002261451k3164d413y77d4989239862f30@mail.gmail.com","threadId":"22832","inReplyTo":"7vfx4oeeol.fsf@alter.siamese.dyndns.org","subject":"Re: Meta-variable naming convention in documentation","fromName":"Mark Lodato","fromEmail":"lodatom@gmail.com","sentAt":"2010-02-26T22:51:03Z","receivedAt":"2010-02-26T22:51:03Z","isPatch":false,"sender":{"key":"lodatom@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58860?v=4"},"body":"On Fri, Feb 26, 2010 at 12:42 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Mark Lodato <lodatom@gmail.com> writes:\n>\n>> The following accept exact filenames or directories.  If a directory,\n>> this matches all files within that directory recursively.\n>>\n>>       git-archive             path                    fdir\n>>\n>>       git-bisect              <paths>/<pathspec>      fdir    (f)\n>\n> What does the gap between these two mean?  Do you mean \"bisect and later\n> are not in the 'exact filenames or directories' group\"?\n\nEach of the three types is divided in two, separated by a blank line.\nThe first group, all without (f) at the end, die if one of the paths\ngiven on the command line does not exist.  The second group, all with\n(f) at the end, do not complain if any of the paths do not match\nanything.  I called the latter group \"filtering\" for lack of a better\nterm.\n\nSo, git-archive, git-add, git-checkout, git-commit, git-rm all take\npathspecs (the first using diff logic, the rest using ls-files logic),\nbut they complain if any of the pathspecs do not match.  It's probably\nnot worth documenting this, but it may be worth implementing\n--ignore-unmatch for all but git-rm (which already has it.)\n\nSimilarly, it may be a nice option to have a --warn-unmatch option (or\na configuration variable) to warn (or possibly die) if any of the\npathspecs hit nothing.   Then again, maybe it's not worth the trouble.\n\nIt appears that git-diff-tree and git-ls-tree take some sort of\npathspec - it ignores unmatching patterns, but it does not allow\nglobbing or directory matches.\n\n> In general, unless the command takes only one filesystem entity (e.g. in\n> \"format-patch -o <dir>\", <dir> cannot be anything but a single directory;\n> in \"blame <file>\", <file> cannot be anything but a single file)\n\nIn this case, I suggest that we use the same meta-variable always:\n<file> or <dir>, or a more specific thing like <source>.\n\n> you never\n> give a single \"filename\" to git command.  Even when you say \"git add\n> Makefile\", you are _not_ giving a filename that is \"M' \"a\" \"k\" \"e\" ...;\n> you are giving a _pattern_ to be matched with files git would find by\n> traversing the filesystem.  In the case of \"Makefile\", it may happen to\n> match only one single file.\n>\n> This pattern is called \"pathspec\", and commands that can take one pathspec\n> can always take more than one.\n\nIn these cases, I think we should always use the meta-variable\n<pathspec> - never <path>, <file>, etc.\n\n> I think it would make sense to document which ones are concrete paths\n> (e.g. \"blame takes a filename\" vs \"diff takes zero or more pathspecs\"),\n> but it would not make much sense to document the two different pathspecs.\n> The effort is better spent at fixing the difference --- obviously we would\n> eventually want to be able to say \"git diff 'lib/*.h'\".\n\nYou're right, it's not worth having two different meta-variables, but\nI do think it is worth noting in the documentation.  In git(1), we\ncould have something like the following:\n\n<pathspec>::\n\tIndicates a pattern for filtering paths.  Matches are either exact,\n\ta leading directory, or a glob(7) pattern on the entire path.\n\tFor example, \"doc/help.txt\" matches \"doc/help.txt\", \"doc\",\n\t\"*.txt\", and \"d*t\", but not \"do\", \"help.txt\", or \"help.*\".\n\n<dir>::\n<file>::\n\tIndicates a physical file or directory relative to\n\tthe current directory.\n\n(Note: the current document says \"almost always relative to the root\nof the tree structure `GIT_INDEX_FILE` describes.\"  Is this true?)\n\nThen, for the diff logic commands, we could document that they do not\naccept globs.  For example, in git-diff(1):\n\n<pathspec>...::\n\tIf given, limit the diff to paths matching the given parameters.\n\t(Does not accept glob(7) patterns.)\n\nOnce the logic is unified, and these commands do accept globs, we can\njust remove the note.\n\nMark\n"},{"id":"135791","messageId":"ca433831002261841i2b0edab6nf1a6e9170c3ba3c@mail.gmail.com","threadId":"22832","inReplyTo":"ca433831002261451k3164d413y77d4989239862f30@mail.gmail.com","subject":"Re: Meta-variable naming convention in documentation","fromName":"Mark Lodato","fromEmail":"lodatom@gmail.com","sentAt":"2010-02-27T02:41:22Z","receivedAt":"2010-02-27T02:41:22Z","isPatch":false,"sender":{"key":"lodatom@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58860?v=4"},"body":"On a similar note, what do you think about dropping the term\n<tree-ish> and just using <tree> everywhere?  The only command that\nonly accepts a <tree>, and not a <tree-ish>, is git-commit-tree.  For\nexample, `git commit-tree master' fails, but `git commit-tree\nmaster^{tree}' works.  This can easily be written in the\ndocumentation, or the program can be fixed so it also accepts a\n<tree-ish> like everything else.  (git-grep(1) uses the term <tree>,\nbut this should be <tree-ish>.)\n\nI imagine a similar thing can be done with <commit> vs <commit-ish> vs\n<committish>, but I haven't verified this.  <commit-ish> is only used\nin git(1) and builtin-revert.c, and <committish> is only used in\ngit-describe(1), git-fast-import(1), git-name-rev(1), git-shortlog(1),\ngitcli(1), and builtin-describe.c.  I would guess that all the other\ncommands that say <commit> really accept a <commit-ish>, but perhaps\nthis is not true.\n\nI also think <rev> should be replaced with <commit>, unless this means\nsomething different.\n\nIf you give the go-ahead, I'll work on a patch to do this.\n\nCheers,\nMark\n"}]}