Exemplo n.º 1
0
	def test_merge_conflict(self):
		logging.debug('Testing a file blob merge conflict')
		reset_storage()
		f_branch_A=open('../resource/branch_A_conflict.txt','rb')
		f_branch_B=open('../resource/branch_B_conflict.txt','rb')
		f_ancest=open('../resource/common_ancestor.txt','rb')
		result = file_blob.merge(f_branch_A.read(), f_branch_B.read(), f_ancest.read())
		print result
Exemplo n.º 2
0
 def test_merge_conflict(self):
     logging.debug('Testing a file blob merge conflict')
     reset_storage()
     f_branch_A = open('../resource/branch_A_conflict.txt', 'rb')
     f_branch_B = open('../resource/branch_B_conflict.txt', 'rb')
     f_ancest = open('../resource/common_ancestor.txt', 'rb')
     result = file_blob.merge(f_branch_A.read(), f_branch_B.read(),
                              f_ancest.read())
     print result
Exemplo n.º 3
0
	def merge(tb_A, tb_B, tb_C, merge_method = 'dupe_on_conflict'):
		"""Merges two trees. C is common ancestor
		merge_method determines how conflicts are handled.
		dupe_on_conflict: default.  try merging.  if a conflict can't be resolved automatically save both file versions.
		dupe_always: if two folders/files need to be merged always save both copies
		force_merge: try merging.  in case of conflict resolve automatically even if result contains unified diff sections.
		"""
		
		"""
		Algorithm
		--------------
		A: update commit
		B: old commit
		C: common ancestor commit
		N: new tree
		-store trees from A, B, C, and N in easily traversable data structure
		-iterate through folders and files from A (from top down.  these iterations only add to wd)
		    -if B has it
		        -no change necessary
		        -add to N as is
		    -if C has it, but B doesn't 
		        -means B deleted file/folder
		        -don't add to N
		    -if neither C nor B have it
		        -means A added it
		        -push change to wd
		        -add to N
		    -if B has same file name and path, but different hash as A
		        -attempt merge
		        -add merged file(s) to N
		
		-iterate through folders and files from B (from bottom up.  these iterations only delete from wd)
		    -if neither C nor A have it
		        -means B added it
		        -add to N
		        -no change necessary
		    -if C has it, but A doesn't 
		        -means A deleted file/folder
		        -delete file/folder from wd
		
		-commit wd as merge
		
		-issues with algorithm
		    -B moves file, A edits file
    """
		
		
		merge_tb = tree_blob()
		merge_tb.root_node = tree_blob.TreeNode()
		merge_tb.root_node.name = tb_A.root_node.name
		merge_tb.root_node.node_type = 'folder'
		merge_tb.root_node.size=0
		print 'walking tree'
		for path, node in tb_A.walk():
			print path
			if path == merge_tb.root_node.name:
				continue
			if tb_B.has_node(path, node.node_type) and 
			        (tb_B.get_node(path, node.node_type)).hash_hex == node.hash_hex:  #not modified
				merge_tb.add_node(path, node.node_type, node.hash_hex, int(node.size))
				continue
			if tb_B.has_node(path, node.node_type) and 
			        (tb_B.get_node(path, node.node_type)).hash_hex != node.hash_hex:  #merge files		
				hash_hex_B = (tb_B.get_node(path, node.node_type)).hash_hex
				fb_B = file_blob()
				fb_B.load(key, storage, hash_hex_B)
				fb_A = file_blob()
				fb_A.load(key, storage, node.hash_hex)
				if tb_C.has_node(path, node.node_type):
					hash_hex_C = (tb_C.get_node(path, node.node_type)).hash_hex
					fb_C = file_blob()
					fb_C.load(key, storage, hash_hex_C)
				else:
					fb_C = fb_B
				merge_text = file_blob.merge(fb_A.apply_delta(key, storage), fb_B.apply_delta(key, storage), fb_C.apply_delta(key, storage))
				fb_merge = file_blob()
				fb_merge.compute_delta(key, merge_text, fb_A, storage)
				merge_tb.add_node(path, node.node_type, node.hash_hex, int(node.size))
				continue	
			if tb_C.has_node(path, node.node_type):  #B deleted
				continue
			
			merge_tb.add_node(path, node.node_type, node.hash_hex, int(node.size))  #A added
			
		for path, node in tb_B.walk():
			print path
			if path == merge_tb.root_node.name:
				continue
			if (not tb_C.has_node(path, node.node_type)) and (not tb_A.has_node(path, node.node_type)):  #B added
				merge_tb.add_node(path, node.node_type, node.hash_hex, int(node.size))
				
		return merge_tb
		
			
			
			


















			
			
			
			
			
			
