We have a very different philosophy here.

At the end you say,

> "Flying Fish"?  If your commits "hose" developers, and/or the development
> and testing of a product, then your commits are one of 2 things.  Either
> they are a) malicious, or b) poorly done.

This is our fundamental disagreement.

I do not believe in a source code tracking tool whose only use is to track
functioning versions of a product.

I do believe in, and want to use, a source code tracking tool whose job is
to track the progress of the code.

"Flying fish", meaning going in and off the trunk, isolating your 'not
usable' progress, solves this.

But it's not just limited to the trunk and a branch. "Flying" off a branch
and then back on during development is also good. It is very usable.

The ultimate idea is this: When you check out something, you get a local
copy; you then track changes to it; when you are satisfied, you commit it
back to where you got it.

The current CVS update/commit, without built-in support for flying fish,
does not support that middle step: track changes to it.

I'll get to the rest of what you say in a second. But briefly, I cannot
write scripts to do this -- it has to be supported in CVS as a primitive.

Tobias Weingartner wrote:
> 
> On Monday, March 6, Michael Gersten wrote:
> >
> > Toby, do you program in assembly? I don't anymore.
> 
> If the need presents itself, yes.  If using a couple assembly routines,
> which are already written, will easily solve the problem, yes.

Then you have more time than I do.

I have used Z-80, 68000, and MIX.
I don't know 80x86, and don't have the time to learn. Meaning that there
are other things more important, such as a job that is currently taking
60-75 hours per week (and either that changes, or my job changes).
 
> > I like the windows find tool that combines find, xargs, and grep in
> > one box. Yes, it's limited, but it often works faster than trying to
> > get the correct command typed in. And, it's more of what I think of.
> 
> I'm sorry to hear that.  What you are telling me, is that you like to be
> limited by convenience...

No. When I need to, I write the find ... | xargs. The windows find tool
only supports looking for one type of file, or all files; it cannot say
"any non-directory"; it cannot say "modified in the last 10 minutes" (but
many find's cannot either; the apple one on web objects cannot).

The find construct takes longer to write, and double check. Yes, it's more
powerful. But it's slower to use.

I like convenience. I do not like to be limited by convenience. There is no
reason that a gui can't be written like the windows gui, that builds up a
command-line string on the bottom, that you can use as a starting point,
and then make a minor change to the command-line string with the keyboard
and hit 'go'. Use the gui to build the starting syntax blocks, add the
odd-argument manually. No one does this, I don't know why. I do not
consider GUI to mean 'easy to use', nor do I consider command-line to mean
'powerful'. Nor do I consider the two _inherently_ incompatible.
 
> > I don't want to be told "Here's a list of commands you can use to get
> > this done". I want one command that does it.
> 
> Then I urge you to go somewhere else.  I'm telling you an easy, straight-
> forward way of doing it.  It may not be an "automatic", but I'm telling you
> that if you put it in 1st, let out the clutch, and step on the gas, you will
> have accomplished all you wished, in the time it took to explain to me that
> you really were looking to have an "automatic"...

Let me tell you about my one time working with a manual car. I knew all
that; I put one foot on the clutch, started the car, shifted into first,
put the second on the gas, removed the first from the clutch, and then the
car stalled.

Yes, once I get to the point of learning how to use a manual, it will work.
Mostly.

I was talking with a friend who drives a manual, and is very good with it.
He was telling me something that I never thought of: that one time, a truck
almost crashed into him. He got away by DOWNSHIFTING, then flooring the
gas.

With hindsight, that's exactly what happens when you floor an automatic.
Without specific case training, I would not have thought of it.

As I said,
> > I don't want to have to remember a list of steps, and worry about "did
> > I make a mistake anywhere?".
> 
> Welcome to high-level languages.  The ones you like.  Make a script, put the
> sequence into a shell alias.  Be creative...

And do error checking. In scripts. (The worst thing about shell scripts,
actually).

Yes, PERL would let me do this better, do better error checking, etc. Have
you seen the thickness of the perl manual when you print it all out? Have
you tried watching someone who is learning perl 5.003 from scratch trying
to read it, and dealing with all the 'what the blazes ???' in the first two
real chapters? (syntax and datatypes) (That's as far as I've gotten so far
-- I've moved, and haven't unpacked (or even found) the manual yet).

I haven't gotten through it enough that I'd be comfortable writing a large
perl script, or even a mission critical simple one.

Just as an example: Sybase's stored procedure to rename a database element
is something like 1200 lines of SQL. 5 lines to do the rename, 1195 to do
error checking.

You want me to do all that in a script, covering all the possible problems
that can arise, etc, when the CVS code has subroutines and libraries that
do 80-90% of what I want already?
 
> > Yes, there is the ability to do this in CVS. As you said,
> > > Cripes, use "cvs diff" to give you a diff of your changes, checkout
> > > a new sandbox (or revert your old one), add the branch, apply the
> > > diffs (using patch), commit.

First, I've realize that this isn't sufficient. It works only if no one has
modified the trunk since you.

It won't mark conflicts properly. That requires CVS.

How about this compromise: A CVS command to walk the local sandbox, find
all the patch reject files, and mark conflicts properly? (With an option to
clean up the patch output files afterwards, perhaps smarts or a switch to
remove those patch outputs that were successfully dealt with already/prior
run/manually, etc?)

Or a CVS command to take diff files as input and apply the changes, marking
conflicts appropriately?

> I'm sorry if CVS does not cater to your "spoon-fed" mentality.

Now that's personal. I do not have a spoon fed mentality.

There is a fundamental philosophy: "If you don't like it, change the source
code", that I disagree with.

** I don't have the time to change the source code. I have other things
that are more important to me, that need to be dealt with first. On
windows, I don't even have the tools to deal with this properly. **

Besides, that philosophy says "Only developers should use this". A
non-developer can't get it to work, but is expected to modify it. Think X
windows. Now really think X windows, and novice computer users.

Now look at how big your X-windows modifications file is, and how long it
took you to build it. I lost mine when I left UCLA, that I spent years
building up/improving; when it was lost, that was when I realized just how
bad the X environment was.

> > WinCVS does a GUI on the CVS operations. No other abstractions other
> > than the CVS stuff. It is a gui, so the organization of the data
> > presented is a little better -- that's a plus (better
> > layout/organizaation of the data returned means better understanding
> > of more data).
> 
> Great, a tool, layered above a usefull tool.  In other words, a button
> doing a series of operations.  Sorta like the thing I mentioned above,
> in a "script" sense...

No. It is a GUI interface -- meaning that it has better layout, better
presentation, etc.

It has much better support for the log command -- it can graphically show
you all the branches made, and the tags assigned, in a way that you can see
what goes where.

But everything that it does turns into a single CVS command. No scripting.
No support for a series of operations. The same primitives that CVS has
(with a few cases that they didn't think of supporting).

It has the really nice ability to re-use check-in messages, and it gives
you a MRU sorted list of tags. But that's the limit of what it gives over
CVS -- layout.
 
> > But it's the CVS operations that matter.
> 
> Why complicate the matter?  Why add "yet another feature, knob, etc", when
> the existing framework fully encompases what you wish to do?

What is the job of CVS?

Take (as an example), fetchmail. Fetchmail started as one thing
(combination transport and delivery for mail), and then turned into nothing
more than a tool to move mail from a remote system to the local (or
specified machine) smtp port.

It has all sorts of things in it for that. But that's all it has.

Is CVS supposed to be a source code tracking system, or a functioning
source code tracking system?
 
> > Right now, I can (usually, not always, and no I don't remember why it
> > failed when it did) do:
> > To decide that I want to create a branch at checkin, with modified
> > files:
> > cvs tag base-branch
> > cvs tag -b branch
> > cvs update -r branch
> > cvs commit
> >
> > Why do I need 4 commands to do one operation?
> 
> Because you have not discovered high-level shell scripting yet.  You claim to
> program in high-level languages, why not use them?  They are good for more
> than just producing code you sell/ship.  They can be used to further your
> development environment as well, without needing to change CVS...

I can write a script for this. And, test it. I find that it works for my
test cases.

I don't know CVS. I don't know it's ins and outs. I don't know all that it
does; I don't use all that I know.

I know that I don't know enough to know how to test this, or even what
failure cases can occur.

As I said, it _USUALLY_ works. I don't know why it doesn't when it doesn't.
I certainly can't make a script to cover errors that I don't know of. The
next time it fails, I'll know (because it's now important to me) to find
out why, and fix it. Then, maybe, I can write this script.
 
