1064 if not self.check_perm(req, 'push', False): |
1064 if not self.check_perm(req, 'push', False): |
1065 bail(_('push not authorized\n'), |
1065 bail(_('push not authorized\n'), |
1066 headers={'status': '401 Unauthorized'}) |
1066 headers={'status': '401 Unauthorized'}) |
1067 return |
1067 return |
1068 |
1068 |
1069 req.httphdr("application/mercurial-0.1") |
|
1070 |
|
1071 their_heads = req.form['heads'][0].split(' ') |
1069 their_heads = req.form['heads'][0].split(' ') |
1072 |
1070 |
1073 def check_heads(): |
1071 def check_heads(): |
1074 heads = map(hex, self.repo.heads()) |
1072 heads = map(hex, self.repo.heads()) |
1075 return their_heads == [hex('force')] or their_heads == heads |
1073 return their_heads == [hex('force')] or their_heads == heads |
1076 |
1074 |
1077 # fail early if possible |
1075 # fail early if possible |
1078 if not check_heads(): |
1076 if not check_heads(): |
1079 bail(_('unsynced changes\n')) |
1077 bail(_('unsynced changes\n')) |
1080 return |
1078 return |
|
1079 |
|
1080 req.httphdr("application/mercurial-0.1") |
1081 |
1081 |
1082 # do not lock repo until all changegroup data is |
1082 # do not lock repo until all changegroup data is |
1083 # streamed. save to temporary file. |
1083 # streamed. save to temporary file. |
1084 |
1084 |
1085 fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') |
1085 fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') |
1087 try: |
1087 try: |
1088 length = int(req.env['CONTENT_LENGTH']) |
1088 length = int(req.env['CONTENT_LENGTH']) |
1089 for s in util.filechunkiter(req, limit=length): |
1089 for s in util.filechunkiter(req, limit=length): |
1090 fp.write(s) |
1090 fp.write(s) |
1091 |
1091 |
1092 lock = self.repo.lock() |
|
1093 try: |
1092 try: |
1094 if not check_heads(): |
1093 lock = self.repo.lock() |
1095 req.write('0\n') |
1094 try: |
1096 req.write(_('unsynced changes\n')) |
1095 if not check_heads(): |
1097 return |
1096 req.write('0\n') |
1098 |
1097 req.write(_('unsynced changes\n')) |
1099 fp.seek(0) |
1098 return |
1100 header = fp.read(6) |
1099 |
1101 if not header.startswith("HG"): |
1100 fp.seek(0) |
1102 # old client with uncompressed bundle |
1101 header = fp.read(6) |
1103 def generator(f): |
1102 if not header.startswith("HG"): |
1104 yield header |
1103 # old client with uncompressed bundle |
1105 for chunk in f: |
1104 def generator(f): |
1106 yield chunk |
1105 yield header |
1107 elif not header.startswith("HG10"): |
1106 for chunk in f: |
1108 req.write("0\n") |
1107 yield chunk |
1109 req.write(_("unknown bundle version\n")) |
1108 elif not header.startswith("HG10"): |
1110 return |
1109 req.write("0\n") |
1111 elif header == "HG10GZ": |
1110 req.write(_("unknown bundle version\n")) |
1112 def generator(f): |
1111 return |
1113 zd = zlib.decompressobj() |
1112 elif header == "HG10GZ": |
1114 for chunk in f: |
1113 def generator(f): |
1115 yield zd.decompress(chunk) |
1114 zd = zlib.decompressobj() |
1116 elif header == "HG10BZ": |
1115 for chunk in f: |
1117 def generator(f): |
1116 yield zd.decompress(chunk) |
1118 zd = bz2.BZ2Decompressor() |
1117 elif header == "HG10BZ": |
1119 zd.decompress("BZ") |
1118 def generator(f): |
1120 for chunk in f: |
1119 zd = bz2.BZ2Decompressor() |
1121 yield zd.decompress(chunk) |
1120 zd.decompress("BZ") |
1122 elif header == "HG10UN": |
1121 for chunk in f: |
1123 def generator(f): |
1122 yield zd.decompress(chunk) |
1124 for chunk in f: |
1123 elif header == "HG10UN": |
1125 yield chunk |
1124 def generator(f): |
|
1125 for chunk in f: |
|
1126 yield chunk |
|
1127 else: |
|
1128 req.write("0\n") |
|
1129 req.write(_("unknown bundle compression type\n")) |
|
1130 return |
|
1131 gen = generator(util.filechunkiter(fp, 4096)) |
|
1132 |
|
1133 # send addchangegroup output to client |
|
1134 |
|
1135 old_stdout = sys.stdout |
|
1136 sys.stdout = cStringIO.StringIO() |
|
1137 |
|
1138 try: |
|
1139 url = 'remote:%s:%s' % (proto, |
|
1140 req.env.get('REMOTE_HOST', '')) |
|
1141 try: |
|
1142 ret = self.repo.addchangegroup( |
|
1143 util.chunkbuffer(gen), 'serve', url) |
|
1144 except util.Abort, inst: |
|
1145 sys.stdout.write("abort: %s\n" % inst) |
|
1146 ret = 0 |
|
1147 finally: |
|
1148 val = sys.stdout.getvalue() |
|
1149 sys.stdout = old_stdout |
|
1150 req.write('%d\n' % ret) |
|
1151 req.write(val) |
|
1152 finally: |
|
1153 lock.release() |
|
1154 except (OSError, IOError), inst: |
|
1155 req.write('0\n') |
|
1156 filename = getattr(inst, 'filename', '') |
|
1157 # Don't send our filesystem layout to the client |
|
1158 if filename.startswith(self.repo.root): |
|
1159 filename = filename[len(self.repo.root)+1:] |
1126 else: |
1160 else: |
1127 req.write("0\n") |
1161 filename = '' |
1128 req.write(_("unknown bundle compression type\n")) |
1162 error = getattr(inst, 'strerror', 'Unknown error') |
1129 return |
1163 req.write('%s: %s\n' % (error, filename)) |
1130 gen = generator(util.filechunkiter(fp, 4096)) |
|
1131 |
|
1132 # send addchangegroup output to client |
|
1133 |
|
1134 old_stdout = sys.stdout |
|
1135 sys.stdout = cStringIO.StringIO() |
|
1136 |
|
1137 try: |
|
1138 url = 'remote:%s:%s' % (proto, |
|
1139 req.env.get('REMOTE_HOST', '')) |
|
1140 try: |
|
1141 ret = self.repo.addchangegroup(util.chunkbuffer(gen), |
|
1142 'serve', url) |
|
1143 except util.Abort, inst: |
|
1144 sys.stdout.write("abort: %s\n" % inst) |
|
1145 ret = 0 |
|
1146 finally: |
|
1147 val = sys.stdout.getvalue() |
|
1148 sys.stdout = old_stdout |
|
1149 req.write('%d\n' % ret) |
|
1150 req.write(val) |
|
1151 finally: |
|
1152 lock.release() |
|
1153 finally: |
1164 finally: |
1154 fp.close() |
1165 fp.close() |
1155 os.unlink(tempname) |
1166 os.unlink(tempname) |
1156 |
1167 |
1157 def do_stream_out(self, req): |
1168 def do_stream_out(self, req): |