Posted by grepsedawk 10 hours ago
What Changes the Most
jj log --no-graph -r 'ancestors(trunk()) & committer_date(after:"1 year ago")' \
-T 'self.diff().files().map(|f| f.path() ++ "\n").join("")' \
| sort | uniq -c | sort -nr | head -20
Who Built This jj log --no-graph -r 'ancestors(trunk()) & ~merges()' \
-T 'self.author().name() ++ "\n"' \
| sort | uniq -c | sort -nr
Where Do Bugs Cluster jj log --no-graph -r 'ancestors(trunk()) & description(regex:"(?i)fix|bug|broken")' \
-T 'self.diff().files().map(|f| f.path() ++ "\n").join("")' \
| sort | uniq -c | sort -nr | head -20
Is This Project Accelerating or Dying jj log --no-graph -r 'ancestors(trunk())' \
-T 'self.committer().timestamp().format("%Y-%m") ++ "\n"' \
| sort | uniq -c
How Often Is the Team Firefighting jj log --no-graph \
-r 'ancestors(trunk()) & committer_date(after:"1 year ago") & description(regex:"(?i)revert|hotfix|emergency|rollback")'
Much more verbose, closer to programming than shell scripting. But less flags to remember.Not meaning to offend anyone: Nix is cool, but adds complexity. And as a disclaimer: I used jujutsu for a few months and went back to git. Mostly because git is wired in my fingers, and git is everywhere. Those examples of what jujutsu can do and not git sound nice, but in those few months I never remotely had a need for them, so it felt overkill for me.
You can find this pattern again and again. How many redditors say 120fps is essential for gaming or absolutely require a mechanical keyboard?
I don't get the mechanical keyboard one, though. I am fine with any keyboard, I just like my mechanical keyboard at home. Just like I am fine with any chair, but ideally I would have a chair I like at home.
120fps I have no experience with, but I would imagine it's closer to video quality. Once you're used to watching everything in 4K, probably it feels frustrating to watch a 1080p video. But when 4K did not exist, it was not a need. I actively try to not get used to 4K because I don't want to "create the need" for it :-).
For jujutsu, it's fine on your own computer, but you probably have to use git in the CI or on remote servers. And you probably started with git, so moving to jujutsu was an added effort (similar to dvorak).
The most frequent "complex" command I use is to find commits in my name that are unsigned, and then sign them (this is owing to my workflow with agents that commit on my behalf but I'm not going to give agents my private key!)
jj log -r 'mine() & ~signed()'
# or if yolo mode...
jj sign -r 'mine() & ~signed()'
I hadn't even spared a moment to consider the git equivalent but I would humbly expect it to be quite obtuse.Does "own" try to sign working copy snapshot commits too? That would greatly increase the number and frequency of signatures.
> Does "own" try to sign working copy snapshot commits too?
Yes
I don't use aliases, I guess I'm insane?
Also 99.9% of the time, git "just works" for me. If I need to do something special once a year, I can search for it. Like I would with jujutsu.
At this point perhaps a million person-years have been sacrificed to the semantically incoherent shit UX of git. I have loathed git from the beginning but there's effectively no other choice.
That said, the OP's commands are useful, I am copying them (because obviously I won't ever memorize them).
I wrote a cheat sheet in my notes of common commands, until they stuck in my head and I haven't needed it now for a decade or more. I also lean heavily on aliases and "self-documenting" things in my .bashrc file. Curious how others handle it. A search every time I need to do something would be too much friction for me to stand.
Yes! We mostly wouldn’t tolerate the complexity and the terrible UX of a tool we use everyday--but there's enough Stockholm Syndrome out there where most of us are willing to tolerate it.
Git may be sharp and unwieldy, but it's also one of the decreasing amount of tools we still use - the trend of turning tools into toys consumed the regular user market and is eating into tech software as well.
https://github.com/denisidoro/navi
But for Git, I can't recommend lazygit enough. It's an incredible piece of software:
FWIW I too was once a "memorised a few commands and that was it" type of dev, then I read 3 chapters of the Git book https://git-scm.com/book/en/v2 (well really two, the first chapter was a "these are things you already know") and wow did my life with git change.
Or, perhaps better yet, defining your own functions/helpers as you go for things you might care about, which, by virtue of having been named you, are much easier to remember (and still compose nicely).
And yes, I'm also ecstatic when I manage to iterate over anything in `jq` without giving up and reaching for online reference. For `git`, functionality I use divides neatly into "things I do at least every week or two" and "things that make me reach for the git book every single time".
I mean, that was true until ~year or so. Now, I just have an LLM on speed dial. `howto do xyz in $tool`, `wtf is git --blah`, `oneliner for frobbing the widget`, etc.
Don't feel bad - no one remembers them all, we just remember a few idioms we use...
We can't.
Why do you think the `man` command exists?
But jq I use maybe once a week, and it just won't stick. Same for any git features beyond basic wrangling of the history tree (but, on the flip side, that basic wrangling has eliminated 99% of the times I have to look things up).
If you have multiple machines (/must have), just apply your user config to current machine?
I often feel I need to setup bots to make superfluous commits just to make it look like my useful and stable repos are “active”
One example (not mine) a a qr-code generator library. Hasn’t been updated in 10 years. It’s perfect as is. It just provides the size and the bits. You convert those bits to any representation you want. It has no need to be updated
It's not impossible, of course, but if I saw even a qr library that hadn't changed in 10 years I would worry that it wouldn't build on current systems (due to dependencies) and that nobody was actually using it (due to lag of bug reports).
A QR (or barcode) library is exactly the type of thing I’d assume would still work fine, since there’s nothing new to do, the parsing rules don’t change, it’s a static, known, solved problem.
I agree with you - and yet the barcode library I used recently for a variable-data-printing project was last updated 13 hours ago, despite having been around since 2008!
Agreed. Assuming there are no open issues and PRs. When I find a project, if the date of the last commit is old, I next look at the issues and PRs. If there are simple-to-deal-with issues (e.g. a short question or spam) and easy-to-merge PRs (e.g. fixing a typo in the README) which have been left lingering for years, it’s probably abandoned. Looking at the maintainer’s GitHub activity graph should provide more clues.
> I often feel I need to setup bots to make superfluous commits just to make it look like my useful and stable repos are “active”
I have never done it, but a few times thought about making a “maintenance” release to bump the version number and release date, especially since I often use a variant of calendar versioning.
A language that properly maps to the data model, and has readable identifiers is a boon. Git is a database, a database needs a proper query language.
`git log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --`
Which is something I see a lot of people alias in Git for viewing logs.
Disclaimer: I love jq too :)
All joking aside, it really is a chronic problem in the corporate world. Most codebases I encounter just have "changed stuff" or "hope this works now".
It's a small minority of developers (myself included) who consider the git commit log to be important enough to spend time writing something meaningful.
AI generated commit messages helps this a lot, if developers would actually use it (I hope they will).
If I joined a company where people committed their code with "stuff" or "made some changes" or "asdfhlfo;ejfo;ae," that would be a red flag that I might have joined the wrong company, and I'd start to wonder what else the developers here do carelessly.
These things never take much time but people dismiss them because of that. Because each commit and each comment in isolation isn't very valuable but they are very helpful in aggregate. I'm not sure why this bias exists though, since the same is true for lines of code. It's also true about a ton of things. All the little things add up. Just because it's little now doesn't mean it's not important
So we told him to commit at least once every day, with a relevant commit message, or else fail his internship.
He worked 21 more days. There were 21 commits: "17:00, time to go home".
In the company I work for, there is a team that has isolated itself to some extent from other teams and works at a furious pace to keep their particular section of the business happy. We're lucky enough that they spun up their own repo to do their work on, so they don't actually impact other teams, but if the quality of the commit messages is anything to go by, I am 100% certain they're going to end up in a huge mess, if they aren't already. The team lead encourages this, and certainly doesn't care about commit messages etc.
Developers who care about other developers tend to write better quality code, because they care what other developers think of them. If you care about other developers, you will most likely write decent quality commit messages too.
I have seen over many years the types of developers who only care about moving their own code into production as fast as possible and getting to the next thing. There is a very high correlation with a mess at the end, which they inevitably won't have to tidy up because they'll be doing the next thing. These types of developers hate owning stuff in production, so they don't do it, so they don't actually care how maintainable their "clever" code is. I am very certain that a number of people reading this will be those types of developers.
As a manager, one of the first things I do is make sure that the PR titles (the PR text becomes the commit messages in squash-merging workflows) at minimum begin with a ticket number. Then we can later read both the intention and the commentary on it.
Personally no, the code is the "truth". If I need more I'm going to open a dialog with the author, not spend time trying to interpret a 7 word commit message, "good" or otherwise.
And for old enough code, the author may not be available, or more likely doesn't remember.
It feels like we're trying really hard to stretch the utility of commit messages here...
I don't feel that is an accurate statement for any complex system.
To the point of other commenters however, I wouldn't lay something this micro at the foot of the CTO in all but the smallest of organizations.
And I really like that because it leaves room to let the developer do whatever kind of commit messages they want to that makes sense to them. Because nobody's really ever going to read those again after it squashed and merged.
I understand this isn't inline with traditional git scm, but it's a very powerful workflow if you are OK with some hybridization.
One minor nuisance that can come up with GitHub in particular when using a short reference like #123 is that that link breaks if the repo is forked or merged into something else. For that reason, I try to give full-url references at least when I'm manually inserting them, and I wish GitHub would do the same. Or perhaps add some hidden metadata to the merge commit saying "hey btw that #123 refers to <https://github.com/fancy-org/omg-project/issues/123>"
The gold standard is rebased linear unsquashed history with literary commits, but I'll take merged and squashed PR commits with sensible commit messages without complaint.
I work on a lot of 2D system, and the only way to debug is often to plot 1000s of results and visually check it behaves as expected. Sometimes I will fix an issue, look at the results, and it seems resolved (was present is say 100 cases) only to realize that actually there are still 5 cases where it is still present. Sure I could amend the last commit, but I actually keep it as a trace of “careful this first version mostly did the job but actually not quite”
They might not include anything but the Jira ticket number, if the environment is truly lacking.
I have actually seen proper capitalization and correct conventional-commit types to correlate very well with the author being intentional and the patch being of good quality.
e.g.
- (a) chore: update some_module to include new_func
- (b) feat: Add new_func to handle XYZ case
Where:
(a) is not a chore, as it changes functionality, is uncapitalized and is so low-signal I can probably write a 10 line script to reliably generate similar titles.
(b) is using the correct "feat" commit type, capitalized and describe what this is for. I expect the body to explain "why", as well, and not to reiterate the "how" in natural language.
This is just my experience, but I've seen commit messages where people actually put in some effort to usually come with a good patch, and vice-versa.
main branch is advanced on PR level, with squashed commits.
So the "." should never make it to main, and have PR description as commit message.
Is it really a small minority? I have never worked on a project that didn't have commit messages that at least tried to be descriptive (sometimes people fail at it but its very different to an outright "changed stuff").
I don't remember any friend mentioning to me them encountering a work project where the messages were totally neglected either.
relying on git commit messages assumes they're correct by convention since there is no technical constraint to enforce it. and it assumes no work in progress commits, sometimes it's just necessary to hit the save button real quick or move a workspace from one device to another.
my point is: git is a way of storing and loading files at its core.
git log --oneline and a sprinkle of your personal sauce on .claude goes a long way :)
Random, subjective, or written in a state of mental exhaustion commit messages.
I also love the switcheroo the author made: git not logs. But hey :)
For small personal projects I often write one phrase messages with `-m`, but if you're working with other people you should be writing good commit messages.
> git shortlog -sn --no-merges
Is the most egregious. In one codebase there is a developer's name at the top of the list who outpaced the number 2 by almost 3x the number of commits. That developer no longer works at the company? Crisis? Nope, the opposite. The developer was a net-negative to the team in more ways than one, didn't understand the codebase very well at all, and just happened to commit every time they turned around for some reason.
This leaves developers to commit locally and comment as much or little as they like.
Modern problems require modern solutions and all...
Assuming I'm not ego-mad, I like to think this is because I built the project from the ground up before handing it over to the rest of the team.
These days other people commit more often than I do, but my name is still dominant, and probably will be for some time.
If someone came to me and said "I ran these and I see XXX was the most prolific committer and they left X months ago, what will be do???" I'd have to work hard not to laugh.
Since these snippets are self-described as ways to get familiar with the code/projects I wanted to provide the counter point. Most of those snippets do not at all paint the real picture and for all the repos I tested it on they paint the opposite of reality.
I know these codebases like the back of my hand, the purported purpose of these snippets is to better understand the codebase, I can tell you they don't work for anything I tested them on. Maybe they work for other codebases but the sample size I have access to says they don't work for me.
The most changed file is the one people are afraid of touching?
I ran this on the repo I have open and after I filtered out the non code files it really can only tell me which features we worked on in the last year. It says more about how we decided to split up the features into increments than anything to do with bugs and “churn”.
Very different from just counting commits - https://vectree.io/c/delta-compression-heuristics-and-packfi...
I’m not sure why HN attracts this need to poke holes in interesting observations to “prove” they aren’t actually interesting.
It shows places that are problematic much better. High churn, low complexity: fine. Its recognized and optimizef that this is worked on a lot (e.g. some mapping file, a dsl, business rules etc). Low churn high complexity: fine too. Its a mess, but no-one has to be there. But both? Thats probably where most bugs originate, where PRs block, where test coverage is poor and where everyone knows time is needed to refactor.
In fact, quite often I found that a teams' call "to rewrite the app from scratch" was really about those few high-churn-high-complexity modules, files or classes.
Complexity is a deep topic, but even simple checks like how nested smt is, or how many statements can do.
Nobody is afraid of changing it.
# summary: print a helpful summary of some typical metrics
summary = "!f() { \
printf \"Summary of this branch...\n\"; \
printf \"%s\n\" $(git rev-parse --abbrev-ref HEAD); \
printf \"%s first commit timestamp\n\" $(git log --date-order --format=%cI | tail -1); \
printf \"%s latest commit timestamp\n\" $(git log -1 --date-order --format=%cI); \
printf \"%d commit count\n\" $(git rev-list --count HEAD); \
printf \"%d date count\n\" $(git log --format=oneline --format=\"%ad\" --date=format:\"%Y-%m-%d\" | awk '{a[$0]=1}END{for(i in a){n++;} print n}'); \
printf \"%d tag count\n\" $(git tag | wc -l); \
printf \"%d author count\n\" $(git log --format=oneline --format=\"%aE\" | awk '{a[$0]=1}END{for(i in a){n++;} print n}'); \
printf \"%d committer count\n\" $(git log --format=oneline --format=\"%cE\" | awk '{a[$0]=1}END{for(i in a){n++;} print n}'); \
printf \"%d local branch count\n\" $(git branch | grep -v \" -> \" | wc -l); \
printf \"%d remote branch count\n\" $(git branch -r | grep -v \" -> \" | wc -l); \
printf \"\nSummary of this directory...\n\"; \
printf \"%s\n\" $(pwd); \
printf \"%d file count via git ls-files\n\" $(git ls-files | wc -l); \
printf \"%d file count via find command\n\" $(find . | wc -l); \
printf \"%d disk usage\n\" $(du -s | awk '{print $1}'); \
printf \"\nMost-active authors, with commit count and %%...\n\"; git log-of-count-and-email | head -7; \
printf \"\nMost-active dates, with commit count and %%...\n\"; git log-of-count-and-day | head -7; \
printf \"\nMost-active files, with churn count\n\"; git churn | head -7; \
}; f"
EDIT: props to https://github.com/GitAlias/gitaliasgit log -i -E --grep="\b(fix|fixed|fixes|bug|broken)\b" --name-only --format='' | sort | uniq -c | sort -nr | head -20
I have a project with a large package named "debugger". The presence of "bug" within "debugger" causes the original command to go crazy.
git log -i -P --grep="\b(fix|fixed|fixes|bug|broken)\b" --name-only --format='' | sort | uniq -c | gsort -nr | head -20
In my experience, when the team doesn't squash, this will reflect the messiest members of the team.
The top committer on the repository I maintain has 8x more commits than the second one. They were fired before I joined and nobody even remembers what they did. Git itself says: not much, just changing the same few files over and over.
Of course if nobody is making a mess in their own commits, this is not an issue. But if they are, squash can be quite more truthful.
If the commit frequency goes down, does it really mean that the project is dying? Maybe it is just becoming stable?
git log --format='%ad' --date=format:'%Y-%m' | sort | uniq -c | awk '{printf $2" "; for (i=1;i<=$1;i++){printf "-";} print ""; }'
If you work with service oriented software, the projects that are "dying" may very well be the most successful if it's a key component. Even from a business perspective having to write less code can also be a sign of success.
I don't know why this was overlooked when the churn metric is right there.
Whenever we initiated a new (internal) SW project, it had to go through an audit. One of the items in the checklist for any dependency was "Must have releases in the last 2 years"
I think the rationale was the risk of security vulnerabilities not being addressed, but still ...
I (largely) wrote a corporate application 8 years ago, with 2 others. There was one change 2 years ago from another dev.
Lots of programs are functionally done in a relatively short amount of time.
"Accelerating or Dying" sounds like private equity's lazy way to describe opportunity, not as a metric to describe software.
I know people win the lottery every week, but I also believe that buying a lottery ticket is essentially the same as losing. It's the same principle.