[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: CVS diff and unknown files.
Re: CVS diff and unknown files.
Wed, 2 Feb 2005 01:58:31 -0800
On Feb 1, 2005, at 8:16 AM, address@hidden wrote:
Paul Sander <address@hidden> writes:
On Jan 31, 2005, at 9:30 AM, address@hidden wrote:
That's not to say that we will *always* know at add time that the
commit will fail; failures can occur due to problems in their
which are clearly not ready to check at add time.
Well, if I understand correctly, your intentionally want to have
checks at add-time than at commit-time. Instead, you can do it in the
commit-time trigger by skipping some of the tests if the file in
question is new one.
Oh, so what you're saying is that rather than making CVS differentiate
between the two sets of triggers, you want the commitinfo script to do
it instead. I suppose that's doable.
Exactly! I took too much time to explain this. Should be either my or
your fault (or both).
But I'll counter with this: Why not combine commitinfo, loginfo, and
taginfo the same way? My argument is that add-time triggers differ
from commitinfo triggers in the same way that commitinfo triggers
differ from those others: They run at different times for different
All the triggers you've mentioned have no common tasks to do. On the
other hand, add-time checks you have in mind are subset of commit-time
checks you have in mind. The subset is easily achieved by bypassing
Okay so you understand why it's a bad idea to overload too much
functionality. I argue that combining add-time and commit-time
triggers is also overloading things too much. There's the established
commit-time feature that is being modified so that it now runs twice
rather than once. If this were indeed done, then thousands of existing
CVS admins are inconvenienced because they must rewrite their existing
commitinfo triggers to bypass their current operation at add-time, and
plus both the CVS authors and the administrators must work through a
change of interface in an existing feature.
If you examine the implementation, you'd realize that CVS implements
its trigger support pretty much in a generic fashion, basically
invoking a function call with different parameters depending on the
trigger. So there's really no invention going on when adding a new
trigger. And it turns out that overloading an existing one is
I would have no objection to add-time-script if there were a separate
server operation called "add-file-to-the-working-copy", or
"check-if-file-name-is-ok-for-repository", but AFAIK there is currently
no such operations. I consider inventing new server operation just to
implement some policy that you have in mind and that could be
implemented using existing functionality anyway to be an overkill,
If you go back and read Mark's postings, he mentions that my proposal
requires no changes to the client/server protocol, so it's really not
inventing a new server operation in a very real sense. It changes the
behavior of the server, but if at add-time you invoke the option to
avoid contacting the server, then why do you care?
You need to get out of the server. The server's not the one we're
trying to make happy here. It's the user that matters, and the tools
must bend to the users, not the other way around.
From an implementation standpoint, there's no difference between the
triggers, other than the conditions in which they fire and the files
in which they're configured. Thus the argument you make in the above
paragraph simply makes no sense.
It's you who needs to get out of the server, not me. You propose server
changes, not me. If the functionality has nothing to do with the
then get out of the server indeed.
Yes, you do propose server changes: You propose invoking an existing
trigger in a second place. I argue that implementing a second one
performs the same function that you propose, but in a cleaner way that
preserves existing practice.
If I do in fact understand you to be recommending that commitinfo be
used at add time, then I must disagree. Triggers used at commit time
to check the content of files (like Greg's RCS Id trigger, for
example) are not appropriate to use at add time. Things like
that the user has the right to add a file, or checking that the name
of the file complies with policy, are legitimate to check at add
They can also be checked at commit time, and the current proposal
that because the add-time triggers are optional.
So the only thing you need to know in the commitinfo is what user is
trying to do and decide what checks are required based on this
information. If commitinfo currently doesn't have all the required
information, maybe it's better to fix it instead of inventing yet
another hack in the form of add-time triggers?
What you're really proposing is an alternative implementation for
triggers. Think about it.
It's how it looks from your point of view. From my point of view I
propose alternative implementation of the functionality you need
inventing anything new, being add-time triggers or something else.
What you're recommending is to overload something in a way that is not
What you suggest is yet another reincarnation of commit-time triggers
"run at different time" where "time" is defined in terms of operations
on the working copy. Think about it.
I have thought about. Apparently so has Greg. Something you should
understand is that he and I have some history of adversity in this
forum. You may have noticed that he and I both agree that overloading
commit-time triggers in the way you describe is a bad idea. That
really means something.
If users think the wrappers are in their way, they'll drop down to
CVS to add the file, causing more significant breakage later.
Either trust your users or arrange things so that it won't be
for them to invoke cvs commands directly. But even if you choose the
latter way, those that do think the wrappers are in their way will
probably find a way to bypass them anyway.
First, I've already related a horror in which users were trusted and
failed. This is why we need safeguards on the circumstances in which
they can perform certain actions.
They will fail no matter what you do then.
Second, if a wrapper invokes CVS, then there's no way to effectively
hide CVS from the users.
You like to bring wrong statements into discussion very much. If you
don't know a way, it doesn't necessarily mean there is none.
Alright, I know of two ways on Unix to effectively isolate users from
parts of the filesystem: Closed directory permissions and chroot
jails. Giving users limited access to applications involves hiding the
entire application behind these walls and opening holes via setid
wrappers or writing a new client/server application to wrap the
existing application. These solutions are expensive and easy to mess
up. Adding a new trigger to CVS is far simpler, it's generally
applicable, shops that don't need it need not use it, and in this case
clients can opt out.
This is why policy must be enforced below the level of the CVS command
CVS command line tools are no more than wrappers on top of CVS
client/server protocol. They can't enforce anything that the protocol
itself can't enforce. In turn, the protocol can only enforce what
clients can or can't do *to the server*.
That is all true.
You seem to be thinking that in the client/server model the server is a
boss. The reality is closer to the opposite. In fact it is client who
boss. It commands what server should do, and then servers does (or
doesn't) what the boss have told him to do. There is no way for server
to force client to do (or not to do) something.
Nope, it's a negotiated effort. The server can refuse to cooperate as
long as the client makes unreasonable requests. That's the basis of
policy enforcement: In the end, the server really is in control
because it can always say "no".
In the case of the add-time trigger, it's really a request for a sanity
check in which the server can inform the client that it notices an
approaching problem. It's built into the semantics of my proposed
solution that the CVS client can either heed the warning (by refusing
to record an addition in the Entries file) or ignore the warning (by
opting out of making the request). Commit time is when the server
decides whether or not to cooperate, based in part on whether or not
the client chose to ignore an earlier warning.
Beyond that, there is absolutely no implication that the server has
more control over the user's workspace than what I have described in
the past two paragraphs.
It's at that time that they finally learn the value of the process.
If somebody prefers to learn on his own mistakes, -- let him do it
unless it doesn't break others work.
Do you really mean, "let him do it unless it breaks others work"? How
do you prevent them from making mistakes that harm others?
By not allowing him to break the repository, obviously. That's the goal
of server-side policies, -- prevent users from breaking others work.
just can't prevent them from doing their mistakes in their working
for example, one can run 'rm -rf' in his working copy after two days of
Okay, consider my horror story in which the user essentially did a "cvs
rm *" recursively from the top of the project, followed by a commit.
Technically, the repository wasn't broken, and the action was
(eventually) reversible. On the other hand, hiding the entire source
base from the rest of the team wasn't the right thing to do because it
had a real and serious negative effect on the whole project. In our
case, it took hundreds of man-hours to recover. TWICE!!! It's this
kind of stupid, foreseeable, and expensive mistake that simple
automated policies are good at avoiding.
They won't know which mistakes are harmful until they try them.
Yes, they will learn anyway as soon as they try to commit their
i.e., as soon as they try to break others work.
That's fine, but you've forgotten my argument that there are classes of
mistakes that can be caught early, while they're still limited to the
user's workspace. And if they are in fact caught at that time, they
give the user the opportunity to save the user many hours of work.
This is the kind of thing that I'm advocating so strongly in this
That's exactly the point of enforcing policy: It allows the entire
project to learn from the mistakes of others so that when
inexperienced users repeat past mistakes, everybody is protected.
You can't force nobody to learn unless she wishes to learn. You can't
protect user from himself. Either the user wishes to know if she
to policies, in which case she will run whatever commands you tell him
early, or the user doesn't wish to know, in which case you has very
little to do about it.
Actually, you can protect the user from himself in a limited way. (It
may be that you can't stop someone from shooting himself in the foot,
but you can give him bulletproof shoes, for example. You can also give
him an empty gun, but that doesn't help anyone if he's the tribe's
hunter.) And you can protect the project from people who don't adhere
to policy for whatever reasons.
Tell me something. Do you consider policies to be frivolous exercises
by power mongers designed to get in your way for arbitrary reasons, or
do you consider policies to be well-considered tools designed to aid
the completion of the project more efficiently? What is your
experience to back up you belief?
BTW, the definition of "client/server" implies the presence of a
network for communication between the two parts,
Wrong. Client and server can work on the same computer without any
network. Moreover, client/server idiom is heavily used inside
"monolithic" programs as well. Basically, client/server only means
there is some "server" that makes some operations on behalf of
"clients", how clients communicate with the server is a secondary
While your statement is true, the fact is that client and server
programs typically operate on different machines. The fact that they
do is what gives the client/server paradigm its power. Sure, I can
write client/server programs that use loopback interfaces, Unix
sockets, or even named pipes, but they offer no benefit because
function calls are more efficient RPC calls.
Don't you aware that client/server paradigm is widely used inside
"monolithic" programs as well? There are always things left to be
learned in this world.
Frankly, I don't care. And it's not relevant to the topic at hand.
No, it's very relevant to the topic at hand. It's your ignorance of the
true meaning of the client/server model that makes you believe
everything is fine with your proposed design. The client/server model
mostly about splitting of responsibilities, not about media through
which client and server communicate.
Indeed it is about splitting responsibilities. But in the context of
these few paragraphs, the client/server paradigm is but one means to
accomplish a goal of dividing and conquering a problem. The same can
be done with well-designed APIs in a monolithic application, and in
fact there have been times when such APIs were reimplemented, converted
from simple function calls to RPC calls. These facts are still
irrelevant to the discussion of add-time triggers, because the argument
is still relevant to CVS' local mode, which is not a client/server
Well, you've asked "why would you possibly want to deliberately
proceed toward a dead end" and I tried to provide an example when
the end is not actually dead. The problem is that unless I add the
files, 'cvs diff' doesn't work on them, and if your proposal is
implemented, and I bypass the add-time checks, I have no way to
repeat them later without committing the files.
Okay, so when you say "I need the files to be added to the working
copy anyway" what you really mean is that you an entry in the CVS
metadata so that you can do other stuff that won't work without it.
Fine, my proposed add-time trigger implementation allows for this.
*How do I repeat skipped checks later with your proposal?* I already
tired asking this same question again and again just to get no answer.
Have you not been reading my replies?
Answer 1: If you don't ignore the error condition (i.e. you care about
why "cvs add" fails) then correct it and repeat the attempt to the
Answer 2: If you do ignore the error condition (by telling "cvs add"
to act locally), then attempt to commit the file. The add-time checks
will be redone, followed by a more comprehensive set of checks.
Now I ask you: Why is this unreasonable?
Well, this time I've found an answer below, the answer is "run 'cvs -n
commit'", but it doesn't fit into your model. That's what I'm
advocating, -- you don't in fact need anything else but "cvs -n commit"
to let user know ASAP about possible problems.
I've stated on at least two occasions related to this thread that after
the work is done, it doesn't really matter how you get there. But the
add-time checks influence the journey. If you happen to be in a shop
where policies are all voluntary to the point that you must ask if
you're in compliance, fine. Some of us, and not just myself, think
that policies are compulsory, and therefore the tests should run
automatically. Therein lies the reason why "cvs -n commit" alone is
Here's another potential benefit: Most projects have some criteria
that submitted patches must have before they will be accepted. These
criteria might include naming conventions (e.g. all files named in
lower-case). If you intend to send a patch to the project, there's a
greater probability that it will be accepted the first time if you
subject yourself to some of their policies.
Then I need full commit-time checks, not your limited add-time checks.
Better spend your brain forces on improvements of the former than on
invention of the latter.
Full commit-time checks are certainly needed. But as I keep stating,
more limited add-time checks are also strongly desirable. The fact
that *you* don't need, want, or understand them does not mean that I
should not have them. You can always leave them turned off.
This is a complementary view of my proposal: Have a set of triggers
that runs at add and commit times, and another set that runs only at
commit time. It so happens that the second set is already implemented.
There is actually no sense to make them different if you indeed insist
on informing users about problems ASAP.
Invoking commitinfo and passing an argument to distinguish between add
time and commit time, which seems to be what you have in mind, is an
Yes that's what I have in mind.
I think mine is better, and it certainly has fewer backward
Backward-compatible wrong design is not necessarily better than a sane
one even if it's not backward-compatible, though I think there is still
a way to keep backward compatibility in my case either.
Most of us in this forum seem to think that the existing design is a
sane one. I happen to think that the implementation is poor, but
that's a different argument. Either way, neither can be changed
without significant inconvenience to the existing community. This is
why I don't recommend changing commitinfo in any way.
Ah, so the sole purpose of invention of add-time triggers is in fact
attempt to don't break compatibility with the current commit-time
scripts, right? If so, it's better to explicitly state it to avoid
misunderstanding similar to mine.
I thought that was exposed in an earlier message. Sorry for not
No, there was no even such a word, "compatibility" in your earlier
If I propose a way to implement my variant and make it
backward-compatible, will you agree that mine is better? My
understanding is that no, you won't. So compatibility is not in fact
main point of our disagreement.
Well, we won't know until you suggest it, will we? :-)
On the other hand you already know my opinion of overloading functions,
which is that doing so is usually bad unless there are *very*
compelling reasons to do so. If your recommendation involves
overloading commit-time triggers then you may be right. Still, it
won't hurt to try.
Seriously, think about what you're saying. You want to do the
cvs add foo.h
cvs commit foo.h
It's at this point you want to fail, after you've done all the
work. In my opinion it's better all around you fail after two
steps, not five.
You've missed my point. I have nothing against step2 warns me
problems, maybe even by default, if I still have ability to
warnings. I'm strongly against step2 to refuse to add the file as I
believe it would just disturb instead of help: if step2 refuses to
the file, it doesn't prevent me from doing steps 3 and 4. In fact
even doesn't prevent me from invoking 'cvs commit foo.h', but
getting comprehensive explanation from the server why my change
accepted, I'll get less useful message "run cvs add first".
Are you saying that if step 2 fails, you would proceed with steps 3
and 4 and maybe attempt 5 without correcting the failure condition?
I said what I said, your suggested _failure_ to add the file to the
working copy doesn't prevent me from doing the rest of steps. It
that it's not any better than _warning_. And I even showed why it is
Well, what do you expect if you ignore the warning in step 2?
With your proposal? I expect your "enforced policy" to somehow prevent
from continuing my way to the "dead end". You claimed you will be able
to enforce your favorite policy on my working copy. You failed.
Under the condition that you ignore the warning in step 2, I never,
ever suggested that I could prevent you from wandering down the dead
end. Remember, the whole point behind being able to opt out of
performing the add-time check is to empower the user to do things that
he may need to redo later.
Sure, you can change your behavior and move the add down to right
before the commit, and that is consistent with the working styles
of many people, but then they get what they ask for.
So even with you proposals implemented you fail to actually impose
policies you are trying to impose with the proposals, -- too bad.
That's another thing I'm trying to explain, -- you have no way to
actually impose policies on the client side. Thinking otherwise is
more than self-delusion.
Well, that's what I get for pandering to the crowd that thinks that
they simply must be able to add a file while working offline. If an
add-time connection to the server were a requirement (i.e. there
no feature to opt-out of add-time triggers) then this wouldn't be a
problem. Don't blame me for trying to meet your requirements.
I don't. I blame you for the failure to meet your own requirements.
if you make invocation of triggers by "cvs add" an absolute must, the
users will simply don't run "cvs add" for days until they need to
their changes due to your own expectations of your users behavior.
If they're breaching policy in their file additions, then because the
changes will ultimately be rejected, it's not in their best interest
to delay the discovery of the violations.
If it's not in their interest then warning is more appropriate than
failure to complete operation, I believe. My whole point here is that
failure to add the file doesn't prevent your users from misbehavior any
more than a warning, so why failure?
Because in my experience, users don't heed warnings. Whenever I need
to get their attention, I need to hit them over head with a failure.
Case in point: When's the last time you shipped a large project that
compiled completely without warnings? How long did it take you to tire
of reading them and start to ignore them? At least with the opt-out
method, you're forced to at least review the condition and perform some
discrete action to ignore it.
Also, from a standpoint of process automation, I want the failure as
early as possible because I can either stop early and let a human
correct the problem and re-run a smaller amount of lost work, or
because I can make decisions based on the failure and adjust the
control path of my process.
and running commit-time triggers at add-time is not appropriate.
Why? Because it doesn't match the policy you have in mind? Then
you commit-time triggers so that they don't do some tests at
No, it's not because the triggers don't match the policy that I have
in mind. It's because there are certain tests that simply are not
appropriate to perform at add time. Scanning the contents of the new
files, for example, are not appropriate.
No, it is appropriate. You said yourself many times that you need to
check everything ASAP. If the file has contents, why don't you check
No, I never said "you need to check everything ASAP". I said "you need
to perform appropriate checks ASAP". There's a big difference.
At add-time, chances are very high that the file's contents simply
aren't ready for review. That's why I don't check its validity. To
assume otherwise would be to require the user to defer running "cvs
add" until right before running "cvs commit". While that is the work
habit of many users, it's not the general case, and I won't intrude
into their style in quite that way.
On the other hand, checking certain attributes of the file, like its
name, is reasonable to do at add-time. This is why the checks
performed at add time are necessarily a subset of those performed at
Like I said in another post, after the commit has completed, the
effects of the two implementations are identical.
What we're arguing about is what's the right way to make the journey
to that point. My way has merit.
Sorry, but the only real merit I guessed is backwards compatibility
current commit scripts. Anything else?
Backward compatibility is a good one.
My solution could be made backward-compatible as well.
The scripts will be easier to write if the two sets are kept separate
and invoked separately, also.
No, they will be easier to write only when an administrator will try to
implement a policy similar to those you have in your mind where the
checks are different. As I believe the checks must be the same, I in
fact like it very much that implementing inherently broken policies is
slightly more difficult, -- it will force admins to think twice before
actually doing that.
Hmmmm... Let's see. Suppose for a moment that we implement add-time
checks according to my proposal. We now have a set of checks that run
both at add-time and at commit-time. Administrators working in your
style have a method to do that, too.
Mark also mentioned some good ones.
Sorry, I've somehow missed that. Care to repeat or give a reference?
Look in the info-cvs archives for the following message IDs:
address@hidden and address@hidden
You've admitted that you're not familiar with the CVS design.
Please don't argue issues of complexity in a vacuum.
Yes, I'm not familiar with the CVS design, hopefully though it's not
that broken that introducing additional feature is less complex than
tuning an existing one to meet new requirements.
The two implementations are equally complex.
Resulting application complexity is what actually matters in the long
term, not the complexity of turning current implementation to the new
Check the code yourself and consider how you might implement both
features. I believe both implementations are equally complex to build
and that neither implementation significantly increases the overall
complexity of the application. However, I believe that your method
increases the complexity of the administration tasks slightly, for the
reason that conditional actions within scripts invoked by commitinfo
will be more difficult to write. My method increases administrative
tasks even more slightly because the administrator must decide which
one of two files is the right one in which to register the trigger
scripts, but the scripts themselves are simpler.
And that's one of problems with your proposed add-time triggers
solution. The user needs a way to invoke later the checks "cvs add"
didn't do in this case. That's the scenario where user needs
"add file to working copy" and "check file for validity against
repository" actions. Every time I ask you how do I repeat the
check, you don't give satisfactory answer.
I want to know how do I invoke the checks that have been skipped
off-line work when I go on-line?
cvs [-n] commit
Cool! So that's what "cvs add" in fact didn't do when I worked
This fits perfectly into my model! That's exactly my point, -- if any,
"cvs add" should perform the same checks "cvs -n commit" does!
Whoa! You're missing something important. The moment a new file has
been successfully registered with "cvs add", conditions change.
Repeating the same set of add-time checks alone is no longer
appropriate. Assuming you don't abandon your work, the next logical
step is to commit the work. Therefore, the work becomes subject to the
more stringent commit-time checks. The commit-time checks are a
superset of the add-time checks because the user is given the option to
successfully register a new file while defeating the add-time checks.
Well, suppose you are designer and I'm a user then. I, the user,
you, the designer, to explain me why do you think I, the user, will
never need plain and simple "add new file to the working copy" user
The answer is: You can add anything you want to your workspace, but
you intend to commit it then you must comply with the design. And I
will tell you at the moment you declare your intent if I think
not in compliance.
Well, what is the command to just add the file to my working copy
without intent to commit it? Please don't tell me there is one as
you agree that "add new file to the working copy" is a useful user
operation. Please don't tell me there is none as I need it indeed.
I have never disputed that "add new file to the working copy" is a
Really?! What then did you mean here when you've answered YESSSSS here:
me> Ah, now I see. I suggest "add new file to the working copy" to be a
me> useful user operation, and you believe it is not? So the minimum
me> semantics of "cvs add" you agree with is something like "add new
me> the working copy but only after you make sure the file path is OK
me> respect to the repository".
Don't you even care to understand questions before answering, or you've
already changed your opinion?
In my usage model, I am in 100% agreement that the following is a
useful operation: "add new file to the working copy but only after the
add-time triggers completed successfully"
In the statements above, my "make sure the file path is OK with respect
to the repository" is a special case of your "add-time triggers
I have also been convinced that some users, other than myself, might
have legitimate reason turn off add-time triggers at the moment that
"cvs add" is invoked. That means I can accept that "add new file to
the working copy even under failure conditions detected by add-time
triggers" is a valid requirement. I can get over it.
Paul Sander | "Lets stick to the new mistakes and get rid of the
address@hidden | ones" -- William Brown
- Re: CVS diff and unknown files., Sergei Organov, 2005/02/01
- Re: CVS diff and unknown files., Sergei Organov, 2005/02/01
- Re: CVS diff and unknown files.,
Paul Sander <=
- Re: CVS diff and unknown files., Greg A. Woods, 2005/02/01
- Re: CVS diff and unknown files., Greg A. Woods, 2005/02/01
- Re: CVS diff and unknown files., Sergei Organov, 2005/02/02
- Re: CVS diff and unknown files., Greg A. Woods, 2005/02/02
- Re: CVS diff and unknown files., Mark D. Baushke, 2005/02/02
- Re: CVS diff and unknown files., Greg A. Woods, 2005/02/05
- Re: CVS diff and unknown files., Sergei Organov, 2005/02/07