Hacker News new | past | comments | ask | show | jobs | submit login
Git commit accepts several message flags (-m) to allow multiline commits (stefanjudis.com)
339 points by stefanjudis 38 days ago | hide | past | favorite | 152 comments

What's cool is that if you start with -m and add a second -m but notice that you have more to say than initially expected, you can still pass -e to open the editor with the message entered so far:

    $ git commit -m "Fix issue" -m "Lorem ipsum..." -e

I exploit the same trick to have a script automatically set what it thinks a commit message should be, but still pass it for human review/edit before actually committing and pushing. Come to think of it, you could easily use this to set a default message base and do things like always prefix the directory; I like my commits to be something like "modules/foo: added bar", so I could just alias gc='git commit -m "${PWD##*/}" -e' (well, something like that, but more sophisticated).

For this usecase git has the 'prepare-commit-msg' hook that allows you to configure this per repo.

I use this to insert the jira issue key into the commit message.

Smart. The dev tool I use automatically links my commits to the Jira issue that initiated the project/fix/update. The key and sha are forever linked. It does the same with Clubhouse.

How does the script determine what the commit message should be?

I always have the issue number and short description in the branch name, e.g. foo#123-handle-new-orders.

So that might sometimes be good enough for a first automatic commit message. I typically clean the history before I submit I submit my work to review.

Thank you for that tip, that would've saved me some annoying copy/pasting in the past!

I'd just C-x C-e and open the command line buffer in an editor to work on it there.

This isn't enabled by default. You have to configure zsh with some optional features. I found this on Stack Overflow:

    autoload -z edit-command-line
    zle -N edit-command-line
    bindkey "^X^E" edit-command-line
[1] https://unix.stackexchange.com/questions/6620/how-to-edit-co...

> This isn't enabled by default.

It is in Bash.

Oh man nice tip. I've been using bash for 30 years and never noticed that binding.

    "\C-x\C-e": edit-and-execute-command

That's right. If anyone wants to check their bindings, use:

    bind -p

    bind -P
For example:

    $ bind -P |grep execute
    edit-and-execute-command can be found on "\C-x\C-e".
The "bind" shell built-in is detailed in the SHELL BUILTIN COMMANDS section of the "bash" manual.

C-x C-e doesn't do anything in my configuration but beyond that I find that editing long freeform text on the command line gets annoying fast if only because of the careful escaping you have to do, especially for nested quotes.

In zsh (and bash I think) it opens the entire line in a buffer, making it easy to edit it in ways which wouldn't really work well at the shell.

> beyond that I find that editing long freeform text on the command line gets annoying fast if only because of the careful escaping you have to do, especially for nested quotes.

Oh I agree. Here I'd suggest it for the rare case where I was expecting to write a simple commit message and end up needing a much longer one, though usually I'd just create the commit and immediately "amend" into a proper text editor (and most of the time I use a text editor directly, because rare are the commits where the short desc is sufficient).

Sure, but how would you format your message so the lines aren't longer than 80 chars? I guess you can edit the command to read from STDIN, but that sounds much more cumbersome than passing -e:

    git commit -F- <<EOF
    Fix issue

    Hello world...

> Sure, but how would you format your message so the lines aren't longer than 80 chars?

Put linebreaks and fill-paragraph for the later lines? You can put linebreaks in quoted shell strings, so once it's in an editor buffer there's no issue with that.

> I guess you can edit the command to read from STDIN

The use case here is "I've already started writing a commit message inline, I now realise I need more room, I don't want to bother copy/pasting stuff around".

If I know from the start that I will need more than just a shortdesc, I'll obviously be crafting the message in my editor in the first place.

Maybe something like

  fold -c -s -w 80 | git commit -F - <<EOF
  Fix issue

  Hello world...

I typically just do the commit, then afterwards use `git commit --amend` to open the previous commit message in $EDITOR for updating.

I'm not sure I've _ever_ used the -m flag to write a commit message. Naked `git commit` defaults to vim for me, and that's how I like it. Multiline messages, text turns from yellow to white when you go over 80 characters, summary of changes when you're writing the message, the ability to abort with :q! — I can't say the number of times I've realized I left a bug or forgot to tweak something or stage a change while writing a commit message, and bailed out to fix that before committing — the list of advantages goes on and on. I'll never not write my commit messages in vim, and I encourage everyone to do the same.

I use -m often, it's pretty much my default commit method. It doesn't break the flow, I can see the previous commands in the terminal above which is sometimes useful.

