gitgit-flow

Problem moving bugfix on master (git flow branching strategy)


I had small problem with git flow and I'm trying to find right solution for it. I tried to show situation with image I attached.

So...

Master had some bug, feature 1 had small bug, witch already was deployed to production.

Developer 1 was already working on it.

At this time developer 2 was completing PR and moved his commits to master.

Developer 1 finished fix, merged his bugfix branch to release/9.2 branch then master branch. Then released fixed version to prod from branch/9.2 (with updated tag 9.2.1) (at this time feature 2 was merged to master, but it is not deployed at prod yet)

At this moment production is fixed and works fine.

Now Developer 2 wants to move his "feature 2" on production. he sees some commits after his feature but he does not minds it (thinks it is other feature), and creates new release/9.3 from 026b8ef9 his last commit, and deploys it. So he is redeployed feature 1 without fix.

What went wrong? For me developer 2 did right, he dont wanted to take unfamiliar (changes from other team) changes to production He did not know it was bugfix. But he could prevent it. Unfortunately only branch is named "bugfix" and commit messages do not include any indicator that it fixes something. (And also tag 9.2.1 does not show on master branch)

Is there some good solution for this kind of problems? Or is it better to change git flow to more robust one?

enter image description here


Solution

  • It sounds like you are following a rapid CI-CD workflow where devs can create releases and push to production semi-arbitrarily. In Gitflow (and many other workflows), deploying a new release is generally a planned event.

    In your case, the work by Dev 1 in create a bug fix on 9.2 to create 9.2.1 sounds like a hotfix in Gitflow parlance. I can see that as a rapid, small team (or a single dev) that where the 9.2.1 release contains a single feature/bug fix.

    However, the creation of 9.3 sounds more like a Gitflow 'release' which normally built from a planned set of features (and bug fixes) executed as a coordinated release. Such a release would be cut from the latest 'main' (and QA tested, regression tested, release notes added, etc). This may be where your workflow doesn't fit well with Gitflow.

    Regardless, when creating/deploying a release, you may be able to identify if there are any significant commits introduced in a maintenance branch that are not yet merged into the main development branch - or in your case not missing from a freshly created release branch, or missing from an arbitrary commit on the main branch that is about to be used to create release branch.

    I tried to replicate your repo structure at the point after Dev 2 merged their feature to main and then Dev 1 merged the bugfix to main, BUT just before Dev 2 created release/9.3 off of their merge of their feature branch to main. Full disclosure: I am familiar with Gitflow from researching workflows for my team, but I don't use it in practice - I created this repo structure manually based on my book-ish (rather than practical) understanding of Gitflow.

    Master:

    $ git log --graph --decorate --oneline master
    *   01983fc (tag: 9.2.1, master) Release 9.2.1 master
    |\  
    | * ccef9e6 (release/9.2.1) Release 9.2.1
    | * 2a31706 (bugfix-on.9.2) bugfix on 9.2
    * | b43c8ab (tag: 9.2) Release 9.2 master
    |/  
    * bdaad25 (release/9.2) Release 9.2
    * 18792be feature 0
    

    Main:

    $ git log --graph --decorate --oneline main  
    *   0c12930 (HEAD -> main) Merge bugfix on 9.2 (used to create 9.2.1) into main
    |\  
    | * 2a31706 (bugfix-on.9.2) bugfix on 9.2
    * |   8e68470 Merge feature-1
    |\ \  
    | * | 424534c (feature-1) commit 2 of feature-1
    | * | bdec09f commit 1 of feature-1
    | * | 3441b54 Start 9.2 development
    | |/  
    * / 4e66643 Start 9.3 development
    |/  
    * bdaad25 (release/9.2) Release 9.2
    * 18792be feature 0
    

    Dev 2 could at this point check if their target commit (8e68470) for creating a release is missing any significant commits that are present in the last 'master'. This 'git log' command is literally: show me commits in 'master' (reachable from 'master') but remove ('^') any commits that are part of (reachable from) '8e68470' and remove ('^') commits that are part of tag '9.2' (the release Dev 2 thinks is on production now).

    $ git log --graph --decorate --oneline master ^8e68470 ^9.2                    
    *   01983fc (tag: 9.2.1, master) Release 9.2.1 master
    |\  
    | * ccef9e6 (release/9.2.1) Release 9.2.1
    | * 2a31706 (bugfix-on.9.2) bugfix on 9.2
    

    Most of these commits are gitflow 'plumbing' commits except 2a31706 which is a real code change (the --name-status option might make this more obvious). At that point, Dev 2 would have to start asking questions about A) what is this 9.2.1 release, and B) what is this a code change 2a31706 that is present in master (and thus on production) that is not in their target commit that they want to turn into a release.

    Contrast this to checking if main is missing any maintenance commits, i.e. if 'master' has any commits that aren't already in 'main'

    $ git log --graph --decorate --oneline master ^main ^9.2 
    * 01983fc (tag: 9.2.1, master) Release 9.2.1 master
    * ccef9e6 (release/9.2.1) Release 9.2.1
    

    These are all gitflow plumbing commits (as opposed to code changes), so main could be turned into a release without any missing bug fixes.