I wanted to write a bash alias for the git commit command. I typically use it like so: git commit -m "my message here", so I wrote an alias like this:

alias commit='git commit'

which allows me to do this:

$ commit -m "My message"

However, then I thought I could also update my alias to remove the -m option, getting me

$ commit "my message"

Then I thought, "Do I even need to type the quotes?" What I envisioned was this:

$ commit
> My message here

Where > is the quote-continuation prompt you get when you are type enter in a quoted string:

$ git commit -m "I am about to hit the enter key

And it completes the command when I hit enter.

Is there any way I can script this behavior in bash?

Bonus: the command aborts when I hit Ctrl+c.

  • 2
    It appears you want to re-implement git commit without the -m option. – glenn jackman Apr 26 '19 at 13:35
  • @glennjackman A fair assessment-- but with the caveat that I still want its feature. – user394 Apr 26 '19 at 13:41

I wonder if you want this function:

commit() {
    if (( $# == 0 )); then
        command git commit  # no `-m`: invoke an editor
        command git commit -m "$*"

As you don't want to open an editor, perhaps:

commit() {
    [[ $# -eq 0 ]] && set -- A default commit message here.
    command git commit -m "$*"
  • My git doesn't behave this way $ git commit On branch master nothing to commit, working directory clean $ git version git version 2.7.4 – user394 Apr 26 '19 at 13:46
  • You have to do something commit worthy first: touch some_file; git add some_file; git commit – glenn jackman Apr 26 '19 at 13:54
  • Ah, okay, I see, thanks. I don't want to open an editor; I just want to avoid typing quote marks. – user394 Apr 26 '19 at 14:08
  • 1
    expanded my answer. – glenn jackman Apr 26 '19 at 14:32
  • So now I have the command where I can write commit this is my commit message. But I wonder, can I get it so that I type commit, hit enter, and get a prompt like this: >, where I type my commit message, and cancel with Ctrl+c? – user394 Apr 26 '19 at 20:52

You could write a function that uses bash's read -e:

commit() {
  local commitlog
  IFS= read -rep '> ' commitlog &&
     git commit -m "$commitlog" "$@"

read -e lets you insert a litterral newline by pressing Ctrl+VCtrl+J, but because read reads only one line, everything past the first newline will be discarded.

You can work around that by adding a -d $'\r' option to read, but then I found that at least with version 5.0.7 and 4.4.19, that messes up the handling of Enter afterwards at the prompt.

In any case, it's easier in zsh:

commit() {
  local commitlog=
  vared -ep '> ' commitlog &&
    git commit -m "$commitlog" "$@"

Where newline can be entered with Ctrl+VCtrl+J like in bash or with Alt+Enter

Or with history (here shared and avoiding duplicates):

commit() {
  emulate -L zsh
  setopt sharehistory histignorealldups histsavenodups
  local commitlog=
  fc -ap ~/.zcommit-history 500
  vared -ehp '> ' commitlog || return
  print -rs -- "$commitlog"
  git commit -m "$commitlog" "$@"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.