{"thread":{"id":"57958","subject":"[PATCH] ls-files.c: add --only-object-name option","startedAt":"2022-06-06T10:01:25Z","lastAt":"2022-06-13T19:24:16Z","messageCount":8,"participants":["ZheNing Hu via GitGitGadget","Ævar Arnfjörð Bjarmason","ZheNing Hu","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"456708","messageId":"pull.1250.git.1654509678718.gitgitgadget@gmail.com","threadId":"57958","inReplyTo":null,"subject":"[PATCH] ls-files.c: add --only-object-name option","fromName":"ZheNing Hu via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-06-06T10:01:18Z","receivedAt":"2022-06-06T10:01:25Z","isPatch":true,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"From: ZheNing Hu <adlternative@gmail.com>\n\n`git ls-files --stage` default output format is:\n\n[<tag> ]<mode> <object> <stage> <file>\n\nsometime we want to find a path's corresponding objectname,\nwe will parse the output and extract objectname from it\nagain and again.\n\nSo introduce a new option `--only-object-name` which can only\noutput objectname when giving `--stage` or `--resolve-undo`.\n\nSigned-off-by: ZheNing Hu <adlternative@gmail.com>\n---\n    ls-files.c: add --only-object-name option\n    \n    Something we want to extract objectname from git ls-files --stage, but\n    git ls-file don't support something like --format=%(objectname) (which\n    git ls-tree have implemented)\n    \n    So now add a new option --only-object-name which can only output\n    objectname.\n    \n    (Maybe we should add something like git ls-files --format ?)\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1250%2Fadlternative%2Fzh%2Fls-file-only-objectname-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1250/adlternative/zh/ls-file-only-objectname-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/1250\n\n Documentation/git-ls-files.txt |  6 +++++-\n builtin/ls-files.c             | 18 +++++++++++++++++-\n t/t2030-unresolve-info.sh      | 33 +++++++++++++++++++++++++++++++++\n t/t3004-ls-files-basic.sh      | 32 ++++++++++++++++++++++++++++++++\n 4 files changed, 87 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt\nindex 0dabf3f0ddc..0e3f4f094f3 100644\n--- a/Documentation/git-ls-files.txt\n+++ b/Documentation/git-ls-files.txt\n@@ -13,7 +13,7 @@ SYNOPSIS\n \t\t[-c|--cached] [-d|--deleted] [-o|--others] [-i|--|ignored]\n \t\t[-s|--stage] [-u|--unmerged] [-k|--|killed] [-m|--modified]\n \t\t[--directory [--no-empty-directory]] [--eol]\n-\t\t[--deduplicate]\n+\t\t[--deduplicate] [--only-object-name]\n \t\t[-x <pattern>|--exclude=<pattern>]\n \t\t[-X <file>|--exclude-from=<file>]\n \t\t[--exclude-per-directory=<file>]\n@@ -88,6 +88,10 @@ OPTIONS\n \tWhen any of the `-t`, `--unmerged`, or `--stage` option is\n \tin use, this option has no effect.\n \n+--only-object-name:\n+\tWhen giving `--stage` or `--resolve-undo` , only output `<object>`\n+\tinstead of `[<tag> ]<mode> <object> <stage> <file>` format.\n+\n -x <pattern>::\n --exclude=<pattern>::\n \tSkip untracked files matching pattern.\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex e791b65e7e9..fd9c10e9f94 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -26,6 +26,7 @@ static int show_deleted;\n static int show_cached;\n static int show_others;\n static int show_stage;\n+static int only_object_name;\n static int show_unmerged;\n static int show_resolve_undo;\n static int show_modified;\n@@ -241,10 +242,15 @@ static void show_ce(struct repository *repo, struct dir_struct *dir,\n \t\tif (!show_stage) {\n \t\t\tfputs(tag, stdout);\n \t\t} else {\n+\t\t\tconst char *object_name = repo_find_unique_abbrev(repo, &ce->oid, abbrev);\n+\t\t\tif (only_object_name) {\n+\t\t\t\tprintf(\"%s%c\", object_name, line_terminator);\n+\t\t\t\treturn;\n+\t\t\t}\n \t\t\tprintf(\"%s%06o %s %d\\t\",\n \t\t\t       tag,\n \t\t\t       ce->ce_mode,\n-\t\t\t       repo_find_unique_abbrev(repo, &ce->oid, abbrev),\n+\t\t\t       object_name,\n \t\t\t       ce_stage(ce));\n \t\t}\n \t\twrite_eolinfo(repo->index, ce, fullname);\n@@ -274,6 +280,10 @@ static void show_ru_info(struct index_state *istate)\n \t\tfor (i = 0; i < 3; i++) {\n \t\t\tif (!ui->mode[i])\n \t\t\t\tcontinue;\n+\t\t\tif (only_object_name) {\n+\t\t\t\tprintf(\"%s%c\", find_unique_abbrev(&ui->oid[i], abbrev), line_terminator);\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tprintf(\"%s%06o %s %d\\t\", tag_resolve_undo, ui->mode[i],\n \t\t\t       find_unique_abbrev(&ui->oid[i], abbrev),\n \t\t\t       i + 1);\n@@ -635,6 +645,8 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)\n \t\t\tDIR_SHOW_IGNORED),\n \t\tOPT_BOOL('s', \"stage\", &show_stage,\n \t\t\tN_(\"show staged contents' object name in the output\")),\n+\t\tOPT_BOOL(0, \"only-object-name\", &only_object_name,\n+\t\t\tN_(\"only show staged contents' object name in the output\")),\n \t\tOPT_BOOL('k', \"killed\", &show_killed,\n \t\t\tN_(\"show files on the filesystem that need to be removed\")),\n \t\tOPT_BIT(0, \"directory\", &dir.flags,\n@@ -734,6 +746,10 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)\n \t\tdie(\"ls-files --recurse-submodules does not support \"\n \t\t    \"--error-unmatch\");\n \n+\tif (only_object_name && !show_stage && !show_resolve_undo)\n+\t\tdie(\"ls-files --only-object-name only used with --stage \"\n+\t\t    \"or --resolve-undo\");\n+\n \tparse_pathspec(&pathspec, 0,\n \t\t       PATHSPEC_PREFER_CWD,\n \t\t       prefix, argv);\ndiff --git a/t/t2030-unresolve-info.sh b/t/t2030-unresolve-info.sh\nindex f691e6d9032..d940226c5f9 100755\n--- a/t/t2030-unresolve-info.sh\n+++ b/t/t2030-unresolve-info.sh\n@@ -32,6 +32,31 @@ check_resolve_undo () {\n \ttest_cmp \"$msg.expect\" \"$msg.actual\"\n }\n \n+check_resolve_undo_only_object_name() {\n+\tmsg=$1\n+\tshift\n+\twhile case $# in\n+\t0)\tbreak ;;\n+\t1|2|3)\tdie \"Bug in check-resolve-undo test\" ;;\n+\tesac\n+\tdo\n+\t\tpath=$1\n+\t\tshift\n+\t\tfor stage in 1 2 3\n+\t\tdo\n+\t\t\tsha1=$1\n+\t\t\tshift\n+\t\t\tcase \"$sha1\" in\n+\t\t\t'') continue ;;\n+\t\t\tesac\n+\t\t\tsha1=$(git rev-parse --verify \"$sha1\")\n+\t\t\tprintf \"%s\\n\" $sha1\n+\t\tdone\n+\tdone >\"$msg.expect\" &&\n+\tgit ls-files --resolve-undo --only-object-name >\"$msg.actual\" &&\n+\ttest_cmp \"$msg.expect\" \"$msg.actual\"\n+}\n+\n prime_resolve_undo () {\n \tgit reset --hard &&\n \tgit checkout second^0 &&\n@@ -194,4 +219,12 @@ test_expect_success 'rerere forget (add-add conflict)' '\n \ttest_i18ngrep \"no remembered\" actual\n '\n \n+test_expect_success '--resolve-undo with --only-object-name' '\n+\tprime_resolve_undo &&\n+\tcheck_resolve_undo_only_object_name kept fi/le initial:fi/le second:fi/le third:fi/le &&\n+\tgit checkout second^0 &&\n+\techo switching clears &&\n+\tcheck_resolve_undo cleared\n+'\n+\n test_done\ndiff --git a/t/t3004-ls-files-basic.sh b/t/t3004-ls-files-basic.sh\nindex a16e25c79bd..e42f6e7e548 100755\n--- a/t/t3004-ls-files-basic.sh\n+++ b/t/t3004-ls-files-basic.sh\n@@ -52,4 +52,36 @@ test_expect_success SYMLINKS 'ls-files with absolute paths to symlinks' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'git ls-files --stage with --only-object-name' '\n+\tgit init test &&\n+\ttest_when_finished \"rm -rf test\" &&\n+\t(\n+\t\tcd test &&\n+\t\techo a >a.txt &&\n+\t\techo b >b.txt &&\n+\t\tgit add a.txt b.txt &&\n+\t\toid1=$(git hash-object a.txt) &&\n+\t\toid2=$(git hash-object b.txt) &&\n+\t\tgit ls-files --stage --only-object-name >actual &&\n+\t\tcat >expect <<-EOF &&\n+\t\t$oid1\n+\t\t$oid2\n+\t\tEOF\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n+test_expect_success 'git ls-files --only-object-name without --stage or --resolve-undo' '\n+\tgit init test &&\n+\ttest_when_finished \"rm -rf test\" &&\n+\t(\n+\t\tcd test &&\n+\t\techo a >a.txt &&\n+\t\techo b >b.txt &&\n+\t\tgit add a.txt b.txt &&\n+\t\ttest_must_fail git ls-files --only-object-name 2>stderr &&\n+\t\ttest_i18ngrep \"fatal: ls-files --only-object-name only used with --stage or --resolve-undo\" stderr\n+\t)\n+'\n+\n test_done\n\nbase-commit: ab336e8f1c8009c8b1aab8deb592148e69217085\n-- \ngitgitgadget\n"},{"id":"456734","messageId":"220606.86zgipvg7e.gmgdl@evledraar.gmail.com","threadId":"57958","inReplyTo":"pull.1250.git.1654509678718.gitgitgadget@gmail.com","subject":"Re: [PATCH] ls-files.c: add --only-object-name option","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2022-06-06T17:42:33Z","receivedAt":"2022-06-06T17:45:44Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Mon, Jun 06 2022, ZheNing Hu via GitGitGadget wrote:\n\n> From: ZheNing Hu <adlternative@gmail.com>\n>\n> `git ls-files --stage` default output format is:\n>\n> [<tag> ]<mode> <object> <stage> <file>\n>\n> sometime we want to find a path's corresponding objectname,\n> we will parse the output and extract objectname from it\n> again and again.\n>\n> So introduce a new option `--only-object-name` which can only\n> output objectname when giving `--stage` or `--resolve-undo`.\n>\n> Signed-off-by: ZheNing Hu <adlternative@gmail.com>\n> ---\n>     ls-files.c: add --only-object-name option\n>     \n>     Something we want to extract objectname from git ls-files --stage, but\n>     git ls-file don't support something like --format=%(objectname) (which\n>     git ls-tree have implemented)\n>     \n>     So now add a new option --only-object-name which can only output\n>     objectname.\n>     \n>     (Maybe we should add something like git ls-files --format ?)\n\nYes I think that would be very useful, especially if we could see if\nsome of the code could be shared (maybe not).\n\nBut in any case shouldn't this be called --name-only to go with \"git\nls-tree\"'s version of this? Or is there some subtle difference I'm\nmissing...?\n\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1250%2Fadlternative%2Fzh%2Fls-file-only-objectname-v1\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1250/adlternative/zh/ls-file-only-objectname-v1\n> Pull-Request: https://github.com/gitgitgadget/git/pull/1250\n>\n>  Documentation/git-ls-files.txt |  6 +++++-\n>  builtin/ls-files.c             | 18 +++++++++++++++++-\n>  t/t2030-unresolve-info.sh      | 33 +++++++++++++++++++++++++++++++++\n>  t/t3004-ls-files-basic.sh      | 32 ++++++++++++++++++++++++++++++++\n>  4 files changed, 87 insertions(+), 2 deletions(-)\n>\n> diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt\n> index 0dabf3f0ddc..0e3f4f094f3 100644\n> --- a/Documentation/git-ls-files.txt\n> +++ b/Documentation/git-ls-files.txt\n> @@ -13,7 +13,7 @@ SYNOPSIS\n>  \t\t[-c|--cached] [-d|--deleted] [-o|--others] [-i|--|ignored]\n>  \t\t[-s|--stage] [-u|--unmerged] [-k|--|killed] [-m|--modified]\n>  \t\t[--directory [--no-empty-directory]] [--eol]\n> -\t\t[--deduplicate]\n> +\t\t[--deduplicate] [--only-object-name]\n>  \t\t[-x <pattern>|--exclude=<pattern>]\n>  \t\t[-X <file>|--exclude-from=<file>]\n>  \t\t[--exclude-per-directory=<file>]\n> @@ -88,6 +88,10 @@ OPTIONS\n>  \tWhen any of the `-t`, `--unmerged`, or `--stage` option is\n>  \tin use, this option has no effect.\n>  \n> +--only-object-name:\n> +\tWhen giving `--stage` or `--resolve-undo` , only output `<object>`\n> +\tinstead of `[<tag> ]<mode> <object> <stage> <file>` format.\n> +\n>  -x <pattern>::\n>  --exclude=<pattern>::\n>  \tSkip untracked files matching pattern.\n> diff --git a/builtin/ls-files.c b/builtin/ls-files.c\n> index e791b65e7e9..fd9c10e9f94 100644\n> --- a/builtin/ls-files.c\n> +++ b/builtin/ls-files.c\n> @@ -26,6 +26,7 @@ static int show_deleted;\n>  static int show_cached;\n>  static int show_others;\n>  static int show_stage;\n> +static int only_object_name;\n>  static int show_unmerged;\n>  static int show_resolve_undo;\n>  static int show_modified;\n> @@ -241,10 +242,15 @@ static void show_ce(struct repository *repo, struct dir_struct *dir,\n>  \t\tif (!show_stage) {\n>  \t\t\tfputs(tag, stdout);\n>  \t\t} else {\n> +\t\t\tconst char *object_name = repo_find_unique_abbrev(repo, &ce->oid, abbrev);\n> +\t\t\tif (only_object_name) {\n> +\t\t\t\tprintf(\"%s%c\", object_name, line_terminator);\n> +\t\t\t\treturn;\n> +\t\t\t}\n>  \t\t\tprintf(\"%s%06o %s %d\\t\",\n>  \t\t\t       tag,\n>  \t\t\t       ce->ce_mode,\n> -\t\t\t       repo_find_unique_abbrev(repo, &ce->oid, abbrev),\n> +\t\t\t       object_name,\n>  \t\t\t       ce_stage(ce));\n>  \t\t}\n>  \t\twrite_eolinfo(repo->index, ce, fullname);\n> @@ -274,6 +280,10 @@ static void show_ru_info(struct index_state *istate)\n>  \t\tfor (i = 0; i < 3; i++) {\n>  \t\t\tif (!ui->mode[i])\n>  \t\t\t\tcontinue;\n> +\t\t\tif (only_object_name) {\n> +\t\t\t\tprintf(\"%s%c\", find_unique_abbrev(&ui->oid[i], abbrev), line_terminator);\n> +\t\t\t\tcontinue;\n> +\t\t\t}\n>  \t\t\tprintf(\"%s%06o %s %d\\t\", tag_resolve_undo, ui->mode[i],\n>  \t\t\t       find_unique_abbrev(&ui->oid[i], abbrev),\n>  \t\t\t       i + 1);\n> @@ -635,6 +645,8 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)\n>  \t\t\tDIR_SHOW_IGNORED),\n>  \t\tOPT_BOOL('s', \"stage\", &show_stage,\n>  \t\t\tN_(\"show staged contents' object name in the output\")),\n> +\t\tOPT_BOOL(0, \"only-object-name\", &only_object_name,\n> +\t\t\tN_(\"only show staged contents' object name in the output\")),\n>  \t\tOPT_BOOL('k', \"killed\", &show_killed,\n>  \t\t\tN_(\"show files on the filesystem that need to be removed\")),\n>  \t\tOPT_BIT(0, \"directory\", &dir.flags,\n> @@ -734,6 +746,10 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)\n>  \t\tdie(\"ls-files --recurse-submodules does not support \"\n>  \t\t    \"--error-unmatch\");\n>  \n> +\tif (only_object_name && !show_stage && !show_resolve_undo)\n> +\t\tdie(\"ls-files --only-object-name only used with --stage \"\n> +\t\t    \"or --resolve-undo\");\n\nmissing _().\n\n> +\n>  \tparse_pathspec(&pathspec, 0,\n>  \t\t       PATHSPEC_PREFER_CWD,\n>  \t\t       prefix, argv);\n> diff --git a/t/t2030-unresolve-info.sh b/t/t2030-unresolve-info.sh\n> index f691e6d9032..d940226c5f9 100755\n> --- a/t/t2030-unresolve-info.sh\n> +++ b/t/t2030-unresolve-info.sh\n> @@ -32,6 +32,31 @@ check_resolve_undo () {\n>  \ttest_cmp \"$msg.expect\" \"$msg.actual\"\n>  }\n>  \n> +check_resolve_undo_only_object_name() {\n> +\tmsg=$1\n> +\tshift\n> +\twhile case $# in\n> +\t0)\tbreak ;;\n> +\t1|2|3)\tdie \"Bug in check-resolve-undo test\" ;;\n\nUse the \"BUG\"  helper in thaht case.\n> +\tesac\n> +\tdo\n> +\t\tpath=$1\n> +\t\tshift\n> +\t\tfor stage in 1 2 3\n> +\t\tdo\n> +\t\t\tsha1=$1\n> +\t\t\tshift\n> +\t\t\tcase \"$sha1\" in\n> +\t\t\t'') continue ;;\n> +\t\t\tesac\n> +\t\t\tsha1=$(git rev-parse --verify \"$sha1\")\n\nmissing && here when invoking \"git\".\n\n> +test_expect_success 'git ls-files --stage with --only-object-name' '\n> +\tgit init test &&\n> +\ttest_when_finished \"rm -rf test\" &&\n\nFWIW you can do all the below with -C to relevant commands and skip the\nsub-shell.\n\n> +\t(\n> +\t\tcd test &&\n> +\t\techo a >a.txt &&\n> +\t\techo b >b.txt &&\n> +\t\tgit add a.txt b.txt &&\n> +\t\toid1=$(git hash-object a.txt) &&\n> +\t\toid2=$(git hash-object b.txt) &&\n> +\t\tgit ls-files --stage --only-object-name >actual &&\n> +\t\tcat >expect <<-EOF &&\n> +\t\t$oid1\n> +\t\t$oid2\n> +\t\tEOF\n> +\t\ttest_cmp expect actual\n> +\t)\n> +'\n> +\n> +test_expect_success 'git ls-files --only-object-name without --stage or --resolve-undo' '\n> +\tgit init test &&\n> +\ttest_when_finished \"rm -rf test\" &&\n> +\t(\n> +\t\tcd test &&\n> +\t\techo a >a.txt &&\n> +\t\techo b >b.txt &&\n> +\t\tgit add a.txt b.txt &&\n> +\t\ttest_must_fail git ls-files --only-object-name 2>stderr &&\n> +\t\ttest_i18ngrep \"fatal: ls-files --only-object-name only used with --stage or --resolve-undo\" stderr\n\nuse \"grep\", not \"test_i18ngrep\".\n"},{"id":"456864","messageId":"CAOLTT8Sz3q2db1fRcHp7Exnarw4sMCnUfAF6bot+pwYxmXJjiw@mail.gmail.com","threadId":"57958","inReplyTo":"220606.86zgipvg7e.gmgdl@evledraar.gmail.com","subject":"Re: [PATCH] ls-files.c: add --only-object-name option","fromName":"ZheNing Hu","fromEmail":"adlternative@gmail.com","sentAt":"2022-06-08T14:38:47Z","receivedAt":"2022-06-08T14:39:07Z","isPatch":true,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> 于2022年6月7日周二 01:45写道：\n>\n>\n> On Mon, Jun 06 2022, ZheNing Hu via GitGitGadget wrote:\n>\n> > From: ZheNing Hu <adlternative@gmail.com>\n> >\n> > `git ls-files --stage` default output format is:\n> >\n> > [<tag> ]<mode> <object> <stage> <file>\n> >\n> > sometime we want to find a path's corresponding objectname,\n> > we will parse the output and extract objectname from it\n> > again and again.\n> >\n> > So introduce a new option `--only-object-name` which can only\n> > output objectname when giving `--stage` or `--resolve-undo`.\n> >\n> > Signed-off-by: ZheNing Hu <adlternative@gmail.com>\n> > ---\n> >     ls-files.c: add --only-object-name option\n> >\n> >     Something we want to extract objectname from git ls-files --stage, but\n> >     git ls-file don't support something like --format=%(objectname) (which\n> >     git ls-tree have implemented)\n> >\n> >     So now add a new option --only-object-name which can only output\n> >     objectname.\n> >\n> >     (Maybe we should add something like git ls-files --format ?)\n>\n> Yes I think that would be very useful, especially if we could see if\n> some of the code could be shared (maybe not).\n>\n\nMaybe I can try to implement it :-)\n\n> But in any case shouldn't this be called --name-only to go with \"git\n> ls-tree\"'s version of this? Or is there some subtle difference I'm\n> missing...?\n>\n\nEh, git ls-tree --name-only will only show file paths, so maybe\n--only-object-name\nwill be better than --object-name-only in git ls-files.\n\n> > +check_resolve_undo_only_object_name() {\n> > +     msg=$1\n> > +     shift\n> > +     while case $# in\n> > +     0)      break ;;\n> > +     1|2|3)  die \"Bug in check-resolve-undo test\" ;;\n>\n> Use the \"BUG\"  helper in thaht case.\n> > +     esac\n> > +     do\n> > +             path=$1\n> > +             shift\n> > +             for stage in 1 2 3\n> > +             do\n> > +                     sha1=$1\n> > +                     shift\n> > +                     case \"$sha1\" in\n> > +                     '') continue ;;\n> > +                     esac\n> > +                     sha1=$(git rev-parse --verify \"$sha1\")\n>\n> missing && here when invoking \"git\".\n>\n\nSorry, but this function check_resolve_undo_only_object_name() is\njust a mock version of check_resolve_undo(), so maybe I should fix\nthis function first?\n"},{"id":"456871","messageId":"xmqq7d5rrvbf.fsf@gitster.g","threadId":"57958","inReplyTo":"CAOLTT8Sz3q2db1fRcHp7Exnarw4sMCnUfAF6bot+pwYxmXJjiw@mail.gmail.com","subject":"Re: [PATCH] ls-files.c: add --only-object-name option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-06-08T16:09:24Z","receivedAt":"2022-06-08T16:09:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"ZheNing Hu <adlternative@gmail.com> writes:\n\n>> But in any case shouldn't this be called --name-only to go with \"git\n>> ls-tree\"'s version of this? Or is there some subtle difference I'm\n>> missing...?\n>\n> Eh, git ls-tree --name-only will only show file paths, so maybe\n> --only-object-name will be better than --object-name-only in git\n> ls-files.\n\nYeah, it is not \"--name-only\" which is about paths, but\n\"--object-name-only\" would be more correct but it is a tad long.\n\nI think ls-tree learned \"--object-only\" for that fairly recently.\nWhen in doubt, always check the documentation of a similar command\nfor inspiration.\n\nThanks.\n"},{"id":"456938","messageId":"pull.1250.v2.git.1654778272871.gitgitgadget@gmail.com","threadId":"57958","inReplyTo":"pull.1250.git.1654509678718.gitgitgadget@gmail.com","subject":"[PATCH v2] ls-files.c: add --object-only option","fromName":"ZheNing Hu via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2022-06-09T12:37:52Z","receivedAt":"2022-06-09T12:38:19Z","isPatch":true,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"From: ZheNing Hu <adlternative@gmail.com>\n\n`git ls-files --stage` default output format is:\n\n[<tag> ]<mode> <object> <stage> <file>\n\nsometime we want to find a path's corresponding objectname,\nwe will parse the output and extract objectname from it\nagain and again.\n\nSo introduce a new option `--object-only` which can only\noutput objectname when giving `--stage` or `--resolve-undo`.\n\nSigned-off-by: ZheNing Hu <adlternative@gmail.com>\n---\n    ls-files.c: add --object-only option\n    \n    v1 -> v2: rename option '--only-object-name' to '--object-only'.\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1250%2Fadlternative%2Fzh%2Fls-file-only-objectname-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1250/adlternative/zh/ls-file-only-objectname-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/1250\n\nRange-diff vs v1:\n\n 1:  10efe3bd9ca ! 1:  aed0bd2c791 ls-files.c: add --only-object-name option\n     @@ Metadata\n      Author: ZheNing Hu <adlternative@gmail.com>\n      \n       ## Commit message ##\n     -    ls-files.c: add --only-object-name option\n     +    ls-files.c: add --object-only option\n      \n          `git ls-files --stage` default output format is:\n      \n     @@ Commit message\n          we will parse the output and extract objectname from it\n          again and again.\n      \n     -    So introduce a new option `--only-object-name` which can only\n     +    So introduce a new option `--object-only` which can only\n          output objectname when giving `--stage` or `--resolve-undo`.\n      \n          Signed-off-by: ZheNing Hu <adlternative@gmail.com>\n     @@ Documentation/git-ls-files.txt: SYNOPSIS\n       \t\t[-s|--stage] [-u|--unmerged] [-k|--|killed] [-m|--modified]\n       \t\t[--directory [--no-empty-directory]] [--eol]\n      -\t\t[--deduplicate]\n     -+\t\t[--deduplicate] [--only-object-name]\n     ++\t\t[--deduplicate] [--object-only]\n       \t\t[-x <pattern>|--exclude=<pattern>]\n       \t\t[-X <file>|--exclude-from=<file>]\n       \t\t[--exclude-per-directory=<file>]\n     @@ Documentation/git-ls-files.txt: OPTIONS\n       \tWhen any of the `-t`, `--unmerged`, or `--stage` option is\n       \tin use, this option has no effect.\n       \n     -+--only-object-name:\n     ++--object-only:\n      +\tWhen giving `--stage` or `--resolve-undo` , only output `<object>`\n      +\tinstead of `[<tag> ]<mode> <object> <stage> <file>` format.\n      +\n     @@ builtin/ls-files.c: static int show_deleted;\n       static int show_cached;\n       static int show_others;\n       static int show_stage;\n     -+static int only_object_name;\n     ++static int object_only;\n       static int show_unmerged;\n       static int show_resolve_undo;\n       static int show_modified;\n     @@ builtin/ls-files.c: static void show_ce(struct repository *repo, struct dir_stru\n       \t\t\tfputs(tag, stdout);\n       \t\t} else {\n      +\t\t\tconst char *object_name = repo_find_unique_abbrev(repo, &ce->oid, abbrev);\n     -+\t\t\tif (only_object_name) {\n     ++\t\t\tif (object_only) {\n      +\t\t\t\tprintf(\"%s%c\", object_name, line_terminator);\n      +\t\t\t\treturn;\n      +\t\t\t}\n     @@ builtin/ls-files.c: static void show_ru_info(struct index_state *istate)\n       \t\tfor (i = 0; i < 3; i++) {\n       \t\t\tif (!ui->mode[i])\n       \t\t\t\tcontinue;\n     -+\t\t\tif (only_object_name) {\n     ++\t\t\tif (object_only) {\n      +\t\t\t\tprintf(\"%s%c\", find_unique_abbrev(&ui->oid[i], abbrev), line_terminator);\n      +\t\t\t\tcontinue;\n      +\t\t\t}\n     @@ builtin/ls-files.c: int cmd_ls_files(int argc, const char **argv, const char *cm\n       \t\t\tDIR_SHOW_IGNORED),\n       \t\tOPT_BOOL('s', \"stage\", &show_stage,\n       \t\t\tN_(\"show staged contents' object name in the output\")),\n     -+\t\tOPT_BOOL(0, \"only-object-name\", &only_object_name,\n     ++\t\tOPT_BOOL(0, \"object-only\", &object_only,\n      +\t\t\tN_(\"only show staged contents' object name in the output\")),\n       \t\tOPT_BOOL('k', \"killed\", &show_killed,\n       \t\t\tN_(\"show files on the filesystem that need to be removed\")),\n     @@ builtin/ls-files.c: int cmd_ls_files(int argc, const char **argv, const char *cm\n       \t\tdie(\"ls-files --recurse-submodules does not support \"\n       \t\t    \"--error-unmatch\");\n       \n     -+\tif (only_object_name && !show_stage && !show_resolve_undo)\n     -+\t\tdie(\"ls-files --only-object-name only used with --stage \"\n     -+\t\t    \"or --resolve-undo\");\n     ++\tif (object_only && !show_stage && !show_resolve_undo)\n     ++\t\tdie(_(\"ls-files --object-only only used with --stage \"\n     ++\t\t    \"or --resolve-undo\"));\n      +\n       \tparse_pathspec(&pathspec, 0,\n       \t\t       PATHSPEC_PREFER_CWD,\n     @@ t/t2030-unresolve-info.sh: check_resolve_undo () {\n       \ttest_cmp \"$msg.expect\" \"$msg.actual\"\n       }\n       \n     -+check_resolve_undo_only_object_name() {\n     ++check_resolve_undo_object_only() {\n      +\tmsg=$1\n      +\tshift\n      +\twhile case $# in\n      +\t0)\tbreak ;;\n     -+\t1|2|3)\tdie \"Bug in check-resolve-undo test\" ;;\n     ++\t1|2|3)\tBUG \"wrong arguments\" ;;\n      +\tesac\n      +\tdo\n      +\t\tpath=$1\n     @@ t/t2030-unresolve-info.sh: check_resolve_undo () {\n      +\t\t\tcase \"$sha1\" in\n      +\t\t\t'') continue ;;\n      +\t\t\tesac\n     -+\t\t\tsha1=$(git rev-parse --verify \"$sha1\")\n     ++\t\t\tsha1=$(git rev-parse --verify \"$sha1\") &&\n      +\t\t\tprintf \"%s\\n\" $sha1\n      +\t\tdone\n      +\tdone >\"$msg.expect\" &&\n     -+\tgit ls-files --resolve-undo --only-object-name >\"$msg.actual\" &&\n     ++\tgit ls-files --resolve-undo --object-only >\"$msg.actual\" &&\n      +\ttest_cmp \"$msg.expect\" \"$msg.actual\"\n      +}\n      +\n     @@ t/t2030-unresolve-info.sh: test_expect_success 'rerere forget (add-add conflict)\n       \ttest_i18ngrep \"no remembered\" actual\n       '\n       \n     -+test_expect_success '--resolve-undo with --only-object-name' '\n     ++test_expect_success '--resolve-undo with --object-only' '\n      +\tprime_resolve_undo &&\n     -+\tcheck_resolve_undo_only_object_name kept fi/le initial:fi/le second:fi/le third:fi/le &&\n     ++\tcheck_resolve_undo_object_only kept fi/le initial:fi/le second:fi/le third:fi/le &&\n      +\tgit checkout second^0 &&\n      +\techo switching clears &&\n      +\tcheck_resolve_undo cleared\n     @@ t/t3004-ls-files-basic.sh: test_expect_success SYMLINKS 'ls-files with absolute\n       \ttest_cmp expect actual\n       '\n       \n     -+test_expect_success 'git ls-files --stage with --only-object-name' '\n     ++test_expect_success 'git ls-files --stage with --object-only' '\n      +\tgit init test &&\n      +\ttest_when_finished \"rm -rf test\" &&\n     -+\t(\n     -+\t\tcd test &&\n     -+\t\techo a >a.txt &&\n     -+\t\techo b >b.txt &&\n     -+\t\tgit add a.txt b.txt &&\n     -+\t\toid1=$(git hash-object a.txt) &&\n     -+\t\toid2=$(git hash-object b.txt) &&\n     -+\t\tgit ls-files --stage --only-object-name >actual &&\n     -+\t\tcat >expect <<-EOF &&\n     -+\t\t$oid1\n     -+\t\t$oid2\n     -+\t\tEOF\n     -+\t\ttest_cmp expect actual\n     -+\t)\n     ++\techo a >test/a.txt &&\n     ++\techo b >test/b.txt &&\n     ++\tgit -C test add a.txt b.txt &&\n     ++\toid1=$(git -C test hash-object a.txt) &&\n     ++\toid2=$(git -C test hash-object b.txt) &&\n     ++\tgit -C test ls-files --stage --object-only >actual &&\n     ++\tcat >expect <<-EOF &&\n     ++\t$oid1\n     ++\t$oid2\n     ++\tEOF\n     ++\ttest_cmp expect actual\n      +'\n      +\n     -+test_expect_success 'git ls-files --only-object-name without --stage or --resolve-undo' '\n     ++test_expect_success 'git ls-files --object-only without --stage or --resolve-undo' '\n      +\tgit init test &&\n      +\ttest_when_finished \"rm -rf test\" &&\n     -+\t(\n     -+\t\tcd test &&\n     -+\t\techo a >a.txt &&\n     -+\t\techo b >b.txt &&\n     -+\t\tgit add a.txt b.txt &&\n     -+\t\ttest_must_fail git ls-files --only-object-name 2>stderr &&\n     -+\t\ttest_i18ngrep \"fatal: ls-files --only-object-name only used with --stage or --resolve-undo\" stderr\n     -+\t)\n     ++\techo a >test/a.txt &&\n     ++\techo b >test/b.txt &&\n     ++\tgit -C test add a.txt b.txt &&\n     ++\ttest_must_fail git -C test ls-files --object-only 2>stderr &&\n     ++\tgrep \"fatal: ls-files --object-only only used with --stage or --resolve-undo\" stderr\n      +'\n      +\n       test_done\n\n\n Documentation/git-ls-files.txt |  6 +++++-\n builtin/ls-files.c             | 18 +++++++++++++++++-\n t/t2030-unresolve-info.sh      | 33 +++++++++++++++++++++++++++++++++\n t/t3004-ls-files-basic.sh      | 26 ++++++++++++++++++++++++++\n 4 files changed, 81 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt\nindex 0dabf3f0ddc..9736b02b565 100644\n--- a/Documentation/git-ls-files.txt\n+++ b/Documentation/git-ls-files.txt\n@@ -13,7 +13,7 @@ SYNOPSIS\n \t\t[-c|--cached] [-d|--deleted] [-o|--others] [-i|--|ignored]\n \t\t[-s|--stage] [-u|--unmerged] [-k|--|killed] [-m|--modified]\n \t\t[--directory [--no-empty-directory]] [--eol]\n-\t\t[--deduplicate]\n+\t\t[--deduplicate] [--object-only]\n \t\t[-x <pattern>|--exclude=<pattern>]\n \t\t[-X <file>|--exclude-from=<file>]\n \t\t[--exclude-per-directory=<file>]\n@@ -88,6 +88,10 @@ OPTIONS\n \tWhen any of the `-t`, `--unmerged`, or `--stage` option is\n \tin use, this option has no effect.\n \n+--object-only:\n+\tWhen giving `--stage` or `--resolve-undo` , only output `<object>`\n+\tinstead of `[<tag> ]<mode> <object> <stage> <file>` format.\n+\n -x <pattern>::\n --exclude=<pattern>::\n \tSkip untracked files matching pattern.\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex e791b65e7e9..2fef5f40a3f 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -26,6 +26,7 @@ static int show_deleted;\n static int show_cached;\n static int show_others;\n static int show_stage;\n+static int object_only;\n static int show_unmerged;\n static int show_resolve_undo;\n static int show_modified;\n@@ -241,10 +242,15 @@ static void show_ce(struct repository *repo, struct dir_struct *dir,\n \t\tif (!show_stage) {\n \t\t\tfputs(tag, stdout);\n \t\t} else {\n+\t\t\tconst char *object_name = repo_find_unique_abbrev(repo, &ce->oid, abbrev);\n+\t\t\tif (object_only) {\n+\t\t\t\tprintf(\"%s%c\", object_name, line_terminator);\n+\t\t\t\treturn;\n+\t\t\t}\n \t\t\tprintf(\"%s%06o %s %d\\t\",\n \t\t\t       tag,\n \t\t\t       ce->ce_mode,\n-\t\t\t       repo_find_unique_abbrev(repo, &ce->oid, abbrev),\n+\t\t\t       object_name,\n \t\t\t       ce_stage(ce));\n \t\t}\n \t\twrite_eolinfo(repo->index, ce, fullname);\n@@ -274,6 +280,10 @@ static void show_ru_info(struct index_state *istate)\n \t\tfor (i = 0; i < 3; i++) {\n \t\t\tif (!ui->mode[i])\n \t\t\t\tcontinue;\n+\t\t\tif (object_only) {\n+\t\t\t\tprintf(\"%s%c\", find_unique_abbrev(&ui->oid[i], abbrev), line_terminator);\n+\t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tprintf(\"%s%06o %s %d\\t\", tag_resolve_undo, ui->mode[i],\n \t\t\t       find_unique_abbrev(&ui->oid[i], abbrev),\n \t\t\t       i + 1);\n@@ -635,6 +645,8 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)\n \t\t\tDIR_SHOW_IGNORED),\n \t\tOPT_BOOL('s', \"stage\", &show_stage,\n \t\t\tN_(\"show staged contents' object name in the output\")),\n+\t\tOPT_BOOL(0, \"object-only\", &object_only,\n+\t\t\tN_(\"only show staged contents' object name in the output\")),\n \t\tOPT_BOOL('k', \"killed\", &show_killed,\n \t\t\tN_(\"show files on the filesystem that need to be removed\")),\n \t\tOPT_BIT(0, \"directory\", &dir.flags,\n@@ -734,6 +746,10 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)\n \t\tdie(\"ls-files --recurse-submodules does not support \"\n \t\t    \"--error-unmatch\");\n \n+\tif (object_only && !show_stage && !show_resolve_undo)\n+\t\tdie(_(\"ls-files --object-only only used with --stage \"\n+\t\t    \"or --resolve-undo\"));\n+\n \tparse_pathspec(&pathspec, 0,\n \t\t       PATHSPEC_PREFER_CWD,\n \t\t       prefix, argv);\ndiff --git a/t/t2030-unresolve-info.sh b/t/t2030-unresolve-info.sh\nindex f691e6d9032..cdab953980c 100755\n--- a/t/t2030-unresolve-info.sh\n+++ b/t/t2030-unresolve-info.sh\n@@ -32,6 +32,31 @@ check_resolve_undo () {\n \ttest_cmp \"$msg.expect\" \"$msg.actual\"\n }\n \n+check_resolve_undo_object_only() {\n+\tmsg=$1\n+\tshift\n+\twhile case $# in\n+\t0)\tbreak ;;\n+\t1|2|3)\tBUG \"wrong arguments\" ;;\n+\tesac\n+\tdo\n+\t\tpath=$1\n+\t\tshift\n+\t\tfor stage in 1 2 3\n+\t\tdo\n+\t\t\tsha1=$1\n+\t\t\tshift\n+\t\t\tcase \"$sha1\" in\n+\t\t\t'') continue ;;\n+\t\t\tesac\n+\t\t\tsha1=$(git rev-parse --verify \"$sha1\") &&\n+\t\t\tprintf \"%s\\n\" $sha1\n+\t\tdone\n+\tdone >\"$msg.expect\" &&\n+\tgit ls-files --resolve-undo --object-only >\"$msg.actual\" &&\n+\ttest_cmp \"$msg.expect\" \"$msg.actual\"\n+}\n+\n prime_resolve_undo () {\n \tgit reset --hard &&\n \tgit checkout second^0 &&\n@@ -194,4 +219,12 @@ test_expect_success 'rerere forget (add-add conflict)' '\n \ttest_i18ngrep \"no remembered\" actual\n '\n \n+test_expect_success '--resolve-undo with --object-only' '\n+\tprime_resolve_undo &&\n+\tcheck_resolve_undo_object_only kept fi/le initial:fi/le second:fi/le third:fi/le &&\n+\tgit checkout second^0 &&\n+\techo switching clears &&\n+\tcheck_resolve_undo cleared\n+'\n+\n test_done\ndiff --git a/t/t3004-ls-files-basic.sh b/t/t3004-ls-files-basic.sh\nindex a16e25c79bd..6c81ead140e 100755\n--- a/t/t3004-ls-files-basic.sh\n+++ b/t/t3004-ls-files-basic.sh\n@@ -52,4 +52,30 @@ test_expect_success SYMLINKS 'ls-files with absolute paths to symlinks' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'git ls-files --stage with --object-only' '\n+\tgit init test &&\n+\ttest_when_finished \"rm -rf test\" &&\n+\techo a >test/a.txt &&\n+\techo b >test/b.txt &&\n+\tgit -C test add a.txt b.txt &&\n+\toid1=$(git -C test hash-object a.txt) &&\n+\toid2=$(git -C test hash-object b.txt) &&\n+\tgit -C test ls-files --stage --object-only >actual &&\n+\tcat >expect <<-EOF &&\n+\t$oid1\n+\t$oid2\n+\tEOF\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'git ls-files --object-only without --stage or --resolve-undo' '\n+\tgit init test &&\n+\ttest_when_finished \"rm -rf test\" &&\n+\techo a >test/a.txt &&\n+\techo b >test/b.txt &&\n+\tgit -C test add a.txt b.txt &&\n+\ttest_must_fail git -C test ls-files --object-only 2>stderr &&\n+\tgrep \"fatal: ls-files --object-only only used with --stage or --resolve-undo\" stderr\n+'\n+\n test_done\n\nbase-commit: ab336e8f1c8009c8b1aab8deb592148e69217085\n-- \ngitgitgadget\n"},{"id":"456962","messageId":"xmqq35gdk44i.fsf@gitster.g","threadId":"57958","inReplyTo":"pull.1250.v2.git.1654778272871.gitgitgadget@gmail.com","subject":"Re: [PATCH v2] ls-files.c: add --object-only option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-06-09T19:50:53Z","receivedAt":"2022-06-09T19:51:03Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"ZheNing Hu via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: ZheNing Hu <adlternative@gmail.com>\n>\n> `git ls-files --stage` default output format is:\n>\n> [<tag> ]<mode> <object> <stage> <file>\n>\n> sometime we want to find a path's corresponding objectname,\n\n\"sometime\" -> \"When\", perhaps.  If you really want to say that,\n\"Sometimes, \" is also good, though.\n\nBy the way, I do not think you are \"want to find a path's\ncorresponding objectname\" at all with this feature.  The output from\n\"ls-files -s\" will have many object names, one per each path if the\nindex is merged, and if you discard the path, you no longer can tell\nwhich object name corresponds to which path.\n\n> we will parse the output and extract objectname from it\n> again and again.\n\nWhy is that a problem?  \"again and again\" is over-exaggerating;\nyou'd munge each line just once.\n\nIt would help readers if you say WHY you want to find object names.\nPerhaps you want to find the set of objects that are registered in\nthe index, regardless of their paths?\n\nIn any case, the paragraph needs a rewrite.\n\n> So introduce a new option `--object-only` which can only\n> output objectname when giving `--stage` or `--resolve-undo`.\n\n\"which can only\" makes it sound like you are complaining about its\nlimitation.\n\nI read these two lines to mean \"git ls-files -s --object-only\" does\nnot even give me the stage information, but that would make the\ncommand completely useless, so I am assuming that is not what you\nmeant to say.  The same comment applies for resolve-undo, which is\nmerely \"what 'ls-files -s' may have given before you resolved\".\n\nIf you borrowed a feature from another existing command, say that\nexplicitly, which will allow your commit to gain confidence by\nreviewers and future readers by showing that you care about overall\nconsistency in the system.\n\n\tAdd a new option `--object-only` that omits the mode and\n\tfilename from the output, taking inspiration from the option\n\twith the same name in the `git ls-tree` command.\n\nor something like that, perhaps.\n\nHow does/should this interact with the `--deduplicate` option?\n\nIf we are not giving stages and truly giving only object names\n(which I doubt is what we want, by the way), then we can and should\ndeduplicate the output when the option is given.  If we have two\nidentical blobs at different paths, or two identical blobs at the\nsame path but at different stages, shouldn't we get only a single\ncopy of output for that blob, as we are not showing paths nor\nstages, right?\n\nHow does/should this behave when --stage is not given?\n\nI have a suspicion that this whole thing is misdesigned.  Instead of\nmaking it piggy back on --stage, don't you want to make it an\nindependent option?  I.e.\n\n\tgit ls-files --object-only\n\nwith no other option would behave like\n\n\tgit ls-files -s | sed -e 's/^[0-6]* \\([0-9a-f]*\\) .*/\\1/'\n\nand it is an error to combine it with -s or --deduplicate.  If the\npurpose is to learn the set of objects registered in the index, then\nit might even make sense to make it an equivalent to\n\n\tgit ls-files -s |\n\tsed -e 's/^[0-6]* \\([0-9a-f]*\\) .*/\\1/' |\n\tsort -u\n\nas duplicates or order of the entries is no use for such a use\ncase.  \n\nIt entirely depends on WHY you want to find object names, and that\nis why I asked it much earlier in this message.\n\nAnd I do not think it makes any sense to give resolve-undo\ninformation without paths nor stages at all.  Please do not tie this\nwith that mode.\n\nIn short\n\n - this probably is better done as a separate independent mode\n   \"--object-only\", rather than a piggy-back feature on top of\n    existing other features like \"-s\" and \"--resolve-undo\".\n\n - the new mode should be made mutually incompatible with \"-s\" and\n   \"--resolve-undo\".  There may be other options that this should be\n   incompatible, like \"--tag\" and \"--full-name\".\n\nThanks.\n"},{"id":"457087","messageId":"CAOLTT8SNOYYVmk3fvEc=Vp9MuRp+1H--wh72rP=ORRtffonUfQ@mail.gmail.com","threadId":"57958","inReplyTo":"xmqq35gdk44i.fsf@gitster.g","subject":"Re: [PATCH v2] ls-files.c: add --object-only option","fromName":"ZheNing Hu","fromEmail":"adlternative@gmail.com","sentAt":"2022-06-12T10:24:26Z","receivedAt":"2022-06-12T10:24:42Z","isPatch":true,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"Junio C Hamano <gitster@pobox.com> 于2022年6月10日周五 03:51写道：\n>\n> \"ZheNing Hu via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n>\n> > From: ZheNing Hu <adlternative@gmail.com>\n\n> I read these two lines to mean \"git ls-files -s --object-only\" does\n> not even give me the stage information, but that would make the\n> command completely useless, so I am assuming that is not what you\n> meant to say.  The same comment applies for resolve-undo, which is\n> merely \"what 'ls-files -s' may have given before you resolved\".\n>\n> If you borrowed a feature from another existing command, say that\n> explicitly, which will allow your commit to gain confidence by\n> reviewers and future readers by showing that you care about overall\n> consistency in the system.\n>\n>         Add a new option `--object-only` that omits the mode and\n>         filename from the output, taking inspiration from the option\n>         with the same name in the `git ls-tree` command.\n>\n> or something like that, perhaps.\n>\n\nYes, this message will be better. I think it omits not only mode,\nfilename, but also tag, stage, eol info, debug message.\n\n> How does/should this interact with the `--deduplicate` option?\n>\n> If we are not giving stages and truly giving only object names\n> (which I doubt is what we want, by the way), then we can and should\n> deduplicate the output when the option is given.  If we have two\n> identical blobs at different paths, or two identical blobs at the\n> same path but at different stages, shouldn't we get only a single\n> copy of output for that blob, as we are not showing paths nor\n> stages, right?\n>\n\nI have think about it for a long time, I think deduplicate is used for\nremoving duplicates entries which caused by one path can have\ndifferent stage.\n\nBut we now care about a output format just like %(objectname), if we\nneed to deduplicate it, when we use --format=\"%(objectname) %(path)\" later,\ndo we need to deduplicate its output too? I think we should disable\n--deduplicate\nwhen we are using --object-only.\n\n> How does/should this behave when --stage is not given?\n>\n> I have a suspicion that this whole thing is misdesigned.  Instead of\n> making it piggy back on --stage, don't you want to make it an\n> independent option?  I.e.\n>\n>         git ls-files --object-only\n>\n> with no other option would behave like\n>\n>         git ls-files -s | sed -e 's/^[0-6]* \\([0-9a-f]*\\) .*/\\1/'\n>\n> and it is an error to combine it with -s or --deduplicate.  If the\n> purpose is to learn the set of objects registered in the index, then\n> it might even make sense to make it an equivalent to\n>\n>         git ls-files -s |\n>         sed -e 's/^[0-6]* \\([0-9a-f]*\\) .*/\\1/' |\n>         sort -u\n>\n> as duplicates or order of the entries is no use for such a use\n> case.\n>\n> It entirely depends on WHY you want to find object names, and that\n> is why I asked it much earlier in this message.\n>\n\nMy origin requirement is to do a app which can move one file to another\nfile in a bare git-repo, so I need to get first file object-name for\nsecond file to\nupdate-index. It can parsed by the app of course, but I think such kind of work\nleft to git itself can help other app programers.\n\nMaybe you are right that --object-only or --format should not be\nsub-option of --stage\nor --resolve-undo, I will think about how to implement it later.\n\n> And I do not think it makes any sense to give resolve-undo\n> information without paths nor stages at all.  Please do not tie this\n> with that mode.\n>\n> In short\n>\n>  - this probably is better done as a separate independent mode\n>    \"--object-only\", rather than a piggy-back feature on top of\n>     existing other features like \"-s\" and \"--resolve-undo\".\n>\n>  - the new mode should be made mutually incompatible with \"-s\" and\n>    \"--resolve-undo\".  There may be other options that this should be\n>    incompatible, like \"--tag\" and \"--full-name\".\n>\n\nBy the way, if we need --format for git ls-files, which atoms should we keep?\n\nI think those atoms are undoubtedly necessary to keep\n\n%(tag)\n%(objectmode)\n%(objectname)\n%(stage)\n%(path)\n\ngit ls-files --stage just like\n\ngit ls-file --format=\"%(tag)%(obejctmode) %(objectname) %(stage)\\t%(path)\"\n\nbut for these follow atoms, I am not sure if we need them?\n\n%(eofinfo)\n%(debug)\n%(eol)\n%(ctime)\n%(ctime:sec)\n%(ctime:nsec)\n%(mtime)\n%(mtime:sec)\n%(mtime:nsec)\n%(dev)\n%(ino)\n%(uid)\n%(gid)\n%(size)\n%(flags)\n\nThanks\n"},{"id":"457110","messageId":"xmqqwndk7a7j.fsf@gitster.g","threadId":"57958","inReplyTo":"CAOLTT8SNOYYVmk3fvEc=Vp9MuRp+1H--wh72rP=ORRtffonUfQ@mail.gmail.com","subject":"Re: [PATCH v2] ls-files.c: add --object-only option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-06-13T17:19:12Z","receivedAt":"2022-06-13T19:24:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"ZheNing Hu <adlternative@gmail.com> writes:\n\n> I think those atoms are undoubtedly necessary to keep\n>\n> %(tag)\n> %(objectmode)\n> %(objectname)\n> %(stage)\n> %(path)\n\nI am not sure what you mean by \"keep\".  You cannot keep what you do\nnot have yet ;-)\n\nIf ls-files needs (that is a big if; it is a plumbing to be used by\nwhatever program that want to assemble the pieces, and it shouldn't\nhave to learn such assembly itself) to support \"--format\", so that\npeople can reinvent its \"-s\" output (but why?  There already is \"-s\"\noutput available), then the above would be necessary (assuming that\nvia the \"--format\" the user will be able to supply inter-field\nspaces and tabs properly).  I do not know if there are other things\navailable in output other than the \"-s\" option produces offhand, but\nif there are, they would need to be added for completeness.\n"}]}