implement personal reference
diff --git a/main.py b/main.py
index 72fb39b..db4f02d 100755
--- a/main.py
+++ b/main.py
@@ -79,6 +79,11 @@
                           dest='show_version', action='store_true',
                           help='display this version of repo')
 
+group = global_options.add_option_group('mtk customization options')
+group.add_option('--local-cache',
+                 dest='local_cache',
+                 help='personal reference location')
+
 class _Repo(object):
   def __init__(self, repodir):
     self.repodir = repodir
@@ -121,7 +126,7 @@
       return 1
 
     cmd.repodir = self.repodir
-    cmd.manifest = XmlManifest(cmd.repodir)
+    cmd.manifest = XmlManifest(cmd.repodir, gopts.local_cache)
     Editor.globalConfig = cmd.manifest.globalConfig
 
     if not isinstance(cmd, MirrorSafeCommand) and cmd.manifest.IsMirror:
diff --git a/manifest_xml.py b/manifest_xml.py
index e2f58e6..94c6864 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -106,7 +106,9 @@
 class XmlManifest(object):
   """manages the repo configuration file"""
 
-  def __init__(self, repodir):
+  def __init__(self, repodir, localcache=None):
+    self.localcache = None
+    if localcache: self.localcache = os.path.abspath(localcache)
     self.repodir = os.path.abspath(repodir)
     self.topdir = os.path.dirname(self.repodir)
     self.manifestFile = os.path.join(self.repodir, MANIFEST_FILE_NAME)
@@ -738,9 +740,9 @@
     groups = [x for x in re.split(r'[,\s]+', groups) if x]
 
     if parent is None:
-      relpath, worktree, gitdir, objdir = self.GetProjectPaths(name, path)
+      relpath, worktree, gitdir, objdir, localcache = self.GetProjectPaths(name, path)
     else:
-      relpath, worktree, gitdir, objdir = \
+      relpath, worktree, gitdir, objdir, localcache = \
           self.GetSubprojectPaths(parent, name, path)
 
     default_groups = ['all', 'name:%s' % name, 'path:%s' % relpath]
@@ -766,7 +768,8 @@
                       clone_depth = clone_depth,
                       upstream = upstream,
                       parent = parent,
-                      dest_branch = dest_branch)
+                      dest_branch = dest_branch,
+                      localcache = localcache)
 
     for n in node.childNodes:
       if n.nodeName == 'copyfile':
@@ -790,7 +793,10 @@
       worktree = os.path.join(self.topdir, path).replace('\\', '/')
       gitdir = os.path.join(self.repodir, 'projects', '%s.git' % path)
       objdir = os.path.join(self.repodir, 'project-objects', '%s.git' % name)
-    return relpath, worktree, gitdir, objdir
+    localcache = None
+    if self.localcache:
+      localcache = os.path.join(self.localcache, '%s.git' % name)
+    return relpath, worktree, gitdir, objdir, localcache
 
   def GetProjectsWithName(self, name):
     return self._projects.get(name, [])
@@ -812,7 +818,10 @@
       worktree = None
     else:
       worktree = os.path.join(parent.worktree, path).replace('\\', '/')
-    return relpath, worktree, gitdir, objdir
+    localcache = None
+    if self.localcache:   
+      localcache = os.path.join(parent.localcache, 'subproject-caches', '%s.git' % name)
+    return relpath, worktree, gitdir, objdir, localcache
 
   def _ParseCopyFile(self, project, node):
     src = self._reqatt(node, 'src')
diff --git a/project.py b/project.py
index f43bcc5..e4ed7d0 100644
--- a/project.py
+++ b/project.py
@@ -525,7 +525,8 @@
                upstream = None,
                parent = None,
                is_derived = False,
-               dest_branch = None):
+               dest_branch = None,
+               localcache = None):
     """Init a Project object.
 
     Args:
@@ -597,6 +598,10 @@
     # This will be filled in if a project is later identified to be the
     # project containing repo hooks.
     self.enabled_repo_hooks = []
+    self.localcache = None
+    if localcache:
+      self.localcache = localcache.replace('\\', '/')
+      self.bare_cache = self._GitGetByExec(self, bare=True, gitdir=localcache)
 
   @property
   def Derived(self):
@@ -1350,6 +1355,14 @@
 
 
 ## Branch Management ##
+  def CleanCache(self, name):
+    refs = GitRefs(self.localcache).all
+    
+    try:
+      self.bare_cache.DeleteRef(name)
+    except:
+      raise 
+    return True
 
   def StartBranch(self, name):
     """Create a new branch off the manifest's revision.
