Comments by "Andrea Laforgia" (@andrealaforgia) on "Git Flow Is A Bad Idea" video.

  1. 8
  2. 4
  3. 2
  4. 2
  5. 2
  6. 2
  7. 2
  8. 2
  9. 2
  10. >I think continuous integration is a good idea, but I think pushing directly to origin/main (or origin/master) is a bad idea. That's a contradiction :) It's not CI if you don't push directly to the main branch of development multiple times a day. Note that CI and trunk-based development are the same thing. >My preferred way of working is to split backlog items / user stories into small (mostly) atomic tasks that aim to introduce one small addition. That's great. >All developers are human and everyone makes mistakes. By peer-reviewing every single addition to the code base we catch these small mistakes early. Sure, and that's why CI is not removing the benefit of code reviews from the picture. It's only advocating a different way of reviewing code, through continuous code reviews that happen while developing, and not at the end. There are various disadvantages of having PRs at the end of development phases: it's extremely hard for a reviewer that has not been involved in the development of a feature to get a good understanding of what the code does. You haven't seen it working live, you only have a bunch of files to statically analyse. The risk is that reviewers only skim through the files for a superficial validation, trusting the creator of the PR (especially if she/he is a senior member of the team who knows the system well) and coming up with a "LGTM". This is were PRs can become really dangerous tools. It is much better to use pair/mob programming and continuously review the code while working on it. >The added benefit of this is that you get to read other people's code daily. Is that a benefit? Having to stop your development activities to read other people's code of which you know very little? >That is a great way to learn. Sure, but learning through collaboration is 10x better.
    2
  11. 1
  12. 1
  13. 1
  14. 1
  15. 1
  16. 1
  17. 1
  18.  @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
  19.  @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
  20. 1
  21. 1
  22. 1
  23. 1
  24. 1
  25. 1
  26. 1
  27. 1
  28. 1
  29. 1
  30. 1
  31. 1
  32. 1
  33. 1
  34. 1
  35. 1
  36. 1
  37. 1
  38. 1
  39. 1
  40. 1
  41. 1
  42. 1
  43. 1
  44. 1
  45. 1
  46. 1
  47. 1
  48. 1
  49. 1
  50. 1
  51. 1
  52. 1
  53. 1
  54. 1
  55. 1
  56. 1
  57. 1
  58. 1
  59. 1
  60. 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
  61.  @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
  62. 1
  63. 1
  64. 1
  65. 1
  66. 1
  67. 1
  68. 1
  69. 1
  70. 1
  71. 1
  72. 1
  73. 1
  74. 1
  75. 1
  76. 1
  77. 1
  78. 1
  79. 1
  80. 1
  81. 1
  82. 1
  83. 1
  84.  @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
  85. 1
  86. 1
  87. 1
  88. 1
  89. 1
  90. 1
  91. 1
  92. Again, quoting some experts here: "...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." (Jez Humble) "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." (Kief Morris) “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.” (ThoughtWorks)
    1
  93. 1
  94. 1
  95. >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
  96. 1
  97. 1
  98. 1