Comments by "Andrea Laforgia" (@andrealaforgia) on "Git Flow Is A Bad Idea" video.
-
8
-
4
-
2
-
2
-
2
-
2
-
2
-
2
-
2
-
2
-
1
-
1
-
1
-
1
-
1
-
1
-
Can you clarify how Git Flow would ever help companies to manage risk of change in codebases with poor test coverage?
Cause if test coverage is poor, no branching strategy helps there.
With regard to "one-size-fits-all": no one ever stated that. In every case, however, where GitFlow is used, then Continuous Integration can be used, because CI would provide a logical segregation of features that is equivalent to the physical one offered by GitFlow.
Sure, every organization has different approaches to risk, and yet so many use the same techniques to manage it: feature branching, GitFlow, PRs.
In virtually every comment from GitFlow fans I've heard "it's not a silver bullet", "it doesn't always work", "in the real world it does not work that way" and yet no real argument was offered to rebut what Dave talks about in his video.
What are the contexts where CD is not applicable? (not provoking, just curious)
1
-
@clickrush >processes and tools cannot substitute communication and engagement with your coworkers. There is not one size fits all, no silver bullet is what I'm getting at.
Again, this is a typical logical fallacy, black&white reasoning. Who ever said that CI is a "silver bullet"? CI is a way of working that has proven to be better than other ways of working to develop software. Period. No one has ever stated, in any books/resources/articles about CI, that CI is a "silver bullet". People keep rejecting CI and trunk-based development putting a lot of emphasis on communication, like communication were the only thing a team needs in order to deliver software. A team needs to be able to continuously integrate their work. That's the point. CI is not substituting communication and engagement with your coworkers.
How is a long-lived feature branch approach fostering any communication, given that it's a way to hide your changes and silo your development? Developers adopting feature branches often do not communicate for days and days, only to discover problems at the time of merging their changes.
>The beauty of git is that is doesn't inherently prevent you from merging or branching.
I don't see that as a "beauty". This video is not about git, it's about GitFlow. It's different.
>Saying that rule/methodology X simplifies things begs the question: Under what circumstance?
How much do you know about CI, which has been going on for almost 2 decades, and all the studies about it that prove it's the best way to develop software we know so far? Read "Accelerate".
1
-
@clickrush >I wasn't arguing against CI generally. I was questioning the notion that one particular way of using git "represents reality" for all
I see a contradiction there. CI does dictate "one particular way of using your VCS". The definition of CI is "practice of merging all developers' working copies to a shared mainline several times a day" so if you're not questioning CI, you shouldn't be questioning trunk-based development either, cause CI and TBD are the same thing. Nobody is saying that this particular way of using git represents reality for all. What has been said is that if you want to implement CI, you need to give up ways of working that are antithetical to CI, and GitFlow is one of them for the reasons exposed. You are still free not to do CI, though.
>What may happen if you don't separate work into branches on the VCS level is that you are separating it on the code level. You introduce configuration and (ad-hoc) logic in your code base so you can accommodate staging environments, beta/prototype features and so on. Which means you need to test that code too, which means you blow up your code base just so you can avoid branching.
Absolutely not. Have you actually ever tried trunk-based development + feature toggles? It's much easier than you'd think. When feature toggles are inactive, you can consider the code they hide as not there at all.
Separating the code physically (feature branches) offers less benefits than separating it logically (feature toggles). The latter approach at least makes sure that the various streams of development are integrated, the former doesn't, and the longer those branches live, the more they diverge from each other and master, the riskier it becomes to merge them into master. You can switch features on in your specific test environment and do all you want. It's much cleaner and simpler. The ability to integrate work and the ability to test/release features are two different aspects of software development.
Note that you say "you blow up your code base just so you can avoid branching". First, you don't blow up at all your code base, quite the contrary. Second: the purpose here is not to avoid branches, but to fulfil the definition of CI. The fact that branches are avoided is a nice side effect.
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
When I talk about continuous delivery, I always think of complex flows. Continuously integrating changes into main/master and releasing features to production are two different concepts. Clearly, if you adopt an Agile way of working, you'd want to deliver as often as possible, but you can schedule releasing specific features, as long as they are present in the code but hidden behind feature flags.
When you release a new version of your product, all you need to do is tag your code. You don't need to create a release branch at that point in time (tags are logical branches). When it comes to hotfixing v.1.0.0, then you can create a branch, apply the hotfix to main, apply the hotfix to the branch, release version 1.1.0 whilst main/master happily navigates towards v.2.0.0. But that branch is not for continuous integration. It's for hotfixing. And what you really want is to converge that version into the main one asap. I would much prefer continuously delivering and not having to maintain multiple concurrent versions, parked on side tracks for ages. If you have hundred/thousand customers, that model becomes unsustainable. So, yes, you can achieve what you mention by having a single branch for continuous integration and deciding when to release features as a parallel process.
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
Scenario 1: You can indeed have only 1 function in your code that will implement one behaviour or the other based on the version (for example, you could use the Strategy pattern there). No need to keep your code physically separated when you can have logical separation.
You don’t need to duplicate any other version of the code that the two libraries have in common. No need to fix bugs in that part of the code multiple times.
In general, you can use feature toggles to logically separate “branches” of logic in the same code base. It works really well.
In some languages (e.g. Java + Spring Boot), leveraging dependency injection, there are some neat ways of injecting behaviours based on conditions that make the above very easy to do (look at how ff4j works, for example).
Scenario 2: the longer code is parked on a feature branch, the higher the risk of diversion from master and merge conflicts. The best way to develop code we know so far is to continuously integrate into a shared mainline multiple times a day (e.g. Continuous Integration). See above: using feature toggles, you can delay releasing a specific feature as long as you want.
The big misunderstanding here is that each push to master will release to production. One thing is pushing to master, another thing is releasing to production. You can have that with Continuous Deployment. With Continuous Delivery, your code is always releasable but not always released. The key point here is that you must be able to release whenever you want with no fear.
The reason why trunk-based development seems dangerous to you is because you’ve never used it. Companies like Google or Facebook (but I could also mention some smaller companies I’ve worked for) use scaled trunk-based development on extremely large projects with thousand developers on them.
What you describe in your last paragraph is not continuous integration.
Continuous Integration is defined as: “a development practice that requires developers to integrate code into a shared repository several times a day. Each check-in is then verified by an automated build, allowing teams to detect problems early.By integrating regularly, you can detect errors quickly, and locate them more easily.” (ThoughtWorks)
1
-
@markar34 Of course I am aware of semver, it's a de facto standard. Semver is irrelevant though. You can use whatever versioning mechanism.
I totally understand why you need to keep two separate versions of your library. That's a common scenario in any software, especially when you deal with "dinosaur" companies that move at a very slow pace and are reluctant to upgrade even when they would need to (e.g. big financial institutions).
I don't think you understood my comment though. I am not questioning the logical separation of your versions; I am questioning the physical separation. Believe it or not, you don't need long-lived branches to maintain that separation. You can have a logical separation of versions within the same single branch. You can deploy from the shared mainline using different configurations for each client and each version.
As I said before, if you have hundred or thousand clients, you cannot possibly afford long-lived branches for all of them. The ability to keep developing your software would grind to a halt.
I mentioned dependency injection with regard to how to use feature toggles properly with some languages/frameworks, just to avoid the mess in the code that you were mentioning. Your code can be architected in a way such that the usage of feature toggles has a very minimal impact on it. Unfortunately, it would take time and a real example to show you how that works. The ff4j library is very powerful from this point of view, leveraging proxies and DI.
>The fact that we share say, the develop branch, and our CI builds it, and runs automated tests, that's enough to say it's continuous integration. I'm not sure what is your definition of continuous integration.
Nope. Not if you use long-lived branches. Continuous Integration, as defined by ThoughtWorks, is: "Continuous Integration (CI) is a development practice that requires developers to integrate code into a shared repository several times a day. Each check-in is then verified by an automated build, allowing teams to detect problems early. By integrating regularly, you can detect errors quickly, and locate them more easily."
If your development happens on long-lived feature branches, it's not CI.
CI doesn't just mean having a CI build. It's a development practice.
1
-
1
-
1
-
1
-
1
-
>In real life you often have to undo days of work, refactor days of code, incorporate feedback from other stakeholders and so on.
People keep mentioning this "real life" like they are the only ones living in the real world and people like Dave Farley come from Mars. Please appreciate the fact that we all belong to the same reality. It's just that we have different work experience. The way of working that Dave is advocating is used effectively by many companies, some of which very large, with extremely large projects, and a huge number of developers.
>people will start using your unfinished code and start editing files you are working on.
Long-lived feature branches only make things worse in that case. TBD is much better, especially when heavy refactoring is involved. Imagine what would happen if we work in the same team, I branch from master, you branch from master, and start refactoring a number of classes you are working on, maybe removing some code that you are changing. I finish and merge into master. At the moment you need to merge, you will end up in merge hell. It will be impossible for you to understand how to fix the merge conflicts cause you don't know my changes. You will need me to help out, which basically means having you redo the work of days on a completely changed codebase.
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
@miletacekovic >Of course, you can delay branch creation till bug is found in it, and create a branch from tag when the bug is found. But once branch is created to fix a bug, you need CI pipeline attached to it.
It's not a CI pipeline, it's a build pipeline. It's different. CI means something specific: Continuous Integration. You don't do Continuous Integration on the releasae branches, you keep them for hotfixes. In general, however, keeping a release branch for every customer, assuming that you have hundreds of customers, is suicidal, a good recipe for disaster. You cannot really expect to have to hotfix a bug on hundreds of branches. You will need to make those customers converge into a new release at some point.
>Verifying if a bug fix did not break anything on developer workstation is little scary for medium to large systems .
What developer workstation? Who has ever talking about developer workstations? Developers' workstations are temporary workbenchs. CI is about integrating developers' work into a shared mainline multiple times a day. Tests run on the mainline.
1
-
@miletacekovic You are not doing continuous integration on the release branch. Therefore you cannot call the build for that release branch a "CI pipeline". You are fixing bugs on that release branch, you are not continuously integrating new development. That bug-fixing activity causes frustration among your developers, rest assured, given that they have to apply the same fixes in multiple places, with all the problems that that practice entails. If you have several bugs, discovered for multiple client's version, you need to multiply that bug-fixing activity for all those branches, increasing frustration and fear of mistakes. The idea that you can keep release branches open indefinitely is not a sustainable model. It doesn't really work anywhere. You will need, at some point, to make your release branch converge into master again or you are doomed to eternal sadness.
Stop calling it "CI pipeline". CI happens ONLY on the shared mainline of development, nowhere else. You are talking about separate builds that happen on the CI server. It's not a "CI pipeline".
1
-
1
-
1
-
1
-
@thenewms5333 LOL :) What a bunch of bs. I never read so many logical fallacies in a single comment.
Where do I start? First of all, I, as an engineer, am ALWAYS accountable for the quality of my team's deliverables. The idea that by doing pair programming your're not is just as ridiculous as the rest of drivel you've written. Now it's clear why you love the way you work so much: because you've made yourself indispensable, you love being an ivory tower, a huge bottleneck for the team, and cause a humongous bus factor for the company. You clearly enjoy being some sort of semi-god with the last word on the team's work. What happens if you're on holiday, you're sick, or you even die? Should the team find themselves in big trouble because you're not there? 20 PRs a day, LOL :D, yeah sure... counting 480 minutes in 8 hours of work, that means one PR every 24 minutes. You have no time to use the toilet, at that point, nevermind do any work. Again, what a bunch of bs!
You may be convinced all you want that pair programming doesn't work or that the continuous review process it entails doesn't work, and you couldn't me more wrong. The proponents of XP prove you wrong, the everyday practice of software development in many places (Amazon, Google, Industrial Logic, Hunter Technologies, and dozens of other companies including the ones I've worked) prove you wrong. The mountain of data that have led to the book "Accelerate" prove you wrong. The State of DevOps reports proves you prove. And so much more. All resources that you are clealry going to ignore because they generate cognitive dissonance in you :)
Pair programming works. Mob programming works. Continuous code reviews work. Senior engineers must sit and work with the rest of the team. Knowledge is spread by working together. Juniors learn by working WITH seniors, not by reading what seniors write in their comments.
The comparisons you make with other fields of the industry are completely fallacious. It's software development, not auto mechanics, hardware or "consultants". Software is a beast that moves and behaves unlike many other human artefacts.
Your problem is clear: you know very little about how software is developed, and angrily reject anything that dissonates with what you do.
Well, good luck, your team and your company need it.
1
-
1
-
1
-
1
-
1
-
1
-
@alexanderzaytsev1265 the release branches you mention are for hotfixing, not continuous deployment. As I said, it is totally possible to keep feature segregated in a way to respect what your customer s accept or don't accept. If you have acceptance critieria for each of your customers, you can test continuously and make sure you don't break any existing contracts.
No, PRs are not thee way you keep track of technical decisions. Indeed no one used them that way. For that, there are other documentation tools to use see ADR for example, or short design docs collecting feedback from architects, experts in an area, etc.
Pairs should be autonomous and, by working together, they continuously review the coee. They don't need third parties to look at what they've done with little to no context. Trust is a very important principle.
1
-
1
-
1
-
The funny thing about pair programming detractors like you is that you guys keep wishing “good luck”, like this is a new idea that people came up overnight, or some sort of new fancy theory they are proposing. Pair programming is one of the pillars of XP, which is more than 30 years old and has been a standard practice in trunk-based development environments for many years now. I have used pair and mob programming approaches in many places, always received very well by the team. The benefits of working that way were immediate, both to the team and the company.
Look, I understand that software development is hard and you have reached a certain equilibrium in your current place that you now consider a holy grail, but there has been a lot of research in the industry, a lot of evidence has been collected that certain ways of working are better than others and conducive to better quality, higher job satisfaction, happier customers. You want to read about it? Look at “Accelerate”, a good book written by the DORA guys.
This agreeing to disagree is often a way of shutting eyes and ears to what’s out there that could really improve your way of working.
Read “Continuous Delivery”, written by Dave. It’s an eye-opening gem.
1
-
1
-
>Did I totally misunderstand what you were saying or did you advocate to committing to main directly? Where does pull requests fit in your workflow?
With pair programming and/or mob programming, you don't need Pull Requests. Pull Requests are not the best model to review code and can have pretty nasty effects on the team. With pp/mp, you get continuous code reviews, which is a much better way of reviewing code than a PR-based model at the end of a long development phase on a feature branch.
>Let's forget PRs for a second (One of the foundations of quality).
Wait. That "one of the foundations of quality" is highly debatable. The usage of PRs within a team of trusted collaborators is a distortion of the original meaning of PRs. They were meant for groups of untrusted collaborators working on open source projects (where the concept of team doesn't really make sense). Used as a quality control tool for a team of colocated, trusted engineers can be detrimental to the team, the company and - above all - the customer. Often engineers have to review very large PRs, from which it's hard, if not impossible, to get a clear idea of how a feature is shaping up. In many cases, reviewers are in a weird situation where they can either reject or reluctantly approve the changes. In many other situations, there is an obnoxious back and forth of comments that waste time, block the team, raise flamewars, and slow down development. In many cases, compromises will be reached ("let's leave it like that for now") that will have no other effect than increase the tech debt in the code base.
It's about time to abandon PRs for a better model.
This is what Kief Morris says:
"Although designed to make it easier to accept contributions from untrusted people outside a team, many teams now use pull requests for people inside their own team. This practice has become so common that many people consider it a default, “best” practice. Some people assume there is no other way to make sure code is reviewed because they’ve never seen anything else."
This is what Jez Humble says:
"...we have to work in very small batches. This is antithetical to the way lots of developers like to work: sitting off on their own going down a coding rabbit hole for days before re-emerging. The elevation of "flow" (by which I mean individual flow, not lean/team flow, which is actually inhibited by this behavior.) [is much at fault here]. Trunk-based development is about putting the needs of the team above the needs of individual. The premise of CI and trunk-based development is that coding is fundamentally a social, team activity. This presents a challenge to the mythos of the developer-as-hero which is still pervasive in our industry."
This is what the guys from ThoughtWorks say:
"Some organizations seem to think peer review equals pull request; they've taken the view that the only way to achieve a peer review of code is via a pull request. We've seen this approach create significant team bottlenecks as well as significantly degrade the quality of feedback as overloaded reviewers begin to simply reject requests. Although the argument could be made that this is one way to demonstrate code review "regulatory compliance" one of our clients was told this was invalid since there was no evidence the code was actually read by anyone prior to acceptance. Pull requests are only one way to manage the code review workflow; we urge people to consider other approaches, especially where there is a need to coach and pass on feedback carefully."
There are much better ways to review code.
>IMO there are still a lot of developers who can't define a workable unit in to a single commit. They have to answer these questions 1. Does it build? 2. Does it run? 3. Does it pass unit tests? Even if that is the case if it's not shippable to production as is they need to put it behind a feature flag. This is a lot of overhead to repeat for every single commit.
No, it's not. You don't have to create a feature flag for every commit. A feature flag can be seen as a logical feature branch: you create it once, at the start, you remove it once the feature is complete. Each small batch of work is validated (build/test/run) before being pushed to master:
1. TDD you change
2. Build/validate
3. Push it
4. Goto 1
>It just means you create a branch off main and create a PR into main when you're ready.
That is not CI. That's feature branching, which is antithetical to CI (Dave has made specific videos on that too). Continuous Integration is defined as: "a development practice that requires developers to integrate code into a shared repository several times a day. Each check-in is then verified by an automated build, allowing teams to detect problems early. By integrating regularly, you can detect errors quickly, and locate them more easily." (ThoughtWorks)
>If your branch lasts more than a day then you reverse integrate main into it every day or multiple time a day. You go slow to go fast.
Merging master into your branch doesn't add any value if no developer has merged their changes into master yet.
If you and I create our own branches and work independently for days on our features, none of us will merge stuff into master for days; we will both do at the end of development on our feature branch, so merging master daily brings no benefit. Moreover, if I am massively refactoring the code and you are modifying part of that code, you'll end up in a huge merge hell: you'll need to reapply your changes from scratch, wasting days of work. With trunk-based development (e.g. CI), instead, you can refactor freely, knowing that any stepping on others' toes will be detected and fixed almost instantaneously.
>I totally get your argument but it assumes great levels of discipline and without the pull request process there is an increased likelihood of unfit code going into main.
See above: that's wrong.
1
-
1
-
1
-
1