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.
See http://docs.google.com/View?id=dcxddbtr_23cg5thdfj for photo credits.
Saturday, October 13, 2012
Why use blogger rather than Google+?
Waiting at carwash...
Why use blogger rather than Google+?
Mainly, I know how to export data from Blogger. I don't know how to grab all of my posts from Google+. (http://www.dataliberation.org/takeout-products/-1s says "At the moment, this only includes sites that you have +1'd (no posts)").
I.e. for some things exportability trumps convenience and access control.
Perhaps in 100 years we will have ubiquitous access control, exportability, etc. And then the differences between wikis and blogs and ... whatever Google+ is, a stream of comments ... will be just user interface and how the information is structured.
I'd like a world where the blog/wiki/stream boundaries are blurred. But I don't need.
Higher priority: it sucks that issues for things that should be ubiquitously available, like access control and exportability, are often the criteria for choosing which tools to use. I wonder how many good UI ideas are dying because they don't do the other stuff right? Certainly, the big reason why I use so many Google tools is that they at least show signs of doing the "utilities".
Why use blogger rather than Google+?
Mainly, I know how to export data from Blogger. I don't know how to grab all of my posts from Google+. (http://www.dataliberation.org/takeout-products/-1s says "At the moment, this only includes sites that you have +1'd (no posts)").
I.e. for some things exportability trumps convenience and access control.
Perhaps in 100 years we will have ubiquitous access control, exportability, etc. And then the differences between wikis and blogs and ... whatever Google+ is, a stream of comments ... will be just user interface and how the information is structured.
I'd like a world where the blog/wiki/stream boundaries are blurred. But I don't need.
Higher priority: it sucks that issues for things that should be ubiquitously available, like access control and exportability, are often the criteria for choosing which tools to use. I wonder how many good UI ideas are dying because they don't do the other stuff right? Certainly, the big reason why I use so many Google tools is that they at least show signs of doing the "utilities".
Friday, October 12, 2012
Rewriting history can be good (esp checkin messages)
It can be good to be able to rewrite history.
Or at least checkin messages - or, rather the text associated with a version.
Checkin messages are really what was entered at checkin time. But if these are rewritten, may warrant a different name.
Writing good checkin messages can be hard. Sometimes I hesitate to merge my changes because it will take too much time to write a good message - especially given our local rule of having a branch merge summarize all changes on the branch. But slow to integrate is bad. Or I write a sub-par checkin message. But that is also bad.
Better to merge, integrate asap, with whatever you can say at that time. And, if necessary, go back and rewrite the messages to improve them.
It's like refactoring.
Or at least checkin messages - or, rather the text associated with a version.
Checkin messages are really what was entered at checkin time. But if these are rewritten, may warrant a different name.
Writing good checkin messages can be hard. Sometimes I hesitate to merge my changes because it will take too much time to write a good message - especially given our local rule of having a branch merge summarize all changes on the branch. But slow to integrate is bad. Or I write a sub-par checkin message. But that is also bad.
Better to merge, integrate asap, with whatever you can say at that time. And, if necessary, go back and rewrite the messages to improve them.
It's like refactoring.
LOD branches (Lines of Development)
Not sure if this is a Glewism, although Brad Appleton's book undoubtedly similar.
A LOD branch is not like a task branch. A task brach ideally exists only briefly.
A LOD branch is long lived. It may be periodically synchronized with other OD branches, and/or the mainline of development. Bidirectionally synchronized - changes may be pushed and pulled.
For long periods of time a LOD branch may be collapsed - basically part of the main line of development. But it may be revived as a separate LOD branch.
Examples of LOD branches:
* branches for different platforms, where there is not a single source tree with ifdeffing or other conditionals
* maintenance branches for old major releases
* branches where you are working on a new experimental feature or system
A LOD branch is not like a task branch. A task brach ideally exists only briefly.
A LOD branch is long lived. It may be periodically synchronized with other OD branches, and/or the mainline of development. Bidirectionally synchronized - changes may be pushed and pulled.
For long periods of time a LOD branch may be collapsed - basically part of the main line of development. But it may be revived as a separate LOD branch.
Examples of LOD branches:
* branches for different platforms, where there is not a single source tree with ifdeffing or other conditionals
* maintenance branches for old major releases
* branches where you are working on a new experimental feature or system
Closing and merging branches
I like developing on branches. Task branches usually, short and sweet, merged back into the parent main line of development as soon as possible. Sometimes longer lived "line of development" branches, merging to and from the mainline. Named branches if I have had foresight, although Mercurial's anonymous branches are not so bad, although they can be misleading. (Wanted: retroactive renaming of branches.)
Just now closing a doubly nested task branch, merging into its parent line of development branch, and merging that into the default trunk.
Straightforward. But annoying in that I have to run tests at each stage of the merge. (Actually, I feel that I should run such tests - the project is not so well disciplined.) Plus check in three times: once for the last change in the task branch, once in the LOD branch, and once in the default trunk. With three separate checkin messages.
Some of this testing is unnecessary. E.g.
hg update -r LOD
// close and merge task branch into LOD branch
hg merge -r task-branch
make -j test
hg merge -r default
// LOD changes, but no changes wrt default. i.e. no LOD changes during task branch life.
make -j test <--- unnecessary, because tested on task branch
hg ci -m 'merged task branch'
// merge from mainline before pushing back
hg merge -r default
// no changes.
make -j test <--- unnecessary
hg ci 'updated LOD branch from default trunk main line of development'
// merge back into trunk
hg update -r default
hg merge -r LOD
// many changes wret default, but no changes wrt LOD
make -j test <--- unnecessary, since file contents same as LOD
hg ci 'updated default trunk main line of development from LOD branch ... need more description'
i.e. it is good to know when there have been no changes in the actual file contents wrt one of the parents.
unnecessary tests could be eliminated.
(unless, of course, the tests do stuff specific to whatever branch the workspace is on. Which we actually have a minor example of. :-( )
---
similarly for checkin messages:
we have the convention of having branch merge messages summarize everything done on the branch.
So above I end up writing almost the same checkin message twice. Which is more hassle than it sounds.
Just now closing a doubly nested task branch, merging into its parent line of development branch, and merging that into the default trunk.
Straightforward. But annoying in that I have to run tests at each stage of the merge. (Actually, I feel that I should run such tests - the project is not so well disciplined.) Plus check in three times: once for the last change in the task branch, once in the LOD branch, and once in the default trunk. With three separate checkin messages.
Some of this testing is unnecessary. E.g.
hg update -r LOD
// close and merge task branch into LOD branch
hg merge -r task-branch
make -j test
hg merge -r default
// LOD changes, but no changes wrt default. i.e. no LOD changes during task branch life.
make -j test <--- unnecessary, because tested on task branch
hg ci -m 'merged task branch'
// merge from mainline before pushing back
hg merge -r default
// no changes.
make -j test <--- unnecessary
hg ci 'updated LOD branch from default trunk main line of development'
// merge back into trunk
hg update -r default
hg merge -r LOD
// many changes wret default, but no changes wrt LOD
make -j test <--- unnecessary, since file contents same as LOD
hg ci 'updated default trunk main line of development from LOD branch ... need more description'
i.e. it is good to know when there have been no changes in the actual file contents wrt one of the parents.
unnecessary tests could be eliminated.
(unless, of course, the tests do stuff specific to whatever branch the workspace is on. Which we actually have a minor example of. :-( )
---
similarly for checkin messages:
we have the convention of having branch merge messages summarize everything done on the branch.
So above I end up writing almost the same checkin message twice. Which is more hassle than it sounds.
Thursday, October 11, 2012
emacs comes up with all characters boxes
This blog item not really a publication, just to record a stupid thing. This blog is the easiest place I know to record little workarounds, etc. It's indexed. Plus, no harm in others seeing. And occasionally they tell me better ways to do things.
Recently have been plagued by emacs come up in VNC with all characters looking like boxes.
This requires xfs, the X Font Server, to be reset.
Error Messages in the VNC Logfiles
Last time I went looking for log messages:
_XSERVTransmkdir: Owner of
/tmp/.X11-unix should be set to root
Xvnc Free Edition 4.1.2
Copyright (C) 2002-2005
RealVNC Ltd.
See http://www.realvnc.com for information on
VNC.
Underlying X server release
70101000, The X.Org Foundation
Tue Jan 3 10:29:51 2012
vncext:
VNC extension running!
vncext:
Listening for VNC connections on port 5904
vncext:
Listening for HTTP connections on port 5804
vncext:
created VNC server for screen 0
Could not init font path
element unix/:7100, removing from list!
Warning: Cannot convert
string "nil2" to type FontStruct
Tue Jan 3 10:30:13 2012
Connections: accepted:
192.168.4.92::59724
SConnection: Client needs
protocol version 3.8
SConnection: Client requests
security type VncAuth(2)
Tue Jan 3 10:30:19 2012
VNCSConnST: Server
default pixel format depth 16 (16bpp) little-endian rgb565
VNCSConnST: Client
pixel format depth 8 (8bpp) rgb max 3,3,3 shift 4,2,0
Tue Jan 3 10:30:20 2012
VNCSConnST: Client
pixel format depth 16 (16bpp) little-endian rgb565
Related errors: missing lucida, courier, etc. fonts.
How to reset XFS
From IT (months ago)
for future reference,
if it happens again, check your vnc log (should be something like ~/.vnc/mipscs587:1.log)
for an error like:
Could not init font path element unix/:7100, removing from list!
if you see this, you need to run, as root:
/etc/init.d/xfs restart
then restart your vncserver session
Could not init font path element unix/:7100, removing from list!
if you see this, you need to run, as root:
/etc/init.d/xfs restart
then restart your vncserver session
Rewriting history makes you look good
One thing I dislike about rewriting history in version control systems: it makes you look smarter than you are.
Let's imagine that you are developing a feature F. So, starting from the trunk, you do it on a branch
trunk -> F1 -> F2 -> ...
Then you realize there is a bug in the trunk is something you depend on. You fix that, but still on your branch
trunk -> F1 -> F2 -> bugfix_in_F
You want to put that bugfix onto the trunk as soon as possible, so you apply t to the trunk. Now we really have a branch:
trunk ---------------------------------> bugfix
\ /
+->F1 -> F2 -> bugfix_in_F ->+
Now, it looks like you were smarter than you actually were: the bugfix happened out of the blue.
Worse... working with a group like my present project that is not test-driven, you may not have a failing test for the bugfix. Or, the failing test for the bugfix may only be integrated when you get the feature.
Sure, don't do that. I wish my project was test driven. But ...
Must rewrite Michael Feathers' Legacy Code book.
Let's imagine that you are developing a feature F. So, starting from the trunk, you do it on a branch
trunk -> F1 -> F2 -> ...
Then you realize there is a bug in the trunk is something you depend on. You fix that, but still on your branch
trunk -> F1 -> F2 -> bugfix_in_F
You want to put that bugfix onto the trunk as soon as possible, so you apply t to the trunk. Now we really have a branch:
trunk ---------------------------------> bugfix
\ /
+->F1 -> F2 -> bugfix_in_F ->+
then eventually you merge the feature
trunk ---------------------------------> bugfix -----> F
\ / /
+->F1 -> F2 -> bugfix_in_F ------> F3 -> F4
\ / /
+->F1 -> F2 -> bugfix_in_F ------> F3 -> F4
on the trunk the bugfix and the feature appear out of order - at least, out of historical order. But at least you can see the way things were really done.
(Of course, Mercurial doesn't really support moving a bugfix like this from a branch to the trunk. It's a partial merge. Hint: don't use hg merge - that's a full merge - you'll get the feature F1 and F2 as well as the bugfix. And if you undo that stuff before checking in the isolated bugfix, mercural will remember that, and make it hard to merge the feature later.
If you are lucky, the partial merge is at file granularity. You can do
hg update -r default; hg revert -r FeatureBranch file-that-was-bugfixed.cpp; test ...
If less lucky, merge by hand, cherrypick, edit patch files. ...
Or just redo.
)
But apart from Mercurial's not supporting partial merges,
what I really dislike is stripping the branch away from the history,
leaving
trunk ---------------------------------> bugfix -----> F
Now, it looks like you were smarter than you actually were: the bugfix happened out of the blue.
Worse... working with a group like my present project that is not test-driven, you may not have a failing test for the bugfix. Or, the failing test for the bugfix may only be integrated when you get the feature.
Sure, don't do that. I wish my project was test driven. But ...
Must rewrite Michael Feathers' Legacy Code book.
Subscribe to:
Posts (Atom)