{"thread":{"id":"61708","subject":"[PATCH 0/3] Add a Hook To git commit --message Bash Completion","startedAt":"2024-06-30T21:33:59Z","lastAt":"2024-06-30T22:12:54Z","messageCount":6,"participants":["Mikko Johannes Koivunalho","brian m. carlson"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"497863","messageId":"20240630213336.2212166-1-mikko.koivunalho@iki.fi","threadId":"61708","inReplyTo":null,"subject":"[PATCH 0/3] Add a Hook To git commit --message Bash Completion","fromName":"Mikko Johannes Koivunalho","fromEmail":"mikko.koivunalho@iki.fi","sentAt":"2024-06-30T21:33:33Z","receivedAt":"2024-06-30T21:33:59Z","isPatch":true,"sender":{"key":"mikko.koivunalho@iki.fi","avatar":"https://gravatar.com/avatar/37d422e492749d7a19604988d9e953c36b019283013261d7cb88095a6274ab67?d=mp&s=160"},"body":"I want to create part or all of the `git commit -m *` command's\nmessage with a script. I work for one Jira ticket at a time and I\nneed to create many commits which all start with \"TKT-123: \"\n(any Jira ticket number/identifier). To make the commits faster,\nI run `git commit --message=\"TKT-123: add new file\"` on the command\nline.\n\nI want the Bash completion mechanism to propose the message for\nme. I would fetch the newest ticket number and place it on the command\nline when I type `git commit --message=<TAB>`.\n\nExample:\n# Doing commit:\ngit commit --message=<TAB>\n# you would get (also without the closing double quote):\ngit commit --message=\"ABC-1234\n\n\nMikko Johannes Koivunalho (3):\n  completion: Add hook in Bash completion for commit message\n  completion: Add hook in Bash completion for commit message; docs\n  completion: Add hook in Bash completion for commit message; tests\n\n Documentation/config/completion.txt    | 11 +++++\n contrib/completion/git-completion.bash | 40 +++++++++++++++\n t/t9902-completion.sh                  | 68 ++++++++++++++++++++++++++\n 3 files changed, 119 insertions(+)\n\n\nbase-commit: 790a17fb19d6eadd16c52e5d284a5c6921744766\n-- \n2.30.2\n\n"},{"id":"497864","messageId":"20240630213336.2212166-3-mikko.koivunalho@iki.fi","threadId":"61708","inReplyTo":"20240630213336.2212166-1-mikko.koivunalho@iki.fi","subject":"[PATCH 2/3] completion: Add hook in Bash completion for commit message; docs","fromName":"Mikko Johannes Koivunalho","fromEmail":"mikko.koivunalho@iki.fi","sentAt":"2024-06-30T21:33:35Z","receivedAt":"2024-06-30T21:33:59Z","isPatch":true,"sender":{"key":"mikko.koivunalho@iki.fi","avatar":"https://gravatar.com/avatar/37d422e492749d7a19604988d9e953c36b019283013261d7cb88095a6274ab67?d=mp&s=160"},"body":"Signed-off-by: Mikko Johannes Koivunalho <mikko.koivunalho@iki.fi>\n---\n Documentation/config/completion.txt | 11 +++++++++++\n 1 file changed, 11 insertions(+)\n\ndiff --git a/Documentation/config/completion.txt b/Documentation/config/completion.txt\nindex 4d99bf33c9..5032eab5da 100644\n--- a/Documentation/config/completion.txt\n+++ b/Documentation/config/completion.txt\n@@ -5,3 +5,14 @@ completion.commands::\n \tcan add more commands, separated by space, in this\n \tvariable. Prefixing the command with '-' will remove it from\n \tthe existing list.\n+\n+completion.commitMessageCallback::\n+    This is only used by git-completion.bash for declaring an executable\n+    or a shell function which will be used when user types\n+    `git commit --message=` and then presses completion key (TAB).\n+    The callback must return one string for commit message.\n+    This can be used when all commit messages must have, for example,\n+    same prefix, e.g. a work order number.\n+    Instead of this configuration variable, environment variable\n+    GIT_COMPLETION_COMMIT_MESSAGE_CALLBACK can be used.\n+    Environment variable overrides the configuration variable.\n-- \n2.30.2\n\n"},{"id":"497865","messageId":"20240630213336.2212166-4-mikko.koivunalho@iki.fi","threadId":"61708","inReplyTo":"20240630213336.2212166-1-mikko.koivunalho@iki.fi","subject":"[PATCH 3/3] completion: Add hook in Bash completion for commit message; tests","fromName":"Mikko Johannes Koivunalho","fromEmail":"mikko.koivunalho@iki.fi","sentAt":"2024-06-30T21:33:36Z","receivedAt":"2024-06-30T21:33:59Z","isPatch":true,"sender":{"key":"mikko.koivunalho@iki.fi","avatar":"https://gravatar.com/avatar/37d422e492749d7a19604988d9e953c36b019283013261d7cb88095a6274ab67?d=mp&s=160"},"body":"Signed-off-by: Mikko Johannes Koivunalho <mikko.koivunalho@iki.fi>\n---\n t/t9902-completion.sh | 68 +++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 68 insertions(+)\n\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 932d5ad759..4ea80fddd2 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -146,6 +146,74 @@ else\n \tROOT=\"$(pwd)\"\n fi\n \n+test_expect_success 'setup for commit message completion' \"\n+    commit-msg-callback-function () { echo HelloFromCallbackFunction; } &&\n+    printf '#!/usr/bin/env sh\\necho HelloFromCallbackExe\\n' >.git/hooks/commit-callback &&\n+    chmod +x .git/hooks/commit-callback\n+\"\n+\n+test_expect_success 'git commit --message= (empty)' \"\n+    test_completion 'git commit --message=' ' '\n+\"\n+\n+test_expect_success 'setup for commit message completion (run a shell function)' '\n+    git config --local completion.commitMessageCallback commit-msg-callback-function\n+'\n+\n+test_expect_success 'git commit --message=HelloFromCallbackFunction' '\n+    test_completion \"git commit --message=\" \"HelloFromCallbackFunction\"\n+'\n+\n+test_expect_success 'setup for commit message completion (run an executable file)' \"\n+    git config --local completion.commitMessageCallback \\\"${PWD}/.git/hooks/commit-callback\\\"\n+\"\n+\n+test_expect_success 'git commit --message=HelloFromCallbackExe' '\n+    test_completion \"git commit --message=\" \"HelloFromCallbackExe\"\n+'\n+\n+test_expect_success 'setup for commit message completion (do completion in a subdir)' '\n+    mkdir -p commit_message_completion_subdir &&\n+    cd commit_message_completion_subdir\n+'\n+\n+test_expect_success 'git commit --message=HelloFromCallbackExe' '\n+    test_completion \"git commit --message=\" \"HelloFromCallbackExe\"\n+'\n+\n+test_expect_success 'teardown from commit message completion (do completion in a subdir)' '\n+    cd .. &&\n+    rm -r commit_message_completion_subdir\n+'\n+\n+test_expect_success 'setup for commit message completion (run an executable file with ENV var set)' \"\n+    GIT_COMPLETION_COMMIT_MESSAGE_CALLBACK=commit-msg-callback-function &&\n+    export GIT_COMPLETION_COMMIT_MESSAGE_CALLBACK\n+\"\n+\n+test_expect_success 'git commit --message=HelloFromCallbackFunction (ENV var overrides config)' '\n+    test_completion \"git commit --message=\" \"HelloFromCallbackFunction\"\n+'\n+\n+test_expect_success 'setup for commit message completion (completion begins with quote char)' '\n+    commit-msg-callback-function-with-quote () { echo \\\"HelloFromCallbackFunctionWithQuote; } &&\n+    GIT_COMPLETION_COMMIT_MESSAGE_CALLBACK=commit-msg-callback-function-with-quote &&\n+    export GIT_COMPLETION_COMMIT_MESSAGE_CALLBACK\n+'\n+\n+test_expect_success 'git commit --message=HelloFromCallbackFunction (completion begins with quote char)' '\n+    test_completion \"git commit --message=\" \"\\\"HelloFromCallbackFunctionWithQuote\"\n+'\n+\n+test_expect_success 'teardown after commit message completion' '\n+    unset -v GIT_COMPLETION_COMMIT_MESSAGE_CALLBACK &&\n+    git config --local --unset completion.commitMessageCallback &&\n+    unset -f commit-msg-callback-function &&\n+    unset -f commit-msg-callback-function-with-quote &&\n+    rm .git/hooks/commit-callback\n+\n+'\n+\n test_expect_success 'setup for __git_find_repo_path/__gitdir tests' '\n \tmkdir -p subdir/subsubdir &&\n \tmkdir -p non-repo &&\n-- \n2.30.2\n\n"},{"id":"497866","messageId":"20240630213336.2212166-2-mikko.koivunalho@iki.fi","threadId":"61708","inReplyTo":"20240630213336.2212166-1-mikko.koivunalho@iki.fi","subject":"[PATCH 1/3] completion: Add hook in Bash completion for commit message","fromName":"Mikko Johannes Koivunalho","fromEmail":"mikko.koivunalho@iki.fi","sentAt":"2024-06-30T21:33:34Z","receivedAt":"2024-06-30T21:33:59Z","isPatch":true,"sender":{"key":"mikko.koivunalho@iki.fi","avatar":"https://gravatar.com/avatar/37d422e492749d7a19604988d9e953c36b019283013261d7cb88095a6274ab67?d=mp&s=160"},"body":"Signed-off-by: Mikko Johannes Koivunalho <mikko.koivunalho@iki.fi>\n---\n contrib/completion/git-completion.bash | 40 ++++++++++++++++++++++++++\n 1 file changed, 40 insertions(+)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 60a22d619a..5350531c8f 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -81,6 +81,34 @@\n #     case insensitively, even on systems with case sensitive file systems\n #     (e.g., completing tag name \"FOO\" on \"git checkout f<TAB>\").\n \n+#   GIT_COMPLETION_COMMIT_MESSAGE_CALLBACK\n+#\n+#     Name of an executable or a script which returns a commit message.\n+#     Use this, for example, to always start a commit message with a predefined\n+#     prefix. Example:\n+#     # Extract Jira ticket number from branch name:\n+#     extract_ticket () {\n+#       if [[ \"$(git rev-parse --symbolic-full-name HEAD)\" =~ ([[:alpha:]]{3,}-[[:digit:]]{1,}) ]]\n+#       then\n+#         echo \"\\\"${BASH_REMATCH[1]^^} \"\n+#       fi\n+#     }\n+#     GIT_COMPLETION_COMMIT_MESSAGE_CALLBACK=extract_ticket\n+#     # Doing commit:\n+#     git commit --message=<TAB>\n+#     # you would get (without the closing double quote):\n+#     git commit --message=\"ABC-1234\n+#\n+# You can set the following Git configuration variables to influence the behavior of\n+# the completion routines:\n+#\n+#   completion.commitMessageCallback\n+#\n+#     Name of an executable, script or shell functions which returns a commit message.\n+#     See above environment variable GIT_COMPLETION_COMMIT_MESSAGE_CALLBACK.\n+#     The config variable gets overriden by the environment variable if latter is present.\n+#\n+\n case \"$COMP_WORDBREAKS\" in\n *:*) : great ;;\n *)   COMP_WORDBREAKS=\"$COMP_WORDBREAKS:\"\n@@ -1824,6 +1852,18 @@ _git_commit ()\n \t\t\t\" \"\" \"${cur##--cleanup=}\"\n \t\treturn\n \t\t;;\n+\t--message=*)\n+\t\tif test -n \"${GIT_COMPLETION_COMMIT_MESSAGE_CALLBACK-}\"\n+\t\tthen\n+\t\t\t__gitcomp_direct_append \"$(${GIT_COMPLETION_COMMIT_MESSAGE_CALLBACK})\"\n+\t\telif test -n \"$(__git config completion.commitMessageCallback)\"\n+\t\tthen\n+\t\t\t__gitcomp_direct_append \"$(\"$(__git config completion.commitMessageCallback)\")\"\n+\t\telse\n+\t\t\t__gitcomp_direct_append \" \"\n+\t\tfi\n+\t\treturn\n+\t\t;;\n \t--reuse-message=*|--reedit-message=*|\\\n \t--fixup=*|--squash=*)\n \t\t__git_complete_refs --cur=\"${cur#*=}\"\n-- \n2.30.2\n\n"},{"id":"497867","messageId":"ZoHRsoEfh_B5J4HN@tapette.crustytoothpaste.net","threadId":"61708","inReplyTo":"20240630213336.2212166-1-mikko.koivunalho@iki.fi","subject":"Re: [PATCH 0/3] Add a Hook To git commit --message Bash Completion","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2024-06-30T21:44:18Z","receivedAt":"2024-06-30T21:44:27Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2024-06-30 at 21:33:33, Mikko Johannes Koivunalho wrote:\n> I want to create part or all of the `git commit -m *` command's\n> message with a script. I work for one Jira ticket at a time and I\n> need to create many commits which all start with \"TKT-123: \"\n> (any Jira ticket number/identifier). To make the commits faster,\n> I run `git commit --message=\"TKT-123: add new file\"` on the command\n> line.\n> \n> I want the Bash completion mechanism to propose the message for\n> me. I would fetch the newest ticket number and place it on the command\n> line when I type `git commit --message=<TAB>`.\n> \n> Example:\n> # Doing commit:\n> git commit --message=<TAB>\n> # you would get (also without the closing double quote):\n> git commit --message=\"ABC-1234\n\nThis is easy to do with a prepare-commit-msg or commit-msg hook, and\nthose are the intended tools for this purpose.  I've used these hooks to\ngenerate a message for a ticket based on the branch name at a past\ncompany (so a branch called tkt-123 would result in the TKT-123: entry\nin the appropriate place in the commit message).\n\nWhile you certainly can commit on the command line, it's not encouraged\nbecause you're supposed to write a commit message that explains the\ncommit in detail.  Only very rarely is a single line commit message\nuseful, and even in the case you've cited, I'd want to know why you\nadded a new file.  What does the file do?  What problem is it supposed\nto solve?  Why are we adding a new file when we could add the changes to\nan existing file?  Why is this change valuable at all?\n\nThat being said, all of this is possible with a prepare-commit-msg hook,\nand that's a better and more generic way than using the bash completion,\nwhich is specific to bash.\n-- \nbrian m. carlson (they/them or he/him)\nToronto, Ontario, CA\n"},{"id":"497868","messageId":"479d7276-0a8a-4eec-828e-c829b734a620@iki.fi","threadId":"61708","inReplyTo":"ZoHRsoEfh_B5J4HN@tapette.crustytoothpaste.net","subject":"Re: [PATCH 0/3] Add a Hook To git commit --message Bash Completion","fromName":"Mikko Johannes Koivunalho","fromEmail":"mikko.koivunalho@iki.fi","sentAt":"2024-06-30T22:12:39Z","receivedAt":"2024-06-30T22:12:54Z","isPatch":true,"sender":{"key":"mikko.koivunalho@iki.fi","avatar":"https://gravatar.com/avatar/37d422e492749d7a19604988d9e953c36b019283013261d7cb88095a6274ab67?d=mp&s=160"},"body":"\nOn 30/06/2024 23:44, brian m. carlson wrote:\n> On 2024-06-30 at 21:33:33, Mikko Johannes Koivunalho wrote:\n>> I want to create part or all of the `git commit -m *` command's\n>> message with a script. I work for one Jira ticket at a time and I\n>> need to create many commits which all start with \"TKT-123: \"\n>> (any Jira ticket number/identifier). To make the commits faster,\n>> I run `git commit --message=\"TKT-123: add new file\"` on the command\n>> line.\n>>\n>> I want the Bash completion mechanism to propose the message for\n>> me. I would fetch the newest ticket number and place it on the command\n>> line when I type `git commit --message=<TAB>`.\n>>\n>> Example:\n>> # Doing commit:\n>> git commit --message=<TAB>\n>> # you would get (also without the closing double quote):\n>> git commit --message=\"ABC-1234\n> This is easy to do with a prepare-commit-msg or commit-msg hook, and\n> those are the intended tools for this purpose.  I've used these hooks to\n> generate a message for a ticket based on the branch name at a past\n> company (so a branch called tkt-123 would result in the TKT-123: entry\n> in the appropriate place in the commit message).\n>\n> While you certainly can commit on the command line, it's not encouraged\n> because you're supposed to write a commit message that explains the\n> commit in detail.  Only very rarely is a single line commit message\n> useful, and even in the case you've cited, I'd want to know why you\n> added a new file.  What does the file do?  What problem is it supposed\n> to solve?  Why are we adding a new file when we could add the changes to\n> an existing file?  Why is this change valuable at all?\n>\n> That being said, all of this is possible with a prepare-commit-msg hook,\n> and that's a better and more generic way than using the bash completion,\n> which is specific to bash.\n\nI have used the prepare-commit-msg hook for this same purpose, and also \ncommit-msg hook to check that the commit message does contain a valid \nticket identificator string. When doing small changes it is just faster \nand more convenient for me to use command line completion to help. The \nprojects where I work often don't require longer commit messages and \nexplanations so formulating the commit message in editor is not \nnecessary. When longer and more meticulous commit messages are required \nI do them in the editor.\n\n--\nMikko Koivunalho\n\n"}]}