Strategies for push/merge problem?

Roman Kennke roman.kennke at aicas.com
Tue Jul 15 02:06:51 CDT 2008


Hi Peter,

> We all heard that Matt is not interested in the push approach. Fair
> enough. So the question is, do sufficiently motivated people want to
> take this into their own hands?

I would like to do it, but I have no idea of how HG works internally,
especially the communication between client and server. Also, I have a
big lack of time right now.

>  I think it's not that hard to do as a
> client and server extension, which could alleviate both the merge race
> and the mergeful history problems. But, of course, a legimitate
> question is if it stands a chance of getting official extension status
> (Matt?).
> 
> I do believe it would make the transition to Hg easier, even if it
> does not scale indefinitely. And it would make Hg even more versatile.

+1.

> So - to continue a previous thread - how about the following for a
> plan to implement server-based `hg pushmerge` and `hg pushrebase` (or
> whatever better names we can find)?
> 
> It can be done with current tools (rebase is coming), but for best
> performance, let's assume we can provide these currently missing
> pieces:
> 
> (a) a dedicated local overlay repo that uses the parent's config (so
> hooks are the same) and stores only increments to parent revlogs (so
> it is extremely lightweight),
> (b) make conflict-free merging possible without a working copy,
> (c) dito for conflict-free rebasing.
> 
> Given the existing OverlayRepo code and the latest work on
> working-copy-free convert, I think this is not unreasonable.
> 
> Then I think we could implement `hg pushmerge` on the server like this
> (pseudo-code):
> 
> 	inbundle = read client's changes
> 	wlock = repo.wlock()
> 	# no one else is pushing or integrating now
> 	try a straight push of inbundle
> 	if no new heads:
> 		return
> 	# straight push failed and rolled back
> 	intrepo = VeryLightweightClone(repo, '.hg/integrate')
> 	try:
> 		intrepo.unbundle(inbundle)
> 		if not intrepo.conflictfreemerge():
> 			return failure
> 		repo.pull(intrepo) # should succeed now
> 		clientrepo = BundleRepo(repo, inbundle)
> 		outbundle = intbundle.bundle(everything_not_in=clientrepo)
> 		return outbundle # stream outbundle back to client
> 	finally:
> 		intrepo.delete()
> 
> `hg pushrebase` would be similar, but attempt a conflict-free rebase
> instead of a merge. And the client would strip away the old changesets
> when receiving a return indicating a successful rebase. Of course, the
> use of pushrebase means you should not have shared the changesets
> previously. But even if you did, someone with a stray head due to this
> can simply strip it, or merge it back into the rebased series to make
> the elimination pushable.
> 
> While we don't have the VeryLightweightClone and working-copy-less
> merge/rebase, we might instead use a proper clone in .hg/integrate,
> where we
> 
> 	copy repo's config to intrepo (assuming no relative paths)
> 	intrepo.pull(repo) # bring it up to date
> 	intrepo.update -C tip
> 	lastgoodtip = intrepo.tip
> 	try:
> 		...
> 	except:
> 		intrepo.strip(lastgoodtip+1)
> 
> All this while we're holding the wlock on the main repo, of course.

All that sounds very good.

/Roman

-- 
Dipl.-Inform. (FH) Roman Kennke, Software Engineer, http://kennke.org
aicas Allerton Interworks Computer Automated Systems GmbH
Haid-und-Neu-Straße 18 * D-76131 Karlsruhe * Germany
http://www.aicas.com   * Tel: +49-721-663 968-48
USt-Id: DE216375633, Handelsregister HRB 109481, AG Karlsruhe
Geschäftsführer: Dr. James J. Hunt




More information about the Mercurial mailing list