Analyzing KDE Project Health With git!

I was reading the latest edition of Kevin Ottens’ excellent weekly web review and one particular article caught my eye: “The Git Commands I Run Before Reading Any Code“. In a nutshell, you can use the git version control tool to quickly assess a project’s health, what breaks, who’s a key figure, how bad emergencies are, and so on.

So useful!

I immediately wanted to apply this to KDE projects. So I took the commands from the post and made some shell aliases and functions for convenience:

# git repo analysis tools
alias what-changes="echo 'What changes a lot?' && git log --format=format: --name-only --since='1 year ago' | rg -v 'po$|json$|desktop$' | sort | uniq -c | sort -nr | head -20"
alias what-breaks="echo 'What breaks a lot?' && git log -i -E --grep='fix|bug|broke|bad|wrong|incorrect|problem' --name-only --format='' | sort | uniq -c | sort -nr | head -20"
alias emergencies="echo 'And what were the emergencies?' && git log --oneline --since='1 year ago' | grep -iE 'revert|hotfix|emergency|urgent|rollback'"
alias momentum="echo \"What's the project's momentum over the past 5 years?\" && git log --format='%ad' --date=format:'%Y-%m' | sort | uniq -c | tail -n 60"
alias maintainers-recently="echo \"Who's been driving this project in the past year?\" && git shortlog -sn --no-merges --since='1 year ago' | rg -v 'l10n daemon script' | head -n 30"
alias maintainers-alltime="echo 'And what about for all time?' && git shortlog -sn --no-merges | rg -v 'l10n daemon script' | head -n 30"
function repo-analysis {
what-changes
echo
what-breaks
echo
emergencies
echo
momentum
echo
maintainers-recently
echo
maintainers-alltime
}

Now let’s run it on Plasma. Here’s plasma-workspace, the core of Plasma:

$ git clone ssh://git@invent.kde.org/plasma/plasma-workspace.git
$ cd plasma-workspace
$ repo-analysis
What changes a lot?
  1519  
    38 CMakeLists.txt
    29 shell/shellcorona.cpp
    24 runners/services/servicerunner.cpp
    21 wallpapers/image/imagepackage/contents/ui/config.qml
    19 libnotificationmanager/notifications.cpp
    18 shell/org.kde.plasmashell.desktop.cmake
    18 devicenotifications/devicenotifications.cpp
    17 kcms/lookandfeel/kcm.cpp
    16 wallpapers/image/plugin/model/packagelistmodel.cpp
    16 kcms/cursortheme/xcursor/xcursor.knsrc
    15 wallpapers/image/plugin/model/imagelistmodel.cpp
    15 applets/notifications/global/Globals.qml
    15 applets/devicenotifier/devicecontrol.cpp
    14 wallpapers/image/plugin/imagebackend.cpp
    14 shell/panelview.cpp
    14 .kde-ci.yml
    14 applets/systemtray/systemtray.cpp
    13 runners/services/autotests/servicerunnertest.cpp
    12 krunner/qml/RunCommand.qml

What breaks a lot?
   225 shell/shellcorona.cpp
   183 shell/panelview.cpp
    83 CMakeLists.txt
    74 applets/systemtray/package/contents/ui/main.qml
    71 applets/digital-clock/package/contents/ui/DigitalClock.qml
    63 klipper/klipper.cpp
    62 applets/notifications/package/contents/ui/NotificationItem.qml
    58 wallpapers/image/imagepackage/contents/ui/config.qml
    56 shell/desktopview.cpp
    56 libtaskmanager/tasksmodel.cpp
    54 shell/main.cpp
    54 applets/systemtray/systemtray.cpp
    53 shell/shellcorona.h
    52 krunner/view.cpp
    48 applets/digital-clock/package/contents/ui/CalendarView.qml
    47 runners/services/servicerunner.cpp
    46 wallpapers/image/imagepackage/contents/ui/main.qml
    45 applets/notifications/package/contents/ui/NotificationPopup.qml
    44 applets/systemtray/package/contents/ui/ExpandedRepresentation.qml
    43 startkde/startplasma.cpp