> > Just now I made some changes to files, and realized that what I had
> > should have been merged onto the trunk before I made these changes.
> > Nothing else had been modified on the trunk since my branching. So, in
> > theory, I could say
> >
> > cvs move-branch removeLocks onto-parent       as-branch base-newrevision //
> > THIS DOESN'T EXIST -- modify repository only
> > cvs rtag -r base-newrevision -b newrevision   // modify repository --
> > make new branch
> > cvs update -r newrevision     // switch my newly modified files onto
> > newrevsion
> > cvs commit
> >
> > That's another 4 commands, one of which doesn't exist, unless I do a
> > lot of diff, revert, patch, etc.
> 
> Ok, what is to prevent you from making a diff of your current changes (to
> save them), checkout/update on the branch, merge that to the trunk

Tell me the CVS command to "Merge this up one level".

"cvs update -A" will get me back to the trunk from any level down of
branching, assuming that nothing is modified.
What is the flag to update to only go up one level of branching?
What is the command to move elsewhere on the tree only if it won't cause a
conflict, or if it won't cause a merge?

>, and then
> update/checkout on the branch/trunk you wish to be on, then run patch
> against the original diff?
> 
> For that matter, it certainly is not a crime to have 2 sandboxes available
> to work in, diff from one, patch on the other, etc.  As a matter of fact,
> I find this a very usefull thing to do/have.

Hmm. 2 sandboxes on different branches is a good idea. Thank you.
(No, I don't think of everything. Things that are obvious to me are not to
others, and visa-versa.)

> > Why?
> 
> Why not?  Why unix?  Why CVS?  Why NT?

Because of my job. THat's the only reason for NT.

> CVS was originally developed on unix.  I think a lot of the philosophy there,
> is the same as in the original unices.  We give you pleanty of rope, more than
> enough pieces to do what you need to do.  More than enough to hang yourself if
> you should wish to accomplish such a feat.  Just because you wish to have 4
> commands done in a certain way, with a certain type of arguments and switches,
> does not mean that other people will want that, or will be even able to use
> that.  At that point, should we ignore their requests for "enhancement" of the
> (quite adequate, IMHO) CVS source to appease them?  Or should we bloat the code
> even more, adding switches to modify the behaviour of this 4-command sequence
> in every way possible?

Ok, consider this:

Back with RCS, the commands where ci, co, etc.
You could easily add a new command.

Now, the commands are 'cvs ci', 'cvs co', etc.
Do I tell people (co-developers that have less time to learn cvs than I do)
that some commands are 'cvs foo', and others are 'mycvs foo'?
How do I, and how much time do I spend, duplicating the left side
arguments? What about duplicating the right side arguments that are common,
and have a great deal of support in CVS that I have to start from scratch
with in a script?

What enhancements do you add? What is the job of CVS. Does the requested
enhancement fit the job description?

Fetchmail's author was given all sorts of "I want this feature" request. He
simple said, "Is that a mail transport feature, or a mail delivery, or a
mail reader/user interface feature?" Then, if it was transport, he added
it, when it started as a transport/delivery tool he added delivery stuff as
well (later that was all removed and delivery became just 'smtp on
specified host').

So again, what is CVS's job?
What features are consistent with that job?

Do you think that support for automatically merging up one level of nested
branches is something that fits CVS's job? Including proper tracking of
conflicts, etc? I do.

CVS has, through the update/checkout -j merge flags, a way to merge changes
from one section of the tree into another section of the tree. Does that
mean that the common cases cannot get the equivalent of an internal command
alias?

CVS has a '-r' option on commit. I want this to work -- to commit onto a
new branch, rather than on the checked out branch/trunk. Commit gives an
error if the files are not up to date, so it's not really a case of 'this
will cause problems elsewhere in the tree'. This is only intended to cover
'onto a new branch', or 'onto the parent branch if nothing has been
modified'. Those are the only two cases (that I can think of) where the
'up-to-date' check is true, even if the current CVS code doesn't realize
that it is true.

CVS has no primitives to support working with third party modification
tools that leave patch .rej or .orig files lying around -- does that fit
it's job? Does anyone else even think that that is a useful feature?

CVS has no support for adding new user commands -- so that I can write a
script, 'mgmerge', and then say 'cvs -z9 -q mgmerge <options>'. With the
goal that 'mgmerge' would be called in a known environment, with it's
options, one file at a time, and it will work as expected, whether the user
has a -n on the left or not. Does this fit the job of CVS? (Probably not,
at least according to the current job description. Is this wanted? Is the
job description for CVS proper?)

Finally: (And if this doesn't present my case, nothing will).

A typical collection class in an object oriented language might have
primitives like "count" and "objectAt". (In fact, for a non-mutable class,
that, plus a creation method, are all you need). Everything else can be
implemented in terms of that. (Dictionaries take a key for objectAt, arrays
take a number, etc. Ok, a dictionary might need "allKeys".)

Would you use only those, or would you use all the additional methods
defined for convenience?

C language coding, you have all the primitives you need in section 2 of the
manual. Do you ever use the library in section 3?

C++ style object oriented programming is just syntactic sugar on a pointer
lookup in a data structure. Do you use object oriented languages, or do you
do your own pointer lookups? Or do you even use objective C, where you also
have a string->unique number mapping, and then (essentially) a mapping from
that number to a class dependent offset into a class dependent data
structure? (I haven't even mentioned loadable code yet).

If you are designing a new class, how do you decide what to implement? Do
you just figure "These are all the primitives that are needed, that's all
I'll code", or do you ask "How will people use this? What will they want to
do with it?"?

What do you want to be able to do with a source code tree?
What operations do you want to be able to do?

What do you want to be able to do with branches?

To me, saying that the primitives are "Create a branch by name, switch to a
branch by name" isn't very powerful. That's like a collection class that
only knows 'count' and 'objectAtIndex:'.

To me, useful/obvious operations on a branch are "Move one layer down onto
a branch", "Move up a level of branching".

To me, a useful pair of operations is "Switch location in the tree only if
safe", and "switch regardless".

To me, saying "We have a primitive to output diffs" is nice, but begs the
question, "where is the primitive to input a diff?".

To me, (quoting the cederquist docs)
<<
CVS does a pretty good job at hiding these so called magic branches, but in
a few places the hiding is
incomplete: 

     The magic branch number appears in the output from cvs log. 
     You cannot specify a symbolic branch name to cvs admin. 

You can use the admin command to reassign a symbolic name to a branch the
way RCS expects it to
be. If R4patches is assigned to the branch 1.4.2 (magic branch number
1.4.0.2) in file `numbers.c'
you can do this: 

$ cvs admin -NR4patches:1.4.2 numbers.c

It only works if at least one revision is already committed on the branch.
Be very careful so that you do
not assign the tag to the wrong number. (There is no way to see how the tag
was assigned yesterday).
>>
That you have such a state, and that CVS doesn't track/update this for you
on the first commit, (or even make a zero-line commit itself so it can
record this), well, yes, the primitives are sufficient. And yes, you can
hang yourself with it. But how much more work would it take to hide this?
Do you really need the power of being able to assign this arbitrarily?
(About as often as a computed goto, I'd imagine.)

To me, "This is how it has been done so far" is meaningless -- how it will
be tomorrow isn't necessarily how to was yesterday. Otherwise, we wouldn't
have computers, internets, wireless digital, heck, we'd be using hand
carved wood blocks as our printing presses, with low quantity book print
runs. 

So again, my questions to you are:
1. What operations on branches do people really want/need/use?
2. What operations does CVS support?
3. If they do not match, why not? Is the answer to #1 really so huge that
it can't be done reasonably? If so, is there a better set of primitives
that come closer? Can the set of primitives be extended/enhanced with some
non-primitives?

CVS does not have to take the version-7 unix philosophy of "Only one way to
do anything; if you want to add a new kernel primitive, what can be taken
out of the kernel or removed entirely?". Even micro-kernels like Mach add a
compatibility/usability layer that implements usable stuff in those terms.

Ever use C-threads? Or any high level thread abstraction? No need to worry
about setting up a stack section that will grow automatically, etc.

Do you use malloc, or brk()? (Or the equivalent -- mach has a different
primitive, I don't know about hurd).

I don't want my tools to be the lowest level primitive possible; I don't
work in assembly.

I want my tools to be usable. I want my tools' supported operations to
match the actual use behavior of what I do with them.

I want to step on shoulders, not on toes.

Is that wrong of me?
Am I "spoon fed" for that?

"The reasonable man adapts himself to the world; the unreasonable man
alters the world. All progress, therefore, depends on the unreasonable
man".

I'm trying to point out (and if I'm wrong, say so) that the operations that
CVS supports for branches do not match what people want to use branches
for/what they could/would use them for if they could/would do more.
[Translation: If you say 'People only use branches for X', or 'people only
do Y with branches', because that's all that CVS supports, that's not what
I'm talking about. I'm asking, 'What would people do with branches if CVS
could support what they want to do?'. Then what does it take to actually
implement those that have the densest demand?]

Sorry for the length of this.

Michael

Reply via email to