[PATCH] 1/3 to contrib/darcs2hg.py

Terry Smith terry at shebiki.org
Thu Sep 13 14:40:53 CDT 2007


This is my first post to mercurial-devel so please correct me if I've  
done anything wrong.

I've got three patches to contrib/darcs2hg.py that add support for  
darcs renames/tags and work around a problem with darcs conflicts.

I'll post each patch in a separate email as suggested on the wiki at  
http://www.selenic.com/mercurial/wiki/index.cgi/ContributingChanges

Here is a summary of all three however:

   changeset:   4879:bd706eb8bc25
   summary:     darcs2hg: Added support for darcs tags.

   changeset:   4878:ad8783fe20f7
   summary:     darcs2hg: Now detects and recovers from simple darcs  
conflicts.

   changeset:   4877:b62a59fa9d26
   summary:     darcs2hg: Now understands files that were explicitly  
renamed in darcs.

Note that I've stayed with the local style of this file which means  
that my changes contain tabs and long lines.

--Terry

# HG changeset patch
# User Terry Smith <terry at t11e.com>
# Date 1189528972 14400
# Node ID b62a59fa9d26824ebc7b30645a02fc1e042d7f15
# Parent  aea35488ea66d08bd6a33abc0c0336266ab82b28
darcs2hg: Now understands files that were explicitly renamed in darcs.

diff -r aea35488ea66 -r b62a59fa9d26 contrib/darcs2hg.py
--- a/contrib/darcs2hg.py	Fri Aug 31 22:31:43 2007 +0200
+++ b/contrib/darcs2hg.py	Tue Sep 11 12:42:52 2007 -0400
@@ -98,6 +98,33 @@ def darcs_pull(hg_repo, darcs_repo, chas
  	if not new_tip != old_tip + 1:
  		error("Darcs pull did not work as expected: " + res)

+def darcs_changes_summary(darcs_repo, chash):
+	"""Gets the changes from the darcs summary. This returns the  
chronological
+	list of changes as (change_type, args). Eg. ('add_file', 'foo.txt') or
+	('move', ['foo.txt','bar.txt'])."""
+	change = cmd("darcs changes --summary --xml-output --match=\"hash %s 
\"" % (chash), darcs_repo)
+	doc = xml_dom.parseString(change)
+	for patch_node in doc.childNodes[0].childNodes:
+		summary_nodes = filter(lambda n: n.nodeName == "summary" and  
n.nodeType == n.ELEMENT_NODE, patch_node.childNodes)
+		for summary_node in summary_nodes:
+			change_nodes = filter(lambda n: n.nodeType == n.ELEMENT_NODE,  
summary_node.childNodes)
+			for change_node in change_nodes:
+				change = change_node.nodeName
+				if change == 'modify_file':
+					yield change, change_node.childNodes[0].data.strip()
+				elif change == 'add_file':
+					yield change, change_node.childNodes[0].data.strip()
+				elif change == 'remove_file':
+					yield change, change_node.childNodes[0].data.strip()
+				elif change == 'add_directory':
+					yield change, change_node.childNodes[0].data.strip()
+				elif change == 'remove_directory':
+					yield change, change_node.childNodes[0].data.strip()
+				elif change == 'move':
+					yield change, (change_node.getAttribute('from'),  
change_node.getAttribute('to'))
+				else:
+					error('Problem parsing summary xml: Unexpected element: ' +  
change_node.toxml())
+
  #  
------------------------------------------------------------------------ 
------
  #
  # Mercurial interface
@@ -127,6 +154,27 @@ def hg_tip( hg_repo ):
  	tip = tip.split("\n")[0].split(":")[1].strip()
  	return int(tip)

+def hg_rename( hg_repo, from_file, to_file ):
+	cmd("hg rename --after \"%s\" \"%s\"" % (from_file, to_file),  
hg_repo);
+	
+def hg_handle_change( hg_repo, change, arg ):
+	"""Processes a change event as output by darcs_changes_summary. These
+	consist of file move/rename/add/delete commands."""
+	if change == 'modify_file':
+		pass
+	elif change == 'add_file':
+		pass
+	elif change =='remove_file':
+		pass
+	elif change == 'add_directory':
+		pass
+	elif change == 'remove_directory':
+		pass
+	elif change == 'move':
+		hg_rename(hg_repo, arg[0], arg[1])
+	else:
+		error('Unknown change type ' + change + ': ' + arg)
+
  #  
------------------------------------------------------------------------ 
------
  #
  # Main
@@ -167,11 +215,13 @@ if __name__ == "__main__":
  			print "(skipping)"
  		else:
  			text = summary + "\n" + description
-			darcs_pull(hg_repo, darcs_repo, chash)
  			# The commit hash has a date like 20021020201112
  			# --------------------------------YYYYMMDDHHMMSS
  			date = chash.split("-")[0]
  			epoch = int(mktime(strptime(date, '%Y%m%d%H%M%S')))
+			darcs_pull(hg_repo, darcs_repo, chash)
+			for change, arg in darcs_changes_summary(darcs_repo, chash):
+				hg_handle_change(hg_repo, change, arg)
  			hg_commit(hg_repo, text, author, epoch)
  		change_number += 1
  	print "Darcs repository (_darcs) was not deleted. You can keep or  
remove it."



More information about the Mercurial-devel mailing list