Caveat: I know nothing about TortoiseHg and its migrators (as described in the other answer you linked to), but there's a significant difference between the way Mercurial and Git present commits, specifically in terms of how they sort them.
Commit timestamps
... it seems like the problem appears when there is a branch where the parent has an older date than the child (don't ask me how I managed to do that; I have no idea).
It's not as uncommon as one might like.
Aside from the obvious (computer clocks set to the wrong time), there are also time zone issues (commits made in California, where it is three hours earlier than commits made in New York). Not all converters get this right, as it is a difficult problem.
Mercurial tags vs Git tags
Mercurial tags are stored in a file (.hgtags
) which is then stored as a separate commit (with the unfortunate side effect that checking out a tagged version makes the tag itself invisible, since the tag is for the commit that has a .hgtags
that lacks the tag). It looks as though your converter is storing Mercurial tag commits as Git commits: not particularly surprising (it would be easier that way) but not particularly desirable either (a Mercurial tag should probably convert to a Git annotated or lightweight tag, if possible).
Sorting
By default, Mercurial sorts commits by their absolute commit number within the repository. (This is true for hg
commands; whether external programs like TortoiseHg follow along is up to them.) This means the date stamps on commits are completely irrelevant to the presentation order. Mercurial can only do this because every commit within a single repository has a locally-unique index number within that repository, as well as a globally-unique identifier (the SHA-1 hash) that is the same across all clones. (The locally-unique numeric index is not necessarily the same across different clones, even if they contain the same commits, as it depends on the order that those commits entered all the clones. More specifically, two clones start out the same, but then if clone A acquires commit a111111 and a222222 in that order, and clone B acquires them in the order a222222-then-a111111, the index numbers for these two commits will be in the opposite order.)
By default, Git sorts by date, presenting newer commits before older commits. This sort order is modified somewhat when drawing graphs: in this case Git still sorts by date, but adds a topological sort constraint:
--topo-order
Show no parents before all of its children are shown, and avoid showing commits on multiple lines of history intermixed.
For example, in a commit history like this:
---1----2----4----7
\ \
3----5----6----8---
where the numbers denote the order of commit timestamps, git rev-list
and friends with --date-order
show the commits in the timestamp order: 8 7 6 5 4 3 2 1.
With --topo-order
, they would show 8 6 5 3 7 4 2 1 (or 8 7 4 2 6 5
3 1); some older commits are shown before newer ones in order to
avoid showing the commits from two parallel development track mixed
together.
Not all graphing programs use the same constraints: in particular gitk
does its own commit sorting (it silently eats --topo-order
to avoid passing it to git rev-list
).
(A related issue is that Mercurial commits have only a single timestamp, while Git commits have two: the author timestamp and the committer timestamp. Since you are converting in the hg-to-git direction, though, I would assume the git-commit-generator simply sets both time stamps to match the Mercurial time stamp. If not, though, that may affect this as well.)
Back to your conversion issues
I've also found some of the lines go from the bottom of the graph to a merge without any commits on them ...
This is not possible in Git, since a merge can only exist by having at least two parent commit IDs in the merge, and the parent IDs can only be valid if those commit objects exist. Whatever program is drawing the graph is doing so incorrectly (or correctly only if, somehow, you have instructed it not to show those commits).
Is there an explanation to this? An even better, is there any way to avoid it when doing the conversion? Or any way to fix it afterwards?
The above is probably the why; as for how to prevent or alter it, that comes from the why: you would need to fudge the dates somehow, so that they come out in the desired order.