@@ -1702,6 +1715,52 @@
     if command.Wait() != 0:
       raise GitError('git archive %s: %s' % (self.name, command.stderr))
 
+  def _UpdateCache(self, name, ssh_proxy, tag_name, is_sha1):
+    if not name:
+      name = self.remote.name
+
+    remote = self.GetRemote(name)
+    cmd = ['fetch']
+    depth = None
+    if not self.manifest.IsMirror:
+      if self.clone_depth:
+        depth = self.clone_depth
+      else:
+        depth = self.manifest.manifestProject.config.GetString('repo.depth')
+      if depth:
+        cmd.append('--depth=%s' % depth)
+    cmd.append('--no-tags')
+    cmd.append('--quiet')
+    cmd.append('--update-head-ok')
+    cmd.append(remote.url)
+
+    if tag_name is not None:
+      cmd.append('tag')
+      cmd.append(tag_name)
+    else:
+      branch = self.revisionExpr
+      if is_sha1:
+        branch = self.upstream
+      if branch.startswith(R_HEADS):
+        branch = branch[len(R_HEADS):]
+        cmd.append(str((u'+refs/heads/%s:' % branch) + remote.ToLocal('refs/heads/%s' % branch)))
+      else:
+        cmd.append(str((u'+%s:' % branch) + remote.ToLocal(branch)))
+
+    for _i in range(2):
+      ret = GitCommand(self, cmd, bare=True, ssh_proxy=ssh_proxy, gitdir=self.localcache).Wait()
+      if ret == 0:
+        ok = True
+        break
+      elif ret == 128:
+          # Exit code 128 means "couldn't find the ref you asked for"; if we're in sha1
+          # mode, we just tried sync'ing from the upstream field; it doesn't exist, thus
+          # abort the optimization attempt and do a full sync.
+        break
+      time.sleep(random.randint(30, 45))
+    if ok and depth:
+      os.remove('%s/shallow' % self.localcache)
+
   def _RemoteFetch(self, name=None,
                    current_branch_only=False,
                    initial=False,
@@ -1746,6 +1805,12 @@
     if remote.PreConnectFetch():
       ssh_proxy = True
 
+    try:
+      if self.localcache and not depth:
+        self._UpdateCache(name, ssh_proxy, tag_name, is_sha1)
+    except Exception as e:
+      print("update cache failed. %s" % traceback.format_exc(), file=sys.stderr)
+
     if initial:
       if alt_dir and 'objects' == os.path.basename(alt_dir):
         ref_dir = os.path.dirname(alt_dir)
@@ -2044,6 +2109,10 @@
   def _InitGitDir(self, mirror_git=None):
     if not os.path.exists(self.gitdir):
 
+      if self.localcache and not os.path.exists(self.localcache):
+        os.makedirs(self.localcache)
+        self.bare_cache.init()
+
       # Initialize the bare repository, which contains all of the objects.
       if not os.path.exists(self.objdir):
         os.makedirs(self.objdir)
@@ -2076,6 +2145,10 @@
         if ref_dir:
           _lwrite(os.path.join(self.gitdir, 'objects/info/alternates'),
                   os.path.join(ref_dir, 'objects') + '\n')
+      elif self.localcache:
+        _lwrite(os.path.join(self.gitdir, 'objects/info/alternates'),
+                  os.path.join(self.localcache, 'objects') + '\n')
+          
 
       self._UpdateHooks()
 
diff --git a/repo b/repo
index b8c414b..83ab888 100755
--- a/repo
+++ b/repo
@@ -2,8 +2,9 @@
 
 ## repo default configuration
 ##
-REPO_URL = 'https://gerrit.googlesource.com/git-repo'
-REPO_REV = 'stable'
+REPO_URL = 'ssh://mtksgt08:29418/git-repo'
+REPO_REV = 'mediatek/dev'
+LOCAL_CACHE = '{user_home}/.git-objects'
 
 # Copyright (C) 2008 Google Inc.
 #
@@ -216,6 +217,13 @@
                  dest='config_name', action="store_true", default=False,
                  help='Always prompt for name/e-mail')
 
+#MTK
+group = init_optparse.add_option_group('mtk customization options')
+group.add_option('--local-cache',
+                 dest='local_cache',
+                 help='personal reference location')
+
+
 class CloneFailure(Exception):
   """Indicate the remote clone of repo itself failed.
   """
@@ -757,6 +765,11 @@
         '--wrapper-version=%s' % ver_str,
         '--wrapper-path=%s' % wrapper_path,
         '--']
+
+  if LOCAL_CACHE:
+    cache = LOCAL_CACHE.format(user_home=os.environ['HOME'])
+    orig_args.insert(0, '--local-cache=%s' % cache)
+
   me.extend(orig_args)
   me.extend(extra_args)
   try:
