8

Ninety-nine percent of time our team commits on local development boxes and pushes commits, in which case the authorship info on commits is correct. However, under times of high-stress someone will tweak something directly on the dev server and commit from there. When that happens the author info in the commit defaults to the shared deployment account.

Is there a way to prompt users for their author info on commit? They're not going to remember to do --author.

Some things I've looked at, but couldn't quite get across the finish line are:

  1. using a client side hook to reject commits with 'deploy' in the author string
  2. looked for a setting to always-prompt for author info
  3. try to automatically set author based on the ssh-key used to login to the box

Is there a way to get one of those to work or a good way to do it?

Ry4an Brase
  • 78,112
  • 7
  • 148
  • 169
  • 2
    Has your team discussed disallowing editing code directly on the dev server? – Aaron Kurtzhals Aug 09 '12 at 14:43
  • 1
    Definitely. That'll happen down the line I imagine, but right now it happens rarely and only during "emergencies" and putting something in place to prevent in entirely isn't something I can pull off as "the new guy". – Ry4an Brase Aug 09 '12 at 15:20
  • Don't look for a technical solution. Punish your employees for violating your companies development practices. – user229044 Aug 09 '12 at 15:29
  • @meagar I agree, but there's a middle ground. If three weeks into this new job my coworkers (they're not _my_ employees) can't commit in a way they've historically done (very rarely and only in "emergencies") because "the new guy" put a hook in place that prevents it, surely you understand that's sub-optimal. One starts w/ gentle education which requires knowing who's doing it and how often -- which is why this question asks about setting good author info not preventing commits (which is easy). – Ry4an Brase Aug 09 '12 at 15:49

3 Answers3

6

Okay, I found a way to do this, but it works only because we exclusively access this box over ssh using key based authentication.

In the shared deploy user's /home/deploy/.ssh/authorized_keys file I added an environment variable per key so that mine, for example, looks like this:

environment="GIT_AUTHOR_EMAIL=ry4an@host.com",environment="GIT_AUTHOR_NAME=Ry4an on Dev" ssh-rsa AAAA...cXBcmHr ry4an@host.com

which also required adding:

PermitUserEnvironment yes

to the /etc/ssh/sshd_config file.

That works, but I'd rather learn about a user.name=ASK setting if such a thing existed.

Ry4an Brase
  • 78,112
  • 7
  • 148
  • 169
0

I'm not quite sure how it works for you guys but you could have your devs set up an alias to l add the --author to every normal commit.

edhedges
  • 2,722
  • 2
  • 28
  • 61
0

Unfortunately I couldn't find a really satisfying solution either. I will list all solutions I found so far (I think you proposed already the best 3 ones in your question).

(1) Forbid committing without --author

Save the following script as pre-commit hook in in .git/hooks/pre-commit to forbid :

#!/bin/sh

if echo $GIT_AUTHOR_NAME | grep -q "XXX" 2> /dev/null; then
    echo 'You tried to commit as XXX, please use  git commit --author="your name".'
    return 1
fi

Set user name to XXX:

git config user.name XXX

Warning: This works only for normal commits. Merge commits will be committed as XXX. Probably there is way getting this work too

(2a) Prompt for author info before commit (using hooks)

The only way to set the author using hooks, seems to be to amend the commit with post-commit hook, see also here.

This is a weird hack with ugly side effects (e.g. author in commit message displayed wrong).

#!/bin/sh

# env variable to prevent recursion
test -z $AMMEND_COMMIT || exit 0
export AMMEND_COMMIT=1

exec < /dev/tty
echo -n "Author for previous commit: "
read author

git commit -q --no-edit --amend --author "$author"

Use the following script to get a author suggestions based on last commits:

#!/bin/sh

# TODO this doesn't work for repos with <15 commits
NUM_LAST_COMMITS=15  # how many commits in the past to look for authors

# env variable to prevent recursion
test -z $ammend_commit || exit 0
export ammend_commit=1

exec < /dev/tty

last_authors=$(git shortlog -s -e HEAD~${NUM_LAST_COMMITS}..HEAD|sed 's/^\W*[0-9]*\W*//g')
echo "Select an author from list or enter an author:"
echo
echo "$last_authors" | awk '{print "    [" NR "] " $s }'
echo
echo -n "Enter number or author: "
read author

if echo "$author" | egrep -q '^[0-9]+$'; then
    author=$(echo "$last_authors" | sed "${author}q;d")
fi

git commit -q --no-edit --amend --author "$author"

Looks like this:

$ git commit -am "My message"
Select an author from list or enter an author:

    [1] First Author <first_author@domain.com>
    [2] Second Author <second_author@domain.com>
    [3] Third Author <third_author@domain.com>

Enter number or author: 3

(2b) Prompt for author info before commit (using a custom script or alias)

You can create a script git-commit.sh or a git alias git commit-author which prompts for the author to be used and then call git commit --author=<user's selection>. Unfortunately it is not possible to overwrite git commit.

A git-commit.sh script in /usr/local/bin might look like this:

#!/bin/sh

# TODO this doesn't work for repos with <15 commits
NUM_LAST_COMMITS=15  # how many commits in the past to look for authors

last_authors=$(git shortlog -s -e HEAD~${NUM_LAST_COMMITS}..HEAD|sed 's/^\W*[0-9]*\W*//g')
echo "Select an author from list or enter an author:"
echo
echo "$last_authors" | awk '{print "    [" NR "] " $s }'
echo
echo -n "Enter number or author: "
read author

if echo "$author" | egrep -q '^[0-9]+$'; then
    author=$(echo "$last_authors" | sed "${author}q;d")
fi

git commit "$@" --author "$author"

To add the script as alias run:

$ git config alias.commit-author '!git-commit.sh'

(3) Automatically set author based on the ssh-key used to login

That's your own answer, copied here for better overview:

In the shared deploy user's /home/deploy/.ssh/authorized_keys file I added an environment variable per key so that mine, for example, looks like this:

environment="GIT_AUTHOR_EMAIL=ry4an@host.com",environment="GIT_AUTHOR_NAME=Ry4an on Dev" ssh-rsa AAAA...cXBcmHr ry4an@host.com

which also required adding:

PermitUserEnvironment yes

to the /etc/ssh/sshd_config file.

lumbric
  • 7,644
  • 7
  • 42
  • 53