1

I am working on a git repository for which I have full permissions.

I want to temporarily check out the master branch in order to look at a few files in detail, in order to see how they differ from my feature branch. (The git diff command is very useful, but it would not work for my purposes at the moment.)

I really want to avoid even the possibility of accidentally writing to the master branch.

Is there a simple way to make my local version of the branch read-only for the moment without freezing the branch for everybody else on my team?

  • If you really want to make sure not to modify local master, you could simply do a detached checkout (`git checkout --detach master`). This way, if you would commit something, it wouldn't end up on any branch. However, committing to local master accidentally is not really an issue unless you push the commits. If you committed to local master accidentally, you could simply to `git reset --hard origin/master` to restore the state of your local master branch to that of the remote master branch (note that this will permanently discard any uncommitted changes in your worktree/index though). – Alderath Aug 28 '17 at 10:54
  • Worth thinking about: *every commit ever made* is read-only. This means that as long as you do not *remove* commits, adding commits to your repository does not touch any existing history at all. So: why would you care if you accidentally wrote to `master`? All the *old* commits would still be there, exactly as they were. (See @Alderath's comment.) – torek Aug 28 '17 at 14:35

3 Answers3

4

There are two ways you can use:

Option 1: protect master branch in github

Even you committed on master branch by mistake, git will stop you to push your local master branch to github.

The way to protect master as: in your github repo -> settiings -> branches -> choose master -> Require pull request reviews before merging -> save changes. So you can’t make changes on master branch directly, you should use PR to merge changes to master branch.

If you still need to make changes on master branch directly in some way, you can use option2.

Option 2: use pre-commit hook in your local repo

In your local repo, in .git/hooks, rename pre-commit.sample as pre-commit. And add below script in pre-commit:

#!/bin/sh

branch=$(git rev-parse --abbrev-ref HEAD)
if [[ $branch == "master" ]]
then
 {
   git reset HEAD .
   git checkout -- .
   echo "you tried to commit on master branch, recover master branch and stoppped! "
   exit 1
 }
fi

Now if you wrongly commit on master branch, git will reset the master branch as origin and hint you with messages.

Note: the commands git reset HEAD . and git checkout -- . will discard all the uncommitted changes on master branch. It's based on the changes is useless. If you want to keep the uncommitted on master branch, you can ignore the two commands.

Community
  • 1
  • 1
Marina Liu
  • 36,876
  • 5
  • 61
  • 74
  • Wouldn't it be enough to just output the message and exit with 1, won't the two git commands in there discard all his changes? – Lasse V. Karlsen Aug 28 '17 at 09:58
  • Yeah, the two commands will discard the changes on master branch. And it's just one of the situations that suspect the changes not need to applied on feature branch. My initial purpose is to show how does the pre-commit hook work. But thanks any way @LasseV.Karlsen, I will declare it in my answer. – Marina Liu Aug 28 '17 at 13:28
3

You could use Git hook to prevent this

And make .git/hooks/pre-commit

#!/bin/sh
if [ $USER != "git-repo-admin" ];
then
  if [ "$1" == refs/heads/master ];
  then
    echo "Pushing to master is restricted"
    exit 1
  fi
fi

If you keep this script on your own .git, this will not freeze the branch for others developers

Dylan Delobel
  • 786
  • 10
  • 26
-1

There's probably a much better answer to this, so I'll leave the question open, but here's what I ended up doing for the moment:

git checkout master #BE CAREFUL! JUST COPY IT SOMEWHERE AND GO BACK TO YOUR BRANCH!

mkdir ~/fake-project-master-delete-me-after-september-2017

cp -r ./* ~/fake-project-master-delete-me-after-september-2017

git checkout feature/123456

This of could of course take up a lot of drive space if you have a very large repository. I'm still hoping there's a better way.

====

Edit: Dylan and Marina posted their answers while I was putting this one up. Those are almost certainly better for most situations.