Use git worktree in the LLVM helper scripts

This commit adds a new script, llvm-env, which sets up the environment for
working with LLVM. It looks for an environment variable LLVM_ROOT and tries to
create the following hierarchy:

$LLVM_ROOT
  `- repos
  |    `- llvm
  |    `- clang
  |    `- compiler-rt
  |     [...]
  `- <branch1>
  |    `- llvm
  |    `- build
  |    `- debug
  `- <branch2>
  |    `- llvm
  |    `- build
  |    `- debug
  [...]

The $LLVM_ROOT/repos directory contains all the repositories, as checked out by
llvm-prepare, and will always track master. For other branches,
llvm-env <branch_name> will create a new directory, $LLVM_ROOT/<branch_name>,
and will add an llvm worktree directory there. If -d is passed, it will also
create a debug directory there, otherwise it will create a build directory.
Notice that these 2 can live in parallel, and we can switch between them at any
time by invoking llvm-env. It will set LLVM_SRC and LLVM_BLD accordingly, and
also modify the path to point to the binaries in LLVM_BLD.

The other scripts will now work with the LLVM_SRC and LLVM_BLD set by llvm-env
in the current shell. Because llvm-env controls whether or not we're doing a
debug build, llvm-build will no longer take a -d flag (it will instead look
after a LLVM_DEBUG environment variable, also set by llvm-env). There are
changes in llvm-projs, too, because now it no longer creates links - instead it
creates worktree directories in the corresponding $LLVM_ROOT/<branch>/llvm.
Other scripts have also been updated accordingly.

To make things easier, here are some of the changes that I had to make that are
not particularly important for the review (pretty mechanical stuff):
* Moved function has() from llvm-branch to llvm-common, so I could reuse it
* Because of this, I had to rename the has() function in llvm-projs to
has_link(), which is actually a better name for it anyway
* Disable the checks for LLVM_SRC and LLVM_BLD in llvm-common

Change-Id: I9e02f6d8e0c803e79838845013b81331dffba99c
diff --git a/helpers/llvm-common b/helpers/llvm-common
index 47b4937..33a9129 100755
--- a/helpers/llvm-common
+++ b/helpers/llvm-common
@@ -2,16 +2,17 @@
 
 # The common script is only meant to be included from other LLVM helper scripts
 
-if [[ $LLVM_SRC = '' ]]; then
-  echo "Please, define \$LLVM_SRC"
+# Verify the compulsory environment variables - these must be set for all the
+# helper scripts.
+if [[ $LLVM_ROOT = '' ]]; then
+  echo "Please, define \$LLVM_ROOT to point to the root"
+  echo "path where the worktree setup should be performed"
   exit -1
 fi
-if [[ $LLVM_BLD = '' ]]; then
-  echo "Please, define \$LLVM_BLD"
-  exit -1
-fi
+
 if [[ $LLVM_GITRW = '' ]]; then
-  echo "Please, define \$LLVM_GITRW"
+  echo "Please, define \$LLVM_GITRW to yes if you"
+  echo "want to set up Git-SVN and no otherwise"
   exit -1
 fi
 if [[ $LLVM_GITUSER = '' ]]; then
@@ -24,6 +25,36 @@
   exit 1
 fi
 
+# Verify the environment variables that should be set by llvm-env
+verify_env() {
+  if [[ $LLVM_SRC = '' ]]; then
+    echo "Please, define \$LLVM_SRC to point to the current LLVM"
+    echo "worktree directory, or run llvm-env to set it for you"
+    exit -1
+  fi
+  if [[ $LLVM_BLD = '' ]]; then
+    echo "Please, define \$LLVM_BLD to point to the current LLVM"
+    echo "build directory, or run llvm-env to set it for you"
+    exit -1
+  fi
+}
+
+has() {
+  if [[ $1 = '' || $2 = '' ]]; then
+    echo no
+    return
+  fi
+  local item=$1
+  shift
+  for each in $*; do
+    if [[ $item = $each ]]; then
+      echo yes
+      return
+    fi
+  done
+  echo no
+}
+
 get_branch() {
   branch=`git rev-parse --abbrev-ref HEAD`
   if [[ $? != 0 ]]; then
@@ -44,6 +75,13 @@
   echo $branches
 }
 
+has_branch() {
+  branch=$1
+  branches=`get_branches`
+  result=`has $branch $branches`
+  echo $result
+}
+
 safe_run() {
   "$@"
   if [[ $? != 0 ]]; then
@@ -59,3 +97,45 @@
 is_git_svn() {
   test -f `git rev-parse --show-toplevel`/.git/svn/.metadata
 }
+
+# Quiet pushd & popd
+pushdq() {
+  pushd "$@" > /dev/null
+}
+
+popdq() {
+  popd "$@" > /dev/null
+}
+
+add_worktree() {
+  repo_dir=$1
+  worktree_dir=$2
+  branch=$3
+
+  pushdq $repo_dir
+
+  if [ `get_branch` != 'master' ]; then
+    echo "$repo_dir isn't on master, bailing out"
+    exit 1
+  fi
+
+  if [ `has_branch $branch` = "yes" ]; then
+    safe_run git worktree add $worktree_dir $branch
+  else
+    safe_run git worktree add -b $branch $worktree_dir
+  fi
+  popdq
+}
+
+remove_worktree() {
+  repo_dir=$1
+
+  if [ "$2" != "" ]; then
+    worktree_dir=$2
+    safe_run rm -rf $worktree_dir
+  fi
+
+  pushdq $repo_dir
+  safe_run git worktree prune
+  popdq
+}