Prevent Other Git Authors

Prevent people from pushing a git commit with a different author name?

We use the following to prevent accidental unknown-author commits (for example when doing a fast commit from a customer's server or something). It should be placed in .git/hooks/pre-receive and made executable.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import subprocess
from itertools import islice, izip
import sys

old, new, branch = sys.stdin.read().split()

authors = {
"John Doe": "john.doe@example.com"
}

proc = subprocess.Popen(["git", "rev-list", "--pretty=format:%an%n%ae%n", "%s..%s" % (old, new)], stdout=subprocess.PIPE)
data = [line.strip() for line in proc.stdout.readlines() if line.strip()]

def print_error(commit, author, email, message):
print "*" * 80
print "ERROR: Unknown Author!"
print "-" * 80
proc = subprocess.Popen(["git", "rev-list", "--max-count=1", "--pretty=short", commit], stdout=subprocess.PIPE)
print proc.stdout.read().strip()
print "*" * 80
raise SystemExit(1)

for commit, author, email in izip(islice(data, 0, None, 3), islice(data, 1, None, 3), islice(data, 2, None, 3)):
_, commit_hash = commit.split()
if not author in authors:
print_error(commit_hash, author, email, "Unknown Author")
elif authors[author] != email:
print_error(commit_hash, author, email, "Unknown Email")

How to prevent author of Git commit from being changed

Your Git repository is yours. You can do anything you want to it. No one else can stop you, and you cannot stop anyone else from doing anything they want to their repositories.

In short, there is nothing—literally nothing—you can to do prevent someone else from claiming to be you, or to prevent yourself from claiming to be someone else. This is the same problem a bank ATM has. In order to make sure you are you, and Fred is Fred, and so on, you must step outside the problem itself and look to authentication. If someone claims to be Fred, how do you know whether he is or is not Fred? Especially, how can you tell whether he's really Fred if you've never met him before? He might be Ravi, or Binyamin, or Jürgen!

If you and Fred have a shared secret, or some other way of deciding whether to believe him, you can use that. And that's all you can do: decide, at the time you are obtaining some set of commits from someone, whether or not you believe them when they tell you they're Fred.

Git has GPG signature verification built in, to some extent (it does not do the GPG signature stuff itself, it relies on third-party software). You can sign individual commits, or sign an annotated tag. For a bunch of good reasons, signing individual commits is usually more cost than benefit. Git commits form a Merkle Tree, so checking the signature of an annotated tag provides a reasonable level of assurance about the commits reachable from that tag. (The amount of protection, however, is not much greater than that of SHA-1.) See also GPG.

How to prevent gerrit from modifying other commits?

I implemented what I need using git pre-push hook.
Here is a content of my .git/pre-push file:

#!/bin/sh

# A hook script to verify what is about to be pushed. Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed. If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
# <local ref> <local sha1> <remote ref> <remote sha1>

AUTHOR=$(git var GIT_AUTHOR_IDENT)

while read local_ref local_sha remote_ref remote_sha
do
commit_author=$(git log -1 --pretty=format:"%ae" $local_sha)
#echo $local_ref $local_sha $remote_ref $remote_sha $commit_author
found=`echo $AUTHOR | grep -c "$commit_author"`

if [ $found == 0 ]
then
echo
echo "REJECTED by local pre-push hook:"
echo "You are trying to push some other's commit: $local_sha $commit_author"
echo "Use --no-verify if you are sure this is not an error"
exit -1
fi
done
echo "Local pre-push verify passed ok"
exit 0

Stop users committing to git as wrong user

Ooops: While this is a valid technique, it assumes you have effectively full control over the server. If you're using a hosted solution all bets are off.

You can validate the author name and email in the repository's update hook. You can get both values like this:

#!/bin/sh
set -- refname sha1_old sha1_new
author_name=$(git log --pretty=format:%an $sha1_new)
author_email=$(git log --pretty=format:%ae $sha1_new)

The trick, of course, is figuring out whether or not these are valid. Here's one trick:

You can use the command="" option in your ssh configuration to make a wrapper around git-receive-pack that maps ssh keys to author information. For example, something like this:

#!/bin/sh

GV_AUTHOR_NAME="$1"
GV_AUTHOR_EMAIL="$2"

export GV_AUTHOR_EMAIL GV_AUTHOR_NAME
eval exec $SSH_ORIGINAL_COMMAND

And you would use an authorized_keys line something like this:

command="~/bin/gitvalidator 'Lars Kellogg-Stedman' 'lars@seas.harvard.edu'" ssh-rsa ...

The result of all this is that your update script would have the environment variables GV_AUTHOR_NAME and GV_AUTHOR_EMAIL available, and could check these against the commit and exit with an error if they didn't match.

Stop a git commit by a specific author using pre-commit hook

Until v1.7.10.1 (released 2012-05-01), Git did not make --author information available to Git hooks via environment variables, command-line arguments, or stdin. However, instead of requiring the use of the --author command line, you can instruct users to set the GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL environment variables:

#!/bin/sh
AUTHORINFO=$(git var GIT_AUTHOR_IDENT) || exit 1
NAME=$(printf '%s\n' "${AUTHORINFO}" | sed -n 's/^\(.*\) <.*$/\1/p')
EMAIL=$(printf '%s\n' "${AUTHORINFO}" | sed -n 's/^.* <\(.*\)> .*$/\1/p')
[ "${NAME}" != root ] && [ "${EMAIL}" != "root@localhost" ] || {
cat <<EOF >&2
Please commit under your own name and email instead of "${NAME} <${EMAIL}>":
GIT_AUTHOR_NAME="Your Name" GIT_AUTHOR_EMAIL="your@email.com" git commit
EOF
exit 1
}

Like the --author argument, these environment variables control the commit's author. Because these environment variables are in Git's environment, they're also in the environment of the pre-commit hook. And because they're in the environment of the pre-commit hook, they're passed to git var GIT_AUTHOR_IDENT which uses them like git commit does.

Unfortunately, setting these variables is much less convenient than using --author. If you can, upgrade to v1.7.10.1 or later.



Related Topics



Leave a reply



Submit