{"thread":{"id":"32595","subject":"[PATCH v5] git-completion.bash: add support for path completion","startedAt":"2013-01-11T18:48:43Z","lastAt":"2013-04-27T02:52:07Z","messageCount":9,"participants":["Manlio Perillo","Junio C Hamano","Felipe Contreras"],"isPatch":true,"patchVersion":5,"patchTotal":null},"messages":[{"id":"206548","messageId":"1357930123-26310-1-git-send-email-manlio.perillo@gmail.com","threadId":"32595","inReplyTo":null,"subject":"[PATCH v5] git-completion.bash: add support for path completion","fromName":"Manlio Perillo","fromEmail":"manlio.perillo@gmail.com","sentAt":"2013-01-11T18:48:43Z","receivedAt":"2013-01-11T18:48:43Z","isPatch":true,"sender":{"key":"manlio.perillo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6217088?v=4"},"body":"The git-completion.bash script did not implemented full, git aware,\nsupport to complete paths, for git commands that operate on files within\nthe current working directory or the index.\n\nAs an example:\n\n\tgit add <TAB>\n\nwill suggest all files in the current working directory, including\nignored files and files that have not been modified.\n\nSupport path completion, for git commands where the non-option arguments\nalways refer to paths within the current working directory or the index,\nas follows:\n\n* the path completion for the \"git rm\" and \"git ls-files\"\n  commands will suggest all cached files.\n\n* the path completion for the \"git add\" command will suggest all\n  untracked and modified files.  Ignored files are excluded.\n\n* the path completion for the \"git clean\" command will suggest all\n  untracked files.  Ignored files are excluded.\n\n* the path completion for the \"git mv\" command will suggest all cached\n  files when expanding the first argument, and all untracked and cached\n  files for subsequent arguments.  In the latter case, empty directories\n  are included and ignored files are excluded.\n\n* the path completion for the \"git commit\" command will suggest all\n  files that have been modified from the HEAD, if HEAD exists, otherwise\n  it will suggest all cached files.\n\nFor all affected commands, completion will always stop at directory\nboundary.  Only standard ignored files are excluded, using the\n--exclude-standard option of the ls-files command.\n\nWhen using a recent Bash version, Git path completion will be the same\nas builtin file completion, e.g.\n\n\tgit add contrib/\n\nwill suggest relative file names.\n\nSigned-off-by: Manlio Perillo <manlio.perillo@gmail.com>\n---\n\nChanges:\n\n\t* Applied Junio patch to fix completion inside a subdirectory.\n\t* Quoted the hopefully last incorrectly unquoted variable.\n\t* Fixed coding style (removed stdout file descriptor in shell\n\t  redirection, since it is redundant).\n\t* Fixed regression in path completion, when using non canonicalized\n\t  or absolute path names.\n\t  The problem has been solved making sure to chdir to the specified\n\t  directory before executing ls-files and diff-index commands.\n\n\t  The only issue is that there is no tilde expansion, but this is\n\t  harmless, since default bash completion will be used (the old\n\t  behaviour).\n\t* Improved path completion when the new compopt builtin is available\n\t  (Bash >= 4.x).\n\t  Now git paths completion is done in exactly the same way as Bash\n\t  builtin filenames completion.\n    * Updated the zsh compatibility code to use the improved path\n      completion support\n\t* Fixed incorrect git mv arguments count used to check the first\n\t  path to be renamed.\n\t  When options are used (unless they are git main options), -- is\n\t  required to separate options from non options arguments.\n\t  It is harmless to not use --; in this case bash will suggest\n\t  untracked files and directories for the first argument.\n\n\t  XXX: should I add this implementation note in the commit message?\n\t* Make sure to sort ls-files and diff-index filtered output before\n\t  removing duplicate directories.\n\t* Merged master.\n\t \nPlease note that before merging this patch in next, we need to update the\nzsh and tcsh completion scripts.\nI have the changes ready, but I will post them later since both scripts\nneeds more patches (I have posted an informal patch for zsh, and changes\nto tcsh should be in pu, but I need to test them).\n\n contrib/completion/git-completion.bash | 250 ++++++++++++++++++++++++++++++---\n 1 file changed, 234 insertions(+), 16 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex a4c48e1..51b8b3b 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -13,6 +13,7 @@\n #    *) .git/remotes file names\n #    *) git 'subcommands'\n #    *) tree paths within 'ref:path/to/file' expressions\n+#    *) file paths within current working directory and index\n #    *) common --long-options\n #\n # To use these routines:\n@@ -233,6 +234,118 @@ __gitcomp_nl ()\n \tCOMPREPLY=($(compgen -P \"${2-}\" -S \"${4- }\" -W \"$1\" -- \"${3-$cur}\"))\n }\n \n+# Generates completion reply with compgen from newline-separated possible\n+# completion filenames.\n+# It accepts 1 to 3 arguments:\n+# 1: List of possible completion filenames, separated by a single newline.\n+# 2: A directory prefix to be added to each possible completion filename\n+#    (optional).\n+# 3: Generate possible completion matches for this word (optional).\n+__gitcomp_file ()\n+{\n+\tlocal IFS=$'\\n'\n+\n+\t# XXX does not work when the directory prefix contains a tilde,\n+\t# since tilde expansion is not applied.\n+\t# This means that COMPREPLY will be empty and Bash default\n+\t# completion will be used.\n+\tCOMPREPLY=($(compgen -P \"${2-}\" -W \"$1\" -- \"${3-$cur}\"))\n+\n+\t# Tell Bash that compspec generates filenames.\n+\tcompopt -o filenames 2>/dev/null\n+}\n+\n+__git_index_file_list_filter_compat ()\n+{\n+\tlocal path\n+\n+\twhile read -r path; do\n+\t\tcase \"$path\" in\n+\t\t?*/*) echo \"${path%%/*}/\" ;;\n+\t\t*) echo \"$path\" ;;\n+\t\tesac\n+\tdone\n+}\n+\n+__git_index_file_list_filter_bash ()\n+{\n+\tlocal path\n+\n+\twhile read -r path; do\n+\t\tcase \"$path\" in\n+\t\t?*/*)\n+\t\t\t# XXX if we append a slash to directory names when using\n+\t\t\t# `compopt -o filenames`, Bash will append another slash.\n+\t\t\t# This is pretty stupid, and this the reason why we have to\n+\t\t\t# define a compatible version for this function.\n+\t\t\techo \"${path%%/*}\" ;;\n+\t\t*)\n+\t\t\techo \"$path\" ;;\n+\t\tesac\n+\tdone\n+}\n+\n+# Process path list returned by \"ls-files\" and \"diff-index --name-only\"\n+# commands, in order to list only file names relative to a specified\n+# directory, and append a slash to directory names.\n+__git_index_file_list_filter ()\n+{\n+\t# Default to Bash >= 4.x\n+\t__git_index_file_list_filter_bash\n+}\n+\n+# Execute git ls-files, returning paths relative to the directory\n+# specified in the first argument, and using the options specified in\n+# the second argument.\n+__git_ls_files_helper ()\n+{\n+\t# NOTE: $2 is not quoted in order to support multiple options\n+\tcd \"$1\" && git ls-files --exclude-standard $2\n+} 2>/dev/null\n+\n+\n+# Execute git diff-index, returning paths relative to the directory\n+# specified in the first argument, and using the tree object id\n+# specified in the second argument.\n+__git_diff_index_helper ()\n+{\n+\tcd \"$1\" && git diff-index --name-only --relative \"$2\"\n+} 2>/dev/null\n+\n+# __git_index_files accepts 1 or 2 arguments:\n+# 1: Options to pass to ls-files (required).\n+#    Supported options are --cached, --modified, --deleted, --others,\n+#    and --directory.\n+# 2: A directory path (optional).\n+#    If provided, only files within the specified directory are listed.\n+#    Sub directories are never recursed.  Path must have a trailing\n+#    slash.\n+__git_index_files ()\n+{\n+\tlocal dir=\"$(__gitdir)\" root=\"${2-.}\"\n+\n+\tif [ -d \"$dir\" ]; then\n+\t\t__git_ls_files_helper \"$root\" \"$1\" | __git_index_file_list_filter |\n+\t\t\tsort | uniq\n+\tfi\n+}\n+\n+# __git_diff_index_files accepts 1 or 2 arguments:\n+# 1) The id of a tree object.\n+# 2) A directory path (optional).\n+#    If provided, only files within the specified directory are listed.\n+#    Sub directories are never recursed.  Path must have a trailing\n+#    slash.\n+__git_diff_index_files ()\n+{\n+\tlocal dir=\"$(__gitdir)\" root=\"${2-.}\"\n+\n+\tif [ -d \"$dir\" ]; then\n+\t\t__git_diff_index_helper \"$root\" \"$1\" | __git_index_file_list_filter |\n+\t\t\tsort | uniq\n+\tfi\n+}\n+\n __git_heads ()\n {\n \tlocal dir=\"$(__gitdir)\"\n@@ -430,6 +543,46 @@ __git_complete_revlist_file ()\n }\n \n \n+# __git_complete_index_file requires 1 argument: the options to pass to\n+# ls-file\n+__git_complete_index_file ()\n+{\n+\tlocal pfx cur_=\"$cur\"\n+\n+\tcase \"$cur_\" in\n+\t?*/*)\n+\t\tpfx=\"${cur_%/*}\"\n+\t\tcur_=\"${cur_##*/}\"\n+\t\tpfx=\"${pfx}/\"\n+\n+\t\t__gitcomp_file \"$(__git_index_files \"$1\" \"$pfx\")\" \"$pfx\" \"$cur_\"\n+\t\t;;\n+\t*)\n+\t\t__gitcomp_file \"$(__git_index_files \"$1\")\" \"\" \"$cur_\"\n+\t\t;;\n+\tesac\n+}\n+\n+# __git_complete_diff_index_file requires 1 argument: the id of a tree\n+# object\n+__git_complete_diff_index_file ()\n+{\n+\tlocal pfx cur_=\"$cur\"\n+\n+\tcase \"$cur_\" in\n+\t?*/*)\n+\t\tpfx=\"${cur_%/*}\"\n+\t\tcur_=\"${cur_##*/}\"\n+\t\tpfx=\"${pfx}/\"\n+\n+\t\t__gitcomp_file \"$(__git_diff_index_files \"$1\" \"$pfx\")\" \"$pfx\" \"$cur_\"\n+\t\t;;\n+\t*)\n+\t\t__gitcomp_file \"$(__git_diff_index_files \"$1\")\" \"\" \"$cur_\"\n+\t\t;;\n+\tesac\n+}\n+\n __git_complete_file ()\n {\n \t__git_complete_revlist_file\n@@ -722,6 +875,43 @@ __git_has_doubledash ()\n \treturn 1\n }\n \n+# Try to count non option arguments passed on the command line for the\n+# specified git command.\n+# When options are used, it is necessary to use the special -- option to\n+# tell the implementation were non option arguments begin.\n+# XXX this can not be improved, since options can appear everywhere, as\n+# an example:\n+#\tgit mv x -n y\n+#\n+# __git_count_arguments requires 1 argument: the git command executed.\n+__git_count_arguments ()\n+{\n+\tlocal word i c=0\n+\n+\t# Skip \"git\" (first argument)\n+\tfor ((i=1; i < ${#words[@]}; i++)); do\n+\t\tword=\"${words[i]}\"\n+\n+\t\tcase \"$word\" in\n+\t\t\t--)\n+\t\t\t\t# Good; we can assume that the following are only non\n+\t\t\t\t# option arguments.\n+\t\t\t\t((c = 0))\n+\t\t\t\t;;\n+\t\t\t\"$1\")\n+\t\t\t\t# Skip the specified git command and discard git\n+\t\t\t\t# main options\n+\t\t\t\t((c = 0))\n+\t\t\t\t;;\n+\t\t\t?*)\n+\t\t\t\t((c++))\n+\t\t\t\t;;\n+\t\tesac\n+\tdone\n+\n+\tprintf \"%d\" $c\n+}\n+\n __git_whitespacelist=\"nowarn warn error error-all fix\"\n \n _git_am ()\n@@ -770,8 +960,6 @@ _git_apply ()\n \n _git_add ()\n {\n-\t__git_has_doubledash && return\n-\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"\n@@ -780,7 +968,9 @@ _git_add ()\n \t\t\t\"\n \t\treturn\n \tesac\n-\tCOMPREPLY=()\n+\n+\t# XXX should we check for --update and --all options ?\n+\t__git_complete_index_file \"--others --modified\"\n }\n \n _git_archive ()\n@@ -930,15 +1120,15 @@ _git_cherry_pick ()\n \n _git_clean ()\n {\n-\t__git_has_doubledash && return\n-\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--dry-run --quiet\"\n \t\treturn\n \t\t;;\n \tesac\n-\tCOMPREPLY=()\n+\n+\t# XXX should we check for -x option ?\n+\t__git_complete_index_file \"--others\"\n }\n \n _git_clone ()\n@@ -969,8 +1159,6 @@ _git_clone ()\n \n _git_commit ()\n {\n-\t__git_has_doubledash && return\n-\n \tcase \"$prev\" in\n \t-c|-C)\n \t\t__gitcomp_nl \"$(__git_refs)\" \"\" \"${cur}\"\n@@ -1005,7 +1193,13 @@ _git_commit ()\n \t\t\t\"\n \t\treturn\n \tesac\n-\tCOMPREPLY=()\n+\n+\tif git rev-parse --verify --quiet HEAD >/dev/null; then\n+\t\t__git_complete_diff_index_file \"HEAD\"\n+\telse\n+\t\t# This is the first commit\n+\t\t__git_complete_index_file \"--cached\"\n+\tfi\n }\n \n _git_describe ()\n@@ -1223,8 +1417,6 @@ _git_init ()\n \n _git_ls_files ()\n {\n-\t__git_has_doubledash && return\n-\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --deleted --modified --others --ignored\n@@ -1237,7 +1429,10 @@ _git_ls_files ()\n \t\treturn\n \t\t;;\n \tesac\n-\tCOMPREPLY=()\n+\n+\t# XXX ignore options like --modified and always suggest all cached\n+\t# files.\n+\t__git_complete_index_file \"--cached\"\n }\n \n _git_ls_remote ()\n@@ -1369,7 +1564,14 @@ _git_mv ()\n \t\treturn\n \t\t;;\n \tesac\n-\tCOMPREPLY=()\n+\n+\tif [ $(__git_count_arguments \"mv\") -gt 0 ]; then\n+\t\t# We need to show both cached and untracked files (including\n+\t\t# empty directories) since this may not be the last argument.\n+\t\t__git_complete_index_file \"--cached --others --directory\"\n+\telse\n+\t\t__git_complete_index_file \"--cached\"\n+\tfi\n }\n \n _git_name_rev ()\n@@ -2075,15 +2277,14 @@ _git_revert ()\n \n _git_rm ()\n {\n-\t__git_has_doubledash && return\n-\n \tcase \"$cur\" in\n \t--*)\n \t\t__gitcomp \"--cached --dry-run --ignore-unmatch --quiet\"\n \t\treturn\n \t\t;;\n \tesac\n-\tCOMPREPLY=()\n+\n+\t__git_complete_index_file \"--cached\"\n }\n \n _git_shortlog ()\n@@ -2448,6 +2649,15 @@ if [[ -n ${ZSH_VERSION-} ]]; then\n \t\tcompadd -Q -S \"${4- }\" -p \"${2-}\" -- ${=1} && _ret=0\n \t}\n \n+\t__gitcomp_file ()\n+\t{\n+\t\temulate -L zsh\n+\n+\t\tlocal IFS=$'\\n'\n+\t\tcompset -P '*[=:]'\n+\t\tcompadd -Q -p \"${2-}\" -f -- ${=1} && _ret=0\n+\t}\n+\n \t__git_zsh_helper ()\n \t{\n \t\temulate -L ksh\n@@ -2469,6 +2679,14 @@ if [[ -n ${ZSH_VERSION-} ]]; then\n \n \tcompdef _git git gitk\n \treturn\n+elif [[ -n ${BASH_VERSION-} ]]; then\n+\tif ((${BASH_VERSINFO[0]} < 4)); then\n+\t\t# compopt is not supported\n+\t\t__git_index_file_list_filter ()\n+\t\t{\n+\t\t\t__git_index_file_list_filter_compat\n+\t\t}\n+\tfi\n fi\n \n __git_func_wrap ()\n-- \n1.8.1.rc1.31.ga3c84da\n"},{"id":"206562","messageId":"7v8v7zbcoi.fsf@alter.siamese.dyndns.org","threadId":"32595","inReplyTo":"1357930123-26310-1-git-send-email-manlio.perillo@gmail.com","subject":"Re: [PATCH v5] git-completion.bash: add support for path completion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-01-11T22:02:53Z","receivedAt":"2013-01-11T22:02:53Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Manlio Perillo <manlio.perillo@gmail.com> writes:\n\n> +# Process path list returned by \"ls-files\" and \"diff-index --name-only\"\n> +# commands, in order to list only file names relative to a specified\n> +# directory, and append a slash to directory names.\n> +__git_index_file_list_filter ()\n> +{\n> +\t# Default to Bash >= 4.x\n> +\t__git_index_file_list_filter_bash\n> +}\n> +\n> +# Execute git ls-files, returning paths relative to the directory\n> +# specified in the first argument, and using the options specified in\n> +# the second argument.\n> +__git_ls_files_helper ()\n> +{\n> +\t# NOTE: $2 is not quoted in order to support multiple options\n> +\tcd \"$1\" && git ls-files --exclude-standard $2\n> +} 2>/dev/null\n\nI think this redirection is correct but a bit tricky; it is in\neffect during the execution of the { block } (in other words, it is\nnot about squelching errors during the function definition).\n\n-- >8 --\n#!/bin/sh\ncat >t.sh <<\\EOF &&\necho I am \"$1\"\nt () { echo \"Goes to stdout\"; echo >&2 \"Goes to stderr\"; } 2>/dev/null\nt\nfor sh in bash dash ksh zsh\ndo\n\t$sh t.sh $sh\ndone\n-- 8< --\n\nBash does (so do dash and real AT&T ksh) grok this correctly, but\nzsh does not seem to (I tried zsh 4.3.10 and 4.3.17; also zsh\npretending to be ksh gets this wrong as well).  Not that what ksh\ndoes matters, as it won't be dot-sourcing bash completion script.\n\nIt however may affect zsh, which does seem to dot-source this file.\nPerhaps zsh completion may have to be rewritten in a similar way as\ntcsh completion is done (i.e. does not dot-source this file but ask\nbash to do the heavy-lifting).\n\nThis function seems to be always called in an subshell (e.g. as an\nupstream of a pipeline), so the \"cd\" may be harmless, but don't you\nneed to disable CDPATH while doing this?\n\n> +# Execute git diff-index, returning paths relative to the directory\n> +# specified in the first argument, and using the tree object id\n> +# specified in the second argument.\n> +__git_diff_index_helper ()\n> +{\n> +\tcd \"$1\" && git diff-index --name-only --relative \"$2\"\n> +} 2>/dev/null\n\nDitto.\n\n> @@ -722,6 +875,43 @@ __git_has_doubledash ()\n>  \treturn 1\n>  }\n>  \n> +# Try to count non option arguments passed on the command line for the\n> +# specified git command.\n> +# When options are used, it is necessary to use the special -- option to\n> +# tell the implementation were non option arguments begin.\n> +# XXX this can not be improved, since options can appear everywhere, as\n> +# an example:\n> +#\tgit mv x -n y\n\nIf that is the case, it is a bug in the command line parser, I\nthink.  We should reject it, and the command line completer\ncertainly should not encourage it.\n"},{"id":"206594","messageId":"50F15CB9.5090603@gmail.com","threadId":"32595","inReplyTo":"1357930123-26310-1-git-send-email-manlio.perillo@gmail.com","subject":"Re: [PATCH v5] git-completion.bash: add support for path completion","fromName":"Manlio Perillo","fromEmail":"manlio.perillo@gmail.com","sentAt":"2013-01-12T12:53:13Z","receivedAt":"2013-01-12T12:53:13Z","isPatch":true,"sender":{"key":"manlio.perillo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6217088?v=4"},"body":"-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA1\n\nIl 11/01/2013 19:48, Manlio Perillo ha scritto:\n> The git-completion.bash script did not implemented full, git aware,\n> support to complete paths, for git commands that operate on files within\n> the current working directory or the index.\n> [...]\n>  \n> +# Try to count non option arguments passed on the command line for the\n> +# specified git command.\n> +# When options are used, it is necessary to use the special -- option to\n> +# tell the implementation were non option arguments begin.\n> +# XXX this can not be improved, since options can appear everywhere, as\n> +# an example:\n> +#\tgit mv x -n y\n> +#\n> +# __git_count_arguments requires 1 argument: the git command executed.\n> +__git_count_arguments ()\n> +{\n> +\tlocal word i c=0\n> +\n> +\t# Skip \"git\" (first argument)\n> +\tfor ((i=1; i < ${#words[@]}; i++)); do\n> +\t\tword=\"${words[i]}\"\n> +\n> +\t\tcase \"$word\" in\n> +\t\t\t--)\n\nSorry, I have incorrectly (again) indented the case labels.\nI have now configured my editor to correctly indent this.\n\n> +\t\t\t\t# Good; we can assume that the following are only non\n> +\t\t\t\t# option arguments.\n> +\t\t\t\t((c = 0))\n> +\t\t\t\t;;\n\nHere I was thinking to do something like this (not tested):\n\n\t\t-*)\n\t\t\tif [ -n ${2-} ]; then\n\t\t\t\t# Assume specified git command only\n                                # accepts simple options\n\t\t\t\t# (without arguments)\n\t\t\t\t((c = 0))\n\nSince git mv only accepts simple options, this will make the use of '--'\nnot required.\n\nNote that I'm assuming the single '-' character is used as a non-option\nargument; not sure this is the case of Git.\n\n> [...]\n\n\nRegards  Manlio\n-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1.4.10 (GNU/Linux)\nComment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/\n\niEYEARECAAYFAlDxXLkACgkQscQJ24LbaUR+QQCaA4WZP5h5lktXJqSB7c494fAY\nB6IAoIRWyIzBq29S7+l+TfRjbyp19HNL\n=JRpR\n-----END PGP SIGNATURE-----\n"},{"id":"206600","messageId":"50F178C8.40806@gmail.com","threadId":"32595","inReplyTo":"7v8v7zbcoi.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v5] git-completion.bash: add support for path completion","fromName":"Manlio Perillo","fromEmail":"manlio.perillo@gmail.com","sentAt":"2013-01-12T14:52:56Z","receivedAt":"2013-01-12T14:52:56Z","isPatch":true,"sender":{"key":"manlio.perillo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6217088?v=4"},"body":"-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA1\n\nIl 11/01/2013 23:02, Junio C Hamano ha scritto:\n> Manlio Perillo <manlio.perillo@gmail.com> writes:\n> \n>> +# Process path list returned by \"ls-files\" and \"diff-index --name-only\"\n>> +# commands, in order to list only file names relative to a specified\n>> +# directory, and append a slash to directory names.\n>> +__git_index_file_list_filter ()\n>> +{\n>> +\t# Default to Bash >= 4.x\n>> +\t__git_index_file_list_filter_bash\n>> +}\n>> +\n>> +# Execute git ls-files, returning paths relative to the directory\n>> +# specified in the first argument, and using the options specified in\n>> +# the second argument.\n>> +__git_ls_files_helper ()\n>> +{\n>> +\t# NOTE: $2 is not quoted in order to support multiple options\n>> +\tcd \"$1\" && git ls-files --exclude-standard $2\n>> +} 2>/dev/null\n> \n> I think this redirection is correct but a bit tricky;\n\nIt's not tricky: it is POSIX:\nhttp://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_10\n\n\n> it is in\n> effect during the execution of the { block } (in other words, it is\n> not about squelching errors during the function definition).\n> \n\nWhat do you mean by \"squelching\"?\n\nNote that I originally wrote the code as\n\n__git_ls_files_helper ()\n{\n\t# NOTE: $2 is not quoted in order to support multiple options\n\t { cd \"$1\" && git ls-files --exclude-standard $2 } 2>/dev/null\n}\n\nbut then I checked the POSIX standard, noting that it is redundant.\n\n> -- >8 --\n> #!/bin/sh\n> cat >t.sh <<\\EOF &&\n> echo I am \"$1\"\n> t () { echo \"Goes to stdout\"; echo >&2 \"Goes to stderr\"; } 2>/dev/null\n> t\n> for sh in bash dash ksh zsh\n> do\n> \t$sh t.sh $sh\n> done\n> -- 8< --\n> \n\nThere is a missing EOF delimiter.\nAnd I'm not sure to understand the meaning of && after EOF.\n\n> Bash does (so do dash and real AT&T ksh) grok this correctly, but\n> zsh does not seem to (I tried zsh 4.3.10 and 4.3.17; also zsh\n> pretending to be ksh gets this wrong as well).  Not that what ksh\n> does matters, as it won't be dot-sourcing bash completion script.\n>\n\nI have added tcsh to the sh list, but it fails with:\nBadly placed ()'s.\n\n\n> It however may affect zsh, which does seem to dot-source this file.\n> Perhaps zsh completion may have to be rewritten in a similar way as\n> tcsh completion is done (i.e. does not dot-source this file but ask\n> bash to do the heavy-lifting).\n> \n\nOk, I was wrong on assuming all modern shells were POSIX compliant.\nI will change the code to use a nested {} group.\n\n> This function seems to be always called in an subshell (e.g. as an\n> upstream of a pipeline), so the \"cd\" may be harmless, but don't you\n> need to disable CDPATH while doing this?\n> \n\nI don't know.\n\n> [..]\n\n\n>> +# Try to count non option arguments passed on the command line for the\n>> +# specified git command.\n>> +# When options are used, it is necessary to use the special -- option to\n>> +# tell the implementation were non option arguments begin.\n>> +# XXX this can not be improved, since options can appear everywhere, as\n>> +# an example:\n>> +#\tgit mv x -n y\n> \n> If that is the case, it is a bug in the command line parser, I\n> think.  We should reject it, and the command line completer\n> certainly should not encourage it.\n> \n\n$ mkdir y\n$ git mv x -n y\nChecking rename of 'x' to 'y/x'\nRenaming x to y/x\n$ git status\n# On branch master\nnothing to commit, working directory clean\n\nI was assuming it to be \"normal\", given how complex Git command line\nparsing is (IMHO).\n\n\nThanks  Manlio\n-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1.4.10 (GNU/Linux)\nComment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/\n\niEYEARECAAYFAlDxeMgACgkQscQJ24LbaUTmaQCeMbZ0lRJxZIx3U31gMPmcqTLp\n54sAmwYrjJVuvRYcsbGaMa3rb9/EKrBU\n=ky30\n-----END PGP SIGNATURE-----\n"},{"id":"206716","messageId":"7vzk0chfal.fsf@alter.siamese.dyndns.org","threadId":"32595","inReplyTo":"50F15CB9.5090603@gmail.com","subject":"Re: [PATCH v5] git-completion.bash: add support for path completion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-01-13T22:46:42Z","receivedAt":"2013-01-13T22:46:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Manlio Perillo <manlio.perillo@gmail.com> writes:\n\n>> +\t# Skip \"git\" (first argument)\n>> +\tfor ((i=1; i < ${#words[@]}; i++)); do\n>> +\t\tword=\"${words[i]}\"\n>> +\n>> +\t\tcase \"$word\" in\n>> +\t\t\t--)\n>\n> Sorry, I have incorrectly (again) indented the case labels.\n> I have now configured my editor to correctly indent this.\n\nYeah, thanks for spotting.\n\nI wouldn't worry *too* much about the style in this script at this\npoint, though.  It uses a style on its own that is totally different\nfrom the rest of the system (e.g. \"[\" instead of \"test\", semicolon\nin \"if ...; then\", etc.) and it probably is better to emulate the\nsurrounding code, and leave the style \"fixes\" to a separate topic,\nif we want to (as a contrib/ material that is not POSIX but bash\nspecific, I do not know if that is even worth it).\n\n>> +\t\t\t\t# Good; we can assume that the following are only non\n>> +\t\t\t\t# option arguments.\n>> +\t\t\t\t((c = 0))\n>> +\t\t\t\t;;\n>\n> Here I was thinking to do something like this (not tested):\n>\n> \t\t-*)\n> \t\t\tif [ -n ${2-} ]; then\n> \t\t\t\t# Assume specified git command only\n>                                 # accepts simple options\n> \t\t\t\t# (without arguments)\n> \t\t\t\t((c = 0))\n>\n> Since git mv only accepts simple options, this will make the use of '--'\n> not required.\n\nUnless you have a file whose name begins with a dash, perhaps?\n"},{"id":"206717","messageId":"7vsj64hetm.fsf@alter.siamese.dyndns.org","threadId":"32595","inReplyTo":"50F178C8.40806@gmail.com","subject":"Re: [PATCH v5] git-completion.bash: add support for path completion","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-01-13T22:56:53Z","receivedAt":"2013-01-13T22:56:53Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Manlio Perillo <manlio.perillo@gmail.com> writes:\n\n> Il 11/01/2013 23:02, Junio C Hamano ha scritto:\n>> Manlio Perillo <manlio.perillo@gmail.com> writes:\n>> \n>>> +# Process path list returned by \"ls-files\" and \"diff-index --name-only\"\n>>> +# commands, in order to list only file names relative to a specified\n>>> +# directory, and append a slash to directory names.\n>>> +__git_index_file_list_filter ()\n>>> +{\n>>> +\t# Default to Bash >= 4.x\n>>> +\t__git_index_file_list_filter_bash\n>>> +}\n>>> +\n>>> +# Execute git ls-files, returning paths relative to the directory\n>>> +# specified in the first argument, and using the options specified in\n>>> +# the second argument.\n>>> +__git_ls_files_helper ()\n>>> +{\n>>> +\t# NOTE: $2 is not quoted in order to support multiple options\n>>> +\tcd \"$1\" && git ls-files --exclude-standard $2\n>>> +} 2>/dev/null\n>> \n>> I think this redirection is correct but a bit tricky;\n>\n> It's not tricky: it is POSIX:\n\nI know that.  It is an instance of \"Even it is in POSIX, we may want\nto refrain using it, because some shells get it wrong, and it is\neasy to work it around\".\n\n>> effect during the execution of the { block } (in other words, it is\n>> not about squelching errors during the function definition).\n>\n> What do you mean by \"squelching\"?\n\nSilencing, not showing the end user.  Sending to /dev/null.\n\n> I have added tcsh to the sh list, but it fails with:\n> Badly placed ()'s.\n\ntcsh (and csh) are not even in the Bourne shell family and is not\nexpected to be able to run any non trivial POSIX shell scripts.  The\ncompletion script for it does not dot-source this but instead lets\nbash read it, so it is fine.\n\n>> It however may affect zsh, which does seem to dot-source this file.\n>> Perhaps zsh completion may have to be rewritten in a similar way as\n>> tcsh completion is done (i.e. does not dot-source this file but ask\n>> bash to do the heavy-lifting).\n>\n> Ok, I was wrong on assuming all modern shells were POSIX compliant.\n\nShells in csh family will never be, and being non-POSIX is not a\ncrime.  It only matters when such a shell is allowed to dot-source\nthis script, and this script uses constructs that such a shell does\nnot understand.\n\n> I will change the code to use a nested {} group.\n>\n>> This function seems to be always called in an subshell (e.g. as an\n>> upstream of a pipeline), so the \"cd\" may be harmless, but don't you\n>> need to disable CDPATH while doing this?\n>\n> I don't know.\n\nThe caller of this function figures out the value of $subdirname,\nand calls you; your \"cd $subdirname\" may not go to ./$subdirname as\nyou expect, but to the $subdirname directory under one of the\ndirectories listed in CDPATH, before running ls-tree or ls-files.\n"},{"id":"215005","messageId":"CAMP44s1TjTiZ9HsXn9YiJ8E6+jC=s+g_tps6AY2ixrrgX=0jnw@mail.gmail.com","threadId":"32595","inReplyTo":"1357930123-26310-1-git-send-email-manlio.perillo@gmail.com","subject":"Re: [PATCH v5] git-completion.bash: add support for path completion","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-21T10:14:38Z","receivedAt":"2013-04-21T10:14:38Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Fri, Jan 11, 2013 at 12:48 PM, Manlio Perillo\n<manlio.perillo@gmail.com> wrote:\n> The git-completion.bash script did not implemented full, git aware,\n> support to complete paths, for git commands that operate on files within\n> the current working directory or the index.\n\n> +__git_index_file_list_filter_compat ()\n> +{\n> +       local path\n> +\n> +       while read -r path; do\n> +               case \"$path\" in\n> +               ?*/*) echo \"${path%%/*}/\" ;;\n> +               *) echo \"$path\" ;;\n> +               esac\n> +       done\n> +}\n> +\n> +__git_index_file_list_filter_bash ()\n> +{\n> +       local path\n> +\n> +       while read -r path; do\n> +               case \"$path\" in\n> +               ?*/*)\n> +                       # XXX if we append a slash to directory names when using\n> +                       # `compopt -o filenames`, Bash will append another slash.\n> +                       # This is pretty stupid, and this the reason why we have to\n> +                       # define a compatible version for this function.\n> +                       echo \"${path%%/*}\" ;;\n\nWhich version of bash is that? It works perfectly fine here with or\nwithout the /.\n\n> +# __git_index_files accepts 1 or 2 arguments:\n> +# 1: Options to pass to ls-files (required).\n> +#    Supported options are --cached, --modified, --deleted, --others,\n> +#    and --directory.\n> +# 2: A directory path (optional).\n> +#    If provided, only files within the specified directory are listed.\n> +#    Sub directories are never recursed.  Path must have a trailing\n> +#    slash.\n> +__git_index_files ()\n> +{\n> +       local dir=\"$(__gitdir)\" root=\"${2-.}\"\n> +\n> +       if [ -d \"$dir\" ]; then\n> +               __git_ls_files_helper \"$root\" \"$1\" | __git_index_file_list_filter |\n> +                       sort | uniq\n> +       fi\n> +}\n> +\n> +# __git_diff_index_files accepts 1 or 2 arguments:\n> +# 1) The id of a tree object.\n> +# 2) A directory path (optional).\n> +#    If provided, only files within the specified directory are listed.\n> +#    Sub directories are never recursed.  Path must have a trailing\n> +#    slash.\n> +__git_diff_index_files ()\n> +{\n> +       local dir=\"$(__gitdir)\" root=\"${2-.}\"\n> +\n> +       if [ -d \"$dir\" ]; then\n> +               __git_diff_index_helper \"$root\" \"$1\" | __git_index_file_list_filter |\n> +                       sort | uniq\n> +       fi\n> +}\n\nThese two are exactly the same, except one calls\n__git_ls_files_helper, and the other one __git_diff_index_helper,\ncan't we make another argument that is and select one or the other\nbased on that?\n\n>  __git_heads ()\n>  {\n>         local dir=\"$(__gitdir)\"\n> @@ -430,6 +543,46 @@ __git_complete_revlist_file ()\n>  }\n>\n>\n> +# __git_complete_index_file requires 1 argument: the options to pass to\n> +# ls-file\n> +__git_complete_index_file ()\n> +{\n> +       local pfx cur_=\"$cur\"\n> +\n> +       case \"$cur_\" in\n> +       ?*/*)\n> +               pfx=\"${cur_%/*}\"\n> +               cur_=\"${cur_##*/}\"\n> +               pfx=\"${pfx}/\"\n> +\n> +               __gitcomp_file \"$(__git_index_files \"$1\" \"$pfx\")\" \"$pfx\" \"$cur_\"\n> +               ;;\n> +       *)\n> +               __gitcomp_file \"$(__git_index_files \"$1\")\" \"\" \"$cur_\"\n> +               ;;\n> +       esac\n> +}\n> +\n> +# __git_complete_diff_index_file requires 1 argument: the id of a tree\n> +# object\n> +__git_complete_diff_index_file ()\n> +{\n> +       local pfx cur_=\"$cur\"\n> +\n> +       case \"$cur_\" in\n> +       ?*/*)\n> +               pfx=\"${cur_%/*}\"\n> +               cur_=\"${cur_##*/}\"\n> +               pfx=\"${pfx}/\"\n> +\n> +               __gitcomp_file \"$(__git_diff_index_files \"$1\" \"$pfx\")\" \"$pfx\" \"$cur_\"\n> +               ;;\n> +       *)\n> +               __gitcomp_file \"$(__git_diff_index_files \"$1\")\" \"\" \"$cur_\"\n> +               ;;\n> +       esac\n> +}\n\nThese are also exactly the same, we could pass the argument to the\nfunction above.\n\n-- \nFelipe Contreras\n"},{"id":"215241","messageId":"5176A7E4.2070608@gmail.com","threadId":"32595","inReplyTo":"CAMP44s1TjTiZ9HsXn9YiJ8E6+jC=s+g_tps6AY2ixrrgX=0jnw@mail.gmail.com","subject":"Re: [PATCH v5] git-completion.bash: add support for path completion","fromName":"Manlio Perillo","fromEmail":"manlio.perillo@gmail.com","sentAt":"2013-04-23T15:25:24Z","receivedAt":"2013-04-23T15:25:24Z","isPatch":true,"sender":{"key":"manlio.perillo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6217088?v=4"},"body":"-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA1\n\nIl 21/04/2013 12:14, Felipe Contreras ha scritto:\n> On Fri, Jan 11, 2013 at 12:48 PM, Manlio Perillo\n> <manlio.perillo@gmail.com> wrote:\n>> The git-completion.bash script did not implemented full, git aware,\n>> support to complete paths, for git commands that operate on files within\n>> the current working directory or the index.\n> \n>> +__git_index_file_list_filter_compat ()\n>> +{\n>> +       local path\n>> +\n>> +       while read -r path; do\n>> +               case \"$path\" in\n>> +               ?*/*) echo \"${path%%/*}/\" ;;\n>> +               *) echo \"$path\" ;;\n>> +               esac\n>> +       done\n>> +}\n>> +\n>> +__git_index_file_list_filter_bash ()\n>> +{\n>> +       local path\n>> +\n>> +       while read -r path; do\n>> +               case \"$path\" in\n>> +               ?*/*)\n>> +                       # XXX if we append a slash to directory names when using\n>> +                       # `compopt -o filenames`, Bash will append another slash.\n>> +                       # This is pretty stupid, and this the reason why we have to\n>> +                       # define a compatible version for this function.\n>> +                       echo \"${path%%/*}\" ;;\n> \n> Which version of bash is that? It works perfectly fine here with or\n> without the /.\n> \n\nGNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)\non a GNU Linux Debian 6\n\n>> +# __git_index_files accepts 1 or 2 arguments:\n>> +# 1: Options to pass to ls-files (required).\n>> +#    Supported options are --cached, --modified, --deleted, --others,\n>> +#    and --directory.\n>> +# 2: A directory path (optional).\n>> +#    If provided, only files within the specified directory are listed.\n>> +#    Sub directories are never recursed.  Path must have a trailing\n>> +#    slash.\n>> +__git_index_files ()\n>> +{\n>> +       local dir=\"$(__gitdir)\" root=\"${2-.}\"\n>> +\n>> +       if [ -d \"$dir\" ]; then\n>> +               __git_ls_files_helper \"$root\" \"$1\" | __git_index_file_list_filter |\n>> +                       sort | uniq\n>> +       fi\n>> +}\n>> +\n>> +# __git_diff_index_files accepts 1 or 2 arguments:\n>> +# 1) The id of a tree object.\n>> +# 2) A directory path (optional).\n>> +#    If provided, only files within the specified directory are listed.\n>> +#    Sub directories are never recursed.  Path must have a trailing\n>> +#    slash.\n>> +__git_diff_index_files ()\n>> +{\n>> +       local dir=\"$(__gitdir)\" root=\"${2-.}\"\n>> +\n>> +       if [ -d \"$dir\" ]; then\n>> +               __git_diff_index_helper \"$root\" \"$1\" | __git_index_file_list_filter |\n>> +                       sort | uniq\n>> +       fi\n>> +}\n> \n> These two are exactly the same, except one calls\n> __git_ls_files_helper, and the other one __git_diff_index_helper,\n> can't we make another argument that is and select one or the other\n> based on that?\n> \n\nThey are not exactly the same.\n\nThe first function requires, as first parameter, (space separed) options\nto pass to ls-files command; the second function, instead, requires the\nid of a tree object.\n\nIMHO, using only one function may be confusing.\n\n>>  __git_heads ()\n>>  {\n>>         local dir=\"$(__gitdir)\"\n>> @@ -430,6 +543,46 @@ __git_complete_revlist_file ()\n>>  }\n>>\n>>\n>> +# __git_complete_index_file requires 1 argument: the options to pass to\n>> +# ls-file\n>> +__git_complete_index_file ()\n>> +{\n>> +       local pfx cur_=\"$cur\"\n>> +\n>> +       case \"$cur_\" in\n>> +       ?*/*)\n>> +               pfx=\"${cur_%/*}\"\n>> +               cur_=\"${cur_##*/}\"\n>> +               pfx=\"${pfx}/\"\n>> +\n>> +               __gitcomp_file \"$(__git_index_files \"$1\" \"$pfx\")\" \"$pfx\" \"$cur_\"\n>> +               ;;\n>> +       *)\n>> +               __gitcomp_file \"$(__git_index_files \"$1\")\" \"\" \"$cur_\"\n>> +               ;;\n>> +       esac\n>> +}\n>> +\n>> +# __git_complete_diff_index_file requires 1 argument: the id of a tree\n>> +# object\n>> +__git_complete_diff_index_file ()\n>> +{\n>> +       local pfx cur_=\"$cur\"\n>> +\n>> +       case \"$cur_\" in\n>> +       ?*/*)\n>> +               pfx=\"${cur_%/*}\"\n>> +               cur_=\"${cur_##*/}\"\n>> +               pfx=\"${pfx}/\"\n>> +\n>> +               __gitcomp_file \"$(__git_diff_index_files \"$1\" \"$pfx\")\" \"$pfx\" \"$cur_\"\n>> +               ;;\n>> +       *)\n>> +               __gitcomp_file \"$(__git_diff_index_files \"$1\")\" \"\" \"$cur_\"\n>> +               ;;\n>> +       esac\n>> +}\n> \n> These are also exactly the same, we could pass the argument to the\n> function above.\n> \n\nSee previous note.\n\n\n\nRegards  Manlio Perillo\n-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1.4.10 (GNU/Linux)\nComment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/\n\niEYEARECAAYFAlF2p+QACgkQscQJ24LbaUQVcACfeYFO8umJDbgTrXWChqqbk69E\nCE4AniZFP7PQkOZCbBY+6hZ2gMpNIJTn\n=HqAf\n-----END PGP SIGNATURE-----\n"},{"id":"215674","messageId":"CAMP44s30zWa6qU9CPJ4eL5KHZ0kST7UL8y6Xk_Yqk00-Gr2AqQ@mail.gmail.com","threadId":"32595","inReplyTo":"5176A7E4.2070608@gmail.com","subject":"Re: [PATCH v5] git-completion.bash: add support for path completion","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-04-27T02:52:07Z","receivedAt":"2013-04-27T02:52:07Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Tue, Apr 23, 2013 at 10:25 AM, Manlio Perillo\n<manlio.perillo@gmail.com> wrote:\n> -----BEGIN PGP SIGNED MESSAGE-----\n> Hash: SHA1\n>\n> Il 21/04/2013 12:14, Felipe Contreras ha scritto:\n>> On Fri, Jan 11, 2013 at 12:48 PM, Manlio Perillo\n>> <manlio.perillo@gmail.com> wrote:\n>>> The git-completion.bash script did not implemented full, git aware,\n>>> support to complete paths, for git commands that operate on files within\n>>> the current working directory or the index.\n>>\n>>> +__git_index_file_list_filter_compat ()\n>>> +{\n>>> +       local path\n>>> +\n>>> +       while read -r path; do\n>>> +               case \"$path\" in\n>>> +               ?*/*) echo \"${path%%/*}/\" ;;\n>>> +               *) echo \"$path\" ;;\n>>> +               esac\n>>> +       done\n>>> +}\n>>> +\n>>> +__git_index_file_list_filter_bash ()\n>>> +{\n>>> +       local path\n>>> +\n>>> +       while read -r path; do\n>>> +               case \"$path\" in\n>>> +               ?*/*)\n>>> +                       # XXX if we append a slash to directory names when using\n>>> +                       # `compopt -o filenames`, Bash will append another slash.\n>>> +                       # This is pretty stupid, and this the reason why we have to\n>>> +                       # define a compatible version for this function.\n>>> +                       echo \"${path%%/*}\" ;;\n>>\n>> Which version of bash is that? It works perfectly fine here with or\n>> without the /.\n>>\n>\n> GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)\n> on a GNU Linux Debian 6\n\nI compiled 4.1 and I can't reproduce, and I tried on a debian squeeze\nchroot and I also can't reproduce. What am I missing?\n\nGNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)\n\n>>> +# __git_index_files accepts 1 or 2 arguments:\n>>> +# 1: Options to pass to ls-files (required).\n>>> +#    Supported options are --cached, --modified, --deleted, --others,\n>>> +#    and --directory.\n>>> +# 2: A directory path (optional).\n>>> +#    If provided, only files within the specified directory are listed.\n>>> +#    Sub directories are never recursed.  Path must have a trailing\n>>> +#    slash.\n>>> +__git_index_files ()\n>>> +{\n>>> +       local dir=\"$(__gitdir)\" root=\"${2-.}\"\n>>> +\n>>> +       if [ -d \"$dir\" ]; then\n>>> +               __git_ls_files_helper \"$root\" \"$1\" | __git_index_file_list_filter |\n>>> +                       sort | uniq\n>>> +       fi\n>>> +}\n>>> +\n>>> +# __git_diff_index_files accepts 1 or 2 arguments:\n>>> +# 1) The id of a tree object.\n>>> +# 2) A directory path (optional).\n>>> +#    If provided, only files within the specified directory are listed.\n>>> +#    Sub directories are never recursed.  Path must have a trailing\n>>> +#    slash.\n>>> +__git_diff_index_files ()\n>>> +{\n>>> +       local dir=\"$(__gitdir)\" root=\"${2-.}\"\n>>> +\n>>> +       if [ -d \"$dir\" ]; then\n>>> +               __git_diff_index_helper \"$root\" \"$1\" | __git_index_file_list_filter |\n>>> +                       sort | uniq\n>>> +       fi\n>>> +}\n>>\n>> These two are exactly the same, except one calls\n>> __git_ls_files_helper, and the other one __git_diff_index_helper,\n>> can't we make another argument that is and select one or the other\n>> based on that?\n>>\n>\n> They are not exactly the same.\n>\n> The first function requires, as first parameter, (space separed) options\n> to pass to ls-files command; the second function, instead, requires the\n> id of a tree object.\n>\n> IMHO, using only one function may be confusing.\n\nThe functions down in the call-stack might be doing something\ndifferent but these functions themselves are not. At the end of the\nday they simply pass arguments to ls-files or diff-index.\n\nI'm certain these can be simplified greatly.\n\nCheers.\n\n-- \nFelipe Contreras\n"}]}