Besides it's trivial to change the commit in an editor if you're not happy with it with a simple "git commit --amend". It's even possible to change your mind in the middle of the commit command by adding '-e' as somebody else helpfully pointed out in this comment section.

I mean, I don't think my way is superior to yours, but I don't think it's inferior either. It's just a matter of taste and workflow I suppose. In particular I don't really see why editing text in vim is going to make you more or less likely to realize that you forgot to "tweak something or stage a change". And at any rate as long as you haven't pushed anything it's trivial to rewrite the commit.

I think the biggest difference is once I switched away from `-m`, I tend to write multi-line commit messages. Specifically, I do a title line and a full description in the commit message itself. GitHub will pick this up (if you have a single FF commit) and automatically populate a pull request description with your commit's title and message. As a side-effect, you have a detailed history available for all code patches.

You don't even need to quit editor without saving changes, you can just ^Z it, add new changes, fg the editor back and continue with your commit message.

I actually type my commit messages in a new window in the editor (vim).

  :r !git status -v
Type my commit message above the output, and then visually highlight the lines of my commit message and then run

  :'<,'> !git commit -F -
In fact, if I see an issue with the diff, I can update the relevant file and then run:

  :!git add %
and then go back to the window with the status output, delete it and rerun the status -v command.

In fact, if I want to be more fine grained with the changes I stage in git, I can run:

  :r !git diff
to get the output of the unstaged changes, copy the hunk header lines, paste them above the hunk I want to stage, visually highlight the hunk with the header lines, and then run:

  :'<,'> !git apply --cached -
to stage that hunk. I've even done things like using recountdiff to update the hunk header if I decide to removed added lines or restore deleted lines in a hunk. Personally, I think it's easier than using git add -p or reset -p.

This is me all the time.

[is writing commit message]

Oh wait… What did I change?

  git diff --cached
Oh yeah.


You should be using `git commit -v` then; it will include the full diff of your changes, so you can quickly check them while writing your commit message.

Yeah this is what I use, the only issue being extraordinarily large commits may get bogged down some times.

I have no idea why anyone would ever not use this to be honest.

That workflow seems really slow when dealing with multiple repos/subrepos actively compared to what UI frontends offer.

But it's still more efficient method for single repository project where using UI git client would be the overkill.

Sometimes it's very convenient to start writing your message in the command line, either to delay the "mental context switch" from the command line to vim or when you want to prepend some fixed text to a series of commits.

You can just add -e to the end to either finish writing or checking it in Vim then, which is what I almost always do when I use -m.

> summary of changes when you're writing the message

-v makes this so much better - forget seeing the list of files in the commit; you can see the whole diff! :)

"-m" can be used by automatiom. One of our teams' integrations uses this when automated commits are performed in response to certain actions. E.g., they trigger webpacker builds automatically which are then committed in response to a tag, sprint completion, or other action. (We used to use git hooks which I thought were better, IMHO.)

For anything other than personal projects where messages don't matter much, -m is an anti-patern.

Any good commit message should have at least a paragraph explaining the rationale, functional change and maybe links to design docs or bugs. All the time I come across commit descriptions from decades ago, that are useful because of this.

Git commit messages aren't just messages that you push to whatever central repository; they're also messages for yourself to review while squashing your local history before pushing. I usually make a git commit before testing my proposed change; I don't want to write the full-blown commit message before I know that the tests pass. In that case, -m is very useful to place a marker in the reflog for future reference, even though it won't end up as a message that you share with your collaborators.

I personally tend to write pretty short commit messages, I think any important info is better stored either in comments in the code or the module's documentation. Who goes digging into old commit messages to understand what a piece of code does? I know I don't.

Not to say that verbose commit messages are a bad thing, it's always better to have too many details than not enough, but I think very long commit messages might also sometimes hint that either the commit is "too big" and should've been broken down in smaller, atomic changes or, as I said above, that you're really just writing documentation and that may be better suited for an other place.

Commits should definitely be descriptive and accurate, but if you break your changes in small chunks you can generally still do that in one or two sentences in my experience.

In my day job I'm frequently chasing down older code, looking through blame/annotate etc. Commit messages with links to bugs and docs are often the fastest answer to the fundamental questions "Why is this thus? What is the reason for this thusness?"

> Who goes digging into old commit messages to understand what a piece of code does? I know I don't.

If long-term-ism in commit messages isn't something you care about (which is understandable), then consider short-term benefits. When working with my team, I'm able to read some of their recent commits and understand very clearly what's being worked on, without needing to dive into the code or have daily stand-ups which aren't producing any value on their own.

