I gave commit rights to someone I didn't know (2016)
tech.davis-hansson.com
tech.davis-hansson.com
This reddit comment covers it pretty well: https://reddit.com/r/ublock/comments/32mos6/_/cte0a3n/?conte...
"Instill" or "inspire" would have the meaning you're going for here.
Like saying "their actions weren't exemplary" when you really mean "their actions were bad"; maybe a British-English style?
When one uses this format, like in the phrase "[something] wasn't ideal" (eg 'I crashed my car and missed my own wedding, which wasn't ideal') the claim to less-than-perfection is really an implicit statement that the object/situation was the opposite of perfection.
Presumably the new maintainer took some rather bold actions which would indeed suggest they had a high degree of confidence themselves, confidence in their own actions. But those actions did not inspire confidence in the product, among the user base.
Saying that the new maintainer did not exude confidence is a completely different meaning.
Generally, when people use words they are trying to communicate something so they try to use meanings that their audience will understand. If you can clarify an incorrect use politely and without condescension, it is often appreciated and helpful.
> The PR was bigger than what I felt I could sensibly review and, in honesty, my desire to go through the hours of work I could tell this would take for a project I no longer used was not stellar.
The PR: https://github.com/django-money/django-money/pull/2/files?di...
Do others share this sentiment?
This doesn't look like a particularly big PR to me, judging solely by the amount of code changed and the nature of the changes at first glance.
Are most of your PRs at work tiny, couple lines of code at most? Am I sloppy for not even consider reviewing this for "hours"? Are all code bases I have worked on sloppy because features often require changing more code than this?
Level of trust with colleagues will hopefully be higher! And individual ownership of and responsibility for the code probably lower.
And even more so, I've often seen the opposite problem: people committing small chunks of a big feature that individually look good, but end up being a huge mess when the whole feature is available. I hate seeing PRs that add a field or method here and there (backwards compatible!) without actually using them for now, only to later find out that they've dispersed state for what should have been one operation over 5 different objects or something.
They almost always can. The exceptions are stuff like autogenerated code or updating a dependency.
It's definitely overall quicker to ship like this, but there are tradeoffs. You are effectively working independently from the rest of your team, there is no context sharing and everything is delivered at once after a longer period of time.
We're performing atomistic simulations. The first edition of the code stored each atom on the heap and had a vector full of pointers to the individual atoms. Obviously this would obliterate the cache, so I crafted a PR to simply store all the atoms in a single vector. On its own, that was a one line change, but it was also a very fundamental change to the type system. Everything as simple as
Atom* linker = atoms[index];
linker->x += 1.57;
Suddenly had to be Atom& linker = atoms[index];
linker.x += 1.57;
If I didn't make those corresponding changes, the code wouldn't type check and the build would fail. I think the final PR came out to about 17 kLOC.Obviously if you make a change to something like your type system it's going to generate a very large diff, but you also aren't going to review the full diff.
You're just going to make the change with find+replace or some other automation then write in the PR description "I made this change to the type system". No one is actually reviewing 17k LOC.
Let's imagine that instead of optimizing the pointers to in-place structs, we were taking the optimized program and adding support for dynamically allocated atoms because of some new feature for dynamically adding/removing atoms.
We could of course split the value->pointer 17k line change into a single PR. But, that PR is only doing a pessimization of the code. On its own, it makes no sense and should be rejected. It only makes sense if I know it will be followed by the other feature, and even then, I would have to see the specific changes being made to know if this pessimization is worth it.
And if it got committed to the main branch, in preparation for other PRs that depend on it, the main branch is no longer in a releasable state, since it would be crazy to release with a performance penalty and no feature gain.
So, the right way to push this is as a single PR with a 17k-changed-LoC commit + the commits that actually use it. Of course, people would only manually review the other changes, but that's easy to do even if it's all in a single PR. And anyone looking back at history would clearly see that the pessimization was only a part of the dynamically-allocated atom feature, not a crazy change that someone did.
This is a very different situation than large PRs containing feature code. I think most people would agree that one large PR is the correct approach for this kind of situation.
Shipping all the changes in a monster PR is usually not a good option. One big reason why is that you do not create any value until the whole thing ships. If you ship piece by piece you can create small amounts of value every time you ship.
Also, if it's a "small feature", why is it 5k+ LOC?
It was an all or nothing thing, as almost every third-party dependency we used had to be swapped by something else.
At least we have amazing test coverage, so it was easy to find bugs.
But there wasn't much I could say other than "trust me".
To use an analogy: if you wanted to reupholster my car seats, or spice up the radio panel, sure knock yourself out - I'll come check when it's done. But if you were to as much as think about tightening or loosening a single screw anywhere near the engine block, believe me I will be paying very close attention to what you're changing.
If I was doing a proper review of a PR that big and making sure you understand how everything works that would easily take multiple days and generate 10s-100s of comments.
In reality I would flat out refuse to review it. Even 1k is very large without being broken down.
The only time I see PRs that big at work are cleanups (E.g. deleting whole directories), automated linting changes across the whole codebase and large structural refactors (E.g. changing directory structure).
And like "the public API is the public API, the private API everything goes" is easy to say, but it's so easy to just break other projects with these kinds of changes. This makes it very hard to move forward with certain kinds of "bug fixes" in projects.
That being said, it's not that that PR is "hard", but it's hard to say "merging this is A-OK" instantly. Hours? I dunno, but I would definitely add some tests and try to figure out how to write code that breaks with those changes.
If I were managing that project at the time, and had motivation, I'd definitely do a lot of cherrypicking, get all the "obviously won't break anything" changes merged in, to leave the problematic bits in for a focused review. Again, this all might be under an hour, but sometimes you look at a thing and are like "I don't really want to deal with this, I have my own life to deal with."
At a higher level, the biggest problem with these kinds of libraries is having the single person who can merge things in, who can hit the "release" button. There's a lot of projects that interact with Django that have heavy usage, and survive mainly thanks to random people making forks and adding patches that properly implement support for newer Django. At $OLD_JOB we used a fork of django-money (including a lot of patches to fix stuff like "USD could be ordered with JPY", pure bug generators). It was very easy to add patches because, well, we had our usage and our test suite and no external users. It's great, but it's also important to try and get patches upstreamed when possible (and we did for a lot of projects).
Strongly typed languages, a well-designed API, and senantic versioning can make this problem largely disappear.
And note that saying "release as a new major version" is not making the problem disappear, it is simply choosing not to solve the problem, but with a warning on top.
It's easier if you're doing version 2 of a well-tested, scope-limited library, and thus can afford to do some holistic design. But the trend in our industry is to develop iteratively, small releases done often, everything kept at 0.x.y perpetual beta, and on the off chance your project grows old enough to warrant 1.x.y version, it has so much evolutionary baggage that you'd have to rewrite it from scratch to get proper typing in (which, of course, is against the zeitgeist).
If you fix a bug, this can break existing code. This is a fact of life. Changing performance characteristics can generate downstream problems! You have to consider this stuff seriously.
Here the change introduced nullability. In another universe the function would already be nullable but the conditions in which a value becomes None changes. A spec can be changed, for the better, and still be bug generating if people just upgrade. That is not captured by most type systems, and there aren’t that many great production web apps running on Idris.
But ultimately the reality is that people have a lot of flexibility with Python projects in general. It’s great, and libraries that are aware of this, well… they write it in release notes. They also have open repositories to enable actual code diffs. It’s non-zero amounts of work but it’s there.
There is a theoretical universe in which a static language with well-designed libs provide good aesthetics to make developing certain software easy. Meanwhile even as a big functional programming lover I still reach for Python because I can get work done because the libraries are in fact well designed, and the code is easy to work with, and I can fix issues quickly. As a user it’s great, as a library maintainer I gotta apply some more care. Could be better but it's alright
Note how things like performance characteristics leak through strong-typing, well designed APIs, and semantic versioning, in spite of non-guarantees around such characteristics.
1. https://medium.com/se-101-software-engineering/what-is-the-h.... 2. https://xkcd.com/1172/
I would however argue that the existence of a user relying on behaviour that has explicitly been reserved as subject to change must not preclude development from rendering improvements to products. At some point the consumer needs to be on the hook for relying on a positive externality that they do not have a right to.
Everything broke.
Investigating, I realised that one of my long departed predecessors forked angular-bootstrap and made a few small changes to it. The problem was that the that library was tied to angular.js 1.3. To update angular.js, we had to update the library. To update the library, we had to remove all the changes in which would break large parts of our UI. The project was already in maintenance mode by that time and we decided to just leave it as is. I spent the next month converting it from coffeescript to es6.
If the code is just fire and forget, then fine. If it's part of a bigger system with rigorous standards then 300 lines can take a day or more to "merge" in.
That kind of implication stops me in my tracks to learn more. I’ve spent literal days tracking down the meaning of single line code changes through multiple dozens of commits, sometimes across repo boundaries (ahem the original author’s suggestion of deprecating in favor of a fork comes to mind).
The size of this particular PR only becomes a factor when any one of those numerous commits can become that rabbit hole. How many humans’ days are going to be spent tracing history through this particular merge? For how many different reasons? I didn’t even look at the changes midway, but how many nuances are buried in there and lost unless this weird bundle of changes is preserved?
It's certainly simpler for the contributor to do the squashing, but when GitHub makes it so simple in practice it doesn't matter.
Pull requests, patch notes, documentation and comments should be source of truth
Git is not project management tool, it just manages my letters history.
(Also, JetBrains tools use "Annotate".)
Especially when you have multiple people working on a shared branch rebasing can be quite painful. The most common example of this is when sharing a branch with a QA.
Imagine writing a highly performant and featureful relational database and successfully using it with large projects for a while without the database itself becoming particularly popular and then having a company come along and popilarise your database by telling lots of people about how good it is as a flat key value store.
Then people are really confused and annoyed as to why their key value store has this complicated and confusing relational database attached to it so they write lots of guides skimming over the details to help people get better at using the database to just store keys and values in one table.
If I was Linus I would be pretty pissed too.
Additionally, many people are paid to work on his project by other companies. Linus doesn’t pay them, yet he’s their boss.
All of this is to say that Linus is very insulated from externalities. He can insist on his platonic ideal of a commit and SCM, if it makes his life easier. He’s like the editor at a publishing house, rejecting countless manuscripts yet never writing a word himself. And that’s fine.
However, most people do not use an SCM like Linus does. If you’re maintaining an open source project on GitHub you’re probably working for free, as are the people submitting PRs. The more difficult you make their lives, the fewer people will be willing to submit PRs and the more work you’ll have to do eventually.
Of course, sometimes bugs showed up in our system. One of the engineering leads would often say "oh lets just clear the redis cache". Every time I told him no, and once again slowly explained how we weren't using redis as a cache, and how deleting everything in redis would delete user data and be a terrible idea. He would have this far away look in his eye while nodding along and pretending he understood. I guess in his mind he was just thinking - why on earth would it be unsafe to clear the "redis cache"?
Months later I went on holidays. They ran into some bug. He reacted by wiping everything in redis. And, predictably, all hell broke loose. User data rollbacks happened, which caused cascading failures in the UI (which assumed that rollbacks would never happen). The team ended up reconstructing some lost data from some JSON which accidentally ended up in web request logs. Users had downtime as the whole app broke. It was a disaster.
When I got back to the office, I was hit with some strange combination of "why weren't you here" and "why didn't you tell us". Ugh. I still think about it sometimes. I have no idea how I could have handled that better. But I can tell you one thing for sure: I lost a lot of respect for that engineer.
This varies greatly from project to project, and is by no means a general expectation.
(Interestingly enough Knuth praised literate programming for TeX as the reason he could get back in and fix bugs after an almost ten year hiatus - where parts of the code he had not looked at in 40 years.)
This was something @whitequark taught me. Having a clean commit history is very important when looking back, and we we look back more often than most people thunk. Self contained commits with good messages is important. I'm still not great at concise descriptions but trying.
Having a bunch of “fix” and merge commits in the main branch history is terrible.
Well the author specified that this was their subjective take on it.
But seriously: that code seems to be touching bits that really should have automated tests attached. If the tests pass, then I would feel more comfortable accepting the PR.
Half of the commits are merges from other fork branches into the contributor's master, and the PR name and description doesn't mirror that in the least.
Then (eyeballing) 90% of the diff is whitespace changes, which would be fine in its own PR ("Formatting changes") because it's easy to eyeball that it's just that, but when you mix it with other changes, it's hard again.
> A diff view with reduced white space has been available since 2011 by adding ?w=1 to the URL.
https://github.blog/2018-05-01-ignore-white-space-in-code-re...
That said, I'd ask the contributor to tidy up the branch first. It's kinda disrespecting to ask others to review branches in such state.
https://app.semanticdiff.com/django-money/django-money/pull/...
It doesn't make a huge difference, but it filters out changes like the added line break in "if value: value = str(value)" nicely. I haven't announced the project yet, but maybe someone will find it useful :-)
The PR review is in public and heavily scrutinized by paying customers and passionate community members. APIs cannot be broken, and even with automated tooling it's very easy to accidentally introduce a change that breaks tens of thousands of deployments. And the code itself is really sensitive. If a bug gets in and released, it can be several days of grind to get a patch out, and after that many months of new tickets for the bug from customers that won't move to the latest patches.
Now I work somewhere where the code I write runs in-house. If a bug sneaks in, it's usually a 5-minute redeploy to resolve and the cost is borne primarily by my own team.
So I think the answer to your question is: it really depends on the environment you're writing code in. In some setups the cost of introducing mistakes is very high, so it makes sense to pay a lot at the review stage; in others the correct balance is less strict review and fast fixes/rollbacks instead.
What are you exactly trying to achieve by comparing the guy's "I'm busy, this is long" with yours or anybody elses? Moreover, what on earth has his job to do with the topic?
Bad day...?
In that case, it’s perfectly reasonable to spend a couple of hours getting back into code you wrote a long time ago. If anything, taking that time is a big win for overall project stability.
Some typo could break everything.
I worked for an (unnamed) company once. For some reason I needed to update the gender of a user on the production server with two million users on it. (There was no interface to change gender I expect)
I accidentally forgot the WHERE clause on the SQL UPDATE and made everyone male.
A fellow developer was watching over my shoulder and we decided to just use the Title column (e.g. Mr/Ms/Mrs) to repopulate the Gender of all users without letting anyone know.
I want to apologize to all the female Drs. in that database.
> maybe I'm underestimating the amount of checks between you and code in windows updates
Access doesn't mean force push rights to master (-:
The biggest reason to disable this is more to prevent accidental mistakes: you think you're force pushing your feature branch but you accidentally force pushed master. We've all done something like that.
Of course MSFT probably requires x code reviews for PR/patch merges.
Why? They give that source away under NDA to non-employees. Handing it to someone who passed all the employment hurdles and has signed a more restrictive NDA shouldn't be a problem.
Apple's operating system used to have "hooks," where you could register to intercept almost anything that went through the system. Basically, any app could intercept the execution thread of another app (or the operating system), and insert its own code.
Doesn't that sound fun?
One of my favorite MacHack projects was the "Energizer Bunny" hack (I think Dean Yu did it). You installed the hack on multiple Macs, and, randomly, the Energizer Bunny would start banging across their screen. When it was done with one machine, it would move to another machine on the network.
These days, security geeks would defecate masonry, if they came across that.
One of my favorite apps, was something called "Kaleidoscope"[0], which allowed you to select custom "themes," for the operating system, bypassing the Appearance Manager[1], which was an API over QuickDraw. The themes could have executable components.
Some of the themes where ghastly (but fun).
This is the risk of open source not figuring out funding.
So it's an entirely different issue.
Not necessarily. There is software I built for me, thought that it could be useful to others, used for some time and then went away. Sure, if it brought me 1M€/month I would work on it hard. But it was not the primary goal anyway.
This commentator puts it well - https://news.ycombinator.com/item?id=36121561
This is simple spammer entropy.
Now with GPT spammers can create entropy very easily, so it's tricker.
My criteria is usually just a willingness to improve the situation. I can observe this over time via pull requests, forks and general community participation.
I'm very reluctant to give access to someone asking for it. I firmly believe this is something that should be given and not to be expected.
I did wonders to foster a community of contributors, and get more patches coming. The CI ensures nothing breaks, and there never was any trust incident.
(The notable exception are people who specifically seek power. Somehow they seem to be the least responsible with it.)
I still haven't figured out why that is[1], and if there are aspects of it that can be recreated remotely.
----
[1]: Some ideas I've had is that it's about sunk costs ("Now that I got my ass here anyway, I may as well contribute") or that there's a visual component (perhaps seeing a face triggers some responsibility chemistry in our brains?) or that it's harder to avoid persistent questions when you share a room with someone.
I've also speculated that eating together may enhance engagement, but I don't know if that acts as some sort of Skinnerian reward mechanism or if people feel cared for and that triggers their desire to care in return.
Definitely definitely.
Even without eating. If it's just "seeing a face", then zoom might suffice -- and zoom might improve things.
But I think it's clear that actually being in the same physical space with other people is an important ingredient of building relationships of trust and respect. I imagine neuroscientists could do a lot of research into why, and I imagine it's not just one thing (like "seeing a face"), but fairly complicated. But from many people's experience, it seems pretty clear that it's true.
(And I agree eating together is special extremely powerful "magic" here -- which btw is/was another severe cost of people's covid pandemic habits of not eating with people they aren't already intimate with...)
Still, I've built relationships of respect and trust with people online too.
I think another thing going on is that when someone shows up with an agenda to abuse your trust, it's somewhat easier to detect face-to-face (which doesn't come close to meaning universally reliable; of course it is quite possible for manipulative and sociopathic people to show up face-to-face with agendas of abuse and get away with it).
[0] https://en.wikipedia.org/wiki/Humankind:_A_Hopeful_History
I gave commit rights to someone I didn't know - https://news.ycombinator.com/item?id=12522654 - Sept 2016 (100 comments)
- instar. I had two guys basically rewrite the entire thing and make it WAY better. I had a good vision for the API but my implementation was pretty bad.
- mutmut. I would never have gotten windows support going without help. (Although I am thinking of abandoning windows anyway soon...)
- iommi. This project is much more complex and has a certain philosophy, but we gave commit access to one developer pretty fast as it was super obvious from the first PR what kind of deep thinking he did.
All in all, great success.
In 2016 I think it wasn't yet/wasn't recognized.
I am very sympathetic to the suggestion in OP prior to recognizing that there may be people actually actively trying to abuse your trust to intentionally inject malware.
And if it did, sorting out the mess and reverting a malicious commit wouldn't be the end of the world.
https://twitter.com/MoOx/status/955903710617620482?t=BvPIWQ-...
Maybe we need a way to declare in the package and repository metadata that the maintainer considers it world-writable and it shouldn't be installed or updated without very carefully reviewing the code of every new version.
I'm glad it worked for him, but just want to remind people of survivorship bias: https://xkcd.com/1827/
I am not sure you'd want this for everything, but for quick paced experimental work it seemed to be incredibly effective.
So I really appreciate projects like JazzBand [1], that gather likeminded contributors and individuals that want to harbour open source repos around an ecosystem (Eg. Django), while giving some assurance on governance. If JazzBand would be around in 2016, django money would be a very good candidate to be harboured by the org.
On a meta level, I really would love that more OSS devs would user orgs, rather than personal accounts and repos, so that they can grow their projects with a team, rather than becoming the bottleneck and gatekeeper for development.
[1]- https://jazzband.co/
Meh. I once stumbled upon a repository the maintainer had abandoned following a change of employment, there were a few things to fix which didn’t seem to hard so I figured I’d ask (thankfully this repo was part of an org I could ask the owner of).
I was able to get access to the repo and have been low-key maintaining it (updating the infra, etc…), it’s small and simple so it ain’t much work anyway.
I can assert that they’d never heard of me, because I never actually used the package. Still don’t.
> On a meta level, I really would love that more OSS devs would user orgs, rather than personal accounts and repos, so that they can grow their projects with a team, rather than becoming the bottleneck and gatekeeper for development.
A personal repo doesn’t preclude “growing your project with a team”, you can give write access to a personal repository. An org means extra overhead and complexity, it doesn’t just pay for itself when you create it. Do you create a new org every time you create a new project? Because that’s essentially what you’re suggesting.