diff --git a/subcmds/clean.py b/subcmds/clean.py
new file mode 100644
index 0000000..c50f5a4
--- /dev/null
+++ b/subcmds/clean.py
@@ -0,0 +1,127 @@
+#
+# Copyright (C) 2009 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.
+
+from __future__ import print_function
+import sys
+from command import Command
+from progress import Progress
+from git_command import GIT, git_require
+from git_refs import GitRefs
+
+try:
+  import threading as _threading
+except ImportError:
+  import dummy_threading as _threading
+
+try:
+  import multiprocessing
+except ImportError:
+  multiprocessing = None
+
+class Clean(Command):
+  common = True
+  helpSummary = "Delete a branch from personal reference"
+  helpUsage = """
+%prog <branchname> [<project>...]
+"""
+  helpDescription = """
+The '%prog' command remove an existing branch and run git gc
+to make more space from personal reference
+"""
+
+  def Execute(self, opt, args):
+    if not args:
+      self.Usage()
+
+    nb = args[0]
+    err = []
+    success = []
+    all_projects = self.GetProjects(args[1:])
+
+    pm = Progress('Remove %s' % nb, len(all_projects))
+    for project in all_projects:
+      pm.update()
+
+      status = project.CleanCache('refs/remotes/%s' % nb)
+      if status is not None:
+        if status:
+          success.append(project)
+        else:
+          err.append(project)
+    pm.end()
+
+    if err:
+      for p in err:
+        print("error: %s/: cannot clean cache %s" % (p.localcache, nb),
+              file=sys.stderr)
+      sys.exit(1)
+    elif not success:
+      print('error: no project has branch %s' % nb, file=sys.stderr)
+      sys.exit(1)
+
+    self._GCProjects(all_projects)
+
+  def _GCProjects(self, projects):
+    gitdirs = {}
+    for project in projects:
+      gitdirs[project.gitdir] = project.bare_cache
+
+    has_dash_c = git_require((1, 7, 2))
+    if multiprocessing and has_dash_c:
+      cpu_count = multiprocessing.cpu_count()
+    else:
+      cpu_count = 1
+    jobs = cpu_count
+
+    if jobs < 2:
+      for bare_git in gitdirs.values():
+        bare_git.gc('--prune=all')
+      return
+
+    config = {'pack.threads': cpu_count / jobs if cpu_count > jobs else 1}
+
+    threads = set()
+    sem = _threading.Semaphore(jobs)
+    err_event = _threading.Event()
+
+    def GC(bare_git):
+      try:
+        try:
+          bare_git.gc('--prune=all', config=config)
+        except GitError:
+          err_event.set()
+        except:
+          err_event.set()
+          raise
+      finally:
+        sem.release()
+
+    for bare_git in gitdirs.values():
+      if err_event.isSet():
+        break
+      sem.acquire()
+      t = _threading.Thread(target=GC, args=(bare_git,))
+      t.daemon = True
+      threads.add(t)
+      t.start()
+
+    for t in threads:
+      t.join()
+
+    if err_event.isSet():
+      print('\nerror: Exited clean up due to gc errors', file=sys.stderr)
+      sys.exit(1)
+
+
diff --git a/subcmds/sync.py b/subcmds/sync.py
index 96908f4..f9133be 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -211,6 +211,10 @@
                    dest='smart_tag', action='store',
                    help='smart sync using manifest from a known tag')
 
+    p.add_option('--force-current-branch-only-off',
+                 dest='force_current_branch_only', action='store_false', default=True,
+                 help='turn off force fetch only current branch from server')
+
     g = p.add_option_group('repo Version options')
     g.add_option('--no-repo-verify',
                  dest='no_repo_verify', action='store_true',
@@ -270,7 +274,7 @@
         start = time.time()
         success = project.Sync_NetworkHalf(
           quiet=opt.quiet,
-          current_branch_only=opt.current_branch_only,
+          current_branch_only=True if opt.force_current_branch_only else opt.current_branch_only,
           clone_bundle=not opt.no_clone_bundle,
           no_tags=opt.no_tags, archive=self.manifest.IsArchive)
         self._fetch_times.Set(project, time.time() - start)
@@ -613,7 +617,7 @@
 
     if not opt.local_only:
       mp.Sync_NetworkHalf(quiet=opt.quiet,
-                          current_branch_only=opt.current_branch_only,
+                          current_branch_only=True if opt.force_current_branch_only else opt.current_branch_only,
                           no_tags=opt.no_tags)
 
     if mp.HasChanges: