Как автоматически генерировать сообщение фиксации

В некоторых (очень) редких случаях я делаю некоторые изменения в моем репозитории, которые настолько понятны, что сообщение о фиксации, описывающее мои намерения, несколько бесполезно. В этих случаях я хотел бы, чтобы сообщение commit в основном просто указывало, какие файлы я добавил/удалил/отредактировал. Например:

Добавлено 'dog.h', 'cat.h'

Сообщение о ручной фиксации будет выглядеть как

Добавлены файлы заголовков

В таких ситуациях было бы неплохо не писать написание, а скорее автоматически генерировать.

Я знаю, что это очень плохая практика, но я бы использовал это только для непрофессиональных репозиториев, используемых для частных проектов. Я знаю, что это лениво, но мне любопытно, как это можно сделать. Предпочитаются сценарии оболочки Unix, но любое решение приветствуется.

Q: Есть ли способ автоматически генерировать сообщение о фиксации git, перечисляя, какие файлы были изменены?

Ответ 1

Если вы действительно ленивы, вы можете просто использовать следующее. Короче говоря, он делает git status, извлекает строки для new files, deleted, renamed и modified и передает его на git commit

# LANG=C.UTF-8 or any UTF-8 English locale supported by your OS may be used
LANG=C git -c color.status=false status \
| sed -n -r -e '1,/Changes to be committed:/ d' \
            -e '1,1 d' \
            -e '/^Untracked files:/,$ d' \
            -e 's/^\s*//' \
            -e '/./p' \
| git commit -F -

Измените часть sed, чтобы настроить, как вы хотите, чтобы сообщение было сгенерировано основанием в результате git status

Отложите его на что-то короткое или сохраните его как script (например, git-qcommit), чтобы вы могли использовать его как git qcommit

Образец сообщения из git log

adrianshum:~/workspace/foo-git (master) $ git log
commit 78dfe945e8ad6421b4be74cbb8a00deb21477437
Author: adrianshum <[email protected]>
Date:   Wed Jan 27 01:53:45 2016 +0000

renamed:    bar.txt -> bar2.txt
modified:   foo.txt

Отредактировано: Изменен оригинал grep до sed, чтобы сделать логику генерации сообщения фиксации более общей, включив строки между Changes to be committed и Untracked files, и создайте немного лучше выглядящее сообщение фиксации)

Ответ 2

Если вы не предоставляете сообщение (используя флаг -m), автоматически созданное сообщение будет открыто и попросит вас его изменить (если вы с ним). Это выглядит так:

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch <branch>
# Changes to be committed:
#       deleted:    <deleted files>
#       modified:   <modified files>
#
# Untracked files:
#       <untracked files>

Теперь вам просто нужно удалить # из строк, которые вы хотите вставить (например, измененные).

Я действительно отговариваю вас от этого, фиксация сообщений очень важна.

Связанный вопрос с другим (возможно, лучшим) подходом.

Ответ 3

Вы можете использовать команду commit -m для передачи любого сообщения в качестве сообщения о фиксации.


Другим решением является использование параметра конфигурации шаблона для определения шаблона по умолчанию.

commit.template

Существует конфигурационная переменная commit.template.

commit.template

Укажите файл для использования в качестве шаблона для новых сообщений фиксации.
"~/" расширяется до значения $HOME и "~ user/" в указанном домашнем каталоге пользователей.

Ответ 4

Иногда я просто хочу зафиксировать с автоматически сгенерированным сообщением. Этот скрипт захватывает вывод состояния git status --porcelain и использует его в качестве сообщения фиксации.

#!/usr/bin/env node
var childProcess = require('child_process');
var spawn = childProcess.spawn;

function getStatusMessage() {
  var bash = spawn('bash');
  bash.stdin.end('git status --porcelain');

  return new Promise(function (resolve) {
    bash.stdout.on('data',function (data) {
      resolve(data.toString());
    });
  });
}

getStatusMessage().then(function (statusMessage) {
  var bash = spawn('bash');
  bash.stdin.end('git commit -m "'+statusMessage+'"');
  bash.stdout.on('data',function (data) {
    console.log(data.toString());
  });
  bash.stderr.on('data',function (data) {
    console.log(data.toString());
  });
});