Как совместить вывод команд `git diff --name-status` и` git diff --stat`? - PullRequest
0 голосов
/ 26 июня 2018

С помощью команды git diff --name-status я могу видеть имена файлов с таким статусом файла:

M       .bashrc
D       .ghc/.ghci.conf.un~
D       .ghc/ghci_history
M       .life
A       .profile
M       .spacemacs

С git diff --stat Я могу видеть статистику количества строк и изменений файла:

 .bashrc             |   3 ++-
 .ghc/.ghci.conf.un~ | Bin 13912 -> 0 bytes
 .ghc/ghci_history   | 100 --------------------------------------------------------------------------------------------
 .life               |   2 ++
 .profile            |  23 +++++++++++++++++++++
 .spacemacs          |   3 +++

Есть ли способ объединить выводы обеих команд? Я хотел бы иметь что-то вроде этого:

M  .bashrc             |   3 ++-
D  .ghc/.ghci.conf.un~ | Bin 13912 -> 0 bytes
D  .ghc/ghci_history   | 100 --------------------------------------------------------------------------------------------
M  .life               |   2 ++
A  .profile            |  23 +++++++++++++++++++++
M  .spacemacs          |   3 +++

Конечно, я могу сделать это вручную, вызывая обе строки, а затем манипулируя строками. Но я не уверен, насколько надежны и последовательны выводы для этих команд. Может быть, это где-то задокументировано. Не могли бы вы предоставить команду оболочки, которая позволит мне видеть такие различия с терминала?

Ответы [ 3 ]

0 голосов
/ 17 марта 2019
DIFF=origin/master..HEAD
join -t $'\t' -1 2 -2 1 -o 1.1,2.1,2.2 \
        <(git diff --name-status $DIFF | sort -k2)
        <(git diff --stat=$((COLUMNS-4)),800 $DIFF | sed -e '$d' -e 's/^ *//;s/ /\t/' | sort) \
        | sed 's/\t/ /g'

Или полностью POSIX в секции [alias] ~/.gitconfig

ndiff = "!f() { TAB=`printf '\t'`; COLUMNS=`stty size|cut -d' ' -f2`; cd $GIT_PREFIX; git diff --name-status $1 | sort -k2 > /tmp/.tmpgitndiff ; git diff --stat=$COLUMNS,800 $1 |sed -e '$d' -e \"s/^ *//;s/ /${TAB}/\" | sort | join -t \"${TAB}\" -1 2 -2 1 -o 1.1,2.1,2.2 /tmp/.tmpgitndiff - | sed \"s/${TAB}/ /g\"; rm -f /tmp/.tmpgitndiff; }; f"
$ git ndiff origin/master..HEAD -- dev/ # example
M dev/main.scss   |   9 +
A dev/rs.js       |  19 ++
0 голосов
/ 28 июня 2019

Вы также можете использовать цикл for для фильтрации выходных данных для каждого возможного состояния:

for filter in A C D M R T U X B; do git diff --diff-filter="$filter" --stat | head -n -1 | sed "s/.*/$filter &/"; done;
  • --diff-filter гарантирует, что отображаются только файлы с текущим статусом (например, только [A] dded файлы)
  • --stat показывает желаемый статус
  • команда head затем удаляет последнюю строку для каждого вывода статистики (например, x files changed, n deletions)
  • наконец, команда sed вставляет текущий фильтр при запуске (например, A)

Это означает, что вы всегда сортируете файлы по их статусу, а не по тому, как они были бы отсортированы одной командой git.

Редактировать

Как уже упоминалось @Shersh в комментариях, tail -n не работает с отрицательными целыми числами в macOS. Есть два решения для этого:

  1. Либо установить ghead: brew install coreutils (кредит к комментарию jchook в этот ответ )
  2. Или используйте tac, чтобы перевернуть строки, начните со второй строки с tail -n +2, а затем снова переверните с tac:
for filter in A C D M R T U X B; do git diff --diff-filter="$filter" --stat | tac | tail -n +2 | tac | sed "s/.*/$filter &/"; done;

Ps. вместо tac вы также можете использовать tail -r, но это работает не на всех системах, и вы теряете выравнивание (см. комментарий @ Shersh, не удалось проверить мою систему).

0 голосов
/ 26 июня 2018

Быстрее всего было использовать wdiff:

$ wdiff -n -w '' -x '' -y '' -z '' <(git diff --name-status) <(git diff --stat)
vvv 2018-06-26 10:08:27-0700
M       foo/baz.py   | 19 +++++++++++--------
M       foo/bar.py   | 37 ++++++++-----------------------------
M       foo/qux.py   |  2 +-
 3 files changed, 20 insertions(+), 38 deletions(-)

Опции -[w-z] устанавливают разделители для начала / конца вставки / удаления.

-n гарантирует, что выходные данные также совпадают ... что, вероятно, не имеет значения при пропуске -[w-z], но является хорошей привычкой для wdiff в целом.

Теоретически, это может привести к ошибке, если ваше имя файла будет похоже на что-либо еще в строке. К счастью, хорошая практика позволяет избегать имен файлов, таких как M, |, 19 и +++++++++++--------


Более правильный способ - использовать paste, но для этого потребуется пропустить вывод через sed, чтобы удалить дублирующиеся детали.

...