lostintangent / gitdoc

VS Code extension that allows you to edit a Git repo, like it's a multi-file, versioned document.
https://aka.ms/gitdoc
MIT License
269 stars 24 forks source link

Feature Request: More Verbose Auto-Commit Messages #51

Open dylan-k opened 1 year ago

dylan-k commented 1 year ago

There's a different extension out there, which can create more detailed commit messages. Even when squashed, it might help to have these details from something like gitdoc. They more closely resemble the so-called Conventional Commits.

I thought to share it here and request this functionality, as it doesn't seem the two work together very well.

lostintangent commented 1 year ago

Apologies for the late reply! I was on vacation for a bit. I think this is a great idea, and I actually already do this for my GistPad extension. Out of curiosity: are you mostly interested in the commit message that includes the impacted file names and operation? Or did you also want to include the conventional commit prefix?

Aincvy commented 1 year ago

I'd like to have the list of changed files. I don't know why, perhaps because Gitlab did it this way.

vergenzt commented 1 year ago

I'd love this too! FWIW I've written a script to do this in the past using the output of git status --porcelain=v1 -z, and using jq to do the core processing. (I also wrapped this up into a git commit-on-save alias to use fswatch to trigger the commits. This repo already handles that part, but I'll include it below for context.)

Here's the scripts, in case they're helpful for anybody else:

# file: ~/.gitconfig
...
[alias]
    summary = "!git status --porcelain=v1 -z | jq -rR git_summarize_changes"
    commit-on-save = "!set -x; fswatch -l20 -0b . | xargs -0n1 git ls-files -z | xargs -0n1 bash -c 'git add -A && git commit -m \"$(git summary)\" && git push'"
# file: ~/.jq
...

def git_summarize_changes: (
  [
    scan("(?x)
      (?: \\A | \\G )
      (?<index_status> (?<is_rename>[RC]) | [^RC] )
      (?<worktree_status> . )
      [ ]
      (?<path> [^\u0000]+ ) 
      (?(<is_rename>) \u0000 (?<renamed_from> [^\u0000]+ ) )
      (?: \\Z | \u0000 )
    ")
    | . as [$index_status, $_, $__, $path, $renamed_path]
    | {$index_status, $path, $renamed_path}
  ]
  | length as $num_files
  | group_by(.index_status)
  | map(

    # https://git-scm.com/docs/git-status#_short_format
    ({
      "M": "update",
      "A": "add",
      "D": "delete",
      "R": "rename",
      "C": "copy",
      "T": "change type of",
    }[.[0].index_status] // empty)

    + " "
    + (
      if $num_files == 1
      then .[] | .path + (if .renamed_path then " from " + .renamed_path else "" end)
      else "\(length) file" + (if length == 1 then "" else "s" end)
      end
    )
  )
  | if length == 0
    then error("No staged git changes")
    else
      join(", ")
      | (.[0:1] | ascii_upcase) + .[1:]
    end
);

I think I did some manual testing when I first wrote this (the details of which have been lost to time), but hopefully it's a starting point.

dylan-k commented 6 months ago

Or did you also want to include the conventional commit prefix?

A prefix might be nice, yes. Perhaps "auto" is a good prefix to have by default, though.

lostintangent commented 5 months ago

Does this look close to what you have in mind? https://copilot-workspace.githubnext.com/lostintangent/gitdoc/issues/51?shareId=4f167bda-f665-4e96-9dd8-25850bf01eab