1

We are in the process of moving from other source/version control methods to git and, because I have no actual experience with git (short of setting some user.* variables), I'd like to ask whether this is a viable direction to take before committing myself down this road.

The solution in "Is it possible to set the users .gitconfig (for git config --global) dynamically?" came close for me but it did not address a situation I discovered using shared service accounts (and which may exist for root, too).

I found that User1 would connect and /home/serviceaccount/.gitconfig would get set, then User2 would connect and overwrite that: an execution of git config --global user.name in either session would return User2 details, suggesting the file is referenced at each call. Because I don't do root, I don't know if this problem exists for two users who sudo to root following @oXiVanisher's solution.

To make this dynamic for shared service accounts, a wrapper script rolls in the appropriate .gitconfig based on the user executing it. The core of it is:

#!/bin/sh

myuser=`who -m | awk '{ print $1 }'`
HOST=`hostname`

# atomic locking over NFS via https://unix.stackexchange.com/a/22062
LOCKFILE="/local/share/bin/.git.lock"
TMPFILE=${LOCKFILE}.$$
echo "$myuser @ $HOST" > $TMPFILE
if ln $TMPFILE $LOCKFILE 2>&-; then
  :
else
  echo "$LOCKFILE detected"
  echo "Script in use by $(<$LOCKFILE)"
  /bin/rm -f $TMPFILE
  exit
fi
trap "/bin/rm -f ${TMPFILE} ${LOCKFILE}" 0 1 2 3 15

# find my gitconfig
CFGFILE="/local/share/DOTfiles/DOTgitconfig.$myuser"
if [ ! -s $CFGFILE ]; then
  echo "No personal /local/share/DOTfiles/DOTgitconfig found."
  exit
fi

# roll it in
cp $CFGFILE $HOME/.gitconfig

# execute git
/usr/bin/git "$@"

# roll it back in case of changes
cp $HOME/.gitconfig $CFGFILE

# zero it out
cat > $HOME/.gitconfig << !
# This file intentionally blank for dynamic use
# The wrapper script is /local/share/bin/git
!

When two users are connected to the shared service account, git config --global user.name reports the proper name for each user. At first blush, this looks like it could make git dynamic for all users sharing one account where environment variables can't be found.

But how am I breaking things? What am I not seeing yet?

Thank you.

3
  • I updated the code above to reflect what I have in place: a file check and a lock file (serves me right for only providing the guts of it). Commented Apr 13, 2017 at 21:36
  • Updated with better locking method Commented Apr 17, 2017 at 15:43
  • Accepted the answer since it addresses the race condition in my seemingly reasonable framework. Commented Apr 24, 2017 at 14:44

1 Answer 1

1

It seems like your solution would have race conditions (what happens during multiple simultaneous invocations of git?) as well as other problems (such as incorrect use of $* instead of "$@".

Instead, why don't use just set $GIT_CONFIG in each user's environment to a different file?

5
  • I did attempt a change to .bashrc that exported GIT_CONFIG="/local/share/DOTfiles/DOTgitconfig.$userid" and that environment variable was good (echo $GIT_CONFIG returned the path) but issuing git config --global user.name returned no results. Commented Apr 13, 2017 at 21:34
  • Thanks for the $* versus "$@" heads-up. Commented Apr 13, 2017 at 21:38
  • Also, this is for a handful of users who may be using the service account at the same time. A lock file approach seemed reasonable. Commented Apr 13, 2017 at 22:52
  • A lock file can work if it's implemented in an atomic fashion, which yours isn't.
    – Celada
    Commented Apr 14, 2017 at 13:02
  • Learned about atomic locking using link() via @Arcege. Thanks. Commented Apr 17, 2017 at 15:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .