Як я можу обчислити кількість рядків, змінених між двома комітами в git?


746

Чи є простий спосіб обчислити кількість рядків, змінених між двома комітами в git?

Я знаю, що вмію робити git diffі рахувати рядки, але це здається нудним. Я також хотів би знати, як я можу це зробити, включаючи лише свої власні зобов'язання в лінійках.


3
Ви дивитесь на BitBucket.
Alex78191

Відповіді:


1112

Ви хочете, щоб --statваріант git diff, або якщо ви хочете проаналізувати це в сценарії, --numstatваріант.

git diff --stat <commit-ish> <commit-ish>

--statстворює зрозумілий для людини вихід, який ви звикли бачити після злиття; --numstatстворює хороший макет таблиці, який сценарії можуть легко інтерпретувати.

Я якось пропустив те, що ви хотіли зробити це на кількох комісіях одночасно - це завдання для git log. Рон ДеВера торкається цього, але ви насправді можете зробити набагато більше того, що він згадує. Оскільки git logвнутрішньо викликує машину diff для друку запитуваної інформації, ви можете надати їй будь-який з варіантів різної статистики - не тільки --shortstat. Можливо, ви хочете використовувати:

git log --author="Your name" --stat <commit1>..<commit2>

але ви можете використовувати --numstatабо --shortstatтакож. git logВи також можете обирати комісії різними іншими способами - ознайомтеся з документацією . Можливо, вас зацікавлять такі речі, як --since(замість того, щоб вказувати діапазони комісій, просто вибирайте комісії з минулого тижня) та --no-merges(об'єднання об'єктів насправді не вносять зміни), а також гарні параметри виводу ( --pretty=oneline, short, medium, full...).

Ось один-лайн, щоб отримати загальні зміни замість змін, що виконуються, з журналу git (змінити параметри вибору комісій за бажанням - це виконуєш ти, від commit1 до commit2):

git log --numstat --pretty="%H" --author="Your Name" commit1..commit2 | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%d\n", plus, minus)}'

(ви повинні дозволити git log друкувати деяку ідентифікаційну інформацію про фіксацію; я довільно вибрав хеш, потім використав awk лише для вибору рядків з трьома полями, які є тими, що мають статистичну інформацію)


2
Це не відповідає на початкове запитання про "змінені лінії". Одна зміна рядка обчислюється як вставлений, так і видалений рядок. Обчислення кількості змінених ліній потребує більшої роботи, ніж описано тут.
Віль Лаїтіла

12
@VilleLaitila: Це так близько, як ви можете дістатись без абсурдної кількості зусиль, і це було досить добре для ОП та 15 інших. (Як ви визначаєте, коли змінений рядок стає доданим рядком та видаленим рядком? Відредагуючи відстань між рядком - та +, як частку довжини рядка?) Усі ми знаємо, що зміни збільшуються вдвічі; ми можемо просто назвати цією корисною метрикою кількість змін і продовжувати своє життя.
Каскабель

188
git diff --shortstat <commit1> <commit2>був той, кого я хотів.
Кім

9
Для довідки, формат дати для --sinceі --untilщо - щось на кшталт: yesterday, 1 month 2 weeks 3 days 1 hour 1 second agoабо1979-02-26 18:30:00
juanmirocks

4
@Bryson Так, саме тому цей рядок говорить <commit-ish>- він працює з усім, що представляє собою коміт, включаючи буквальні коміти, гілки, теги та реф. Дивіться також stackoverflow.com/questions/23303549/…
Cascabel

193

Для ледачих використовуйте git log --stat.


14
Я вважаю це корисним, додав а, -10щоб показати попередні десять комітетів.
Choylton B. Higginbottom

2
Закінчивши перегляд історії фіксування, введіть Qдля повернення до терміналу.
Стевойасяк

180
git diff --shortstat

дає лише кількість змін та доданих рядків. Це працює лише з нестандартними змінами. Для порівняння з галуззю:

git diff --shortstat some-branch

3
Класно! але .. майте на увазі, що це працює лише з нефіксованими змінами
TomCobo

3
Якщо ви влаштували зміни git add, переконайтесь, що це потрібно зробитиgit diff --shortstat --cached
TomNash

Змінено 2463 файли, 39745 вставок (+), 21383 видалень (-) За останній місяць я фактично видалив близько 5 к 10 к. Це майже все, що я робив, окрім переміщення речей. Щось не так. Це не включає вилучені файли чи щось таке?
jgmjgm

46
git diff --stat commit1 commit2

EDIT: Ви також повинні вказати коміти (без параметрів він порівнює робочий каталог з індексом). Напр

git diff --stat HEAD^ HEAD

