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.

  • 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). – Joe Creighton Apr 13 '17 at 21:36
  • Updated with better locking method – Joe Creighton Apr 17 '17 at 15:43
  • Accepted the answer since it addresses the race condition in my seemingly reasonable framework. – Joe Creighton Apr 24 '17 at 14:44
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?

  • 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. – Joe Creighton Apr 13 '17 at 21:34
  • Thanks for the $* versus "$@" heads-up. – Joe Creighton Apr 13 '17 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. – Joe Creighton Apr 13 '17 at 22:52
  • A lock file can work if it's implemented in an atomic fashion, which yours isn't. – Celada Apr 14 '17 at 13:02
  • Learned about atomic locking using link() via @Arcege. Thanks. – Joe Creighton Apr 17 '17 at 15:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.