Git commit accepts several message flags (-m) to allow multiline commits
stefanjudis.com
stefanjudis.com
$ git commit -m "Fix issue" -m "Lorem ipsum..." -e> 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).
"\C-x\C-e": edit-and-execute-command bind -p
or 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. git commit -F- <<EOF
Fix issue
Hello world...
EOFPut 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.
fold -c -s -w 80 | git commit -F - <<EOF
Fix issue
Hello world...
EOF 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...It is in Bash.
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.
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.
[is writing commit message]
Oh wait… What did I change?
^Z
git diff --cached
Oh yeah. fgBut it's still more efficient method for single repository project where using UI git client would be the overkill.
I have no idea why anyone would ever not use this to be honest.
: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.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.
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.
-v makes this so much better - forget seeing the list of files in the commit; you can see the whole diff! :)
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.
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.
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.
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.
Edit: In fact, still don't. The git editor seems to be configured by some git config rather than environment variables.
If you want to use a different editor just for git you can set $GIT_EDITOR in your environment.
If you're using fzf [0] for history recall (ctrl+R) it also has the nice side-effect for not cluttering up your history.
git config --global commit.verbose trueThey 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.
There is also lazygit, it's kind of similar, but different.
Another feature I really like with fugitive is :Ggrep which runs a git grep and returns the result in the quickfix list.
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 add -p` will give you a interactive way of committing partial changes.
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.The only concern is the odd situation where I'd staged something before realising I was missing bits in the commit message.
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
zsh
$ git commit -m $'Bugfix #95\n\nEverything's fine, please move along.'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.
> 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.
I would be curious to hear how others view this.
See the recent discussion here: https://news.ycombinator.com/item?id=23739076
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. 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.
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.
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.
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.
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.
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”.
I even like this in my personal projects: It shows me how good both my commit messages and granularity are.
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 have used it, but it never “clicked” me. I am always uncertain about what to do next as I browse git blame on GitHub
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 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.
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 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.
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).
Found the tautology.
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' :(
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.
Six months later: Why did I do this?
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.
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).
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...
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.
e.g.
git commit -m "Short commit message
Longer description
of my commit"[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
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.
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.
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.
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>`.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 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 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.
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)
Thanks everyone :-)
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.
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).
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.
-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 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.
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.
Brevity is a virtue. Failing to write a descriptive commit message, is not.
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...
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).
Small issue: your last sample has a copy/paste mistake, it says `[master 2fe1ef8] first line` with "first line" instead of "commit title"