I think the sweet spot in Developer productivity was when we had SVN repos and used git-svn on the client. Commits were all rebased on git level prior to pushing. If you committed something that broke unit tests your colleagues would pass you a really ugly plush animal of shame that would sit on your desk until the next coworker broke the build.
We performed code review with a projector in our office jointly looking at diffs, or emacs.
Of course it’s neat to have GitHub actions now and pull-requests for asynchronous code review. But I learned so much from my colleagues directly in that nowadays obscure working mode which I am still grateful for.
> If you committed something that broke unit tests your colleagues would pass you a really ugly plush animal of shame that would sit on your desk until the next coworker broke the build.
We did have an ugly plush animal, but it served more obscure purposes. For blame of broken builds, we had an info screen that counted the number of times a build had passed, and displayed below the name of the person who last broke it.
Explaining to outsiders and non-developers that "Yes, when you make a mistake in this department, we put the person's name on the wall and don't take it down until someone else makes a mistake" sounds so toxic. But it strangely enough wasn't so harsh. Of course there was some stigma that you'd want to avoid, but not to a degree of feeling prolonged shame.
I once interviewed a junior-ish developer who told me that his then-current team had a dunce cap to be worn by whomever broke the build. I copied it immediately. There was no toxicity, it was a good laugh, and as manager I wore it more than once being a bit too liberal with my commits.
On another team I was on, in 2002 using CVS, we had an upside-down solo cup as a base for a small plastic pirate flag. If you were ready to commit, you grabbed the pirate flag as a mutex on the CVS server. Of course, this turned competitive… and piratical.
I despair about long-lived git feature branches and pull requests. The pull request model is fine for open source development, but it’s been a move backwards for internal development, from having a central trunk that a team commits to several times a day. The compensating factors are git’s overall improvements (in speed and in principled approach to being a content addressable filesystem) and all of the fantastic improvements in linters and static analysis tools, and in devops pipelines.
> I despair about long-lived git feature branches and pull requests
This comes up a lot - multiple people on this thread have even said that it's a bad idea to have a long running feature branch.
This seems like a case of the tool imposing it's will on workflows, rather than enabling them. Not all features are tiny. I don't see anything wrong with a long lived branch if the feature is in fact large. After all it may be completely redesigned multiple times over before being merged into the main branch. Or it may never make it.
And no I don't think it always works to break down a large feature into smaller ones, because your course may change as you go, and it's much easier not to have to revert incremental features when it does.
But people are so worried about having a perfect history. So they rebase. But if it's a long lived (shared) branch you don't want to do that. So now what? A merge would be ugly, can't do that. So now you've painted yourself in a corner for no good reason.
A long lived branch was a pain even in the CVS days. I'm in particular thinking about the "aviary" branch (for Phoenix/Thunderbird) Mozilla had for quite a while.
Of course tooling can make it harder — there was no such thing as rebasing on CVS.
A long lived feature branch is not a problem if you rebase it to master often. Move all refactoring to the beginning of the branch and merge them to master if they become too many.
For long-lived feature branches that are the target of multiple smaller PRs, history should never be rewritten. I call these branches integration branches. I agree with you wholeheartedly that master should be merged into the branch. It's also so much easier to resolve merge conflicts all at once in the merge commit rather than iteratively for each commit. Also, the information on how merge conflicts are resolved is then preserved in the merge commit. It's critical however that when you merge the branch back into master, you use --no-ff. It gets really confusing when you fast forward master to the feature branch.
The solution for it being ugly is to look at main/master's history with the --first-parent option. This lets you cut through the noise and just see the true history of the main branch. Without --first-parent, you see a bunch of commits in the log that master was never actually pointing at. This is why it's critical that you use --no-ff when merging these 'integration' branches as I call them. It's important that the integration branch is the second parent of master.
But what you are describing still isn't good enough for a lot of people, because even though `--first-parent` hides the noise it's still there and just knowing there's a mess under the rug is enough to be problematic.
I don't think it's really the fault of the tooling, moreso with what is a common interpretation of what is a mess and what isn't. If the github commit history allowed you to show `--first-parent` maybe it would be less of a problem.
> The pull request model is fine for open source development, but it’s been a move backwards for internal development
The more paranoid would claim that requiring PRs that then require approvals prevents a malicious engineer from adding an obvious back door to the code.
You would hope you can trust your co-workers, but sometimes a hack is an inside job.
No joke, a few weeks ago a colleague from university shared a few anecdotes about his mentor-coworker-boss at work with me, and it's similar. Every time they broke the production branch and the boss had to change the code or pull out some AWS magic to restore a database, he would give the fixed commits names like "Cgada de [Employee Name]" which roughly translates to "[Employee Name] F*ed Up", since he knew they wouldn't forget it that way.
It's specially cool given that he would always see his employees' f*k-ups as learning opportunities. He would always teach them what went wrong and how to fix it before shaming them in the git history. He always told them he did it to assure they wouldn't forget both the shameful f*k-up + the bit of learning that came along with it. They always laugh it off and understand the boss' intentions. It isn't harsh or anything.
Our whole practice revolved around not pushing broken code because all code was tested locally prior to the push. In fact we practiced continuous integration as in its original meaning, integrating code multiple times per day. Releases were performed from a release branch so the occasional hiccup wasn’t worse than let’s say a PR that does not build. However fixing the broken build was the TOP priority if it happens (like every two months)
It is literally the definition of toxic. It is the antithesis of making it okay to fail, having the entire team to take responsibility. Instead individual mistakes are highlighted and publicly shamed. How can you possibly not think this is toxic?
Toxic is not the highlighting of breaking the build with a trophy, it's what gets associated with it.
Imagine an "ugliest shirt" trophy, given out to whoever wheres the ugliest shirt of the week. At a fashion magazine, this may be toxic shaming. At a tech-heavy startup it might have people start buying the worst shirts they can to try to win it.
If the attitude associated with getting the trophy is condemnation, that's bad. If it's a reminder that everyone fucks and be careful, that's fine.
Oof that hits a sore spot. I was the 2016 Winner of the Ugliest Shirts Award at one of the first technology companies I worked at. Being singled out in front of all your peers for poor fashion sense and then the ensuing obligatory laugh ruined my opinion of that company's leadership. I would strongly encourage anyone in a professional environment
(especially those in leadership roles) to keep comments on appearance to yourself.
I'm sorry to remind you of a bad time. I would like to point out that "2016 Ugliest Shirts" is a pretty different concept from "Person who wore the ugliest shirt this week" with a picture of you in a ratty beloved tee. It sounds like those were year end remarks, which means instead of judging an act they were judging your long term taste. Also it implies the most memorable thing about you was your shirt choice. And lastly, you weren't anticipating it, so you found out everyone was secretly judging you on something.
If, during orientation you were told a trophy gets given out every week for it, and some people wear really ugly shirts each Friday to try to win it, it would have felt very different.
But yeah, year end humorous awards like that probably belong confined to episodes of The Office.
Uh no, and please never work with me. The definition of "making it okay to fail" is a pat on the back and a retrospective to figure out what went wrong and prevent it from happening again.
I'm not sure why you think a humorous plush toy precludes any of the other things you mention (retrospective, etc). I see a plush toy as something that makes failure an amusing thing to laugh at, rather than something to be hung up about.
But don't worry. At your request, I will not work with you.
What I meant is that we know, inside our blood cells, that breaking the build can happen to anyone, and probably will. The trophy is not public shaming, it's the camaraderie that comes from shared humility.
You say to somebody downthread "remind me never to work with you". I would find it difficult to work with someone as hyper sensitive -- on other people's behalf, yet! -- as you seem to be in this thread.
I have my old team's rubber chicken and I'm never giving it up.
In-person code review is the only way to do it. Pull requests optimize for the wrong part of code review, so now everyone thinks it's supposed to be a quality gate.
Yep. It makes a lot of sense for open source where gate keeping makes sense (to reduce feature bloat, back doors and an inflated API surface that needs to be maintained almost indefinitely).
Most corporate code bases are written by a smallish team operating under tight time constraints so most contributions are actually improving on the current state of the code base. Then PRs delay the integration, and lead to all kinds of follow up activities in keeping PR associated problems at bay. For example the hours wasted by my team in using stacked PRs to separate Boy Scout rule changes to the code from the feature is just abnormal.
Absolutely. In my experience, it’s only “not toxic” to a few people, and for most others it is toxic, but the people who like it won’t ever be able to see that.
exactly. even if the current team is cool with it, team+1 may not be, and now they're in a position that feels shitty to them. it's good 'ole boys club shit.
people brag about their dunce caps, "john's fault" commit messages from managers, and other forms of public shame as a badge of honor when it would be so much more interesting to here about how they fixed their broken processes that led to the problems in the first place.
"oops, a developer fucked up the prod db" says more about the org and its processes than it does about the developer.
For the record: I am not recommending people to adapt a toxic culture.
What I would like people to take away from these discussions is the curiosity to question established practices and processes and re-evaluate the cost-benefit ratio of process steps just like the manufacturing people I write software for continue to optimize their working mode again and again
In this case I reminisced about the toolset but the work flow is what brought the value so I advise of course against using subversion.
Look up trunk based development and read the continuous integration book published by Addison Wesley (Is it the hez humble book or the Duvall book I always confuse the authors, both books are great though).
The hard part will be to convince people of exploring a different way working mode AND to learn that what is proposed is not an anarchist style of development but a development model that optimizes on efficiency
So I'm thinking about my approach, which is "use commits as game save points, mostly WIP, then use rebase to tidy things up before publishing".
Wouldn't working on trunk still mean I'm working on a feature branch, but it all ends up squashed into a single commit? Or do I lose my opportunity to polish?
We performed code review with a projector in our office jointly looking at diffs, or emacs.
Of course it’s neat to have GitHub actions now and pull-requests for asynchronous code review. But I learned so much from my colleagues directly in that nowadays obscure working mode which I am still grateful for.