There is one thing you can do, but it requires active participation from your users. They must install a pre-commit hook.
The pre-commit hook can be very simple:
#! /bin/sh
# pre-commit: fail if current branch is master or develop
case "$(git rev-parse --abbrev-ref HEAD)" in
master|develop) echo "make a new branch first" 1>&2; exit 1;;
esac
exit 0
You would include this file (be sure to chmod +x
it or otherwise make it executable) in your repository, and they would use the "magic incantation" of:
$ git clone <url>
$ cd <new-clone>
$ cp <path-to-file> .git/hooks/pre-commit
when cloning. However, if they forget to do the cp
step, they will not have a hook. (You can give them a script that does the clone-and-install-hooks, or a more general script that installs hooks for them that they should run after cloning. You can even set up a template directory with hooks—or have them do this themselves, on their systems—and then use git clone --template=<template-dir>
.)
Opinion alert: The whole idea is ultimately futile, because those who know what they are doing can easily get around anything you do here (e.g., git commit --no-verify
); and for those who know what they are doing, there's no point, as branch names are essentially meaningless anyway.1 For those who are totally clueless, you can't provide this automatically. So all you can do is provide hints to users who are willing to take action, but don't understand the action they are taking.
1Consider that after making several commits on my branch named master
, I can run:
git branch -m master feature/xyz
to rename my master
to my feature/xyz
, then:
git checkout master
to create a new master
whose upstream is origin/master
; the new master
points to the same commit as origin/master
. Then:
git checkout feature/xyz
puts me back on my feature/xyz
. My feature/xyz
now probably has its upstream set to origin/master
, but maybe that is what I want anyway.
The branch names in my repository are all just ephemera here: I create, rename, and/or destroy them at will and whim. What matter are the commits. That's not the case for your server-side branch: the branch names there get copied into other users' remote-tracking names when they clone that repository, and those other users are probably naïve about how branch names and remote-tracking names work, so those names do matter. But once you know how names work in Git, they're just for convenience, and easily changed.