Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Environment variables in .git/config

Tags:

git

git-config

I have a git repo created with the --serparate-git-dir option. I often use the same repo form different working trees by specifying --git-dir and --work-tree as arguments.

I have two working trees I switch between frequently so I added a .git file in the secondary work tree pointing to the repository directory. However since the repository's config file points to the primary working tree, I still have to specify it explicitly, otherwise it uses the primary working tree.

I tried setting the value of worktree to $PWD int the .git/config file but this causes the following error: fatal: Could not chdir to '$PWD': No such file or directory

Is there a way to make worktree dynamic?

like image 778
Anthony Avatar asked Dec 02 '14 12:12

Anthony


People also ask

What is environment variable in git?

Git always runs inside a bash shell, and uses a number of shell environment variables to determine how it behaves. Occasionally, it comes in handy to know what these are, and how they can be used to make Git behave the way you want it to.

Where are Git environment variables stored?

To set the Git environment variable, Git provides the git config tool. All the Git global configurations are stored in a . gitconfig file. This file you can easily locate in your system's home directory.

Can I use environment variables in Gitconfig?

In order to expand environment variables you have to pre-process the Git config file yourself, i.e. by creating a template file, and expand variables with a script before copying the file to your $HOME directory.


2 Answers

I had a similar problem in that I wanted to make my ~/.gitconfig portable across platforms, so that I could use the same gitconfig on my Macbook and in my Linux VM. I needed credential.helper to be different depending on the platform.

I ended up writing a little generate_gitconfig script, and add it to my bashrc so that ~/.gitconfig was generated automatically upon starting each shell session.

Writing your gitconfig via a script gives you more flexibility in that you can set values dynamically based on environment variables, whether certain commands are installed, the hostname of the machine, etc.

Here is my generate_gitconfig script, as an example:

#!/bin/bash

cat <<EOF > $HOME/.gitconfig
# This gitconfig was generated via ~/.bin/generate_gitconfig.
# Edit that file, not this one!

[user]
    name = Dave Yarwood
    email = [email protected]
[push]
    default = simple
[core]
    autocrlf = input
    editor = nvim
    excludesfile = $HOME/.gitignore_global
[rerere]
    enabled = true
EOF

if [[ "$(uname)" == Darwin ]]; then
  CREDENTIAL_HELPER="osxkeychain"
elif [[ -n "$(which gnome-keyring-daemon)" ]]; then
  CREDENTIAL_HELPER="/usr/share/doc/git/contrib/credential/gnome-keyring/git-credential-gnome-keyring"
fi

if [[ -n "$CREDENTIAL_HELPER" ]]; then
  cat <<EOF >> $HOME/.gitconfig
[credential]
  helper = $CREDENTIAL_HELPER
EOF
fi
like image 188
Dave Yarwood Avatar answered Oct 20 '22 21:10

Dave Yarwood


EDIT 05-2016 As @amynbe comments, git >= 2.5 has git-worktree https://git-scm.com/docs/git-worktree


I have a script that someone on freenode passed around, I'm not sure of the author but I know I can share, it is used to create different working copyes based on branches, I think it could fit your use case:

#!/bin/sh

usage () {
        echo "usage:" $@
        exit 127
}

die () {
        echo $@
        exit 128
}

if test $# -lt 2 || test $# -gt 3
then
        usage "$0 <repository> <new_workdir> [<branch>]"
fi

orig_git=$1
new_workdir=$2
branch=$3

# want to make sure that what is pointed to has a .git directory ...
git_dir=$(cd "$orig_git" 2>/dev/null &&
  git rev-parse --git-dir 2>/dev/null) ||
  die "Not a git repository: \"$orig_git\""

case "$git_dir" in
.git)
        git_dir="$orig_git/.git"
        ;;
.)
        git_dir=$orig_git
        ;;
esac

# don't link to a configured bare repository
isbare=$(git --git-dir="$git_dir" config --bool --get core.bare)
if test ztrue = z$isbare
then
        die "\"$git_dir\" has core.bare set to true," \
                " remove from \"$git_dir/config\" to use $0"
fi

# don't link to a workdir
if test -h "$git_dir/config"
then
        die "\"$orig_git\" is a working directory only, please specify" \
                "a complete repository."
fi

# don't recreate a workdir over an existing repository
if test -e "$new_workdir"
then
        die "destination directory '$new_workdir' already exists."
fi

# make sure the links use full paths
git_dir=$(cd "$git_dir"; pwd)

# create the workdir
mkdir -p "$new_workdir/.git" || die "unable to create \"$new_workdir\"!"

# create the links to the original repo.  explicitly exclude index, HEAD and
# logs/HEAD from the list since they are purely related to the current working
# directory, and should not be shared.
for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn
do
        case $x in
        */*)
                mkdir -p "$(dirname "$new_workdir/.git/$x")"
                ;;
        esac
        ln -s "$git_dir/$x" "$new_workdir/.git/$x"
done

# now setup the workdir
cd "$new_workdir"
# copy the HEAD from the original repository as a default branch
cp "$git_dir/HEAD" .git/HEAD
# checkout the branch (either the same as HEAD from the original repository, or
# the one that was asked for)
git checkout -f $branch
like image 40
DRC Avatar answered Oct 20 '22 22:10

DRC