remote-bzr: add support to push merges

In order to do that, we need to store the marks of every file, so that they can be fetched when needed. Unfortunately we can't tell bazaar that nothing changed, we need to send the data so that it can figure it out by itself. And since it will be requesting a bunch of information by the file_id, it's better to have a helper dict (rev_files), so that we can fetch it quickly. Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Felipe Contreras committed Apr 30, 2013 at 20:09 UTC f38dfc4c32507de2f7cf05350fe8b34fd4edd45d
2 files changed +57 -8
contrib/remote-helpers/git-remote-bzr
+21 -8
@@ -393,7 +393,7 @@ class CustomTree():
393 tree = repo.repository.revision_tree(revid)
394 try:
395 for path, entry in tree.iter_entries_by_dir():
396 - files[path] = entry.file_id
396 + files[path] = [entry.file_id, None]
397 finally:
398 repo.unlock()
399 return files
@@ -408,12 +408,18 @@ class CustomTree():
408 self.base_files = copy_tree(self.base_id)
409
410 self.files = files_cache[revid] = self.base_files.copy()
411 + self.rev_files = {}
412 +
413 + for path, data in self.files.iteritems():
414 + fid, mark = data
415 + self.rev_files[fid] = [path, mark]
416
417 for path, f in files.iteritems():
413 - fid = self.files.get(path, None)
418 + fid, mark = self.files.get(path, [None, None])
419 if not fid:
420 fid = bzrlib.generate_ids.gen_file_id(path)
421 f['path'] = path
422 + self.rev_files[fid] = [path, mark]
423 self.updates[fid] = f
424
425 def last_revision(self):
@@ -423,10 +429,10 @@ class CustomTree():
429 changes = []
430
431 def get_parent(dirname, basename):
426 - parent_fid = self.base_files.get(dirname, None)
432 + parent_fid, mark = self.base_files.get(dirname, [None, None])
433 if parent_fid:
434 return parent_fid
429 - parent_fid = self.files.get(dirname, None)
435 + parent_fid, mark = self.files.get(dirname, [None, None])
436 if parent_fid:
437 return parent_fid
438 if basename == '':
@@ -453,7 +459,7 @@ class CustomTree():
459 (None, basename),
460 (None, kind),
461 (None, executable))
456 - self.files[path] = change[0]
462 + self.files[path] = [change[0], None]
463 changes.append(change)
464
465 def update_entry(fid, path, kind, mode = None):
@@ -474,7 +480,7 @@ class CustomTree():
480 (None, basename),
481 (None, kind),
482 (None, executable))
477 - self.files[path] = change[0]
483 + self.files[path] = [change[0], None]
484 changes.append(change)
485
486 def remove_entry(fid, path, kind):
@@ -503,16 +509,23 @@ class CustomTree():
509 else:
510 add_entry(fid, path, 'file', f['mode'])
511
512 + self.files[path][1] = f['mark']
513 + self.rev_files[fid][1] = f['mark']
514 +
515 return changes
516
517 def get_file_with_stat(self, file_id, path=None):
509 - mark = self.updates[file_id]['mark']
518 + path, mark = self.rev_files[file_id]
519 return (StringIO.StringIO(blob_marks[mark]), None)
520
521 def get_symlink_target(self, file_id):
513 - mark = self.updates[file_id]['mark']
522 + path, mark = self.rev_files[file_id]
523 return blob_marks[mark]
524
525 + def id2path(self, file_id):
526 + path, mark = self.rev_files[file_id]
527 + return path
528 +
529 def c_style_unescape(string):
530 if string[0] == string[-1] == '"':
531 return string.decode('string-escape')[1:-1]
contrib/remote-helpers/test-bzr.sh
+36
@@ -228,4 +228,40 @@ test_expect_success 'push utf-8 filenames' '
228 test_cmp expected actual
229 '
230
231 +test_expect_success 'pushing a merge' '
232 + mkdir -p tmp && cd tmp &&
233 + test_when_finished "cd .. && rm -rf tmp" &&
234 +
235 + (
236 + bzr init bzrrepo &&
237 + cd bzrrepo &&
238 + echo one > content &&
239 + bzr add content &&
240 + bzr commit -m one
241 + ) &&
242 +
243 + git clone "bzr::$PWD/bzrrepo" gitrepo &&
244 +
245 + (
246 + cd bzrrepo &&
247 + echo two > content &&
248 + bzr commit -m two
249 + ) &&
250 +
251 + (
252 + cd gitrepo &&
253 + echo three > content &&
254 + git commit -a -m three &&
255 + git fetch &&
256 + git merge origin/master || true &&
257 + echo three > content &&
258 + git commit -a --no-edit &&
259 + git push
260 + ) &&
261 +
262 + echo three > expected &&
263 + cat bzrrepo/content > actual &&
264 + test_cmp expected actual
265 +'
266 +
267 test_done