From cd742bee401b7f1282bd47f0f69e7c20032c483c Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Sat, 9 Jul 2016 14:55:18 +0200 Subject: [PATCH] doc: extend manpage with config settings and some technical background --- doc/git-remote-hg.txt | 57 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/doc/git-remote-hg.txt b/doc/git-remote-hg.txt index 0cceb76..a485919 100644 --- a/doc/git-remote-hg.txt +++ b/doc/git-remote-hg.txt @@ -58,6 +58,25 @@ If you want 'git-remote-hg' to be compatible with 'hg-git', and generate exactly % git config --global remote-hg.hg-git-compat true -------------------------------------- +If you would like (why?) the old behaviour (export capability) +where various limitations apply: + +-------------------------------------- +% git config --global remote-hg.capability-push false +-------------------------------------- + +In the new behaviour, performing a git push will make git search for and detect +file rename and copy and turn this into Mercurial commit metadata. To tweak how this +detection happens, e.g. have it search even more: + +-------------------------------------- +% git config --global remote-hg.fast-export-options '-M -C -C' +-------------------------------------- + +The default otherwise is simply `-M -C`. See also e.g. +https://www.kernel.org/pub/software/scm/git/docs/git-log.html[git-log(1) manpage] +for more details on the options used to tweak this. + NOTES ----- @@ -119,3 +138,41 @@ would only see the latest head. Closed branches are not supported; they are not shown and you can't close or reopen. Additionally in certain rare situations a synchronization issue can occur (https://github.com/felipec/git/issues/65[Bug #65]). + +TECHNICAL DISCUSSION +-------------------- + +As `git-remote-hg` is a developer tool after all, it might be interesting to know a +bit about what is going on behind the scenes, without necessarily going into all the +details. + +So let's first have a look in the `.git/hg` directory, which typically +contains a subdirectory for each remote Mercurial repo alias, as well as a `.hg` +subdirectory. If the Mercurial repo is a local one, it will (again typically) +only contain a `marks-git` and a `marks-hg` file. If the repo is a remote one, +then the `clone` contains, well, a local clone of the remote. However, all +these clones share storage through the `.hg` directory mentioned previously (so +they do not add up separately). During a fetch/push, the local (proxy) repo is +used as an intermediate stage. If you would also prefer such an intermediate +stage for local repos, then setting the environment variable +`GIT_REMOTE_HG_TEST_REMOTE` will also use a proxy repo clone for a local repo. + +As for the marks files, `marks-git` is created and used by `git-fast-export` +and `git-fast-import` and contains a mapping from mark to commit hash, where a +mark is essentially a plain number. `marks-hg` similarly contains a (JSON) based +mapping between such mark and hg revision hash. Together they provide for a +(consistent) view of the synchronization state of things. + +Upon a fetch, the helper uses the `marks-hg` file to decide what is already present +and what not. The required parts are then retrieved from Mercurial and turned +into a `git-fast-import` stream as expected by `import` capability of +https://www.kernel.org/pub/software/scm/git/docs/gitremote-helpers.html[gitremote-helpers(1)]. + +Upon a push, the helper has specified the `push` capability in the new approach, and +so git will provide a list of refspecs indicating what should go where. +If the refspecs indicates a remote delete, it is performed appropriately the Mercurial way. +If it is a regular push, then git-fast-export is invoked (using the existing `marks-git`) +and the stream is processed and turned into Mercurial commits (along with bookmarks, etc). +If the refspec specifies a `src:dest` rename, then the requested remote refname is tracked +accordingly. If a dry-run is requested, no remote is touched and no (marks) state of +the run is retained.