by samscully on 2/7/24, 2:25 PM with 124 comments
by appplication on 2/7/24, 3:03 PM
Most of the tests for and new functionality alone in any of our PRs well exceed 50 lines. Indeed we have 2-3x more test code than actual code. So should we be writing less tests? Merging the code first and later the tests? Merging the broken, codeless tests first and then the code?
It’s all ridiculous. Just make PRs that represent unit change, whatever the means to you. The unit functionality is independent of lines of code. Sometimes that is 12 lines, sometimes it’s 800. Yeah large PRs are harder to understand but that’s why you have tests. Also XXL PRs aren’t usually happening every day. If they are, you have a very productive team and maybe you should count yourself lucky.
by hugocbp on 2/7/24, 7:54 PM
I briefly worked with a hard line-count-limit for PRs and I thought it made everything much worse. It is fine for changes that are actually small, but when you need to go back and re-open 4, 5 merged PRs in different tabs to get the full context again, the time to review increases tenfold with tiny PRs that don't really make complete sense by themselves.
I have worked with co-workers that have the complete opposite preference, though, and anything over a set amount of lines wouldn't even be reviewed.
Interesting to see the numbers on the article, however. My anecdotal experience would make me guess the opposite. I feel like work slows to a crawl once the PRs are artificially limited and broekn up like that, specially in fast moving companies and startups.
by ysavir on 2/7/24, 3:27 PM
Those small PRs might not be reverted, but there are probably a fair number of 50 line PR follow ups that end up modifying the original implementation, and using up more total time and effort than if it was just a larger PR implementing the feature in its entirety.
I wonder how many of the large PRs they say take longer to merge and get less comments are actually feature branches into which the smaller PRs are merged, and which we expect to hang open for long periods of time with little interaction.
This analysis seems to take a set of data without much investigation into what the data actually represents and makes an immense effort to find some conclusions about the context-less data.
by Zealotux on 2/7/24, 2:59 PM
The “ideals” are almost never a thing I see in my daily job, and I’ve worked for countless companies as a contractor.
by waffletower on 2/7/24, 4:10 PM
by tcmart14 on 2/7/24, 8:31 PM
by jitl on 2/7/24, 3:29 PM
If CI takes 15 minutes and I create PRs one by one, I’ll need to wait a total of 10 hours just for CI, which is impossible, I’ll need to use stacked PRs. If I’m using stacked PRs, that means I do all the work up front, and then try to painstakingly split up my final code into little 50 line chunks that build incrementally. I’m sure someone will say “oh just write incremental small commits to begin with”, but that never seems viable to me. Code and design evolve as I build in ways that would make the review of the first 50 lines I commit on the project pointless since none were retained in the final product. So not only do I have to build this feature, and write 40 PR descriptions, and write an overall meta-PR-description for the change in aggregate, I also need to cut my finished code up into puzzle pieces for reviewers to mentally re-assemble.
Anyways, maybe for maintaining mostly-done features 50 lines is nice, but I’d much rather a new feature or larger change be a handful (1-3) of larger (500-2000 line) PRs possibly accompanied by pair-review/walkthrough discussion.
by GravityLab on 2/7/24, 9:05 PM
by NickM on 2/7/24, 4:12 PM
Now, yes, it can be a bit more work to split up big PRs into smaller standalone changes that can be merged in isolation, but it seems plausible that the benefits might outweigh the extra work in many cases. The whole idea of a version control system is to create a useful history of changes over time; making each individual changeset simpler and easier to understand seems like an admirable goal.
by lakpan on 2/7/24, 2:57 PM
by distortionfield on 2/7/24, 7:51 PM
by TomSwirly on 2/7/24, 2:59 PM
Reviewing a 50-line code change in 60% of the time it takes to review a 250-line code change means the shorter code review takes _four times_ as long to review per line.
by 3cats-in-a-coat on 2/7/24, 3:30 PM
It cheers me up that people so naive exist.
Size is contextual to the thing the PR regards. Maybe it's one char. Maybe it's 500 lines. Maybe it's 10k lines. Screw this.
by lightbendover on 2/7/24, 3:43 PM
by yurishimo on 2/8/24, 8:24 AM
It was tested in smaller chunks in a feature branch, then the larger feature was merged. There was some testing done on the huge feature branch, but not everything that was present in the smaller PRs.
In our case, this new "feature" was a complete overhaul of our business logic engine. Over time, we had essentially developed 3 or 4 different API versions for various business tasks, with a lot of logic being duplicated between them. We want to bring it all under one umbrella, and after about 8 years, we think that we have a good idea of what sort of abstraction can work for the next 8 years.
Now that the engine is merged, we need to start the grueling task of actually moving logic from the old APIs into it and removing them from our codebase. We spent about 6 months (between 2 devs) writing the engine and I suspect it will take 2 years to move all of the logic into the new engine.
Idk where I was going with this comment anymore, but needless to say, I don't often see 50 line PRs at work!
by binsquare on 2/7/24, 8:49 PM
There's too many facets to what makes a PR good that boiling it down to line count is silly.
Ex. Small code changes are required if the solution requires it - forcing 5 lines change to 50 lines would be considered wildly bad idea. On the other hand a 500 line PR to solve one problem suddenly broken down to 10 PRs makes the review far harder depending on the context.
by the1024 on 2/8/24, 12:19 AM
This worked reasonably well in terms of forcing junior engineers to reason harder about what an atomic change should look like, but also impacted senior folk that were making atomic changes that encompassed broad areas of the codebase. We eventually reverted the change and relied on implementing CODEOWNERs to enforce senior devs to request changes when PRs got out of hand.
There's definitely nuance to enforcement of best practices across an entire organization; haven't really seen it done well although I've primarily worked at startups.
by bvrmn on 2/7/24, 11:08 PM
Changes were quite simple. 600 common lines are about rearranging big module into multiple smaller modules. 300 removed lines are technically could be in a separate PR, but it's some cleanup aftermath related to rearrangement.
by SAI_Peregrinus on 2/8/24, 3:56 AM
by Draiken on 2/7/24, 4:07 PM
PRs that are <50 lines are more often than not documentation, typos and small fixes in my experience.
Most real value add PRs end up bigger due to tests, documentation changes, and the actual change.
This for me is the typical claim that'll become an example of Goodhart's law when implemented. Random people that are not engineers will use this to claim "your PR should be 50 lines long" as some sort of absolute truth, when in reality the number of lines of code is absolutely irrelevant most of the time.
Context and details matter. Sometimes multiple small PRs are better. Sometimes a larger PR is better. It always depends. These absolutist claims that "this is better" is what leads to atrocious management practices that always end up getting summarized to a number, losing all of its meaning in the process.
Had we not we moved on from the lines of code metrics already decades ago? :facepalm:
by karmakaze on 2/7/24, 5:35 PM
For a large PR, I usually regroup my changes into smaller unit commits which can be reviewed commit by commit.
For an even larger (or more complex) PR, I'll make a set of stacked PRs which can be reviewed in pieces, each with a good description of what/why/how stuff is happening in that piece. Once all PRs have been approved, the lot of them can be deployed together.
I've at times had 3 PRs for a total of 3 line changes, because they were for a single table's schema migration picking new indexes and each had many factors to consider. The PR descriptions were of course much longer.
by abroadwin on 2/7/24, 7:55 PM
Not saying the claim is necessarily wrong, but it's also exactly what I'd expect given the source.
by da39a3ee on 2/8/24, 12:20 AM
by avgcorrection on 2/7/24, 3:31 PM
Showing some context per commit makes all the difference when I decide to do a first commit which fixes all formatting in the file that I’m visiting (for the real/substantive change).
by tyleo on 2/7/24, 8:58 PM
Anyways, I don't so much care about the size of a PR as much as I care about how understandable it is. That generally ends up being a few rules of thumb like:
1. If you change a common function name, change it everywhere but please don't do anything else in the same commit.
2. If you need to make a change in code you are depending on to accomplish a goal in your own code, try to break the change to the dependency into another commit. There is a little bit of an art here to both understand how to break things up and to not break them up too small.
3. Try to make your history meaningful rather than just having a bunch of random commits like "fix", "forgotten file", etc.
by detinho on 2/7/24, 4:37 PM
by sithlord on 2/7/24, 4:28 PM
by zer8k on 2/7/24, 3:27 PM
1. The "unit of work" is small enough to decompose into a 50 line PR. This is possible on larger codebases and less verbose languages. It can enforce over-DRY code which often leads to a lower universal ability to understand what is going on.
2. The team responsible for reviewing is responsive. I have never worked at a company where PR reviews happened quickly. Everyone is busy, everyone is overworked, and often times PRs are a chore that can be put off until later. Of course you can make some labyrinthine chain of small PRs all merging into one big PR but the problem still exists. I'd personally rather review a 300 line complete PR written well than 6 PRs that I have to constantly recall context on.
This advice follows the same logic as the asinine cyclomatic complexity rules. Yes, in theory they are sound. In practice, it's more of a flexible benchmark rather than a hard rule. But since someone inevitably writes YASL (yet another stupid linter) that enforces these types of things, an enterprising work-focused engineer will end up spending either more time fixing code to please the linter or more time exploiting loopholes in the rules.
Just write Good Code (TM) - whatever that looks like.
by awestroke on 2/7/24, 2:45 PM
by charcircuit on 2/7/24, 3:35 PM
by Miraltar on 2/7/24, 4:06 PM
by mirekrusin on 2/7/24, 4:10 PM
by hyggetrold on 2/7/24, 10:11 PM
by wredue on 2/7/24, 8:42 PM
The same goes for functions
Please stop listening to this garbage advice.
by sebastianconcpt on 2/7/24, 4:13 PM
by User23 on 2/7/24, 7:20 PM
by xkcd-sucks on 2/7/24, 7:08 PM
> The highest volume coders and repositories have a median change size of only 40-80 lines.
This claim is rational under the Facebook axioms, so to speak.
by siva7 on 2/7/24, 9:12 PM
> We flew down weekly to meet with IBM, but they thought the way to measure software was the amount of code we wrote, when really the better the software, the fewer lines of code.” — Bill Gates
by agilob on 2/7/24, 4:25 PM
by nhggfu on 2/7/24, 3:37 PM
by stratigos on 2/7/24, 3:58 PM
Skimming a PR is pure cognitive dissonance, dont do this and complain when your app turns into a dumpster fire.
by oglop on 2/8/24, 8:03 AM
by progrus on 2/7/24, 7:42 PM
by armatav on 2/7/24, 8:52 PM
Who wants to spend hours bothering with hardline process - you’re the programmer, you’re going to be the guy answering any questions on your pull; therefore you’re going to have to look at it yourself.
by pestatije on 2/7/24, 4:59 PM
by svaha1728 on 2/7/24, 7:19 PM
by tehnub on 2/7/24, 8:58 PM
by physicsguy on 2/7/24, 2:48 PM
by LudwigNagasena on 2/8/24, 12:19 AM