Vscode: Git: Support editing the commit message in a text editor

Created on 13 Jul 2017  路  24Comments  路  Source: microsoft/vscode

When I make a commit, I enjoy writing the commit message in an editor window containing a complete diff of my staged changes. I can do that from the terminal by running the command:

git commit --verbose

However, VSCode doesn't seem to support that commit mode out of the box. Perhaps it could be the fallback behavior if you run one of the Git: Commit commands and enter a blank commit message. (Currently, that fails silently.) Or better yet, how about a git.verboseCommit setting that, set to true, would make the Git: Commit commands take me directly to the verbose commit editor?

feature-request git help wanted

Most helpful comment

Would love to see this feature implemented.

All 24 comments

You expect to edit the commit message in a full blown text editor?

Indeed. That's been my workflow for many years. I find it invaluable to see all my changes in one place as I try describe what I changed. It also makes it easy for me to spot any stray debugger statements and the like before I finalize the commit.

I'll repost my comment from https://github.com/Microsoft/vscode/issues/2718#issuecomment-289389110 where I asked for some specific features for the Git commit message editor (whether it's in a full editor window or not, though being in a full editor window would probably make it easier to implement this request):

... [T]he rule for Git commit message word wrapping should be very simple:

  1. First line warns if it's more than 50 columns. (This is the current behavior).
  2. Second line warns if it isn't blank.
  3. Rest of the commit wraps on spaces (or on any whitespace, but I recommend sticking with plain 0x20 space characters only for simplicity) at a user-configurable column, defaulting to 72 since that's the current standard recommended by Git.
  4. Any line in the commit that does NOT contain spaces does not wrap, but a warning pops up (similar to the warning if the first line is > 50 columns) saying "Your commit message contains # long line(s) which could not be wrapped because they do not contain spaces. If these lines are URLs, that's probably okay, but otherwise you should consider adding spaces so that the lines can be wrapped. Your settings are currently set to wrap any lines longer than 72 characters in your commit message." (With #, of course, being substituted for the actual number of too-long lines in the message.)
  5. That warning can be disabled in the user or workspace config settings, for the sake of any teams who have standardized on languages like Thai which do not use spaces in the language. The word-wrapping behavior can also be completely disabled if the user so desires, but it starts configured to be ON.
  6. (Optional). If the long line starts with the regex [a-zA-Z][-a-zA-Z+.]+: (see RFC 3986), it is assumed to be a URL and no warning is issued for that line, since it's usually not desirable to split a URL across two or more lines.

This would go a long way towards making VS Code's Git message editor usable. As of right now, I avoid using VS Code's Git integration because it doesn't format Git messages correctly according to the coding standards of just about every project I've worked on. So despite the fact that VS Code has pretty good Git integration for most things, I still just Alt-Tab to a terminal and write my Git commits in Vim, where I can set it up to do the right thing for commit messages (wrap at 72 columns, or at 70 for one project I work on that has slightly stricter rules than most).

@rmunn I'm not sure about bringing the issue of automatic wrapping up again in here in this issue that isn't really about it, though I see that you may have commented here because I'd closed #2718, which I've now re-opened.

Something I've learned from writing stkb/Rewrap is that wrapping isn't as simple as you'd first think and people have all sorts of requirements (ok, like just about every project then).

My workflow currently is to go the source control pane and look through the file diffs, then if it's a short commit message just type it in the box there, but it it's longer run git commit from the built-in terminal, which brings up a new vscode window where I have rulers set up at 50 and 72 columns and can use Rewrap to wrap the contents and check how it looks before committing.

So I don't see the need to use Vim, you can set up vscode as your git editor and for me it works fine. It would be nice if there was a faster way to switch to a full editor for the commit message, but I'd only put it in the "nice to have" category rather than essential.

Yes, I reposted it because it looked like #2718 had been prematurely closed, and I didn't want that feature request to get lost. Now that #2718 has been re-opened, that's the right place to track that feature.

Any news on whether this will be implemented? I really like VSCode's Git workflow but I like the commit message style from Atom. I think this could be implemented as an option on commit so that, instead of showing the one-liner text box, it shows a fully fleshed editor (ideally as a split panel) using git commit --verbose. One of the advantages is that all rulers and autocomplete extensions that you add to the editor would be available.

Currently I'm using the run-in-terminal extension with a shortcut tied to a custom script that reproduces the behaviour of VSCode's commit. It works but not always quickly and seems like an overkill.

Would love to see this feature implemented.

Currently I'm using the run-in-terminal extension with a shortcut tied to a custom script that reproduces the behaviour of VSCode's commit. It works but not always quickly and seems like an overkill.

@albireox would you mind sharing the implementation of that script? Do you do something other than shelling out to git commit --verbose, and have code set as your default Git editor?

The "script" I link to run-in-terminal is a simple fish shell function such as

function commit -d "Commits staged or all files"
    set result (eval "git diff --name-only --cached")
    if test -n "$result"
        git commit -v
    else
        git commit -v -a
    end
end

It basically checks if something has been staged and if not it commits everything.

hi, @joaomoreno from what you wrote in https://github.com/Microsoft/vscode/issues/43585 I would like to add that in our company we want to help juniors write good commit messages. It not only helps understand what commits were about but more importantly makes juniors think about the work they have done and most often we found that they go back to edit the commit. For example by splitting them into two or actually rewriting the code because they notice a single responsibility issue. To help them with this process we use git's template feature. This is what our template looks like in case you are curious.

I think it would be great if the warnings that are displayed in the VSCode's source control side-bar at the moment could also be shown in the editor. The auto-wrapping is of course even better but just the warning would also be a great benefit.

# 50-character subject line
#
# 72-character wrapped longer description. This should answer:
#
# * Why was this change necessary?
# * How does it address the problem?
# * Are there any side effects?
#
# Include a link to the ticket, if any.
#
# Add co-authors if you worked on this code with others:
#
# Co-authored-by: Full Name <[email protected]>
# Co-authored-by: Full Name <[email protected]>
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch address_picker
# Changes to be committed:
#   modified:   src/
#
# Changes not staged for commit:
#   modified:   package.json
#   modified:   src/
#

Funny enough, I sometimes end up going to the terminal and running git commit so I'd have a proper editor for my commit message.

@joaomoreno can you update the community on the status of this?

@TrevorBurnham Thanks for the --verbose that's going to be helpful :)

No status, it's in the Backlog.

Glad I'm not the only person whose commit workflow with vscode is to use the UI to commit with a dummy message and then immediately hit the terminal and do 'git commit --amend' so I can write a message in the full editor and not the silly popup.

Regarding the closed issue:

Most people don't really want a full editor taking away workbench space. They just want to type a message and move on.

I'd argue that isn't the case. You try submitting a quick one-liner message to any large project...

We are looking at using VS code for the Linux kernel. Commit messages typically run 20-70 lines long and generally require complex editing tasks like text reflow, copy & paste, careful indenting and managing the git tags list at the end. The tiny commit dialog is totally inadaquate for this task, it is required to have a fully featured editor.

Here are some examples of what is expected:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=28f94a44298c99c0db85539874b62f21d94fcaa7
(requires wrapping paragraphs)

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cc52d9140aa920d8d61c7f6de3fff5fea6692ea9
(requires manging indending and cut&paste alot of text)

Now that global tasks are supported, you can use something like this (at least on Linux). You can then assign a keybinding if you want.

(If anyone knows the appropriate command to do this on Windows, that would be amazing! Of course, it's easier if you have VS Code as your default Git editor to begin with.)

{
    "label": "git commit --verbose",
    "type": "shell",
    "command": "GIT_EDITOR=\"code --wait\" git commit --verbose",
    "presentation": {
        "echo": false,
        "reveal": "silent",
        "focus": false,
        "panel": "shared",
        "showReuseMessage": false,
        "clear": false
    },
    "problemMatcher": []
}

Repeating my specific request from #93117:

I'd like to be able to write a few paragraphs under the main git commit message. I can do that with git commit on the command line, but not in VS Code.

I'd also like to be able to see the diffs of my commit while committing, so a modal would not be ideal, and the sidebar is too thin to add the text area into.

So I suggest adding a panel at the top or bottom of the window, perhaps in the same area the terminal emulator is. That might be fine, although ideally I'd prefer the text area at the top.

Just throwing out my 2垄 and my preferred workflow.

I would like to tackle this and wonder if you already have some thoughts about this @joaomoreno?

My thoughts:

UX/UI

From the UI/UX perspective, I don't see much obstacles, just some decisions need to be made.

When a specific setting (git.commitUseEditor) is set to true, the message box in the repository pane is replaced by a Commit button. When this button, or rather one of the git.commit commands, is pressed, a file COMMIT_EDITMSG should open within the current window. When this file is closed, the commit should finish/continue. Basically the same workflow as if you would use GIT_EDITOR=code git commit.

Because it was mentioned often, another setting git.verboseCommit controls if you have the verbose output in your COMMIT_EDITMSG

Git Integration

So this is the tricky part IMO. I researched how other extensions/editors do it and made a small list of possible options:

1. Use GIT_EDITOR="${VSCODE_PATH} --wait" git commit

Not a lot of integration is required in this case, but it has one large drawback: A full vscode process instance is started. This takes some time and may be too slow for some people. I wouldn't recommend this path

2. Use GIT_EDITOR=false git commit

I found this method used in an old version of fuvitive-vim, specifically here. If the command is run, the commit will fail but COMMIT_EDITMSG will be generated. We can then open this file and once the users closes it, we can supply it via git commit --file .git/COMMIT_EDITMSG. It may sound like a hack, but it would be fast and AFAIK all git hooks would still work.

3. Use a temporary script as GIT_EDITOR

This in the new version of fuvitive-vim. Basically a temporary .sh script is created and used as GIT_EDITOR. This script checks periodically if another file exists (.exit file), and if so, exits. So the workflow could be similar to this:

  1. Create temporary .sh/.bat script in filesystem
  2. Use it as GIT_EDITOR. COMMIT_EDITMSG will be created and can be opened by vscode
  3. When the users closes COMMIT_EDITMSG, create .exit file
  4. .sh/.bat detects .exit file and closes --> git commit succeeds.

I personally think this is a clean way. However it depends heavily on the filesystem, not sure if you like that.

4. Use self-made COMMIT_EDITMSG

This approach is taken by git-plus for atom. It basically trys to recreate a COMMIT_EDITMSG by calling various git functions and dumping the contents to a file. So it never uses the real COMMIT_EDITMSG, only a custom one. Not a fan of this solution. I think the users would like to edit the real COMMIT_EDITMSG with its default contents.

What are your thoughts? Any better ideas I'm not aware of?

I already looked at the code part of the git integration, which is already abstracted heavily. If we have the overall direction, I will investigate in which parts of the code I would add the changes :)

Atom has nice UI for this that allows you to just switch between editing in the commit message text box and the full editor rather than a setting that sets you to only use on or the other.

Atom has nice UI for this that allows you to just switch between editing in the commit message text box and the full editor rather than a setting that sets you to only use on or the other.

Ah, seems like you're referring to the GitHub package. For future reference, they also use a custom file called ATOM_COMMIT_EDITMSG. It's empty when opened and has no info about the commit.

gif

But I like the idea of not having a setting, but a small button which opens the commit message in an editor. 馃憤

An update from my side:

I thought more about the whole git <-> vscode communication and found out, that there is an existing IPC workflow used in the git extension to ask for the password when cloning/pulling repos. Knowing this, I made a small Proof of Concept based on the following principles:

  • Introduced git.useEditorToCommit: boolean, which specifies if the editor should be used for committing. Note, you can still use the small box on the repository panel, but when running any commit command or CTRl+ENTER while the commit inputbox is still empty, it will trigger a editor commit.
  • Introduced git.verboseCommit: boolean, should be self-explanatory, adds verbose output to COMIT_EDITMSG
  • When an editor commit is triggered, the following things happen:

    • No message is supplied to git commit, but GIT_EDITOR points to a custom.sh/.bat, which starts a nodejs process and connects via IPC & HTTP to the main process. This call also contains the COMMITEDIT_MSG path. Very similar to the askpass process of vscode

    • The main process gets the path and opens it as an editor. The HTTP-Server does not immediately send a response. It waits until the file is closed. This has the effect, that git commit waits until the user is finished with editing the message

img
(In this example I press CTRL+ENTER on the inputbox)

Problems:

  • Since the HTTP-Call is kept open and no data is sent, it timeouts after some time. This triggers an empty commit message and aborts the call.

https://github.com/microsoft/vscode/compare/master...JohnnyCrazy:testing-git

Before going further into the rabbit hole, I'll wait for feedback from @joaomoreno. Maybe that's not at all what you have imagined :P

Small bump for feedback from @joaomoreno and a possible fix for the problem stated above:

The default timeout of http.Server, which is used by the IPC, is 2 minutes. A simple solution would be disabling it. This is, btw, also the default in node 13.

@JohnnyCrazy This is great, exactly what we should do. Feel free to start a PR and we'll work from there.

Excited to see this merge. This is the main dealbreaker to a VS Code workflow for Git for me.

Nice work, @JohnnyCrazy.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

philipgiuliani picture philipgiuliani  路  3Comments

curtw picture curtw  路  3Comments

borekb picture borekb  路  3Comments

shanalikhan picture shanalikhan  路  3Comments

lukehoban picture lukehoban  路  3Comments