Think of it as an asynchronous way of describing what you're working on, and the broader context.

> Who goes digging into old commit messages to understand what a piece of code does? I know I don't.

A lot of people do. If you've ever used git blame on a file, you can see which commit each line in the file is associated with. You can then run git show <sha1> for that commit and see the message and associated diff. Having that information can help you understand why a change was made and may help you avoid introducing regression type errors.

I think long commit messages make sense for bugs, because unless it breaks compatibility you're not going to comment the code every time you fix a bug.

The only time I use it is when I'm making a small fix or tweak and will be `rebase -i`ing immediately afterwards. It probably saves me several keystrokes per year.

For that case, commit --fixup and rebase --autosquash might save you even more.

I always use oneliners. Task ID + some short description. Used to use just `-m`, but nowadays I almost exclusively use lazygit to commit.

At work we squash PRs and that's where we can write more details if necessary, or just hope the associated PR with details will be available in the future.

For my personal projects, I don't care that much. When I realize a mistake, there's always amend.

I use -m as a natural filter for line length. If it's unwieldy to fit inside a -m cli flag, it's usually an indicator I can be more concise in my commit message. Obviously, from time to time you'll need to include more information in commit messages; I have sublime set up to be my default editor for these situations.

How do you make naked `git commit` default to emacs?

I believe the default is simply to open your default editor so just set $VISUAL (and $EDITOR, read the manual for your shell) in your environment. This has the added benefit (?) of using that editor for commands that open a visual editor such as crontab -e or even visudo (with some caveats of course).

If you want to use a different editor just for git you can set $GIT_EDITOR in your environment.

git config --global core.editor <EDITOR>

It also respects $EDITOR, though that would impact more than just git, of course.

I'm pretty sour on vim after being forced into it by `git commit` with no introduction or explanation.

Not git's fault, it uses your OS's EDITOR and VISUAL environmental vars (same thing you get when you run, for example, "crontab -e" and other utilities that want a visual editor).

Hm. I don't think I had such a variable prior to the installation of git.

Edit: In fact, still don't. The git editor seems to be configured by some git config rather than environment variables.

The behavior is mostly congruent with other programs, for example less(1) probably also falls back to vi(1) on your system if you press v.

TIL, had no idea about that `less` starts an editor on `v`.

I should clarify, I'm using Windows, which normally doesn't have either of those, except for maybe cygwin or WSL.

The -v option, which the author is referring to when talking about writing commit messages in vim is much better: you get to author the commit message in the $EDITOR of your choice and you can inspect the full diff while doing so.

If you're using fzf [0] for history recall (ctrl+R) it also has the nice side-effect for not cluttering up your history.

[0] https://github.com/junegunn/fzf

I pretty much always write my commit messages in Vim and never knew about -v, this is really nice thanks for the tip. Going to set it as default with:

    git config --global commit.verbose true

It's useful, but makes you wonder why they haven't taken it one step forward and allow you to edit the diff too while you're at it.

You could if you also have the output of git diff. Then you could stage and unstage hunks or parts of them using a combination of recountdiff and git apply --cached

That sounds positively radical. Like magit taken to its conclusion.

Another option, if you're using Vim, is to use Tim Pope's Git plugin, Fugitive[0]

[0] https://github.com/tpope/vim-fugitive

And magit for the emacs folks.

They provide a conceptual framework for developer to orient and frame their actions with (sort of) right information density in the “native” $EDITOR environment.

I think VSCode has that git plugin which is very popular but I can’t remember the name - gives great git log/blame interface.

For me, personally, tig is the sweet spot. It shows me the output of "git status", I can select the files I want, and then commit them.

There is also lazygit, it's kind of similar, but different.


What you describe sounds a lot like the :Git command of fugitive. I looked at tig and it does looks quite similar.

Another feature I really like with fugitive is :Ggrep which runs a git grep and returns the result in the quickfix list.

Oh, thanks for it.

On my computer, I usually commit using `git gui` (and CLI for everything else). Mostly because I can see the full changes I'm commiting. Now, I can do it with vim for the occasional commit from some server.

`git diff --cached` will show you the changes staged.

`git add -p` will give you a interactive way of committing partial changes.

`git commit -p` works as well.

Thanks, one of the myriad options for which I made a mental note to try after becoming proficient with git and then completely forgot

My favourite git shortcut is "git checkout -" it mean switch back to the previous branch, so without having to remember either branch you can switch between two pieces of work easily. This seems to come from "cd -" which does the same thing with the current and the previous directory.

