summaryrefslogtreecommitdiffstats
path: root/project.py
diff options
context:
space:
mode:
authorShawn O. Pearce <sop@google.com>2010-10-08 10:02:09 +0200
committerShawn O. Pearce <sop@google.com>2010-10-29 12:08:50 -0700
commit88443387b1b0508f43b57e104821c6b375806fea (patch)
treed3d1e5a3e6caecd8eabbdf7a1491ddcc2788aa3d /project.py
parent99482ae58a74e236fb40b65c267163a5690f39e1 (diff)
downloadgit-repo-88443387b1b0508f43b57e104821c6b375806fea.tar.gz
sync: Enable use of git clone --reference
Use git clone to initialize a new repository, and when possible allow callers to use --reference to reuse an existing checkout as the initial object storage area for the new checkout. Change-Id: Ie27f760247f311ce484c6d3e85a90d94da2febfc Signed-off-by: Shawn O. Pearce <sop@google.com>
Diffstat (limited to 'project.py')
-rw-r--r--project.py101
1 files changed, 94 insertions, 7 deletions
diff --git a/project.py b/project.py
index 1b5d9a67..8ffed842 100644
--- a/project.py
+++ b/project.py
@@ -622,13 +622,14 @@ class Project(object):
622 """Perform only the network IO portion of the sync process. 622 """Perform only the network IO portion of the sync process.
623 Local working directory/branch state is not affected. 623 Local working directory/branch state is not affected.
624 """ 624 """
625 if not self.Exists: 625 is_new = not self.Exists
626 if is_new:
626 print >>sys.stderr 627 print >>sys.stderr
627 print >>sys.stderr, 'Initializing project %s ...' % self.name 628 print >>sys.stderr, 'Initializing project %s ...' % self.name
628 self._InitGitDir() 629 self._InitGitDir()
629 630
630 self._InitRemote() 631 self._InitRemote()
631 if not self._RemoteFetch(): 632 if not self._RemoteFetch(initial = is_new):
632 return False 633 return False
633 634
634 #Check that the requested ref was found after fetch 635 #Check that the requested ref was found after fetch
@@ -1024,7 +1025,7 @@ class Project(object):
1024 1025
1025## Direct Git Commands ## 1026## Direct Git Commands ##
1026 1027
1027 def _RemoteFetch(self, name=None, tag=None): 1028 def _RemoteFetch(self, name=None, tag=None, initial=False):
1028 if not name: 1029 if not name:
1029 name = self.remote.name 1030 name = self.remote.name
1030 1031
@@ -1032,6 +1033,60 @@ class Project(object):
1032 if self.GetRemote(name).PreConnectFetch(): 1033 if self.GetRemote(name).PreConnectFetch():
1033 ssh_proxy = True 1034 ssh_proxy = True
1034 1035
1036 if initial:
1037 alt = os.path.join(self.gitdir, 'objects/info/alternates')
1038 try:
1039 fd = open(alt, 'rb')
1040 try:
1041 ref_dir = fd.readline()
1042 if ref_dir and ref_dir.endswith('\n'):
1043 ref_dir = ref_dir[:-1]
1044 finally:
1045 fd.close()
1046 except IOError, e:
1047 ref_dir = None
1048
1049 if ref_dir and 'objects' == os.path.basename(ref_dir):
1050 ref_dir = os.path.dirname(ref_dir)
1051 packed_refs = os.path.join(self.gitdir, 'packed-refs')
1052 remote = self.GetRemote(name)
1053
1054 all = self.bare_ref.all
1055 ids = set(all.values())
1056 tmp = set()
1057
1058 for r, id in GitRefs(ref_dir).all.iteritems():
1059 if r not in all:
1060 if r.startswith(R_TAGS) or remote.WritesTo(r):
1061 all[r] = id
1062 ids.add(id)
1063 continue
1064
1065 if id in ids:
1066 continue
1067
1068 r = 'refs/_alt/%s' % id
1069 all[r] = id
1070 ids.add(id)
1071 tmp.add(r)
1072
1073 ref_names = list(all.keys())
1074 ref_names.sort()
1075
1076 tmp_packed = ''
1077 old_packed = ''
1078
1079 for r in ref_names:
1080 line = '%s %s\n' % (all[r], r)
1081 tmp_packed += line
1082 if r not in tmp:
1083 old_packed += line
1084
1085 _lwrite(packed_refs, tmp_packed)
1086
1087 else:
1088 ref_dir = None
1089
1035 cmd = ['fetch'] 1090 cmd = ['fetch']
1036 if not self.worktree: 1091 if not self.worktree:
1037 cmd.append('--update-head-ok') 1092 cmd.append('--update-head-ok')
@@ -1039,10 +1094,21 @@ class Project(object):
1039 if tag is not None: 1094 if tag is not None:
1040 cmd.append('tag') 1095 cmd.append('tag')
1041 cmd.append(tag) 1096 cmd.append(tag)
1042 return GitCommand(self, 1097
1043 cmd, 1098 ok = GitCommand(self,
1044 bare = True, 1099 cmd,
1045 ssh_proxy = ssh_proxy).Wait() == 0 1100 bare = True,
1101 ssh_proxy = ssh_proxy).Wait() == 0
1102
1103 if initial:
1104 if ref_dir:
1105 if old_packed != '':
1106 _lwrite(packed_refs, old_packed)
1107 else:
1108 os.remove(packed_refs)
1109 self.bare_git.pack_refs('--all', '--prune')
1110
1111 return ok
1046 1112
1047 def _Checkout(self, rev, quiet=False): 1113 def _Checkout(self, rev, quiet=False):
1048 cmd = ['checkout'] 1114 cmd = ['checkout']
@@ -1080,6 +1146,27 @@ class Project(object):
1080 os.makedirs(self.gitdir) 1146 os.makedirs(self.gitdir)
1081 self.bare_git.init() 1147 self.bare_git.init()
1082 1148
1149 mp = self.manifest.manifestProject
1150 ref_dir = mp.config.GetString('repo.reference')
1151
1152 if ref_dir:
1153 mirror_git = os.path.join(ref_dir, self.name + '.git')
1154 repo_git = os.path.join(ref_dir, '.repo', 'projects',
1155 self.relpath + '.git')
1156
1157 if os.path.exists(mirror_git):
1158 ref_dir = mirror_git
1159
1160 elif os.path.exists(repo_git):
1161 ref_dir = repo_git
1162
1163 else:
1164 ref_dir = None
1165
1166 if ref_dir:
1167 _lwrite(os.path.join(self.gitdir, 'objects/info/alternates'),
1168 os.path.join(ref_dir, 'objects') + '\n')
1169
1083 if self.manifest.IsMirror: 1170 if self.manifest.IsMirror:
1084 self.config.SetString('core.bare', 'true') 1171 self.config.SetString('core.bare', 'true')
1085 else: 1172 else: