gitbitbucket

Is it possible to prevent a specific file being changed on the remote branch without a git force push


We share a build file named build.sh, that creates a binary file in a specific path. Since many developers change the path in this build.sh file on their local environment frequently and forget to change it back (we want to keep the default build path in the build.sh file on the remote branch), a warning that a force push is necessary to push this file to the remote branch would be great. (sometimes, but not often, we really have to change that file)

.gitignore is not an option, since the file already exists in the repository.

We use bitbucket. A global solution would be better than to change the git settings locally.

Any ideas?

Telling the developers to not use individual paths would surely help, but people often don't stick to that.


Solution

  • You can setup a pre-receieve hook. It will reject pushes where build.sh has been modified unless it's an explicitly allowed commit

    Here's official Bitbucket documentation on pre-receive hooks.

    1. Go to Project settings > Hooks.
    2. Click Add hook
    3. Install a custom hook:
    #!/bin/bash
    protected_file="build.sh"
    
    while read oldrev newrev refname; do
        if git diff --name-only $oldrev $newrev | grep -q "^$protected_file$"; then
            echo "Error: Modifications to $protected_file are restricted. Please revert your changes before pushing."
            exit 1
        fi
    done
    exit 0
    

    Also you can setup a specific keyword like [ALLOW_BUILD_CHANGE] to allow changing your protected file:

    while read oldrev newrev refname; do
        if git diff --name-only $oldrev $newrev | grep -q "^$protected_file$"; then
            commit_msg=$(git log --format=%B -n 1 $newrev)
            if ! echo "$commit_msg" | grep -q "\[ALLOW_BUILD_CHANGE\]"; then
                echo "Error: Modifications to $protected_file are restricted. Use '[ALLOW_BUILD_CHANGE]' in commit message to bypass."
                exit 1
            fi
        fi
    done
    

    Please note that this solution works for BitBucket Server and DataCenter