I also like "git branch -d @{-1}" to delete the previous branch, which can of course be aliased.

And if -m inline message gets screwed up, --amend to the rescue:

  git commit --amend
This will open $EDITOR and let you edit the commit message. It will also modify commit content if you stage changes before it.

I've set up an alias for `commit --amend --no-edit`, this way merging new stuff into a commit is easy, and editing the commit message is just a `-e` away (`-e` flips `--no-edit` back on).

The only concern is the odd situation where I'd staged something before realising I was missing bits in the commit message.

i love those in alias, gca, gcane.

Then when pair programming I can say "Time to pull out the G-Cane"

  $ git commit -m ‘
  > Bugfix #94
  > Help I’\’’m trapped
  > in a bug fixing
  > factory
  > ‘

  $ echo $SHELL
  $ git commit -m $'Bugfix #95\n\nEverything's fine, please move along.'

FYI bash also interpolates C escape strings with $’…’ syntax.

The apostrophe in your example breaks the command.

I actually installed zsh and ran this because I assumed your point was that zsh magically handled the «‘s» in «Everything’s». Alas, no.

And that's why you always test your one-liners before posting. :)

> I assumed your point was that zsh magically handled the «‘s» in «Everything’s»

I'm very glad it doesn't. String parsing and expansion rules in Bourne-like shells are already complex enough as it is.

Do people actually read commit messages? I don't have much experience working on large projects with a larger team, but I keep repositories both for personal things and work so I can look at older versions. I have however never actually looked at my own commit messages, even though I try to keep them informative. I instead search through commits based on strings added/removed or file paths touched. As such, multiline commit messages (whether added on the command line or via the editor) seem doubly pointless to me.

I would be curious to hear how others view this.

When inheriting a project, you use git blame a lot. Who wrote it, when it was written and any hints as to why it was written. If it has a task number like "fixes #1402" and you still have access to the issues, that's great.

If it is like "f*ck python" or "lol java sux" that's a good indication that it was a syntax problem or a trivial mistake.

If it is like "a" or "aaa" or "x" it's just useless and you are on your own.

> If it has a task number like "fixes #1402" and you still have access to the issues, that's great.

If. The flip side is that when you don't have the issue tracker (I'm unclear as to whether they deleted it, or it just didn't come along when the product was acquired), it's maddening. "This [massive, opaque] change fixes #123" "...gee, thanks; that tells me loads."

Ask me how I know.

> When inheriting a project, you use git blame a lot

Obligatory plug for `git log -p`, which is a much better tool for finding out how changes happened to a file.

You can also use `git log -p --follow` with a single file to track the file across renames and moves.

When the first line of the commit is just "Fixes 1429", that's annoying. It belongs on a subsequent line.

I can look through the list of commits for recent changes that seem like they might have caused a new bug, but a list of numbers is no help at all there.



> Do people actually read commit messages? I don't have much experience working on large projects with a larger team

I find them super useful even for personal, my-eyes-only code! They really help answering "why the hell did I write this line of code like that when this alternative version would be much simpler?". It usually goes "oh, there's the commit that changed it from the obvious thing to the weird thing", and then if I've been a good me, the commit message describes the rationale.

Yes, code comments can serve some of the same purpose, but they typically document why code is the way it is, not change of said code.


For the maintainability of a large project with a lot of contributors, the quality of the commit messages is more important than the quality of the code itself. The code and the comments in it only contains the how and what is happening, and even those can get really muddled up in projects where something gets changed over and over again by different people over a long time.

The commit messages provide the why. They grant you a window to the perspective of the person who did the change, explaining why they did something the way they did.


Do you know the tool "git blame"? (You can also use it with "git gui blame", from Github, or from many text editors). It tells you which commit last changed each line of code. Then you can click and see the surrounding history and context.

If the git history is "well written" this is an invaluable tool for understanding the code and how it came to be the way it is! Super useful when working on large code-bases where lots of different people collaborate.

I use git blame, but in the same way I use the rest of git: I find the commit which changed a line, and then look at what else that commit and the ones before/after it did.

I guess there is some value in being able to have a quick description of the commits shown when looking at the blame output though.

I wish there was a video tutorial of sorts to explain how git blame works.

I have used it, but it never “clicked” me. I am always uncertain about what to do next as I browse git blame on GitHub

The git command-line blame is quite awkward, both in syntax and in functional limitations, in almost any situation it's a lot better to use a visual tool such as "git gui blame"

