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-sync b/helpers/llvm-sync
index 0374221..9784006 100755
--- a/helpers/llvm-sync
+++ b/helpers/llvm-sync
@@ -1,21 +1,39 @@
 #!/usr/bin/env bash
 
-# This script checks out all repositories from upstream and pushes master
-# to the origin repo on Linaro's Git server, rebasing all local branches,
-# but *not* pushing them, too.
+# This script pulls all repositories selected with llvm-projs and rebases the
+# current branch on top of the new master.
 
 . llvm-common
 
+safe_run verify_env
+
 function repo_sync () {
-  if [ ! -d $2 ]; then
-    echo " + Not updating $1 (couldn't find source directory)"
+  project=$1
+  repo_dir=$2
+  worktree_dir=$3
+
+  if [ ! -d $repo_dir ]; then
+    echo " + Not updating $project (couldn't find source directory)"
     return;
   fi
-  echo " + Updating $1"
-  cd $2
-  branch=`get_branch`
+
+  if [ ! -d $worktree_dir ]; then
+    echo " + Not updating $project (couldn't find worktree directory)"
+    return;
+  fi
+
+  echo " + Updating $project"
+
+  # To pull master, we must be in the repo dir (we shouldn't checkout master in
+  # the worktree dirs - by default, master lives in the repo dir)
+  cd $repo_dir
   safe_run git-refresh
-  safe_run git-rebase-all $branch
+
+  # To rebase the current branch, we must be in the worktree dir (we shouldn't
+  # checkout the current branch in the repo dir, because it is already checked
+  # out in the worktree dir)
+  cd $worktree_dir
+  safe_run git-rebase
 }
 
 prog=`basename $0`
@@ -29,15 +47,26 @@
 debug=false
 tests=false
 web=false
-if [ -d $LLVM_SRC/tools/clang ]; then clang=true; fi
-if [ -d $LLVM_SRC/tools/clang/tools/extra ]; then cextra=true; fi
-if [ -d $LLVM_SRC/projects/compiler-rt ]; then rt=true; fi
-if [ -d $LLVM_SRC/projects/libcxx ]; then libcxx=true; fi
-if [ -d $LLVM_SRC/projects/libcxxabi ]; then libcxxabi=true; fi
-if [ -d $LLVM_SRC/projects/libunwind ]; then libunwind=true; fi
-if [ -d $LLVM_SRC/tools/lld ]; then linker=true; fi
-if [ -d $LLVM_SRC/tools/lldb ]; then debug=true; fi
-if [ -d $LLVM_SRC/projects/test-suite ]; then tests=true; fi
+
+clang_workdir=$LLVM_SRC/tools/clang
+extra_workdir=$LLVM_SRC/tools/clang/tools/extra
+rt_workdir=$LLVM_SRC/projects/compiler-rt
+libcxx_workdir=$LLVM_SRC/projects/libcxx
+libcxxabi_workdir=$LLVM_SRC/projects/libcxxabi
+libunwind_workdir=$LLVM_SRC/projects/libunwind
+lld_workdir=$LLVM_SRC/tools/lld
+lldb_workdir=$LLVM_SRC/tools/lldb
+test_workdir=$LLVM_SRC/projects/test-suite
+
+if [ -d $clang_workdir ]; then clang=true; fi
+if [ -d $extra_workdir ]; then cextra=true; fi
+if [ -d $rt_workdir ]; then rt=true; fi
+if [ -d $libcxx_workdir ]; then libcxx=true; fi
+if [ -d $libcxxabi_workdir ]; then libcxxabi=true; fi
+if [ -d $libunwind_workdir ]; then libunwind=true; fi
+if [ -d $lld_workdir ]; then linker=true; fi
+if [ -d $lldb_workdir ]; then debug=true; fi
+if [ -d $test_workdir ]; then tests=true; fi
 
 while getopts "wa" opt; do
   case $opt in
@@ -65,59 +94,61 @@
   esac
 done
 
+llvm_repos=$LLVM_ROOT/repos
+
 # Compulsory updates
-repo_sync LLVM $LLVM_SRC
+repo_sync LLVM $llvm_repos/llvm $LLVM_SRC
 
 if $clang; then
-  repo_sync Clang $LLVM_SRC/../clang
+  repo_sync Clang $llvm_repos/clang $clang_workdir
 fi
 
 # Optional updates
 if $cextra; then
-  repo_sync ClangToolsExtra $LLVM_SRC/../clang-tools-extra
+  repo_sync ClangToolsExtra $llvm_repos/clang-tools-extra $extra_workdir
 fi
 
 if $rt; then
-  repo_sync RT $LLVM_SRC/../compiler-rt
+  repo_sync RT $llvm_repos/compiler-rt $rt_workdir
 fi
 
 if $libcxx; then
-  repo_sync LibC++ $LLVM_SRC/../libcxx
+  repo_sync LibC++ $llvm_repos/libcxx $libcxx_workdir
 fi
 
 if $libcxxabi; then
-  repo_sync LibC++ABI $LLVM_SRC/../libcxxabi
+  repo_sync LibC++ABI $llvm_repos/libcxxabi $libcxxabi_workdir
 fi
 
 if $libunwind; then
-  repo_sync LibUnwind $LLVM_SRC/../libunwind
+  repo_sync LibUnwind $llvm_repos/libunwind $libunwind_workdir
 fi
 
 if $linker; then
-  repo_sync Linker $LLVM_SRC/../lld
+  repo_sync Linker $llvm_repos/lld $lld_workdir
 fi
 
 if $debug; then
-  repo_sync Debugger $LLVM_SRC/../lldb
+  repo_sync Debugger $llvm_repos/lldb $lldb_workdir
 fi
 
 if $tests; then
-  repo_sync Test-Suite $LLVM_SRC/../test-suite
-  repo_sync LNT $LLVM_SRC/../lnt
-  repo_sync Zorg $LLVM_SRC/../zorg
+  repo_sync Test-Suite $llvm_repos/test-suite $test_workdir
+  repo_sync LNT $llvm_repos/lnt $llvm_repos/lnt
+  repo_sync Zorg $llvm_repos/zorg $llvm_repos/zorg
 fi
 
 # These are pure SVN repos, not enabled with -a
 # You have to manually force with -w
 if $web; then
-  if [ -d $LLVM_SRC/../www ]; then
+  if [ -d $llvm_repos/www ]; then
     echo " + Updating WWW"
-    cd $LLVM_SRC/../www
+    cd $llvm_repos/www $llvm_repos/www
     svn up
   fi
-  if [ -d $LLVM_SRC/../pubs ]; then
+  if [ -d $llvm_repos/pubs ]; then
     echo " + Updating Pubs"
-    cd $LLVM_SRC/../pubs
+    cd $llvm_repos/pubs $llvm_repos/pubs
     svn up
   fi
 fi