5

Is there any way of preventing a developer from checking out a different branch? My problem is quite simple: someone from my team keeps checking out a different branch on a production environment, which can of course cause all kind of problems with the code that shouldn't end up there or code that was there but disappeared after the checkout.

I checked a list of possible git hooks here https://www.kernel.org/pub/software/scm/git/docs/githooks.html but I was unable to find any hook that could be useful in such a case.

Also, I found a similar question (Prevent a checkout in Git) where it was suggested to use a script instead of the git checkout command in the workflow. But it doesn't really solve my problem as I'm not even sure if the checkout is made manually by some dev not knowing git, or is because of improperly configured IDE that as a result of bad configuration and linking local project to a remote one makes the checkout automatically, so the developer using it isn't even aware of that. In such a case, even if I used scripts instead of the git checkout, I would still have to disable the standard git checkout.

Does anyone know a solution for that? Or maybe a post-checkout hook can be used to checkout back? It's still better than nothing.

Community
  • 1
  • 1
Bartosz Górski
  • 1,140
  • 13
  • 30
  • Can you use file permissions to deny modifications to the .git folder or possibly just the .git/HEAD file? – John Koerner May 23 '15 at 03:02
  • 3
    You need to get control of your production environment. You're asking how to whack one mole here. – jthill May 23 '15 at 03:04
  • This is a terrible idea. If your co-workers can not handle Git, production, or an IDE you have much bigger problems then some kind of rouge program usage. This is a people training problem not a technical one. – Sukima May 23 '15 at 03:27
  • Why does a developer who keeps messing up production still have access to production? Your production environment should be locked down so that only trustworthy people can access it. – ChrisGPT was on strike May 23 '15 at 12:26
  • @Chris even trustworthy people can fail sometimes. Getting to the root of the 'who and why' problem is one thing, but I also want to ensure no one will ever be able to do the same thing again and that's why I asked a question here. – Bartosz Górski May 23 '15 at 23:15
  • @BartoszGórski, that's completely valid. Of course, everybody makes mistakes. It just seems like a big risk that you've got a developer with access to production who *keeps* making this one. IMO it is worth considering whether this person should have the access that they do. – ChrisGPT was on strike May 24 '15 at 13:23

2 Answers2

5

In a distributed environment like Git, you only can enforce policy at the blessed server level (where all programmers need to push back to).
Not at the client level (where each programmer have cloned a repo and can checkout whatever branch they want)

For instance, a simple policy like:

  • a dedicated repo for the prod branch
  • git config receive.denyNonFastForwards true set on that repo would ensure that any push done on prod would at least include all the existing history of the prod branch, plus some new commits.

That alone would make sure that any contribution done to that branch is actually based on said branch.

A more sophisticated policy would be an authorization layer like gitolite, which can protect a specific branch of a repo (or even a specific folder or file), removing the need to isolate the production branch in its own repo.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
1

in my case on some small projects where I do not have automated deployments, I would ssh into the server and then sometime by mistake I would (almost) checkout out another branch believing I was working on my local computer. That scares me a lot when this happens!

To prevent this I created a proxy script for git. This script will run instead of git itself and will filter the sub commands. If the sub command is checkout, it will exit the script. If it is another sub command, it will forward it to the real Git application with original arguments.

This is the proxy script. You can put anywhere on the machine you wish to prevent git checkout.

git-proxy.sh

#!/usr/bin/env bash

# This will not block non-interactive shell execution
if [ ! -z "$PS1" ]; then
    command git $@
    exit 0
fi

case $1 in
    checkout)
        echo "prevented execution of git checkout"
        exit 1
    ;;
esac

# https://www.cyberciti.biz/faq/ignore-shell-aliases-functions-when-running-command/
command git $@

Then in your .bashrc file, you add the following alias

alias git='/home/myuser/scripts/git-proxy.sh'

Then just run git checkout to get the following outcome: prevented execution of git checkout

Other approach

With the alias, it may not cover every possible cases. If that does not help, you could try (I have not tried it) to find the location of Git on your system which git and move it to a different name mv git the-real-git. Then place the proxy in the original place of git mv git-proxy.sh git

Side note

I am not a bash wizard, so this might not be the neatest way to do it, but it should work. Please note that moving the original git application may have unintended consequences. This may delete the proxy when git is updated (or might break git installation, I don't know)

Lunfel
  • 2,499
  • 21
  • 29