Which part is it that confuses you? On github the commit messages and hashes on the left hand side indicate the last commit that touched those lines, and you can click on them to see the full commits, including changes made to other files. Alternatively you can click on the "View blame prior to this change"-icon (between the commit messages and the code), which will do as the name suggests: Show the commit which previously changed those lines.

I absolutely love the GitLens extension for Visual Studio Code: It shows you the current line annotated with `git blame` by default: https://github.com/eamodio/vscode-gitlens/tree/master/#curre...

I even like this in my personal projects: It shows me how good both my commit messages and granularity are.

> As such, multiline commit messages (whether added on the command line or via the editor) seem doubly pointless to me

So your commit messages are always made of less than 80 characters, how can you claim that they are informative??

Personally I very rarely manage to keep them in a single line, almost always there's something to dump from my mind that will help a lot when I or someone else will have to deal with that commit a few months from now.

You don't read your messages because they really are not informative!

I guess "not nonsensical" would be more appropriate than "informative" :)

I tend to dump information like that in "// NB (my name, current date) tralala"-style comments. Do you have git integrated in your editor so you have git-blame-style commit messages next to your code? If that is the case, I guess putting the information in the commit messages makes sense.

Maybe it just comes down to how we choose to store auxiliary information.

> I tend to dump information like that in "// NB (my name, current date) tralala"-style comments. Do you have git integrated in your editor so you have git-blame-style commit messages next to your code? If that is the case, I guess putting the information in the commit messages makes sense.

No but blame is very close by and easy to access, so when I want to know why something was done that way it's not far away.

Comments keep getting out of sync, code gets inserted before or after, … and after a few years (or months on large codebases) it's just complete nonsense. I reserve them for stuff that's really super important to say right here (and todos).

No, commit messages are not meant for "auxiliary information", but for giving the reasoning behind a change.

Yes, a lot. Often the intent behind certain lines is not clear until I dig out the commit message and its corresponding ticket.

> Do people actually read commit messages?

See the recent discussion here: https://news.ycombinator.com/item?id=23739076

You don't know the 'pleasures' of code archaeology? Sometimes you are digging into ancient code, written by somebody that is no longer around, trying to figure out why something is the way it is. Why did this business rule change? Why was this line added? A good commit message will explain the "why" of the change.

It is not a lot of work to write them.

I use them for - Tracking work on specific jira tickets - Giving myself a simple/quick overview on what was done - Tracking down bugs by trying to understand if that code is doing what it should do (bug vs. on purpose) - If i need to revert something, i revert a git commit. might just happend once a year but if required its fundamental

I'm also always slightly surprised about discussions from this topic: Its a nobrainer to just do it.

Its cumbersome if you have to explain to colleges, who are working with code for longer then a few month, why you should just write proper git commits.

It is like 'i'm allowed to write code which does a lot if things but pls exlpain to me again how i write a proper git commit message' :(

I read Git commit history regularly, like this aliased command: git log --color --graph --oneline --decorate

Or this one for a Markdown list: git log --since="last version" --pretty=format:'- %s'

It helps me to:

- See what feature areas have been recently worked on

- Check if commits have been pushed to remotes

- Gather all commit messages since last version, and copy & paste (and edit) into changelog

Occasionally, I need to go back through the history and find a specific change - I typically just grep the commit messages for a word or phrase.

I also read commit messages of forked repos, to keep informed of what's happening upstream.

All the time. I work with a team that pretty much agrees on commit message detail and format. It is so nice to have all changes documented with the "why".

We keep as much of everything as possible in Git, including configuration. I can look back to every time we've adjusted the memory of a service, every time the number of instances has changed and have descriptions as to why that was done, associated tickets, etc.

Another great reason is integration with hosted Git tools. I know that Bitbucket and Github (and likely many others) will populate a pull request title/description with the commit message. Putting all of the necessary background in the commit message is a great way to supply the reviewer with information surrounding the commit, which decreases turn-around time for PRs. That history and reasoning is now ticketing-system agnostic and available in all of the popular editors that I've used (Vim, Emacs, VSCode, Intellij).

Here are the commit messages written by the developers of Git itself: https://git.kernel.org/pub/scm/git/git.git/log/

The most recent commits are a load of merges, but the slightly older ones have very long commit messages. The first one I clicked [1] has 11 changed lines of code, and a 32-line commit message.

[1] https://git.kernel.org/pub/scm/git/git.git/commit/?id=23c431...

