Search code examples
gitgithubdevelopment-environmentproduction-environment

Pushing a bugfix to production when development is not yet stable


New to git, and don't totally comprehend how everything works, so looking for some detailed instructions...

I have three remotes:

  • origin, where code changes are made and developers do preliminary testing. Once those changes seem stable, they're pushed to...
  • staging, where multiple users (not just those who wrote the code) do further testing. Once staging has been beaten apart and is satisfactory to go in front of customers, I push to...
  • production, where the app becomes public and customers can use it.

I have changes in my staging environment that are not ready to go to production, but have an urgent fix that needs to go to production now. How would I go about creating a fix and pushing it to production without pushing the unstable changes in staging?

I've pushed a few commits to staging using this process:

Get the latest code:

git checkout master
git fetch origin
git merge origin/master

Migrate the database:

bundle exec rake db:migrate

Create a new branch:

git checkout -b newbranch

(make some changes, test locally and run test suite)

Commit changes:

git add .
git commit -m "commit message"

Merge changes:

git checkout master
git merge newbranch

(test locally to make sure nothing got messed up in the merge)

Push to repository:

git fetch origin
git merge origin/master
git push origin master

Push to staging/dev environment:

git push staging master

(Further testing in development area to make sure everything is good to go to production. Start over if further changes need to be made before pushing. This loop continues for a while until everything looks good. Currently, I'm at this stage, with changes that are being tested and are not ready to go to production yet.)

Push to production:

git push production master

So let's say I create a new branch with a bug fix...how would these steps change to get that bug fix to production without pushing all the unstable changes that are on staging right now?

I've done a decent amount of searching around, and so far have figured out that there is a way to do it, but I am too shaky with git to figure out the commands to use to get there...Thanks in advance.


Solution

  • Don't pollute your master branch with untested stuff

    You write that you routinely push your local master branch to your staging server; if so, that implies that you're not 100% sure that what's on master is ready for production. But isn't master supposed to be your most stable local branch? Or do you have an even more stable (local) branch?

    If your local master is indeed meant to be your most stable branch, you are wrong to merge untested/experimental stuff (e.g. from newbranch) in master before testing that everything works on your origin and staging servers; you are "polluting" your local master branch with unproven stuff! Not good.

    A suggestion for fixing the immediate problem

    At the very least, you should switch to a workflow that doesn't pollute your local master branch.

    Here is an idea. Create a new local branch called develop pointing to the current tip of master.

    git branch develop master
    

    Then, under the assumption that origin/master is behind your local master branch, reset your local master branch to its last stable state (the current production state):

    git checkout master
    git reset --hard production/master
    

    Now, create and checkout a bugfix branch that points to the same commit as master does:

    git checkout -b bugfix
    

    Then

    1. Make some commits on bugfix to fix the bug.
    2. Push your bugfix branch to the master branch in your origin server:

       git push origin bugfix:master
      

      Force push if you have to.

    3. As long as you're not satisfied with the results on your origin server, go back to step 1.
    4. Once you're satisfied with what you see on your origin server, push your bugfix branch to the master branch in your staging server

      git push staging bugfix:master
      

      Force push if you have to.

    5. As long as you're not satisfied with the results on your staging server, go back to step 1.

    Finally, merge bugfix into master, delete it, and push master to your production remote:

    git checkout master
    git merge bugfix
    git branch -d bugfix
    git push production master
    

    Now that you have deployed the bugfix, it's time to bring your develop branch up to date:

    git checkout develop
    git merge master
    

    Your develop branch now contains the bugfix. You can continue developing your new features on it.

    A suggestion for improving your workflow

    Do all development on develop. If you want to, use intermediate feature branches, that you then merge into develop. When you're ready to test the new stuff,

    1. Push develop to the master branch in your origin server; make sure everything works there.
    2. Push develop to the master branch in your staging server; make sure everything works there.
    3. Merge develop into master.
    4. Push master to the production server.