Quick question on Mercurial. Suppose my colleague and I both have an up to date copy of trunk. We both make changes, then we both push/pull the changes from each other.
I am guessing Mercurial keeps the changes in order based on the date of the commit (since there is no increm开发者_运维技巧enting revision, just a GUID). So what happens if my computer's date is one day behind and I commit half a day after my colleague. Would my change show up half a day before my colleague's?
@Martijn has your correct answer, but it doesn't seem to be clicking. If this makes anything clear pick his:
- The commit times on Mercurial changesets have absolutely nothing to do with how they're merged, interleaved, or combined
Mercurial, and other DVCs, do all history tracking based entirely on the DAG (Directed Acyclic Graph), which means:
- the only piece of metadata that matters is the parent or parents of a changeset
Before you commit you can see what the parent of your changeset is going to be by typing hg parents
and once you commit you can see it in the hg log
.
In your examples if you've pulled your colleague's changesets and updated your working directory to reflect them (hg pull ; hg update
) then his or her changeset will be the parent of your changeset. If you haven't pulled/updated to reflect his or her changeset then both of your changesets will have the same parent -- they'll be siblings -- when when they're merged neither will take precedence over the other in any way.
The ordering when you do a hg log
is determined by the order in which the changeset arrived in your local repository, and can differ from repo to repo depending on where they've pulled from first -- that's why you can't use the integer numbers shown next to changesets for cross-repo operations -- only the hash is global.
In short the date is never consulted in normal operations and is purely metadata with no more relevance than the author or commit description.
Indeed, your changesets are timestamped (internally stored as seconds-since-the-UNIX-epoch and a timezone offset), and when displaying changeset, they are ordered by timestamp and your changesets will be displayed in the incorrect place as their timestamps are be incorrect. See https://www.mercurial-scm.org/wiki/ChangeSet
This is not really that much of a problem though; timestamps have no bearing on how your changes are merged with those of your colleague. Only the changeset IDs matter here and when merging a common ancestor is used. It'll follow the graph of your changesets down looking for a changeset ID that your colleague also has and then merges your and his changes from the on forward. See https://www.mercurial-scm.org/wiki/Merge
So, merges are not affected, only the display of changesets, where your changesets will be sorted into the wrong location. It'll confuse you and your colleague, but your changes themselves are safe.
The order of changesets is not affected by the timestamp in the changesets. The order is determined solely by the order in which the changesets were created in your local repository.
Mercurial has an append-only architecture so when you pull from another repository, the changesets you pull in are placed after your own changesets, regardless of the timestamps in the new changesets.
The revision numbers (the local integer counter) is just a counter: each new changeset gets the next available revision number. The simple range operator in Mercurial works directly on revisions numbers, and so X:Y
means "give me changesets with revision numbers from X to Y (inclusive)". This is not so useful when the revision numbers are based only on the order in which changesets were created or pulled into a repository.
Use X::Y
instead, that gives you changesets that are descendants of X and ancestors of Y, i.e., it follows the branches in the history.
精彩评论