diff --git a/project.py b/project.py
new file mode 100644
index 0000000..7c0c58f
--- /dev/null
+++ b/project.py
@@ -0,0 +1,1058 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import filecmp
+import os
+import re
+import shutil
+import stat
+import sys
+import urllib2
+
+from color import Coloring
+from git_command import GitCommand
+from git_config import GitConfig, IsId
+from gerrit_upload import UploadBundle
+from error import GitError, ImportError, UploadError
+from remote import Remote
+from codereview import proto_client
+
+HEAD    = 'HEAD'
+R_HEADS = 'refs/heads/'
+R_TAGS  = 'refs/tags/'
+R_PUB   = 'refs/published/'
+R_M     = 'refs/remotes/m/'
+
+def _warn(fmt, *args):
+  msg = fmt % args
+  print >>sys.stderr, 'warn: %s' % msg
+
+def _info(fmt, *args):
+  msg = fmt % args
+  print >>sys.stderr, 'info: %s' % msg
+
+def not_rev(r):
+  return '^' + r
+
+class ReviewableBranch(object):
+  _commit_cache = None
+
+  def __init__(self, project, branch, base):
+    self.project = project
+    self.branch = branch
+    self.base = base
+
+  @property
+  def name(self):
+    return self.branch.name
+
+  @property
+  def commits(self):
+    if self._commit_cache is None:
+      self._commit_cache = self.project.bare_git.rev_list(
+        '--abbrev=8',
+        '--abbrev-commit',
+        '--pretty=oneline',
+        '--reverse',
+        '--date-order',
+        not_rev(self.base),
+        R_HEADS + self.name,
+        '--')
+    return self._commit_cache
+
+  @property
+  def date(self):
+    return self.project.bare_git.log(
+      '--pretty=format:%cd',
+      '-n', '1',
+      R_HEADS + self.name,
+      '--')
+
+  def UploadForReview(self):
+    self.project.UploadForReview(self.name)
+
+  @property
+  def tip_url(self):
+    me = self.project.GetBranch(self.name)
+    commit = self.project.bare_git.rev_parse(R_HEADS + self.name)
+    return 'http://%s/r/%s' % (me.remote.review, commit[0:12])
+
+
+class StatusColoring(Coloring):
+  def __init__(self, config):
+    Coloring.__init__(self, config, 'status')
+    self.project   = self.printer('header',    attr = 'bold')
+    self.branch    = self.printer('header',    attr = 'bold')
+    self.nobranch  = self.printer('nobranch',  fg = 'red')
+
+    self.added     = self.printer('added',     fg = 'green')
+    self.changed   = self.printer('changed',   fg = 'red')
+    self.untracked = self.printer('untracked', fg = 'red')
+
+
+class DiffColoring(Coloring):
+  def __init__(self, config):
+    Coloring.__init__(self, config, 'diff')
+    self.project   = self.printer('header',    attr = 'bold')
+
+
+class _CopyFile:
+  def __init__(self, src, dest):
+    self.src = src
+    self.dest = dest
+
+  def _Copy(self):
+    src = self.src
+    dest = self.dest
+    # copy file if it does not exist or is out of date
+    if not os.path.exists(dest) or not filecmp.cmp(src, dest):
+      try:
+        # remove existing file first, since it might be read-only
+        if os.path.exists(dest):
+          os.remove(dest)
+        shutil.copy(src, dest)
+        # make the file read-only
+        mode = os.stat(dest)[stat.ST_MODE]
+        mode = mode & ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH)
+        os.chmod(dest, mode)
+      except IOError:
+           print >>sys.stderr, \
+              'error: Cannot copy file %s to %s' \
+              % (src, dest)
+
+
+class Project(object):
+  def __init__(self,
+               manifest,
+               name,
+               remote,
+               gitdir,
+               worktree,
+               relpath,
+               revision):
+    self.manifest = manifest
+    self.name = name
+    self.remote = remote
+    self.gitdir = gitdir
+    self.worktree = worktree
+    self.relpath = relpath
+    self.revision = revision
+    self.snapshots = {}
+    self.extraRemotes = {}
+    self.copyfiles = []
+    self.config = GitConfig.ForRepository(
+                    gitdir = self.gitdir,
+                    defaults =  self.manifest.globalConfig)
+
+    self.work_git = self._GitGetByExec(self, bare=False)
+    self.bare_git = self._GitGetByExec(self, bare=True)
+
+  @property
+  def Exists(self):
+    return os.path.isdir(self.gitdir)
+
+  @property
+  def CurrentBranch(self):
+    """Obtain the name of the currently checked out branch.
+       The branch name omits the 'refs/heads/' prefix.
+       None is returned if the project is on a detached HEAD.
+    """
+    try:
+      b = self.work_git.GetHead()
+    except GitError:
+      return None
+    if b.startswith(R_HEADS):
+      return b[len(R_HEADS):]
+    return None
+
+  def IsDirty(self, consider_untracked=True):
+    """Is the working directory modified in some way?
+    """
+    self.work_git.update_index('-q',
+                               '--unmerged',
+                               '--ignore-missing',
+                               '--refresh')
+    if self.work_git.DiffZ('diff-index','-M','--cached',HEAD):
+      return True
+    if self.work_git.DiffZ('diff-files'):
+      return True
+    if consider_untracked and self.work_git.LsOthers():
+      return True
+    return False
+
+  _userident_name = None
+  _userident_email = None
+
+  @property
+  def UserName(self):
+    """Obtain the user's personal name.
+    """
+    if self._userident_name is None:
+      self._LoadUserIdentity()
+    return self._userident_name
+
+  @property
+  def UserEmail(self):
+    """Obtain the user's email address.  This is very likely
+       to be their Gerrit login.
+    """
+    if self._userident_email is None:
+      self._LoadUserIdentity()
+    return self._userident_email
+
+  def _LoadUserIdentity(self):
+      u = self.bare_git.var('GIT_COMMITTER_IDENT')
+      m = re.compile("^(.*) <([^>]*)> ").match(u)
+      if m:
+        self._userident_name = m.group(1)
+        self._userident_email = m.group(2)
+      else:
+        self._userident_name = ''
+        self._userident_email = ''
+
+  def GetRemote(self, name):
+    """Get the configuration for a single remote.
+    """
+    return self.config.GetRemote(name)
+
+  def GetBranch(self, name):
+    """Get the configuration for a single branch.
+    """
+    return self.config.GetBranch(name)
+
+
+## Status Display ##
+
+  def PrintWorkTreeStatus(self):
+    """Prints the status of the repository to stdout.
+    """
+    if not os.path.isdir(self.worktree):
+      print ''
+      print 'project %s/' % self.relpath
+      print '  missing (run "repo sync")'
+      return
+
+    self.work_git.update_index('-q',
+                               '--unmerged',
+                               '--ignore-missing',
+                               '--refresh')
+    di = self.work_git.DiffZ('diff-index', '-M', '--cached', HEAD)
+    df = self.work_git.DiffZ('diff-files')
+    do = self.work_git.LsOthers()
+    if not di and not df and not do:
+      return
+
+    out = StatusColoring(self.config)
+    out.project('project %-40s', self.relpath + '/')
+
+    branch = self.CurrentBranch
+    if branch is None:
+      out.nobranch('(*** NO BRANCH ***)')
+    else:
+      out.branch('branch %s', branch)
+    out.nl()
+
+    paths = list()
+    paths.extend(di.keys())
+    paths.extend(df.keys())
+    paths.extend(do)
+
+    paths = list(set(paths))
+    paths.sort()
+
+    for p in paths:
+      try: i = di[p]
+      except KeyError: i = None
+
+      try: f = df[p]
+      except KeyError: f = None
+ 
+      if i: i_status = i.status.upper()
+      else: i_status = '-'
+
+      if f: f_status = f.status.lower()
+      else: f_status = '-'
+
+      if i and i.src_path:
+        line = ' %s%s\t%s => (%s%%)' % (i_status, f_status,
+                                        i.src_path, p, i.level)
+      else:
+        line = ' %s%s\t%s' % (i_status, f_status, p)
+
+      if i and not f:
+        out.added('%s', line)
+      elif (i and f) or (not i and f):
+        out.changed('%s', line)
+      elif not i and not f:
+        out.untracked('%s', line)
+      else:
+        out.write('%s', line)
+      out.nl()
+
+  def PrintWorkTreeDiff(self):
+    """Prints the status of the repository to stdout.
+    """
+    out = DiffColoring(self.config)
+    cmd = ['diff']
+    if out.is_on:
+      cmd.append('--color')
+    cmd.append(HEAD)
+    cmd.append('--')
+    p = GitCommand(self,
+                   cmd,
+                   capture_stdout = True,
+                   capture_stderr = True)
+    has_diff = False
+    for line in p.process.stdout:
+      if not has_diff:
+        out.nl()
+        out.project('project %s/' % self.relpath)
+        out.nl()
+        has_diff = True
+      print line[:-1]
+    p.Wait()
+
+
+## Publish / Upload ##
+
+  def WasPublished(self, branch):
+    """Was the branch published (uploaded) for code review?
+       If so, returns the SHA-1 hash of the last published
+       state for the branch.
+    """
+    try:
+      return self.bare_git.rev_parse(R_PUB + branch)
+    except GitError:
+      return None
+
+  def CleanPublishedCache(self):
+    """Prunes any stale published refs.
+    """
+    heads = set()
+    canrm = {}
+    for name, id in self._allrefs.iteritems():
+      if name.startswith(R_HEADS):
+        heads.add(name)
+      elif name.startswith(R_PUB):
+        canrm[name] = id
+
+    for name, id in canrm.iteritems():
+      n = name[len(R_PUB):]
+      if R_HEADS + n not in heads:
+        self.bare_git.DeleteRef(name, id)
+
+  def GetUploadableBranches(self):
+    """List any branches which can be uploaded for review.
+    """
+    heads = {}
+    pubed = {}
+
+    for name, id in self._allrefs.iteritems():
+      if name.startswith(R_HEADS):
+        heads[name[len(R_HEADS):]] = id
+      elif name.startswith(R_PUB):
+        pubed[name[len(R_PUB):]] = id
+
+    ready = []
+    for branch, id in heads.iteritems():
+      if branch in pubed and pubed[branch] == id:
+        continue
+
+      branch = self.GetBranch(branch)
+      base = branch.LocalMerge
+      if branch.LocalMerge:
+        rb = ReviewableBranch(self, branch, base)
+        if rb.commits:
+          ready.append(rb)
+    return ready
+
+  def UploadForReview(self, branch=None):
+    """Uploads the named branch for code review.
+    """
+    if branch is None:
+      branch = self.CurrentBranch
+    if branch is None:
+      raise GitError('not currently on a branch')
+
+    branch = self.GetBranch(branch)
+    if not branch.LocalMerge:
+      raise GitError('branch %s does not track a remote' % branch.name)
+    if not branch.remote.review:
+      raise GitError('remote %s has no review url' % branch.remote.name)
+
+    dest_branch = branch.merge
+    if not dest_branch.startswith(R_HEADS):
+      dest_branch = R_HEADS + dest_branch
+
+    base_list = []
+    for name, id in self._allrefs.iteritems():
+      if branch.remote.WritesTo(name):
+        base_list.append(not_rev(name))
+    if not base_list:
+      raise GitError('no base refs, cannot upload %s' % branch.name)
+
+    print >>sys.stderr, ''
+    _info("Uploading %s to %s:", branch.name, self.name)
+    try:
+      UploadBundle(project = self,
+                   server = branch.remote.review,
+                   email = self.UserEmail,
+                   dest_project = self.name,
+                   dest_branch = dest_branch,
+                   src_branch = R_HEADS + branch.name,
+                   bases = base_list)
+    except proto_client.ClientLoginError:
+      raise UploadError('Login failure')
+    except urllib2.HTTPError, e:
+      raise UploadError('HTTP error %d' % e.code)
+
+    msg = "posted to %s for %s" % (branch.remote.review, dest_branch)
+    self.bare_git.UpdateRef(R_PUB + branch.name,
+                            R_HEADS + branch.name,
+                            message = msg)
+
+
+## Sync ##
+
+  def Sync_NetworkHalf(self):
+    """Perform only the network IO portion of the sync process.
+       Local working directory/branch state is not affected.
+    """
+    if not self.Exists:
+      print >>sys.stderr
+      print >>sys.stderr, 'Initializing project %s ...' % self.name
+      self._InitGitDir()
+    self._InitRemote()
+    for r in self.extraRemotes.values():
+      if not self._RemoteFetch(r.name):
+        return False
+    if not self._SnapshotDownload():
+      return False
+    if not self._RemoteFetch():
+      return False
+    self._InitMRef()
+    return True
+    
+  def _CopyFiles(self):
+    for file in self.copyfiles:
+      file._Copy()
+
+  def Sync_LocalHalf(self):
+    """Perform only the local IO portion of the sync process.
+       Network access is not required.
+
+       Return:
+         True:  the sync was successful
+         False: the sync requires user input
+    """
+    self._InitWorkTree()
+    self.CleanPublishedCache()
+
+    rem = self.GetRemote(self.remote.name)
+    rev = rem.ToLocal(self.revision)
+    branch = self.CurrentBranch
+
+    if branch is None:
+      # Currently on a detached HEAD.  The user is assumed to
+      # not have any local modifications worth worrying about.
+      #
+      lost = self._revlist(not_rev(rev), HEAD)
+      if lost:
+        _info("[%s] Discarding %d commits", self.name, len(lost))
+      try:
+        self._Checkout(rev, quiet=True)
+      except GitError:
+        return False
+      self._CopyFiles()
+      return True
+
+    branch = self.GetBranch(branch)
+    merge = branch.LocalMerge
+
+    if not merge:
+      # The current branch has no tracking configuration.
+      # Jump off it to a deatched HEAD.
+      #
+      _info("[%s] Leaving %s"
+            " (does not track any upstream)",
+            self.name,
+            branch.name)
+      try:
+        self._Checkout(rev, quiet=True)
+      except GitError:
+        return False
+      self._CopyFiles()
+      return True
+
+    upstream_gain = self._revlist(not_rev(HEAD), rev)
+    pub = self.WasPublished(branch.name)
+    if pub:
+      not_merged = self._revlist(not_rev(rev), pub)
+      if not_merged:
+        if upstream_gain:
+          # The user has published this branch and some of those
+          # commits are not yet merged upstream.  We do not want
+          # to rewrite the published commits so we punt.
+          #
+          _info("[%s] Branch %s is published,"
+                " but is now %d commits behind.",
+                self.name, branch.name, len(upstream_gain))
+          _info("[%s] Consider merging or rebasing the"
+                " unpublished commits.", self.name)
+        return True
+
+    if merge == rev:
+      try:
+        old_merge = self.bare_git.rev_parse('%s@{1}' % merge)
+      except GitError:
+        old_merge = merge
+    else:
+      # The upstream switched on us.  Time to cross our fingers
+      # and pray that the old upstream also wasn't in the habit
+      # of rebasing itself.
+      #
+      _info("[%s] Manifest switched from %s to %s",
+            self.name, merge, rev)
+      old_merge = merge
+
+    if rev == old_merge:
+      upstream_lost = []
+    else:
+      upstream_lost = self._revlist(not_rev(rev), old_merge)
+
+    if not upstream_lost and not upstream_gain:
+      # Trivially no changes caused by the upstream.
+      #
+      return True
+
+    if self.IsDirty(consider_untracked=False):
+      _warn('[%s] commit (or discard) uncommitted changes'
+            ' before sync', self.name)
+      return False
+
+    if upstream_lost:
+      # Upstream rebased.  Not everything in HEAD
+      # may have been caused by the user.
+      #
+      _info("[%s] Discarding %d commits removed from upstream",
+            self.name, len(upstream_lost))
+
+    branch.remote = rem
+    branch.merge = self.revision
+    branch.Save()
+
+    my_changes = self._revlist(not_rev(old_merge), HEAD)
+    if my_changes:
+      try:
+        self._Rebase(upstream = old_merge, onto = rev)
+      except GitError:
+        return False
+    elif upstream_lost:
+      try:
+        self._ResetHard(rev)
+      except GitError:
+        return False
+    else:
+      try:
+        self._FastForward(rev)
+      except GitError:
+        return False
+
+    self._CopyFiles()
+    return True
+
+  def _SnapshotDownload(self):
+    if self.snapshots:
+      have = set(self._allrefs.keys())
+      need = []
+
+      for tag, sn in self.snapshots.iteritems():
+        if tag not in have:
+          need.append(sn)
+
+      if need:
+        print >>sys.stderr, """
+  ***   Downloading source(s) from a mirror site.     ***
+  ***   If the network hangs, kill and restart repo.  ***
+"""
+        for sn in need:
+          try:
+            sn.Import()
+          except ImportError, e:
+            print >>sys.stderr, \
+              'error: Cannot import %s: %s' \
+              % (self.name, e)
+            return False
+        cmd = ['repack', '-a', '-d', '-f', '-l']
+        if GitCommand(self, cmd, bare = True).Wait() != 0:
+          return False
+    return True
+
+  def AddCopyFile(self, src, dest):
+    # dest should already be an absolute path, but src is project relative
+    # make src an absolute path
+    src = os.path.join(self.worktree, src)
+    self.copyfiles.append(_CopyFile(src, dest))
+
+
+## Branch Management ##
+
+  def StartBranch(self, name):
+    """Create a new branch off the manifest's revision.
+    """
+    branch = self.GetBranch(name)
+    branch.remote = self.GetRemote(self.remote.name)
+    branch.merge = self.revision
+
+    rev = branch.LocalMerge
+    cmd = ['checkout', '-b', branch.name, rev]
+    if GitCommand(self, cmd).Wait() == 0:
+      branch.Save()
+    else:
+      raise GitError('%s checkout %s ' % (self.name, rev))
+
+  def PruneHeads(self):
+    """Prune any topic branches already merged into upstream.
+    """
+    cb = self.CurrentBranch
+    kill = []
+    for name in self._allrefs.keys():
+      if name.startswith(R_HEADS):
+        name = name[len(R_HEADS):]
+        if cb is None or name != cb:
+          kill.append(name)
+
+    rev = self.GetRemote(self.remote.name).ToLocal(self.revision)
+    if cb is not None \
+       and not self._revlist(HEAD + '...' + rev) \
+       and not self.IsDirty(consider_untracked = False):
+      self.work_git.DetachHead(HEAD)
+      kill.append(cb)
+
+    deleted = set()
+    if kill:
+      try:
+        old = self.bare_git.GetHead()
+      except GitError:
+        old = 'refs/heads/please_never_use_this_as_a_branch_name'
+
+      rm_re = re.compile(r"^Deleted branch (.*)\.$")
+      try:
+        self.bare_git.DetachHead(rev)
+
+        b = ['branch', '-d']
+        b.extend(kill)
+        b = GitCommand(self, b, bare=True,
+                       capture_stdout=True,
+                       capture_stderr=True)
+        b.Wait()
+      finally:
+        self.bare_git.SetHead(old)
+
+      for line in b.stdout.split("\n"):
+        m = rm_re.match(line)
+        if m:
+          deleted.add(m.group(1))
+
+      if deleted:
+        self.CleanPublishedCache()
+
+    if cb and cb not in kill:
+      kill.append(cb)
+      kill.sort()
+
+    kept = []
+    for branch in kill:
+      if branch not in deleted:
+        branch = self.GetBranch(branch)
+        base = branch.LocalMerge
+        if not base:
+          base = rev
+        kept.append(ReviewableBranch(self, branch, base))
+    return kept
+
+
+## Direct Git Commands ##
+
+  def _RemoteFetch(self, name=None):
+    if not name:
+      name = self.remote.name
+
+    hide_errors = False
+    if self.extraRemotes or self.snapshots:
+      hide_errors = True
+
+    proc = GitCommand(self,
+                      ['fetch', name],
+                      bare = True,
+                      capture_stderr = hide_errors)
+    if hide_errors:
+      err = proc.process.stderr.fileno()
+      buf = ''
+      while True:
+        b = os.read(err, 256)
+        if b:
+          buf += b
+        while buf:
+          r = buf.find('remote: error: unable to find ')
+          if r >= 0:
+            lf = buf.find('\n')
+            if lf < 0:
+              break
+            buf = buf[lf + 1:]
+            continue
+
+          cr = buf.find('\r')
+          if cr < 0:
+            break
+          os.write(2, buf[0:cr + 1])
+          buf = buf[cr + 1:]
+        if not b:
+          if buf:
+            os.write(2, buf)
+          break
+    return proc.Wait() == 0
+
+  def _Checkout(self, rev, quiet=False):
+    cmd = ['checkout']
+    if quiet:
+      cmd.append('-q')
+    cmd.append(rev)
+    cmd.append('--')
+    if GitCommand(self, cmd).Wait() != 0:
+      if self._allrefs:
+        raise GitError('%s checkout %s ' % (self.name, rev))
+
+  def _ResetHard(self, rev, quiet=True):
+    cmd = ['reset', '--hard']
+    if quiet:
+      cmd.append('-q')
+    cmd.append(rev)
+    if GitCommand(self, cmd).Wait() != 0:
+      raise GitError('%s reset --hard %s ' % (self.name, rev))
+
+  def _Rebase(self, upstream, onto = None):
+    cmd = ['rebase', '-i']
+    if onto is not None:
+      cmd.extend(['--onto', onto])
+    cmd.append(upstream)
+    if GitCommand(self, cmd, disable_editor=True).Wait() != 0:
+      raise GitError('%s rebase %s ' % (self.name, upstream))
+
+  def _FastForward(self, head):
+    cmd = ['merge', head]
+    if GitCommand(self, cmd).Wait() != 0:
+      raise GitError('%s merge %s ' % (self.name, head))
+
+  def _InitGitDir(self):
+    if not os.path.exists(self.gitdir):
+      os.makedirs(self.gitdir)
+      self.bare_git.init()
+      self.config.SetString('core.bare', None)
+
+      hooks = self._gitdir_path('hooks')
+      for old_hook in os.listdir(hooks):
+        os.remove(os.path.join(hooks, old_hook))
+
+      # TODO(sop) install custom repo hooks
+
+      m = self.manifest.manifestProject.config
+      for key in ['user.name', 'user.email']:
+        if m.Has(key, include_defaults = False):
+          self.config.SetString(key, m.GetString(key))
+
+  def _InitRemote(self):
+    if self.remote.fetchUrl:
+      remote = self.GetRemote(self.remote.name)
+
+      url = self.remote.fetchUrl
+      while url.endswith('/'):
+        url = url[:-1]
+      url += '/%s.git' % self.name
+      remote.url = url
+      remote.review = self.remote.reviewUrl
+
+      remote.ResetFetch()
+      remote.Save()
+
+    for r in self.extraRemotes.values():
+      remote = self.GetRemote(r.name)
+      remote.url = r.fetchUrl
+      remote.review = r.reviewUrl
+      remote.ResetFetch()
+      remote.Save()
+
+  def _InitMRef(self):
+    if self.manifest.branch:
+      msg = 'manifest set to %s' % self.revision
+      ref = R_M + self.manifest.branch
+
+      if IsId(self.revision):
+        dst = self.revision + '^0',
+        self.bare_git.UpdateRef(ref, dst, message = msg, detach = True)
+      else:
+        remote = self.GetRemote(self.remote.name)
+        dst = remote.ToLocal(self.revision)
+        self.bare_git.symbolic_ref('-m', msg, ref, dst)
+
+  def _InitWorkTree(self):
+    dotgit = os.path.join(self.worktree, '.git')
+    if not os.path.exists(dotgit):
+      os.makedirs(dotgit)
+
+      topdir = os.path.commonprefix([self.gitdir, dotgit])
+      if topdir.endswith('/'):
+        topdir = topdir[:-1]
+      else:
+        topdir = os.path.dirname(topdir)
+
+      tmpdir = dotgit
+      relgit = ''
+      while topdir != tmpdir:
+        relgit += '../'
+        tmpdir = os.path.dirname(tmpdir)
+      relgit += self.gitdir[len(topdir) + 1:]
+
+      for name in ['config',
+                   'description',
+                   'hooks',
+                   'info',
+                   'logs',
+                   'objects',
+                   'packed-refs',
+                   'refs',
+                   'rr-cache',
+                   'svn']:
+        os.symlink(os.path.join(relgit, name),
+                   os.path.join(dotgit, name))
+
+      rev = self.GetRemote(self.remote.name).ToLocal(self.revision)
+      rev = self.bare_git.rev_parse('%s^0' % rev)
+
+      f = open(os.path.join(dotgit, HEAD), 'wb')
+      f.write("%s\n" % rev)
+      f.close()
+
+      cmd = ['read-tree', '--reset', '-u']
+      cmd.append('-v')
+      cmd.append('HEAD')
+      if GitCommand(self, cmd).Wait() != 0:
+        raise GitError("cannot initialize work tree")
+
+  def _gitdir_path(self, path):
+    return os.path.join(self.gitdir, path)
+
+  def _revlist(self, *args):
+    cmd = []
+    cmd.extend(args)
+    cmd.append('--')
+    return self.work_git.rev_list(*args)
+
+  @property
+  def _allrefs(self):
+    return self.bare_git.ListRefs()
+
+  class _GitGetByExec(object):
+    def __init__(self, project, bare):
+      self._project = project
+      self._bare = bare
+
+    def ListRefs(self, *args):
+      cmdv = ['for-each-ref', '--format=%(objectname) %(refname)']
+      cmdv.extend(args)
+      p = GitCommand(self._project,
+                     cmdv,
+                     bare = self._bare,
+                     capture_stdout = True,
+                     capture_stderr = True)
+      r = {}
+      for line in p.process.stdout:
+        id, name = line[:-1].split(' ', 2)
+        r[name] = id
+      if p.Wait() != 0:
+        raise GitError('%s for-each-ref %s: %s' % (
+                       self._project.name,
+                       str(args),
+                       p.stderr))
+      return r
+
+    def LsOthers(self):
+      p = GitCommand(self._project,
+                     ['ls-files',
+                      '-z',
+                      '--others',
+                      '--exclude-standard'],
+                     bare = False,
+                     capture_stdout = True,
+                     capture_stderr = True)
+      if p.Wait() == 0:
+        out = p.stdout
+        if out:
+          return out[:-1].split("\0")
+      return []
+
+    def DiffZ(self, name, *args):
+      cmd = [name]
+      cmd.append('-z')
+      cmd.extend(args)
+      p = GitCommand(self._project,
+                     cmd,
+                     bare = False,
+                     capture_stdout = True,
+                     capture_stderr = True)
+      try:
+        out = p.process.stdout.read()
+        r = {}
+        if out:
+          out = iter(out[:-1].split('\0'))
+          while out:
+            info = out.next()
+            path = out.next()
+
+            class _Info(object):
+              def __init__(self, path, omode, nmode, oid, nid, state):
+                self.path = path
+                self.src_path = None
+                self.old_mode = omode
+                self.new_mode = nmode
+                self.old_id = oid
+                self.new_id = nid
+
+                if len(state) == 1:
+                  self.status = state
+                  self.level = None
+                else:
+                  self.status = state[:1]
+                  self.level = state[1:]
+                  while self.level.startswith('0'):
+                    self.level = self.level[1:]
+
+            info = info[1:].split(' ')
+            info =_Info(path, *info)
+            if info.status in ('R', 'C'):
+              info.src_path = info.path
+              info.path = out.next()
+            r[info.path] = info
+        return r
+      finally:
+        p.Wait()
+
+    def GetHead(self):
+      return self.symbolic_ref(HEAD)
+
+    def SetHead(self, ref, message=None):
+      cmdv = []
+      if message is not None:
+        cmdv.extend(['-m', message])
+      cmdv.append(HEAD)
+      cmdv.append(ref)
+      self.symbolic_ref(*cmdv)
+
+    def DetachHead(self, new, message=None):
+      cmdv = ['--no-deref']
+      if message is not None:
+        cmdv.extend(['-m', message])
+      cmdv.append(HEAD)
+      cmdv.append(new)
+      self.update_ref(*cmdv)
+
+    def UpdateRef(self, name, new, old=None,
+                  message=None,
+                  detach=False):
+      cmdv = []
+      if message is not None:
+        cmdv.extend(['-m', message])
+      if detach:
+        cmdv.append('--no-deref')
+      cmdv.append(name)
+      cmdv.append(new)
+      if old is not None:
+        cmdv.append(old)
+      self.update_ref(*cmdv)
+
+    def DeleteRef(self, name, old=None):
+      if not old:
+        old = self.rev_parse(name)
+      self.update_ref('-d', name, old)
+
+    def rev_list(self, *args):
+      cmdv = ['rev-list']
+      cmdv.extend(args)
+      p = GitCommand(self._project,
+                     cmdv,
+                     bare = self._bare,
+                     capture_stdout = True,
+                     capture_stderr = True)
+      r = []
+      for line in p.process.stdout:
+        r.append(line[:-1])
+      if p.Wait() != 0:
+        raise GitError('%s rev-list %s: %s' % (
+                       self._project.name,
+                       str(args),
+                       p.stderr))
+      return r
+
+    def __getattr__(self, name):
+      name = name.replace('_', '-')
+      def runner(*args):
+        cmdv = [name]
+        cmdv.extend(args)
+        p = GitCommand(self._project,
+                       cmdv,
+                       bare = self._bare,
+                       capture_stdout = True,
+                       capture_stderr = True)
+        if p.Wait() != 0:
+          raise GitError('%s %s: %s' % (
+                         self._project.name,
+                         name,
+                         p.stderr))
+        r = p.stdout
+        if r.endswith('\n') and r.index('\n') == len(r) - 1:
+          return r[:-1]
+        return r
+      return runner
+
+
+class MetaProject(Project):
+  """A special project housed under .repo.
+  """
+  def __init__(self, manifest, name, gitdir, worktree):
+    repodir = manifest.repodir
+    Project.__init__(self,
+                     manifest = manifest,
+                     name = name,
+                     gitdir = gitdir,
+                     worktree = worktree,
+                     remote = Remote('origin'),
+                     relpath = '.repo/%s' % name,
+                     revision = 'refs/heads/master')
+
+  def PreSync(self):
+    if self.Exists:
+      cb = self.CurrentBranch
+      if cb:
+        base = self.GetBranch(cb).merge
+        if base:
+          self.revision = base
+
+  @property
+  def HasChanges(self):
+    """Has the remote received new commits not yet checked out?
+    """
+    rev = self.GetRemote(self.remote.name).ToLocal(self.revision)
+    if self._revlist(not_rev(HEAD), rev):
+      return True
+    return False