And what were the emergencies?
4f526a7bd1 Revert “applets/systemtray: Prevent popups from overlapping with the panel”
dca5788fee lookandfeel/components: Revert Plasma::setupPlasmaStyle
2c0fd34541 Revert “ContainmentLayoutManager: send recursive mouse release events too”
b6b230f4ff Revert “Read selenium-webdriver-at-spi-run location from CMake”
b8651b56f6 hotfix: Remove doc translations without actual doc
1f43f576e8 Revert “Add forceImageAnimation property to force animated image play”
f0349b6c81 hotfix: remove stray .po file
3ff7ae4269 Revert “CI: enable parallel testing”
83bebc7896 Revert “Limit evaluateScript execution at 2 seconds”
4f45f672be Revert “kcms/componentchooser: Don’t offer NoDisplay services”
3bf0ff8f56 Revert “Disable linux-qt6-next while the regression in Qt gets fixed”
80996f0633 Revert “kcms/wallpaper: set roleNames for WallpaperConfigModel”

What’s the project’s momentum over the past 5 years?
   148 2021-05
    87 2021-06
    62 2021-07
    85 2021-08
   121 2021-09
   106 2021-10
   146 2021-11
   190 2021-12
   191 2022-01
    84 2022-02
   168 2022-03
   130 2022-04
   146 2022-05
   141 2022-06
   136 2022-07
   107 2022-08
   232 2022-09
   234 2022-10
   181 2022-11
   150 2022-12
   154 2023-01
   161 2023-02
   156 2023-03
   156 2023-04
   163 2023-05
   137 2023-06
   186 2023-07
   190 2023-08
   275 2023-09
   226 2023-10
   283 2023-11
   157 2023-12
   131 2024-01
   147 2024-02
   249 2024-03
   180 2024-04
   188 2024-05
   158 2024-06
   128 2024-07
   146 2024-08
   169 2024-09
   156 2024-10
   116 2024-11
    98 2024-12
   145 2025-01
   126 2025-02
   120 2025-03
   116 2025-04
   131 2025-05
   131 2025-06
   132 2025-07
   115 2025-08
   110 2025-09
    97 2025-10
   147 2025-11
   114 2025-12
   140 2026-01
   131 2026-02
   119 2026-03
    44 2026-04

Who’s been driving this project in the past year?
  116  Vlad Zahorodnii
  113  Nicolas Fella
   87  Christoph Wolk
   82  Fushan Wen
   78  Nate Graham
   66  Kai Uwe Broulik
   48  Bohdan Onofriichuk
   37  Harald Sitter
   34  Tobias Fella
   31  Marco Martin
   30  David Edmundson
   25  Akseli Lahtinen
   21  Ismael Asensio
   17  David Redondo
   16  Niccolò Venerandi
   15  Bhushan Shah
   11  Alexander Lohnau
   11  Kristen McWilliam
    9  Oliver Beard
    9  Shubham Arora
    8  Alexey Rochev
    8  Han Young
    8  Philipp Kiemle
    7  Albert Astals Cid
    6  Aleix Pol
    6  Méven Car
    5  Devin Lin
    5  Joshua Goins
    4  Alexander Wilms
    4  Arjen Hiemstra

And what about for all time?
 1543  Fushan Wen
 1497  Marco Martin
 1374  Kai Uwe Broulik
 1030  David Edmundson
  772  Nate Graham
  658  Alexander Lohnau
  551  Aleix Pol
  548  Nicolas Fella
  438  ivan tkachenko
  385  Eike Hein
  264  Sebastian Kügler
  250  Martin Gräßlin
  238  Harald Sitter
  232  Martin Klapetek
  223  Jonathan Riddell
  207  Vlad Zahorodnii
  194  David Redondo
  190  Friedrich W. H. Kossebau
  189  Laurent Montel
  144  Bhushan Shah
  134  Christoph Wolk
  134  Ismael Asensio
  126  Lukáš Tinkl
  121  Niccolò Venerandi
  117  Méven Car
  105  Natalie Clarius
   91  Konrad Materka
   80  Vishesh Handa
   80  Volker Krause
   79  Ivan Čukić

ShellCorona both changing and breaking a lot is no great surprise to me; it’s fiddly and complicated. We need to do something about that. The number of emergencies doesn’t look too bad, and momentum feels fine too. The project also appears to have a nice healthy diversity of contributors. Excellent!

It’s been quite illuminating to run these tools on KDE projects that I’m both more and less familiar with. Give it a try!

Leave a comment