It all depends on how well you use git I guess. Imagine you developed a feature on a branch, then merged it into main. Later you have to change something at that feature, from the commit message you can find the commit, then you can see which parts of code is effected by that.

Then you are working on a subset of code, and can see of your change is effecting something else, or where else you need to make changes.

Or maybe someone fixed a bug there, then from commit message you can go to related bug, see their intentions more clearly.

I’d like to add, squashing is important in this workflow.

A string of commit messages on a branch saying, “add x”, “typo”, say a lot less than a single commit along the lines of “TICKET-XXX new feature”.

When you share code with other people, "your" code gets updated continuously. In that context, you often want to know what motivated an update, and how it may affect what you are doing.

Consider a bug fix, you want to know what was the bug, and why the fix is actually a fix. This is complementary to comments which don't tell anything about the code evolution.

A good commit message can save a lot of work to your colleagues and even yourself in the future.

I think it depends on the project and the culture of the team. If they're there they can be handy, but it really only works if everyone is disciplined about it so it becomes a reliable source of information. If, on the other hand, half the commits in the repo just say "fixes," you get in the habit pretty fast of digging through code via other means first.

In my small personal projects, no, but in a collaborative project I use them constantly. Helped by my IDE showing `git blame` inline

Of course people read them.

If you work in projects with a hundred other engineers or projects with maintenance, then there is no way you can get a sane code base without commit messages and reviews.

However, if you work alone and do not need maintenance, then yes, they are pointless since you will never need to read them.

> you will never need to read them.

Six months later: Why did I do this?

The commit is the reason behind a change, not the reason why some code is written like that.

It depends. if you've just fixed a fairly obvious bug then no but if you're (for example) merging something like ebpf into the kernel then expect to be writing a fairly large commit documenting how, why, where etc.

Most of the time I see/need them when blaming some code that is buggy or seems dodgy.

> Do people actually read commit messages? I don't have much experience

Found the tautology.

You can also just add a line break inside the ""


  git commit -m "Short commit message
  Longer description
  of my commit"

This is shell dependent.

Emacs and git users who haven’t tried magit should make a point to try it this week, IMO.

[0] - https://magit.vc/

[1] - Another commenter made the recommendation first, but it is buried in a thread, so I’m raising it up here. https://news.ycombinator.com/item?id=23768518

While CLI users are reading article after article to discover hidden features of their tools, I'm using a GUI that makes those features obvious and streamlines actions to make my work go faster than any CLI user could possibly achieve outside of automating their workflow entirely.

And I do everything with the keyboard.

I do this on Linux, Mac and Windows with VS Code. Before I used VS Code, on Windows I'd use TortoiseGit - again, all with the keyboard. I can operate the entirety of Windows with just a keyboard and most of XFCE on Linux.

To be fair, entering multiple lines of text into the VS Code Git commit sidebar is somewhat "hidden" as well, but using Shift+Enter to get a newline is fairly common and easy to try and guess.

Even when using the command line, you typically use an interactive editor to type your commit. Enter is enough to create a new line.

What you are saying doesn't help when automating things, unless you want to make a macro that controls the mouse and keyboard? That'd be risky. GUIs are great for discovering features. So great in fact that the API ("user interface") often changes, if only by a bit. Terrible if you are in this for the long run, or want to automate things.

I don't really want this to be a command-line vs GUi thread, but you kind of started it (even if a bit off-topic).

> but using Shift+Enter to get a newline is fairly common and easy to try and guess.

How on Earth is that intuitive? User interfaces (coomand line, GUI, web, voice) typically rely on common patterns (desktop metaphor, doule click, right click, alt+letter, F1, ctrl+c, etc) being memorized by their users.

At least, command line interfaces have the merit of often being documented (that feature is documented line 91 of my offline `man git commit`). I had overlooked that bit, but had I needed it, that would have been pretty easy to find. Most GUI software do not even pretend to have documentation anymore (KDE is still pretty good at this).

command-line vs GUI is a choice. I work most often with the former as I've grown comfortable with its patterns over time, after seeing it a lot. An added benefit is that I can often re-purpose the knowledge I learn for writing scripts. But not everyone necessarily needs to do so. And I think that picking the same tool for every task is pretty dumb. I like GUIs a lot for stuff I'm not familiar with, or don't do often.

> At least, command line interfaces have the merit of often being documented (that feature is documented line 91 of my offline `man git commit`)