для порівняння батьків HEADз HEAD.


1
Ніколи насправді не потрібно використовувати diff-index- diffінтерфейс може впоратися з усім; Справа diff-indexохоплюється --cached/--staged, я вважаю. (І немає можливості використовувати diff-indexдля порівняння двох довільних комітетів, як просив ОП.)
Cascabel

Вихід цього для мене нічого.
Майк

@Mike: Ти залишив карат? Чи був ваш останній вчинення злиття? Якщо git каже, що немає різниці, це тому, що немає різниці.
Каскабель

6
або якщо не git diff --stat HEAD
сполучається

1
Крім того, ви можете порівняти далі назад, ніж просто батьківський, використовуючи HEAD~n, де nдалеко ви хочете повернутися назад. git diff --stat HEAD~5 HEADпокаже комбіновану статистику за останні 5 коміттів щодо HEAD.
Натан Бек

18

Припускаючи, що ви хочете порівняти всі ваші зобов’язання між abcd123 (перша комісія) та wxyz789 (остання фіксація), включно:

git log wxyz789^..abcd123 --oneline --shortstat --author="Mike Surname"

Це дає короткий вихід, як:

abcd123 Made things better
 3 files changed, 14 insertions(+), 159 deletions(-)
wxyz789 Made things more betterer
 26 files changed, 53 insertions(+), 58 deletions(-)

Вихід з цього приводу для мене нічого (я робив фіксації та перевіряв --author правильний, використовуючи його з журналом git та інших аргументів).
Майк

Це сталося і зі мною. Два комітети були в неправильному порядку, міняючи їх навколо виправленого.
bob esponja

1
Оновлено порядок здійснення зобов’язань та уточнив, що представляють два SHA. Дякуємо за те, що ви це
зробили

3
--shortstatПрапор є дивним, він працює з , git diffхоча (НЕ git log).
lucke84

Як їх узагальнити?
xpto

13

Ще один спосіб отримати весь журнал змін за визначений проміжок часу

git log --author="Tri Nguyen" --oneline --shortstat --before="2017-03-20" --after="2017-03-10"

Вихід:

2637cc736 Revert changed code
 1 file changed, 5 insertions(+), 5 deletions(-)
ba8d29402 Fix review
 2 files changed, 4 insertions(+), 11 deletions(-)

Маючи довгий вихідний вміст, ви можете експортувати у файл для більшої читабельності

git log --author="Tri Nguyen" --oneline --shortstat --before="2017-03-20" --after="2017-03-10" > /mnt/MyChangeLog.txt

2

Хоча всі вищевказані відповіді правильні, нижче одна зручна для використання, якщо вам потрібна кількість останніх чисел

нижче одного - підрахувати останні 5 комітів

git diff $(git log -5 --pretty=format:"%h" | tail -1) --shortstat

щоб підрахувати останні 10 комітів

git diff $(git log -10 --pretty=format:"%h" | tail -1) --shortstat

загальна - змініть N з кількістю останніх багатьох комісій, які вам потрібні

git diff $(git log -N --pretty=format:"%h" | tail -1) --shortstat

щоб підрахувати всі комісії з початку

git diff $(git log --pretty=format:"%h" | tail -1) --shortstat


Це дає "" хвіст "не розпізнається як внутрішня чи зовнішня команда, функціонуюча програма чи пакетний файл."
Чарльз Родді


1

Я просто вирішив цю проблему для себе, тому поділюся тим, що придумав. Ось кінцевий результат:

> git summary --since=yesterday
total: 114 file changes, 13800 insertions(+) 638 deletions(-)

Основна команда виглядає приблизно так:

git log --numstat --format="" "$@" | awk '{files += 1}{ins += $1}{del += $2} END{print "total: "files" files, "ins" insertions(+) "del" deletions(-)"}'

Зауважте $@в команді журналу, щоб передати свої аргументи, такі як --author="Brian"або --since=yesterday.

Уникнути awk, щоб вкласти його в псевдонім git, було безладним, тому замість цього я поставив його у виконуваний сценарій на своєму шляху ( ~/bin/git-stat-sum), а потім застосував сценарій у псевдонімі в моєму .gitconfig:

[alias]
    summary = !git-stat-sum \"$@\"

І це працює дуже добре. Останнє, що слід зазначити, file changes- це кількість змін у файлах, а не кількість унікальних змін. Це я шукав, але це може бути не те, чого ви очікуєте.

Ось ще один приклад чи два

git summary --author=brian
git summary master..dev
# combine them as you like
git summary --author=brian master..dev
git summary --all

Дійсно, ви повинні мати можливість замінити будь-яку git logкоманду на git summary.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.