Annotation of wikisrc/users/dholland/hgnb.mdwn, revision 1.1

1.1     ! dholland    1: ## Mercurial usage for NetBSD
        !             2: (hypothetically assuming the repositories have been converted)
        !             3: 
        !             4: Here are some directions for how one would use Mercurial after a
        !             5: NetBSD transition from CVS to Mercurial.
        !             6: Most of this is pretty trivial (especially for anyone who's used
        !             7: Mercurial before...)
        !             8: 
        !             9: There is a lot of FUD circulating about using a distributed version
        !            10: control system, what with talk of "workflows" and "topic branches" and
        !            11: other unfamiliar terms.
        !            12: Most of this arises from git user communities and git advocates;
        !            13: because git is screwy, using git is more complicated than using other
        !            14: better designed tools.
        !            15: Also, those suffering from Stockholm syndrome with respect to git tend
        !            16: to believe that the complexities of git are inherent to distributed
        !            17: version control, which is not the case; and many other people have been
        !            18: alarmed (or scared, or confused) by things such people have told them.
        !            19: 
        !            20: ### Basic usage
        !            21: 
        !            22: First, NetBSD will go on using a central master repository. There is
        !            23: nothing to be gained by changing this; we have the project
        !            24: infrastructure to support it, and ultimately there has to be some tree
        !            25: somewhere that constitutes the master copy regardless.
        !            26: 
        !            27: Therefore, the basic usage is almost entirely unchanged:
        !            28: 
        !            29:        CVS                     Mercurial
        !            30: 
        !            31:        cvs checkout            hg clone
        !            32:        cvs update -dP          hg pull && hg update
        !            33:        cvs -n update           hg status
        !            34:        cvs log file            hg log file  [or just hg log]
        !            35:        cvs update -p file      hg cat file
        !            36:        cvs annotate            hg annotate
        !            37:        cvs diff -u             hg diff
        !            38:        cvs add                 hg add
        !            39:        cvs rm                  hg rm
        !            40:        [no can do]             hg cp
        !            41:        [no can do]             hg mv
        !            42:        cvs commit              hg commit && hg push
        !            43:        cvs tag                 hg tag
        !            44: 
        !            45: You will notice that CVS's update and commit have been divided into
        !            46: two now-separable actions: in Mercurial, pull fetches changes from a
        !            47: remote repository but doesn't affect your working tree, and update
        !            48: updates your working tree to (by default) the latest new changes.
        !            49: Similarly, commit integrates changes from your working tree, but
        !            50: locally only; push publishes those changes to the remote repository.
        !            51: 
        !            52: This means that you can commit many times before pushing; this is
        !            53: often desirable if you're working on something nontrivial and you want
        !            54: to wait until it's ready before shipping it out.
        !            55: 
        !            56: There is one catch, which is that other people can commit (and push to
        !            57: the master repository) while you're working. You can mostly avoid
        !            58: this, if you haven't committed anything locally yet, by doing "hg pull
        !            59: && hg update" before committing, which will merge into your
        !            60: uncommitted changes and works exactly like updating before committing
        !            61: in CVS. However, if you've committed a number of changes, or someone
        !            62: got a new change in right between when you last pulled and when you
        !            63: committed, you need to do an explicit merge instead, and then you can
        !            64: push.
        !            65: 
        !            66: In the simple case, you do an explicit merge as follows:
        !            67:                                hg pull
        !            68:                                hg merge
        !            69:                                hg commit
        !            70: 
        !            71: When you get a merge conflict, you first need to resolve it (in the
        !            72: usual way by editing) and then you must tag it resolved in hg before
        !            73: hg will let you commit, like this:
        !            74:                                hg resolve -m file
        !            75: 
        !            76: You can list unresolved conflicts thus:
        !            77:                                hg resolve -l
        !            78: 
        !            79: Note that even with the explicit merge this is almost exactly
        !            80: equivalent to the CVS behavior when someone commits ahead of you.
        !            81: The chief difference is that because Mercurial does whole-tree
        !            82: commits, *any* change ahead of you needs to be merged, not just one
        !            83: that touches the same files you've edited.
        !            84: 
        !            85: There is one gotcha, which is that you can't do explicit merges in a
        !            86: tree with uncommitted changes. The best way around this is to stash
        !            87: your changes:
        !            88:                                hg stash
        !            89:                                hg merge
        !            90:                                ...whatever merge stuff...
        !            91:                                hg unstash
        !            92: 
        !            93: You can also do the merge in another tree; because Mercurial is a
        !            94: distributed tool, you can create a temporary copy of your tree, or
        !            95: push the changes you need to another tree you already have, do the
        !            96: work there, and push the results back. Let's suppose you have two
        !            97: trees, "src" and "scratch", where you never keep uncommitted changes
        !            98: in "scratch" so it can be used for this kind of thing. Then you can do
        !            99: the following (starting at the top of src):
        !           100: 
        !           101:                                hg push ../scratch
        !           102:                                cd ../scratch
        !           103:                                hg update
        !           104:                                hg merge
        !           105:                                ...whatever merge stuff, including commit...
        !           106:                                cd ../src
        !           107:                                hg pull ../scratch
        !           108:                                hg update
        !           109: 
        !           110: ### Disconnected operation
        !           111: 
        !           112: Mercurial is a distributed system, and works by cloning the entire
        !           113: history into each tree you create.
        !           114: This has its downsides; but it means that you get disconnected
        !           115: operation for free.
        !           116: The only operations that need to contact the master repository are
        !           117: push, pull, incoming, and outgoing.
        !           118: 
        !           119: ### Some other bits
        !           120: 
        !           121: A commit with no descendents (that is, the most recent commit on any
        !           122: line of development) is called a "head".
        !           123: You can list these as follows:
        !           124:                                hg heads
        !           125: 
        !           126: This will include commits that have descendents only on other
        !           127: branches, e.g. the last commit on a development branch that's been
        !           128: merged but not closed. Use "-t" ("topological heads") to hide these.
        !           129: 
        !           130: You can see what "hg pull" and "hg push" are going to do via "hg
        !           131: incoming" and "hg outgoing" respectively.
        !           132: (FWIW, git can't do this.)
        !           133: 
        !           134: If you interrupt Mercurial (or Mercurial gets interrupted, e.g. by a
        !           135: system crash) you want to do this afterwards:
        !           136:                                hg recover
        !           137: 
        !           138: and if you have reason to think the repository might be corrupt you
        !           139: can check it like this:
        !           140:                                hg verify
        !           141: 
        !           142: ### Development branches
        !           143: 
        !           144: A development branch is one where you're working on some new feature
        !           145: and you expect to merge the branch into the trunk later.
        !           146: Unlike in CVS, this is very cheap in Mercurial.
        !           147: The following are the operations you need, using "libc13" as an
        !           148: example branch name.
        !           149: 
        !           150: Note that even if you're working on something nontrivial that will
        !           151: take a number of commits, if you aren't intending to push the changes
        !           152: out before they're done you don't need to make a branch and there's
        !           153: nothing gained by doing so.
        !           154: However, if you expect to be working over a long period of time on a
        !           155: major effort (such as the mythical libc version bump), and/or you
        !           156: want or expect other developers to contribute or at least test your
        !           157: changes before they're done, go ahead and create a branch.
        !           158: 
        !           159: Create a new branch:
        !           160: 
        !           161:        cvs update -dP          hg pull && hg update    (if needed)
        !           162:        update doc/BRANCHES     update doc/BRANCHES     (if appropriate)
        !           163:        cvs commit doc/BRANCHES hg commit doc/BRANCHES  (if needed)
        !           164:        cvs tag libc13-base     hg tag libc13-base
        !           165:        cvs ph'tagn             hg branch libc13
        !           166:        [make first change]     [make first change]
        !           167:        cvs commit              hg commit
        !           168:                                hg push
        !           169: 
        !           170: Mercurial warns you that branches are permanent and expensive; this
        !           171: warning is aimed at git users who ought to be creating bookmarks
        !           172: instead and not something you need to be concerned about.
        !           173: 
        !           174: Check out a new tree on a branch:
        !           175:        cvs co -P -rlibc13      hg clone [url]
        !           176:                                cd src
        !           177:                                hg update -r libc13
        !           178: 
        !           179: Switch to a new tree on a branch:
        !           180:        cvs up -dP -A -rlibc13  hg pull                 (if needed)
        !           181:                                hg update -r libc13
        !           182: 
        !           183: Note that if you have uncommitted changes, Mercurial will balk at
        !           184: crossing from one branch to another because it doesn't know how to
        !           185: merge them.
        !           186: In that case do this:
        !           187:                                hg update -r libc13-base
        !           188:                                [resolve conflicts if needed]
        !           189:                                hg update -r libc13
        !           190:                                [resolve conflicts if needed]
        !           191: 
        !           192: Check which branch you're currently on:
        !           193: 
        !           194:        cat CVS/Tag             hg branch
        !           195: 
        !           196: See list of branches:
        !           197:        [no can do reliably]    hg branches     
        !           198: 
        !           199: Note that unlike with CVS there's no version-control-related reason to
        !           200: get a new tree just to work on a branch.
        !           201: (Although of course it's still possible to commit to the wrong branch
        !           202: by accident.)
        !           203: Get a new tree if and only if you want to have a different tree for
        !           204: administrative reasons.
        !           205: 
        !           206: Sync your branch with the trunk ("HEAD" in CVS):
        !           207: 
        !           208:        cvs ph'tagn             hg merge default
        !           209:        [resolve conflicts]     [resolve conflicts]
        !           210:        cvs commit              hg commit
        !           211:                                hg push
        !           212: 
        !           213: When you're done with your branch, in Mercurial you can "close" it so
        !           214: it's no longer active.
        !           215: This causes it to disappear from some reports, reduces some internal
        !           216: management overheads, and prevents accidental commits on it.
        !           217: 
        !           218:        [no can do]             hg commit --close-branch
        !           219: 
        !           220: Don't forget to update doc/BRANCHES too.
        !           221: 
        !           222: ### Vendor branches
        !           223: 
        !           224: A vendor branch is one where code from a third party is committed in
        !           225: unmodified state, so it can be updated easily from upstream later.
        !           226: 
        !           227: Note that in CVS vendor branches are magic (in a bad way); in
        !           228: Mercurial we'll just use an ordinary branch. We'll start it from the
        !           229: empty revision so it doesn't contain any unwanted rubbish.
        !           230: 
        !           231: To start a new vendor branch for the upstream package "frobozz",
        !           232: assuming you've already written frobozz2netbsd if one's needed:
        !           233: 
        !           234:        mkdir tmp
        !           235:        cd tmp
        !           236:                                hg update -r0000
        !           237:                                mkdir external && cd external
        !           238:                                mkdir bsd && cd bsd
        !           239:                                mkdir frobozz && cd frobozz
        !           240:        tar -xvzf \             tar -xvzf \
        !           241:          frobozz-1.0.tgz         frobozz-1.0.tgz
        !           242:        mv frobozz-1.0 dist     mv frobozz-1.0 dist
        !           243:        cp .../frobozz2netbsd . cp .../frobozz2netbsd .
        !           244:        ./frobozz2netbsd        ./frobozz2netbsd        (if needed)
        !           245:        cvs import \
        !           246:          src/distrib/bsd/frobozz \
        !           247:          FROBOZZ frobozz-1-0
        !           248:                                hg add
        !           249:                                hg branch FROBOZZ
        !           250:                                hg commit
        !           251:                                hg tag frobozz-1-0
        !           252:        cd ../src
        !           253:        cvs update -dP
        !           254:                                hg update -r default
        !           255:                                hg merge FROBOZZ
        !           256:                                hg commit
        !           257:        [hack as needed]        [hack as needed]
        !           258:        cvs commit              hg commit
        !           259:                                hg push
        !           260:        cd ..
        !           261:        rm -r tmp
        !           262: 
        !           263: Note that in both cases this imports frobozz2netbsd on the branch;
        !           264: this seems the most convenient but I'm not sure if it's been our
        !           265: standard procedure.
        !           266: 
        !           267: To update "frobozz" to 1.1:
        !           268: 
        !           269:        mkdir tmp
        !           270:        cd tmp
        !           271:                                hg update -rFROBOZZ
        !           272:                                cd external/bsd/frobozz
        !           273:        tar -xvzf \             tar -xvzf \
        !           274:          frobozz-1.1.tgz         frobozz-1.1.tgz
        !           275:                                rm -r dist
        !           276:        mv frobozz-1.1 dist     mv frobozz-1.1 dist
        !           277:        ./frobozz2netbsd        ./frobozz2netbsd
        !           278:        cvs import \
        !           279:          src/distrib/bsd/frobozz \
        !           280:          FROBOZZ frobozz-1-0
        !           281:                                hg addremove
        !           282:                                hg commit
        !           283:                                hg tag frobozz-1-1
        !           284:        cd ..
        !           285:        mkdir tmp2 && cd tmp2
        !           286:        cvs ph'tagn
        !           287:                                hg update -r default
        !           288:                                hg merge FROBOZZ
        !           289:        [resolve conflicts]     [resolve conflicts]
        !           290:        cvs commit              hg commit
        !           291:        cd ../src
        !           292:        cvs update -dP
        !           293:        [hack as needed]        [hack as needed]
        !           294:        cvs commit              hg commit
        !           295:                                hg push
        !           296:        cd ..
        !           297:        rm -r tmp tmp2
        !           298: 
        !           299: ### Release branches
        !           300: 
        !           301: A release branch is one that diverges from the main branch and is not
        !           302: expected to be merged back into it.
        !           303: However, changes from the main branch are (individually) merged into
        !           304: it after review.
        !           305: 
        !           306: Creating a release branch in Mercurial is the same as creating a
        !           307: feature branch; see above.
        !           308: So is checking it out.
        !           309: Committing a change to a release branch is no different from
        !           310: committing to the default branch or any other branch.
        !           311: 
        !           312: TODO: we should probably use the Mercurial cherrypick extension for at
        !           313: least some release branch pullups; I don't know how to do that offhand
        !           314: without looking it up.
        !           315: 
        !           316: Tagging a release:
        !           317: 
        !           318:        cvs rtag -r netbsd-7 \  hg tag -r netbsd-7 \
        !           319:          netbsd-7-0-RELEASE      netbsd-7-0-RELEASE
        !           320: 
        !           321: Viewing the changes on a branch:
        !           322: 
        !           323:        cvs log > file          hg log -b netbsd-7
        !           324:        [page through & curse]
        !           325: 
        !           326: Extracting tarballs:
        !           327: 
        !           328:                                cd src
        !           329:        hg export -r \          hg archive -r \
        !           330:          netbsd-7-0-RELEASE \    netbsd-7-0-RELEASE \
        !           331:          src                     .../netbsd-7.0.tar.gz
        !           332:        mv src netbsd-7.0
        !           333:        tar -cvzf \
        !           334:          netbsd-7.0.tar.gz \
        !           335:          netbsd-7.0
        !           336: 
        !           337: ### Reverting a bad commit
        !           338: 
        !           339: Sometimes somebody commits something that needs to be unwound later.
        !           340: In CVS you have to track down each per-file change and undo each one
        !           341: separately, then commit them all.
        !           342: In Mercurial, because Mercurial has whole-tree commits, you can do it
        !           343: with a single command.
        !           344: 
        !           345:        cvs update -j1.6 -j1.5 foo.c
        !           346:        cvs update -j1.9 -j1.8 bar.c
        !           347:        cvs update -j1.15 -j1.14 baz.c
        !           348:                                hg backout -r 101abcde
        !           349:        [resolve conflicts]     [resolve conflicts]
        !           350:        cvs commit              hg commit
        !           351:                                hg push
        !           352: 
        !           353: Note that apparently if you use hg backout to back out the most recent
        !           354: commit, it auto-commits.
        !           355: (This seems to me like a UI bug.)
        !           356: 
        !           357: ### Carrying local changes
        !           358: 
        !           359: In CVS you can keep uncommitted changes in your tree indefinitely with
        !           360: no ill effects.
        !           361: (Or at least, no ill effects until you want to commit other changes to
        !           362: the same files, run into merge conflicts, or hit PR 42961.)
        !           363: 
        !           364: In Mercurial having uncommitted changes keeps you from doing explicit
        !           365: merges, which you need to do much more often than in CVS.
        !           366: There are several ways around this:
        !           367: 
        !           368: * You can stash your uncommitted changes any time you need to merge.
        !           369: This works fine but it quickly becomes a nuisance.
        !           370: * You can use different trees for hacking and for building the system
        !           371: for install, since presumably you only need the local changes in
        !           372: the latter case.
        !           373: This works fine until you need to shift partially-completed hacking to
        !           374: the installable tree, and then becomes painful.
        !           375: * You can commit your local changes as "secret" using the evolve
        !           376: extension (I recommend reading the docs for the evolve extension);
        !           377: then they're committed and can be merged and so on, but won't get
        !           378: pushed back to the master repository.
        !           379: The downside of this is that you can't readily distribute your local
        !           380: changes among your own repositories.
        !           381: * You can use the mq patch queue extension and store your local
        !           382: changes as patches against the tree; then they can be popped off
        !           383: easily for other work.
        !           384: The downside of this is that merging stuff into your local changes
        !           385: becomes awkward.
        !           386: * You can finish your local changes so they can be committed upstream :-)
        !           387: 
        !           388: None of these solutions is perfect, but one or the other of these
        !           389: approaches is probably good enough in most cases.
        !           390: 
        !           391: ### Reverting stuff locally
        !           392: 
        !           393: In CVS you can use "cvs update" to pin a subtree down to a specific
        !           394: point in history, where it will stay while you update the rest of the
        !           395: tree around it.
        !           396: (Accidental engagement of this feature is probably as common as
        !           397: intentional use...)
        !           398: 
        !           399: There is no direct equivalent in Mercurial.
        !           400: However, you can easily alter a file or subtree to roll it back to a
        !           401: specific point in history, and then carry the resulting diff as a
        !           402: local modification until whatever issue prompted you to do this gets
        !           403: sorted out.
        !           404: 
        !           405: To revert to a specific version:
        !           406:                                hg revert -r rev subtree
        !           407: To revert to a specific date:
        !           408:                                hg revert -d date subtree
        !           409: 
        !           410: 
        !           411: ### Other stuff
        !           412: 
        !           413: Have I forgotten anything?
        !           414: Email me questions...

CVSweb for NetBSD wikisrc <wikimaster@NetBSD.org> software: FreeBSD-CVSweb