Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I relate an existing Mercurial and git repositories using hg-git?

This is a pretty esoteric question, so just to make clear here from the start: I am not talking about converting from svn to git, git to mercurial, or mercurial to git. I am talking about a complex situation that has arisen from taking advantage of "cross-system" plugins that allow Mercurial to interoperate, to some extent, with git and SVN.

For some time I have used the hg-subversion plugin to Mercurial to "track" an upstream SVN repository on code.google.com. Thanks to this plugin, Mercurial considers the repository to be "related" and is able to pull in just changes that have occurred since I last pulled from the repo. This allows me to maintain my own, private Mercurial repository that includes private changesets, branches, tags, etc., but which periodically syncs up and merges with the changes that have been occurring on the upstream SVN repo.

The upstream repo has moved, cleanly, from SVN to git. When I say cleanly, I mean they have taken with them the entire commit tree, or at least the part affecting the default/master branch that I care about.

I am now in a situation where I have a Mercurial repository that is up-to-date merged with the very last checkin on the now-defunct SVN repository, and I want to start pulling in changes from the new upstream git repository, starting at the change that occurred just after the svn repository was moved to github.

I can use the wonderful hg-git plugin to pull changes from this repository, but as the current repository has no notion of being "related" to the git upstream repo, it will pull ALL changes, including all the changes whose mirror-image changesets are already present in my repository.

So what I'm looking for is advice for how I can get my Mercurial repository to consider itself, via hg-git, related to the upstream git repository, and also consider all the appropriate commits from the git repository as "already pulled" for purposes of maintaining changeset parity.

I see that internally hg-git appears to use a file .hg/git-mapfile which I presume maps changesets between the upstream git and the local Mercurial repository. This is probably a clue.

What's the easiest way to get my local Mercurial repository into such a state where it essentially behaves as though it started as a clone of the upstream git repository, but maintains all of my own unrelated changesets that have been added over time?

(Note: I would prefer not to "start over" with a fresh clone, and then applying my private changes, because I want to maintain the historical integrity of this repository for my own build/debugging purposes).

like image 656
danielpunkass Avatar asked Sep 21 '11 14:09

danielpunkass


People also ask

What is hg in Git?

The Hg-Git plugin can convert commits/changesets losslessly from one system to another, so you can push via a Mercurial repository and another Mercurial client can pull it. In theory, the changeset IDs should not change, although this may not hold true for complex histories. Commands.

Can you use Mercurial on GitHub?

The answer is: yes, it can! You will be able to do that by using the Mercurial bookmark, which are the Mercurial counterpart of Git branches and are used as such by the hggit plugin.

Does GitLab work with Mercurial?

There is no current plan to add Mercurial support to GitLab, but we are providing support to the Octobus team where needed as they work on Heptapod.

Is Git better than Mercurial?

Mercurial Is Safer For Less Experienced Users By default, Mercurial doesn't allow you to change history. However, Git allows all involved developers to change the version history. Obviously, this can have disastrous consequences. With basic Mercurial, you can only change your last commit with “hg commit – amend”.


3 Answers

I have done something similar with git before. In the git->git case I was able to do a git-merge --strategy=ours which basically made my current repository believe that everything that was being merged in was a no-op.

What you need to do that is a branch that represents everything upstream that you know is already merged into your tree and then do a no-op style of merge into your tree then start pulling in changes with "real" merges.

From this site:

https://www.mercurial-scm.org/wiki/TipsAndTricks#Keep_.22My.22_or_.22Their.22_files_when_doing_a_merge

I see that a command like the following may be able to help you merge in the upstream repository and ignore everything upstream:

$ hg --config ui.merge=internal:local merge #keep my files

That should allow you to re-sync your downstream with upstream.

like image 70
Ben Goodwyn Avatar answered Oct 08 '22 13:10

Ben Goodwyn


I would clone the new upstream repository with Hg-git, then try to use the Convert extension to splice all the changes in the old local repository into the new one. In fact, I'd probably clone the local Hg-git repository into a native Mercurial repository and use a two-step pull from the upstream Git repository.

like image 29
james woodyatt Avatar answered Oct 08 '22 15:10

james woodyatt


If no existing solution exists, I suppose one could write a script that patches and commits your changes to a new repository that is based on the git-clone instead. You "just" need to correlate the svn versions between hg-git-fromsvn and hg-svn, and replicate the update/patch/commit/merge sequence you've done on a new repo.

A fun project, to whomever does it. :)

like image 27
Macke Avatar answered Oct 08 '22 15:10

Macke