By default, pressing "Enter" in VS Code adds a new line. I don't think that needs to be documented. And the input box for the commit message says as its placeholder "Cmd+Enter to commit on [branch]", which is a whole lot more discoverable than going to line 91 of some man page. Plus, every keybinding can be searched and configured using the built in keybinding editor.

>> but using Shift+Enter to get a newline is fairly common and easy to try and guess.

> How on Earth is that intuitive? User interfaces (coomand line, GUI, web, voice) typically rely on common patterns

You'll find many "Enter to submit" boxes across the technosphere have some way of adding a new line, typically shiftenter, ctrlenter, etc. So this is a common pattern.

Skimming the help of a git command once in a while (or when you have that feeling that there must be a way to achieve a specific thing) is rather quick and, thanks the pager's built in search feature, very accessible.

Having an alias for help (and for git) makes this quite convenient:

    $ g h commit
Then search for something in there, e.g. `/stdin<ENTER>`.

I refuse to use GUI's for multiple reasons and I've been using the -m flag for as long as I can remember... Truthfully I've never been big on fancy IDE's or GUI's, which eat up cpu, memory and disk io like a bodybuilder after a training session.

I tend to use a GUI (SourceTree) for most of my git work. It allows (encourages, even) me to write fairly extensive commit messages.

One of my tricks is to copy the entry I made in my CHANGELOG.md file, and make that part of my commit message. I may add a bit of extra to it, in order to establish a technical context.

I went an embarrassingly long time without knowing you could use a second -m flag. I tend to do all my git stuff on the command line. Since I learned this, I have made it a regular habit to add more detailed messages to my commits when necessary. Very helpful when looking back at old history, to remember details or problems I encountered while working on that commit.

I see a lot of people say they always use vim to edit commits, I think I will have to try this out. The -m flags in the terminal have always worked fine for my workflow, so I guess I never really thought about using vim.

I always wonder how using cli to commit changes is faster than using dedicated git frontends such as Fork to do such tasks.

I used to use it like that but it was too much work to manage multiple repositories in such way especially if i didn't remember all changes I made.

Using Fork greatly reduced time spent making useful commit messages by having all changes visible at glance. It even allows to stage specific lines of source code and has insanely good interactive rebase UX.

Things like that are impossible to achieve with only using cli productively.

Also I like the ability to see commits from all branches at glance.

I used to think the same, then I learned a bit more about how to use git on the cli. I'm not saying you haven't, I'm just saying for me, I was able to perform tasks quicker with a few tweaks.

Things i've done to do this

- replace default diff tool (I use https://github.com/so-fancy/diff-so-fancy) - added many alias for commonly used commands and ones I often forget - use `git add -p` (or `g a -p` in my setup) which goes through changes file by file, allowing me to add bits i want (this was the main thing I loved about a GUI based git client)

This whole thread so full of nice tips and hidden gems!!

Thanks everyone :-)

I use Gitbook to create dev docs and it incredulously doesn’t pass merge messages to GitHub via its integration. A big fail, imho. All you see in GitHub is “Gitbook updated ## files.” I mention this because I could use this flag to see if I can add a manual process to get my messages assigned to corresponding commits.

This is great to know. For years I've been adding `&& git commit --amend` to write any amendments.

That looks like much more effort then the default behaviour of git commit to open your editor.

Note that each subsequent use of the -m flag appears to prepend a line feed to the beginning of the commit message.

This results in more of a paragraph-style spacing, rather than true multiline. You can see this in the author's own screenshots, or just by trying it yourself.

Opens the temptation to write essays. One liners forced a certain brevity

I love essays in commit messages! They can be very useful, especially when they describe why the change is being applied, instead of what is being done, which is usually the case.

Many high-profile projects have essays in their commits; I'm familiar with those of Go, e.g. https://github.com/golang/go/commit/5779bb4e92911271583faa13... (picked one at random).

Both are best! A brief concise first line summary together with a full message.

I like to go with a brief "what i've done and why". Maybe "BUG-123 (Broken profile page) - Fixed missing CSS".

Why did the bug happen? How were users affected?

