Many people - e.g. the people who want me to edit version control history - really want a status, rather than a log.
A log tends to record diffs. Deltas. Changes, What I did or am doing.
A log message for a version control system tends to describe what has changed between this and the last.
Note that a version control log is less complete than a human log. A human log may describe what you tried, but which failed, and which you did not commit. Sometimes I think it is as important to record that, as it is to record what worked well enough to release.
Oftentimes what people really want is a status. "Here's the state of the project - this works, this does not".
Note that in a human log, sometimes you may step back and write a status.
Tools like hg bisect really want a status. E.h. hg bisect only wants to attempt to test on versions that are known good - good enough to have run some sort of test in the past.
Statuses change. "Passes all tests" may become false, if more tests are added.
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.
Sunday, June 03, 2012
Logs
I like keeping a manual log (journal or diary) as I go.
Logs want to be a meta-file concept.
E.g. I only want to edit and view one log. I want to be able to track all of my work in a single place.
But, I also want to associate subsets of my overall log with particular projects.
E.g. I want to view log entries related to a project under ~/work/project/LOG. But I want to view these, and all others, under ~/LOG.
Editing this in ordinary files sucks. If I place it in a subdir/LOG I can't see it in ~/LOG, etc.
Suboptimal interactions with version control. I want version control for logs, but... Even if I am just working in projectdir/, editing projectdir/LOG, if I go off on a branch, edit projectdir/LOG, and switch back, I lose the log. The log wants to transcend branches.
I have occasionally tried to work around this by placing all of my log in the ciommit log. But that's not all that great an idea.
I wahnt as much automated log support, support for tracking personal history, as possible.
E.g. record the fact that I sent an email.
Automatically copy version control commit messages into my overall log. But, of course, make everything filterable/foldable.
Logs want to be a meta-file concept.
E.g. I only want to edit and view one log. I want to be able to track all of my work in a single place.
But, I also want to associate subsets of my overall log with particular projects.
E.g. I want to view log entries related to a project under ~/work/project/LOG. But I want to view these, and all others, under ~/LOG.
Editing this in ordinary files sucks. If I place it in a subdir/LOG I can't see it in ~/LOG, etc.
Suboptimal interactions with version control. I want version control for logs, but... Even if I am just working in projectdir/, editing projectdir/LOG, if I go off on a branch, edit projectdir/LOG, and switch back, I lose the log. The log wants to transcend branches.
I have occasionally tried to work around this by placing all of my log in the ciommit log. But that's not all that great an idea.
I wahnt as much automated log support, support for tracking personal history, as possible.
E.g. record the fact that I sent an email.
Automatically copy version control commit messages into my overall log. But, of course, make everything filterable/foldable.
Friday, June 01, 2012
hg subrepos
hg subrepos:
push - by default pushes subrepos
pull - does not recurse by default
nor does hg status
This is almost exactly the wrong thing: the dangerous thing, that can write master repos, is the default. But the thing that does not modify anything are not default enabled for subrepos.
The docs warn: hg subrepos are a feature of last resort.
http://mercurial.selenic.com/wiki/Subrepository
http://mercurial.selenic.com/wiki/FeaturesOfLastResort
push - by default pushes subrepos
pull - does not recurse by default
nor does hg status
This is almost exactly the wrong thing: the dangerous thing, that can write master repos, is the default. But the thing that does not modify anything are not default enabled for subrepos.
The docs warn: hg subrepos are a feature of last resort.
http://mercurial.selenic.com/wiki/Subrepository
http://mercurial.selenic.com/wiki/FeaturesOfLastResort
Thursday, May 31, 2012
Edit the log message, not the history.
I don't want to edit the history.
I want to edit the bleeding log message.
F**k hg.
Version control the old log message, for sure.
But don't make me use a bleeding sledgehammer, history editing, to change the commentary.
--
Is history what happened, or is it the commentary on what happened? Historians write the latter.
I want to edit the bleeding log message.
F**k hg.
Version control the old log message, for sure.
But don't make me use a bleeding sledgehammer, history editing, to change the commentary.
--
Is history what happened, or is it the commentary on what happened? Historians write the latter.
Friday, May 25, 2012
Debugging
I often still debug via printf. Or, rather, via other code that eventually calls printf.
I used to feel guilty about this, embarassed that I did not always use a debugger like gdb. But then I heard some famous programmers say "I debug using printf".
Even better, since I started doing Agile, I spend less and less time debugging. (Conversely, when I work with legacy code, code that doesn't have tests, I spend more time debugging.)
Now, I have gotten better at using debuggers like gdb over the years. And some of my "add code" debugging cooperates well with debuggers like gdb.
For example, many many years ago another student/lab manager/research assistant/TA (who I think is reading this blog - thanks, Steve) said that he was in the habit of writing data structure printing tools and consistency checks, even if not used in his "production" code - if for no other reason than to be able to call them from a debugger. To this I add that such code is often also useful in automated unit tests. (Diffing taking into account hex addresses...) And also useful if you have to fallback to printf debugging.
What I like about printf debugging is that it often develops assets, code that can be reused. Both for future debugging, and for other purposes.
Whereas gdb style debugging often does not. Yes, you can write debug scripts - e.g. I found some useful scripts that can dump STL datastructures in a nice manner, rather than in the unreadable manner that so many debuggers print them. So-called symbolic, but not very high level.
Even better, since I started doing Agile, I spend less and less time debugging. (Conversely, when I work with legacy code, code that doesn't have tests, I spend more time debugging.)
Now, I have gotten better at using debuggers like gdb over the years. And some of my "add code" debugging cooperates well with debuggers like gdb.
For example, many many years ago another student/lab manager/research assistant/TA (who I think is reading this blog - thanks, Steve) said that he was in the habit of writing data structure printing tools and consistency checks, even if not used in his "production" code - if for no other reason than to be able to call them from a debugger. To this I add that such code is often also useful in automated unit tests. (Diffing taking into account hex addresses...) And also useful if you have to fallback to printf debugging.
What I like about printf debugging is that it often develops assets, code that can be reused. Both for future debugging, and for other purposes.
Whereas gdb style debugging often does not. Yes, you can write debug scripts - e.g. I found some useful scripts that can dump STL datastructures in a nice manner, rather than in the unreadable manner that so many debuggers print them. So-called symbolic, but not very high level.
assert/ignore pattern
Here's a pattern I observed today. I have seen it before. (In my wont to record neat little tidbits that m,ay be worthy of further thought.)
Started with code:
Object* objptr = ...; assert( objptr->consistency_check() ); assert( objptr->fooptr->consistency_check() ); assert( more_consistency_checks(objptr) ); ... do something with objptr ...Now, often enough it might be correct not to error exit with an assert. Often enough, in my problem domain, if one of the consistency checks fails you can just ignore the object, and go on. In my domain, computer architecture, this may arise because of speculative execution. So, pseudo-equivalent code might look like
Object* objptr = ...; if( ! objptr->consistency_check() ) { } else if( ! objptr->fooptr->consistency_check() ) { } else if( ! more_consistency_checks(objptr) ) { ... do something with objptr ... }I know, you might prefer
Object* objptr = ...; if( objptr->consistency_check() && objptr->fooptr->consistency_check() && more_consistency_checks(objptr) ) ) { ... do something with objptr ... }but I have found that I often want to do stuff like keep stats for which forms of inconsistencies were found, i.e. which assert would have failed if we had been failing. Or
Object* objptr = ...; try { assert( objptr->consistency_check() ); assert( objptr->fooptr->consistency_check() ); assert( more_consistency_checks(objptr) ); ... do something with objptr ... } catch(...) { ... }although it can be unfortunate if the catch is a long way away from the assert. You might want to specify the assert fail action at the assert - which is what the OF statements do. --- No biggy, just a pattern I have seen before.
Thursday, May 24, 2012
Rewriting history in version control systems
Some people like rewriting history in version control systems.
These people do not want "history" - they do not want an accurate record of events. They want a "narrative", an arc of development. With some of the ugliness and irregularity of what actually happened removed.
--
Recently overheard: "Oh, we can't go back to the version used for that test, because somebody rewrote history."
--
My take, as explained earlier:
Record the history. The real, raw, history. (Heck, I am occasionally willing to check in broken code - on a branch., NOT into the main line. NOT released to others.
E.g. sometimes it is worth recording, in the project history, all of the standing upon your head that you had to do to work around compiler bugs.)
But clean up the history, the logs, the narrative, when releasing. Merging back into parent branch. Etc.
And teach people how to look at the cleaned up history, the narrative. And only have to look at all the details if absolutely necessary.
--
A simple example of a narrative versus history:
It sometimes happen that two features are implemented in an interleaved manner:
Feature A - first step
Feature B - first step
Feature A - second step
Feature B - second step
Now, while it would be nice if somebody created separate branches for feature A and feature B, we all know it doesn't always happen. That is why we may be rewritging the history, cleaning up the narrative.
It may look better as
Feature A - first step
Feature A - second step
Feature B - second step
Feature B - first step
i.e. do both steps of Feature A, then both steps of Feature B.
Or even, retroactively create separate branches.
This can actually be accomplished by creating new branches, selectively patched and merged.
But, it may not be worth the work to do this.
But it may be worth the work to record the narrative showing it. So long as the actual history is also stored.
Heck, perhaps tools could make it easier to reconstruct the narrativem, as it woulda/coulda/shoulda happened. Albeit with a warning "This is not an actual historical reconstruction, so it may not actually work".
Subscribe to:
Posts (Atom)