Disclaimer

The content of this blog is my personal opinion only. Although I am an employee - currently of Nvidia, in the past of other companies such as Iagination Technologies, MIPS, Intellectual Ventures, Intel, AMD, Motorola, and Gould - I reveal this only so that the reader may account for any possible bias I may have towards my employer's products. The statements I make here in no way represent my employer's position, nor am I authorized to speak on behalf of my employer. In fact, this posting may not even represent my personal opinion, since occasionally I play devil's advocate.

See http://docs.google.com/View?id=dcxddbtr_23cg5thdfj for photo credits.

Wednesday, January 18, 2012

VCS thoughts

Some fast, probably cryptic, thoughts after a day merging with a "I wasn't familiar with it originally but I am painfully familiar with it now" VCS tool.


  •  Merges are branches.
    • Mercurial tracks merge workflow in a workspace, assuming that a merge will be a single commit.
    • But today I had a complicated enough merge that I started a named branch off just for it. Accomplished the merge between my tasj branch and the trunk. And then merged back from this "merge branch" to the trunk.
    • Worked fine, but it would have been nice to have some workflow tracking along the branch. Like "hg resolve", but "hg resolve" stops at the first commit boundary.
    • Had to fall back to tracking things by hand, in a text file.


  • Mercurial 's names are awkard
    • "hg revert" isn't revert
      • "hg revert -r REV file" isn't "revert".  It is "include this revision of the file in the candidate commit that you are building in your workspace.
      • hg revert corresponds to cvs update
    • "hg update" isn't update
      • "hg update -r REVorBRABCH" isn't "update". It is "switch the revision or branch that the candidate commit you are building ijn the workspace will be applied to as a child."
      • hg update corresponds to cvs checkout, although cvs is pretty sucky there too.  
      • It's rather like a rebase when you have no revisions checked in yet
    • Mercurial's branchs are not branches.
      • They are floating tags
      • Not necessarily lines of evolution.
      • What would be a better name? "Stream of development?" "Genealogy line"?
      • I'd like to have evolutionary branch0lines, as well as what Mercurial has.

  • Tags should be versioned. 
    • At least Mercurial got that right.
    • But old tag versions should be visible in the log.
    • And it should be possible to refer to an old tag version, something like "last week's official release"

  • Mercurial's anonymous branches rule
    • See, I am not purely dissing hg
    • But "hg tip" has obviously not been brought up0 to date with named branches

  • Can anyone tell me how to do the equivalent of "cvs update -j branch-base -j branch" in Mercurial?
    • Without using an external patch
    • Hint: "hg merge -r branch" doesn't work, if you have anti-patches on the branch

  • I want to be able to "pull onto a branch" or "push a branch".  Not just "push or pull all the branches in the repository".  I.e. I want branch renaming or mapping in pull and push

  • Mercurial doesn't do partial checkouts or checkins?
    • Maybe not everywhere
    • But you can screw yourself up in the same way with "hg ci incomplete list of files"
      • I'm not suggesrting denying hg ci files partial
      • But I'd like to do it in general.

  • Partial checkins and checjkourts should correspond to brancges, with merging actively encouraged.
    • I've talked about this many times.

Enough already.

"system/command" versus "system command"

A lot of tools have a master command with subcommands. For example
hg clone ...
hg merge

cvs co
cvs update

git clomne
...
I think that the first place I encountered this was with mh. Or, since my friend MH says that mh did not have subcommands, I may have made the following change myself for mh. Why subcommands? I think mainly to avoid name collisions in the bin. Years ago, I kluged - I think it may have been the shell, whoever processes PATH - to search not just for "executable" on the PATH, but also "dir/executable". I.e. instead of saying
hg update
I colud have said
hg/update
Not much of a difference. But it makes it easier for guys to code systems that have lots of subcommands. Also, for users of shells like bash and csh: !hg/update works, whereas "!hg update" doesn't (unless your shell has tweaks.

Tuesday, January 17, 2012

Mercurial whine:
hg merge -r tip
is NOT the same as
hg merge -r default
Because Mercurial's tip may be on a branch. tip is just the most recent changeset, anywhere. I have hit bugs caused by following hg recipes that talk about using -r tip. Sigh.

Tentative checkin for branch only, not to be merged?

Here's another: Working on a branch, I just did a pull, and merged from trunk onto the beranch. I notice that somebody else has a minor bug on the trunk: it looks like they forgot to check in a test reference pattern, although it is also possible that the test has been checked in before the golden behavior is established. I report the bug. But I would like to silence the error, at least on my branch. I can make the change to the reference patterns. However, I do not know if that change is goosd. I just want to silence it, or mark it as a known error. I don't want my change to propagate back to the trunk when eventually I merge and push. I.e. my branch now contains some tentative stuff, as well as some stuff that I am confident will soon be merghed. On CVS I would create a per file branch for the reference, and work off a merged directory. Eventually, I would update to the main branch, ahnd not get5 my patched test. Unclear how to do this in Mercurial, apart from remembering that I have to delete it eventually. Oh, here's a way:
// working on branch B
hg pull
hg merge -r tip
make test
// make change to silence test error
hg branch Bb
// somehow copy old version of patched file to pre brahnch
hg ci // on Bb
hg update -r B
// now work
// when ready to merge, do the usual
hg pull
hg merge
make test
// now do the extra step to be confident that you aren't pushing anything broken
hg update -r Bb
hg merge -r B
// now should have B, except for that one change that was tenative
make test
// see if the bug was fixed by someone else...
// ok, now merge to default branch, and then push
// - since I am paranoid, I might pull and test again
hg update -r default
hg merge -r Bb
make test
hg push
Works, but is complicated. I am quite likely to forget that I am supposed to merge from branch B onto Bb before merging to the trunk. {{Category-VCS}}{{Category-hg}}
AFAICT Mercurial only allows you to merge entire changesets.

Here is an example of why I may want to do a merge at lower granularity:

  • I am working on a branch B
  • I do a pull from the parent, hg pull
  • I merge from the parent on to my branch B, because I am not yet ready to merge back onto the trunk (aka default branch)
  • I run my tests
Now I notice that the .hgignore that I got from the parent is missing a file.  I fix it in my repository, to shut it up.

Then I realize that I should push such a generic change back to the trunk asap.

What I want to do is something like"

  hg clone work-repo quick-fix
  cd quick-fix
  hg update -r default
  hg merge -r B  .hgignore     # to merge just the change to .hgignore into the trunk
  make clean;hg purge
  make test
  hg ci
  ...
  hg push
I.e. I want to merge JUST the change to .hgignore, using "hg merge -r B .hgignore". Instead I do
  hg clone work-repo quick-fix
  cd quick-fix
  hg update -r default
  cp ../work-repo/.hgignore .
  make clean;hg purge
  make test
  hg ci
  ...
  hg push
I.e. "cp ../work-repo/.hgignore ." is used instead of "hg merge -r B .hgignore". Although this works, it makes me unhappy. E.g. I may blithely have overwritten other changes, e.g. if I cloned from the master rather than the work-repo. Not to mention the fact that the "hg push" abnove would push my branch. And my teammates do not want my branch to be pushed, because it has too many fine grain checkins - they want just a single checkin message. But that's another story.

Saturday, January 14, 2012


I'd like to have a text parser, like Perl CPAN Text::ParseWords,
that *only* breaks the text into words
- but which does not transform the words, handle escape characters, etc.

For example,
   Text::ParseWords::
      shellwords("a b 'c d' e")
returns
   a
   b
   c d
   e
i.e. it breaks the text up into words,
but it also transforms the words.

I would like to separate the breakup from the transformation:
   a
   b
   'c d'
   e

Note that if you ever encounter such a list whose words can themselves be further broken up,
then you know that it has been parsed by some tool after your original parser.

[[Category:Programming]] [[Categy::Text]]

Sunday, January 08, 2012

Thumb drive as a webserver / NAS

I wish that I could find a flash drive that acted as a NAS.

Most USB flash drives are passive storage. Encryption is done by the OS you plug into.  Since I run Windows and various *IXes, and want to access my data from each, depending on a particular OS is a pain.

Booting an OS from the USB flash drive is better - but still not great, since it makes assumptions about the platform you are plugging in to. Typically, that it is a PC.

Flash drives have non-trivial processors in them.  Probably running Linux.  Why not make them a peer?

Issue: network interface.

I don't really want to add a typical Cat 5 ethernet connector - what is that, RJ45, 8P8C plug? - to the flash drive, neither in addition to nor replacing USB.

Q: I am sure there is a standard for networking over USB - but how ubiquitous is it?  I do not recall ever getting the option, when I plug in a USB flash drive, of connecting a webnrowser to a server running on tghe drive.