Why was this particular "fix" chosen, instead of perhaps a more obvious alternative? (If I can choose only one thing to improve, it'd be this one! Had I gotten a penny for every head scratching "fix" that seems unnecessarily complicated or not a fix at all...)

What steps have been taken to avoid this in the future? New validations? Have new exceptions been introduced? New log rules? New monitoring rules? And if not, then why not?

Are these corresponding changes in other repos or this one? Is this change part of a larger series of changes?

There's so much more you'd like to know when you stumble on a commit like "fix missing css". Yes, some of this info is probably in the ticket. Yes, there is probably a discussion in the pull request. But likely not, if we are to be honest about it. And if it is, then all the easier to summarize in the commit message.

I'm one of those persons that read more code than I write nowadays, git log -G is my favorite command, and commit messages like the above hurts me daily.

I've already made a similar comment elsewhere in this discussion but I really don't get why most of these things is better stored in a commit message than, say, as a comment in the code itself, which will always be here even if I'm just browsing through the code by following a call stack or if the file gets copied into another project for instance.

I don't "git blame" all the code I read all the time, and even if I did one small refactor or variable renaming is enough to make it tricky to track the original change back. Comments are forever.

Comments and commit messages are complementary. The commit message describes the changeset and includes things like the above, the whys and the necessary context to understand the change. The comment describes the actual code as it is, and should describe how it works and how it interfaces with other code. Comments tend to be, as you say, forever while the code changes.

Both are well worth the time to write. Nicely written ones might even take a full minute or two to write, but how many cleaned-up and rebased commits does one produce in a day? A few, at most, unless they are absolutely trivial. Those minutes per workday are well spent.

> I'm one of those persons that read more code than I write nowadays, git log -G is my favorite command, and commit messages like the above hurts me daily.

-G just looks for changes in the patch so the commit message would not be relevant save possibly once you've reached an interesting-looking revision, do you mean `--grep`?

I'd assumed people only used -m for commits they're planning on discarding later. A single line is rarely descriptive enough for real work.

Brevity is a virtue. Failing to write a descriptive commit message, is not.

I'd say a message saying just "typos" is fine for a commit that fixes a bunch of quite obvious typos, for example. Or "added accidentally missing files" for one that adds some files that should have been tracked all along. Or "cosmetic" for one that cleans up some extra newlines or something.

You're right, it might make sense for simple changes, in the absence of a standard format for commit messages.

If you make lots of small commits, a single line is enough.

I generally disagree. Someone already linked to [0]. The background there is quite involved, and it doesn't go away if you break down the commit into many smaller ones. You could argue that sort of write-up belongs on a task-tracker like Jira rather than in a git commit message, but that's a different question.

Besides, overly small, overly numerous git commit messages are clunky. They clutter the commit graph without adding value, making it harder to get a clear picture of the work history in the repo. There's a happy middle-ground for the size of a commit: it should correspond to a meaningful unit of work, not the smallest committable unit of work. Of course, using too few very large commits is a problem too.

Perhaps, as gspr says, a single-line format may make sense in some instances. If a formalised format is used (as shown in [0]) then of course you'll never have the option.

[0] https://github.com/golang/go/commit/5779bb4e92911271583faa13...

I do make lots of awfully small commits, and a single line is rarely enough (but sometimes it indeed is)

> One liners forced a certain brevity

To the point that they're useless. Single-line commit message means you get at best the outline of the purpose of the commit, which is often fine but as I age I find that properly explaining the why and how, and possibly alternatives which were considered and discarded (and why) are absolutely invaluable.

My "model" for commits is postgresql, many messages are simple matching the commit itself (e.g. fix typo), but a number provide necessary background to the change e.g. https://github.com/postgres/postgres/commit/f3faf35f370f5586... says what it does in the short description, but then spends 4 paragraphs explaining the background of the issue, the change's concept, justification for changes going alongside it, and a link for more extensive discussions in case the rest was not sufficient (which it usually is).

... why did it never occur to me? x)

Small issue: your last sample has a copy/paste mistake, it says `[master 2fe1ef8] first line` with "first line" instead of "commit title"

Yep, amazing what you can learn when you read the manual.

This is great as it leaves the second line empty without you having to specify. It's a common mistake for people to put stuff onto the second line.

What's wrong with not flagging -m at all and simply writing a structured commit message in your cli text editor of choice?

why not just use `git commit` without the `-m` flag and when the terminal editor opens, type the commit message in the editor? That way you can format the commit message however you want and write whatever you want. And when you want to update the commit message just do `git commit --amend`.

my got foo is good enough that a GUI will only get in the way of what I want to do. But I never use the -m flag. Seeing the files that a I'm about to actually commit in my $EDITOR saved me a lot of headache because I forgot to add a file or added one that shouldn't have been. also really helps with writing extensive commit messages that actually describes the changes and why a certain solution was chosen. Was often grateful to my past self for writing down why I implemented it in a certain way and what other things I tried before that didn't work. Saved a lot of time retrying the same failed solutions

+1 for the -m option and commit messages :P


Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact