How to Avoid Pushing In-development Changes to The Production Repository

Once a code base is sophisticated enough to require both a public, customer-facing production environment and private development environment, it becomes vital to prevent potentially breaking development changes from being accidentally pushed to production.

This post will go over three methods of preventing development changes from being pushed to production:

  • Changing the Remote’s URL
  • Using Git Hooks
  • Adding Branch Protection
Book a Call with Dojo Five Embedded Experts

Changing the Remote’s URL to Prevent Accidental Pushes to the Production Branch

This method prevents accidentally pushing in-development changes to the wrong environment by changing the remote’s URL using git CLI commands:

# git command to change remote's URL 
$ git remote set-url --push <REMOTE_NAME> <NEW_URL>

By adding the –push flag to the command, only the push URL is manipulated. So it is still possible to pull from that remote. Then, we want to set the push URL to anything that won’t be a real endpoint such as no_push. Now, when someone accidentally pushes their changes, the URL is invalid and the command will fail.

# git command to disable the push
$ git remote set-url --push <REMOTE_NAME> no_push
# Example
$ git remote set-url --push prod no_push

# git command to list the remote repositories
$ git remote -v
origin	<https://github.com/user/repo_forked.git> (fetch)
origin	<https://github.com/user/repo_forked.git> (push)
prod	<https://github.com/user/repo.git> (fetch)
prod	no_push (push)

# When one accidentally push changes to prod with push URL set to no_push 
$ git push prod
fatal: 'no_push' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

If you need to push code to that remote in the future, you can simply re-enable the push by doing the following.

$ git remote set-url --push &lt;REMOTE_NAME> &lt;REPO_URL>
# Example
$ git remote set-url --push prod &lt;https://github.com/user/repo.git>

# git command to list the remotes
$ git remote -v
origin	&lt;https://github.com/user/repo_forked.git> (fetch)
origin	&lt;https://github.com/user/repo_forked.git> (push)
prod	&lt;https://github.com/user/repo.git> (fetch)
prod	&lt;https://github.com/user/repo.git> (push)

Using Git Hooks to Prevent Accidentally Pushing Development Changes to a Production Branch

Another effective method to prevent pushing development changes to a production branch is to use Git Hooks . Git Hooks are scripts that run automatically at certain points in the Git lifecycle, such as before a commit is made, before pushing changes, or before merging. By leveraging Git Hooks, you can enforce additional checks before changes are pushed to a production branch.

Setting Up a Pre-Push Hook

The pre-push hook is a powerful tool for intercepting a push operation before the changes are sent to the remote repository. You can use this hook to check whether the branch being pushed is the production branch (e.g., main or production), block the operation, and display an error message.

1. Navigate to Your Local Git Hooks Folder

In your local repository, Git Hooks are located in the .git/hooks directory. If you’re working in a shared team environment, make sure to create a shared version of the hooks to ensure uniformity across all developers’ machines. For now, let’s focus on setting up the pre-push hook.

2. Create or Modify the pre-push Hook

If the pre-push hook does not already exist, you can create a new file called pre-push in the .git/hooks/ directory. If it does exist, you can modify it.

Example of a pre-push hook script:

#!/bin/bash


# Get the current branch name
current_branch=$(git rev-parse --abbrev-ref HEAD)


# Define your production branches (you can add more as needed)
protected_branches=("main" "production")


# Check if the current branch is a protected branch
if [[ " ${protected_branches[@]} " =~ " ${current_branch} " ]]; then
    echo "Error: You are trying to push to a protected branch ($current_branch)."
    echo "Please ensure you are pushing to a non-production branch."
    exit 1
fi


# Allow the push to continue if not pushing to a protected branch
exit 0

3. Make the Hook Executable

After creating or editing the hook, make it executable by running the following command:

chmod +x .git/hooks/pre-push

4. Push Attempt to a Protected Branch

Now, when a developer tries to push changes to a protected branch (e.g., main or production), the pre-push hook will run and display an error message, preventing the push. For example:

$ git push origin prod
Error: You are trying to push to a protected branch (prod).
Please ensure you are pushing to a non-production branch.

5. Allowing Pushing to Other Branches

If the developer tries to push to any other branch, the push will be allowed without interference, as the hook only prevents pushes to protected branches.