Exemplo n.º 4
0
	def merge(tb_A, tb_B, tb_C, merge_method = 'dupe_on_conflict'):
		"""Merges two trees. C is common ancestor
		merge_method determines how conflicts are handled.
		dupe_on_conflict: default.  try merging.  if a conflict can't be resolved automatically save both file versions.
		dupe_always: if two folders/files need to be merged always save both copies
		force_merge: try merging.  in case of conflict resolve automatically even if result contains unified diff sections.
		"""
		
		"""
		Algorithm
		--------------
		A: update commit
		B: old commit
		C: common ancestor commit
		N: new tree
		-store trees from A, B, C, and N in easily traversable data structure
		-iterate through folders and files from A (from top down.  these iterations only add to wd)
		    -if B has it
		        -no change necessary
		        -add to N as is
		    -if C has it, but B doesn't 
		        -means B deleted file/folder
		        -don't add to N
		    -if neither C nor B have it
		        -means A added it
		        -push change to wd
		        -add to N
		    -if B has same file name and path, but different hash as A
		        -attempt merge
		        -add merged file(s) to N
		
		-iterate through folders and files from B (from bottom up.  these iterations only delete from wd)
		    -if neither C nor A have it
		        -means B added it
		        -add to N
		        -no change necessary
		    -if C has it, but A doesn't 
		        -means A deleted file/folder
		        -delete file/folder from wd
		
		-commit wd as merge
		
		-issues with algorithm
		    -B moves file, A edits file
    """
		
		
		merge_tb = tree_blob()
		merge_tb.root_node = tree_blob.TreeNode()
		merge_tb.root_node.name = tb_A.root_node.name
		merge_tb.root_node.node_type = 'folder'
		merge_tb.root_node.size=0
		print 'walking tree'
		for path, node in tb_A.walk():
			print path
			if path == merge_tb.root_node.name:
				continue
			if tb_B.has_node(path, node.node_type) and 
			        (tb_B.get_node(path, node.node_type)).hash_hex == node.hash_hex:  #not modified
				merge_tb.add_node(path, node.node_type, node.hash_hex, int(node.size))
				continue
			if tb_B.has_node(path, node.node_type) and 
			        (tb_B.get_node(path, node.node_type)).hash_hex != node.hash_hex:  #merge files		
				hash_hex_B = (tb_B.get_node(path, node.node_type)).hash_hex
				fb_B = file_blob()
				fb_B.load(key, storage, hash_hex_B)
				fb_A = file_blob()
				fb_A.load(key, storage, node.hash_hex)
				if tb_C.has_node(path, node.node_type):
					hash_hex_C = (tb_C.get_node(path, node.node_type)).hash_hex
					fb_C = file_blob()
					fb_C.load(key, storage, hash_hex_C)
				else:
					fb_C = fb_B
				merge_text = file_blob.merge(fb_A.apply_delta(key, storage), fb_B.apply_delta(key, storage), fb_C.apply_delta(key, storage))
				fb_merge = file_blob()
				fb_merge.compute_delta(key, merge_text, fb_A, storage)
				merge_tb.add_node(path, node.node_type, node.hash_hex, int(node.size))
				continue	
			if tb_C.has_node(path, node.node_type):  #B deleted
				continue
			
			merge_tb.add_node(path, node.node_type, node.hash_hex, int(node.size))  #A added
			
		for path, node in tb_B.walk():
			print path
			if path == merge_tb.root_node.name:
				continue
			if (not tb_C.has_node(path, node.node_type)) and (not tb_A.has_node(path, node.node_type)):  #B added
				merge_tb.add_node(path, node.node_type, node.hash_hex, int(node.size))
				
		return merge_tb