By using the pre-push hook, you automate a safety check that ensures no one accidentally pushes code to the production branch. This is especially useful when working with local or remote repositories that don’t have branch protection rules in place. Even if a developer forgets to follow the standard process or is working in a rush, the hook acts as a last line of defense to catch potentially catastrophic errors before they reach your production environment.

Adding Branch Protection to Prevent Accidental Pushes to the Production Branch

Branch protection helps ensure that critical branches, such as  main or production, are not accidentally modified. By enforcing rules that restrict who can push or merge to production branches, you significantly reduce the risk of errors and issues making their way into a production environment.

Steps to Set Up Branch Protection on GitHub:

1. Navigate to Your Repository Settings

Go to your repository on GitHub, then click on the Settings tab. This is where you can manage many aspects of your repository, including branch protection.

2. Access Branch Protection Settings

On the left sidebar, select Branches. Under the “Branch protection rules” section, click on the Add rule button.

3. Choose the Branch to Protect

In the “Branch name pattern” field, type the name of the branch you want to protect (e.g., main, production, or any other branch that holds your production code).

4. Enable Protection Rules

Once you’ve selected your branch, enable the rules you want to enforce. Here are some key options:

  1. Require pull request reviews before merging
    This ensures that all changes to the protected branch must go through a code review.
  2. Require status checks to pass before merging
    This ensures that all automated tests (CI/CD) pass before the code can be merged.
  3. Include administrators
    This enforces the same protection rules on repository administrators, preventing accidental changes even by people with elevated permissions.

5. Save the Rule

After configuring the protection settings, click Create or Save changes to activate the protection rule.

Once branch protection is enabled it is impossible for developers to push changes directly to production branches. Instead, they must use pull requests, which can be reviewed and approved before merging. This adds an additional layer of safety, especially in larger teams where collaboration and testing changes are key to overall project success. 

Do Embedded Firmware Right with Dojo Five on Your Team

In conclusion, by using remote URL settings in combination with other safeguards such as Git Hooks and branch protection, it is possible to prevent accidentally pushing changes to critical branches. Spending a few minutes on prevention will certainly save you from some hassle in the future.

Are you looking to modernize your embedded firmware development and support processes? You can book a call with us to get the conversation started. Or if you’re into DevOps, you can sign up for our EmbedOps platform. We look forward to hearing from you!

Discover why Dojo Five EmbedOps is the embedded enterprise choice for build tool and test management.

Sign up to receive a free account to the EmbedOps platform and start building with confidence..

  • Connect a repo
  • Use Dev Containers with your Continuous Integration (CI) provider
  • Analyze memory usage
  • Integrate and visualize static analysis results
  • Perform Hardware-in-the-Loop (HIL) tests
  • Install the Command Line Interface for a developer-friendly experience

Subscribe to our Monthly Newsletter

Subscribe to our monthly newsletter for development insights delivered straight to your inbox.

Interested in learning more?

Best-in-class embedded firmware content, resources and best practices

Laptop with some code on screen

I want to write my first embedded program. Where do I start?

The boom in the Internet of Things (IoT) commercial devices and hobbyist platforms like the Raspberry Pi and Arduino have created a lot of options, offering inexpensive platforms with easy to use development tools for creating embedded projects. You have a lot of options to choose from. An embedded development platform is typically a microcontroller chip mounted on a circuit board designed to show off its features. There are typically two types out there: there are inexpensive versions, sometimes called

Read More »
Medical device monitoring vitals

IEC-62304 Medical Device Software – Software Life Cycle Processes Primer – Part 1

IEC-62304 Software Lifecycle requires a lot of self-reflection to scrutinize and document your development processes. There is an endless pursuit of perfection when it comes to heavily regulated industries. How can you guarantee something will have zero defects? That’s a pretty hefty task. The regulatory approach for the medical device industry is process control. The concept essentially states that if you document how every step must be completed, and provide checks to show every step has been completed properly, you

Read More »
Operating room filled with medical devices

IEC-62304 Medical Device Software – Software Life Cycle Processes Primer – Part II

Part I provides some background to IEC-62304. Part II provides a slightly more in-depth look at some of the specifics. The IEC 62304 Medical Device Software – Software Lifecycle Processes looks into your development processes for creating and maintaining your software. The standard is available for purchase here. So what activities does the standard look at? Here are some of the major topics. For any given topic, there will be a lot more specifics. This will look at a few

Read More »