• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: CVS & .nibs
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: CVS & .nibs


  • Subject: Re: CVS & .nibs
  • From: Bill Bumgarner <email@hidden>
  • Date: Tue, 26 Jun 2001 10:37:29 -0400

[Taking the liberty of cross posting because this'll probably be useful to a number of folks on all three lists. Also, I wrote a hints/tips email regarding CVS a few months ago-- if you are dealing with CVS on a regular basis, I would suggest having a look for that message in the archive.]

In versions of EOModeler prior to that shipped with WebObjects 4.5 (4.0?), you need the EOModeler bundle from Omni that preserves the CVS directory information in a fashion similar to the Omni IB palette that is no longer needed with OSX.

In any case, for both EOModels and NIB files, treat them as a normal directory. As Ian suggested, add the wrapper information that treats the objects.nib as a binary file, but treat everything else (save for images, if you happen to have 'em in the NIB file-- not recommended) as text.

I.e. Say I created the project FooApp-- a Cocoa application using EOF/Java-- and I want to add it to my cvs repository. The cvs repository's CVSROOT specification is "borg.codefab.com:/some/path/cvsroot/".

The first thing I would do is ensure that there is a top level directory in CVS that contains the project and any other stuff. This ensures that you always have a single directory that you can check things out against and get everything in the repository related to your project. So, I start by building a directory structure something like:

FooProject/
README.txt
FooApp/
... project stuff here ...

The next step is go into the FooApp directory and make sure that every file in the project is a file that you really want in the CVS repository. CVS takes that attitude that once something has been added to a repository, subsequent removal should be a fully audited event. As such, it can be a pain to remove files/directories after the initial import. You are far better off ensuring that the hierarchy of stuff to be imported into CVS is clean and has a structure that you plan on sticking with. The most painful CVS task is to restructure a project to reflect naming changes and hierarchy changes-- you are generally better of using 'cvs export' to export a copy of the source, then 'cvs import' to create a new repository.

In any case, after cleaning, we use the following command to import the source:

[localhost:~/FooProject] bbum% cvs -d localhost:/tmp/cvsroot import -m 'Importing base.' FooProject CODEFAB REL_000
bbum@localhost's password:
U FooProject/README.txt
cvs server: Importing /tmp/cvsroot/FooProject/FooApp
N FooProject/FooApp/FooAppDelegate.java
N FooProject/FooApp/main.m
cvs server: Importing /tmp/cvsroot/FooProject/FooApp/English.lproj
N FooProject/FooApp/English.lproj/InfoPlist.strings
cvs server: Importing /tmp/cvsroot/FooProject/FooApp/English.lproj/MainMenu.nib
.........
N FooProject/FooApp/German.lproj/MainMenu.nib/info.nib
N FooProject/FooApp/German.lproj/MainMenu.nib/objects.nib
cvs server: Importing /tmp/cvsroot/FooProject/FooApp/Japanese.lproj
N FooProject/FooApp/Japanese.lproj/InfoPlist.strings
cvs server: Importing /tmp/cvsroot/FooProject/FooApp/Japanese.lproj/MainMenu.nib
N FooProject/FooApp/Japanese.lproj/MainMenu.nib/classes.nib
N FooProject/FooApp/Japanese.lproj/MainMenu.nib/info.nib
N FooProject/FooApp/Japanese.lproj/MainMenu.nib/objects.nib

No conflicts created by this import

VERY IMPORTANT: At this point, you want to verify that things have been correctly added to the repository and then *delete the tree of stuff that you imported*. Yes, delete it. This will prevent you from continuing development in that tree of stuff. A cvs import does not make the tree you are importing into a cvs controlled workarea-- if you DO continue working in it while other developers have checked out copies of the repository in the normal fashion and have committed changes, you will be facing a nasty integration issue. So:

[localhost:~] bbum% cd ~/Developer

cvs -d localhost:/tmp/cvsroot checkout FooProject
cvs server: Updating FooProject
U FooProject/README.txt
cvs server: Updating FooProject/FooApp
U FooProject/FooApp/FooAppDelegate.java
U FooProject/FooApp/main.m
..............
U FooProject/FooApp/Japanese.lproj/MainMenu.nib/classes.nib
U FooProject/FooApp/Japanese.lproj/MainMenu.nib/info.nib
U FooProject/FooApp/Japanese.lproj/MainMenu.nib/objects.nib

[localhost:~/Developer] bbum% diff -x CVS -r ~/FooProject FooProject
[localhost:~/Developer] bbum%

Good-- no differences between the imported tree and the tree checked out from the workarea. (omit the -x CVS and you will see that there are differences; the second tree has the all important CVS administrative directories).

Now that it has been imported, we should assert that the appropriate administrative flags have been set on files that should be handled as binary:

[localhost:~/Developer] bbum% cd FooProject/FooApp/French.lproj/MainMenu.nib/
[localhost:FooApp/French.lproj/MainMenu.nib] bbum% cvs status -v objects.nib
===================================================================
File: objects.nib Status: Up-to-date

Working revision: 1.1.1.1
Repository revision: 1.1.1.1 /tmp/cvsroot/FooProject/FooApp/French.lproj/MainMenu.nib/objects.nib,v
Sticky Tag: (none)
Sticky Date: (none)
Sticky Options: -kb

Existing Tags:
REL_000 (revision: 1.1.1.1)
CODEFAB (branch: 1.1.1)

The Sticky Options indicate that the file is being handled as a binary file. The working version and branching information is fallout from doing a cvs import. As soon as you commit any file, the working revision of that file will become "1.2" (etc). This may seem odd, but can actually be quite helpful when tracking and modifying third part sources. It means that you can always switch to the branch of code containing exactly what was shipped to you, can then apply patches, and subsequently use 'cvs update' to apply the patches on the branch to the main trunk of development.

If the objects.nib did NOT have the -kb flag because you forgot to modify the cvswrappers file then, you would need to:

[localhost:FooApp/German.lproj/MainMenu.nib] bbum% cvs admin -kb objects.nib

This will add the binary flag. However, you *must* verify that the file hasn't been corrupted by cvs keyword expansion!!!! If it has been, you will need to:

[localhost:FooApp/German.lproj/MainMenu.nib] cp ~/FooProject/FooApp/German.lproj/MainMenu.nib/objects.nib objects.nib
[localhost:FooApp/German.lproj/MainMenu.nib] bbum% cvs commit -m 'Fixed objects.nib because keyword expansion blew it up. Copied original.'
cvs commit: Examining .
Checking in objects.nib;
/tmp/cvsroot/FooProject/FooApp/German.lproj/MainMenu.nib/objects.nib,v <-- objects.nib
new revision: 1.2; previous revision: 1.1
done

Note: If keyword expansion HAD actually blown up any of the files in your project, the diff command shown above would have identified the files that had been modified.

Note2: CVS keyword expansion basically substitutes various bits of information for things like $Id$ and $Log$. While they sound useful, they really aren't. In particular, they pretty much guarantee that any two revisions of a file will have differences. In particular, the $Log$ ensures that you will run into a constant stream of conflicts when updating your workarea. There are far better ways of dealing with this information.

Build the project and make sure it does what you expect.

Now that we have verified that the project works as checked out from the repository-- that it is identical to our originally imported source-- go ahead and remove the originally imported tree of goo to prevent making the mistake of doing any kind of development work on it. At this point, the cvs repository is your master copy. We basically ensure the cvs repository is backed up in at least 2 locations-- one via rsync to another host (a hot nightly backup) and one to tape. We treat workareas as totally throwaway; they are not backed up and the developer is encouraged to make sure they check in working code early and often. This minimizes integration issues and, combined with testing suites, ensures that the software continues to work as a system and not just as individual pieces.

[localhost:~/Developer] bbum% rm -rf ~/FooProject

That'll keep me from wasting more of my life doing unnecessary code integrations.... :-)

As you work with the project, always use 'cvs -q update -dP' to update your workarea. Do this often; more often then needed to simply pull changes from the repository. Not only will this reduce integration issues, it also gives you an inventory of every file in your workarea that isn't controlled by CVS. For example:

[localhost:~/Developer/FooProject/FooApp] bbum% cvs -q update -dP
? MyDocument.java
? German.lproj/MyDocument.nib

This indicates that I have a nib file and a java file in my workarea that are not in CVS. To add:

[localhost:~/Developer/FooProject/FooApp] bbum% cvs add MyDocument.java German.lproj/MyDocument.nib
? German.lproj/MyDocument.nib/classes.nib
? German.lproj/MyDocument.nib/info.nib
? German.lproj/MyDocument.nib/objects.nib
cvs server: scheduling file `MyDocument.java' for addition
Directory /tmp/cvsroot/FooProject/FooApp/German.lproj/MyDocument.nib added to the repository
cvs server: use 'cvs commit' to add this file permanently

OK-- I added the .niib directory, and now CVS is telling me the contents of that directory are not under CVS control. Need to add those, as well:

[localhost:~/Developer/FooProject/FooApp] bbum% cvs add German.lproj/MyDocument.nib/*.nib
cvs server: scheduling file `German.lproj/MyDocument.nib/classes.nib' for addition
cvs server: scheduling file `German.lproj/MyDocument.nib/info.nib' for addition
cvs server: scheduling file `German.lproj/MyDocument.nib/objects.nib' for addition
cvs server: use 'cvs commit' to add these files permanently

Finally, another cvs update to check the status on my workarea:

[localhost:~/Developer/FooProject/FooApp] bbum% cvs -q update -dP
bbum@localhost's password:
A MyDocument.java
A German.lproj/MyDocument.nib/classes.nib
A German.lproj/MyDocument.nib/info.nib
A German.lproj/MyDocument.nib/objects.nib

Might as well check to make sure that the objects.nib will be handled as a binary file:

[localhost:~/Developer/FooProject/FooApp] bbum% cvs status -v German.lproj/MyDocument.nib/objects.nib
===================================================================
File: objects.nib Status: Locally Added

Working revision: New file!
Repository revision: No revision control file
Sticky Tag: (none)
Sticky Date: (none)
Sticky Options: -kb

Yup; commit:

[localhost:~/Developer/FooProject/FooApp] bbum% cvs -q commit -m 'Added MyDocument interface and implementation [interface in German only, for now].'
RCS file: /tmp/cvsroot/FooProject/FooApp/MyDocument.java,v
done
Checking in MyDocument.java;
/tmp/cvsroot/FooProject/FooApp/MyDocument.java,v <-- MyDocument.java
initial revision: 1.1
done
......
Checking in German.lproj/MyDocument.nib/objects.nib;
/tmp/cvsroot/FooProject/FooApp/German.lproj/MyDocument.nib/objects.nib,v <-- objects.nib
initial revision: 1.1
done

See the other message for a bunch of hints/tips regarding "power" use of CVS. Some final tips:

- if you cp -r a NIB file (or Save As.... from Interface Builder), *** MAKE SURE *** you remove the CVS directory from the COPY. DO NOT SCREW THIS UP. If you do screw it up, you are in for a bit of hell undoing the problem. Notably, CVS really doesn't care about directories-- the copied CVS entries will cause the contents of the .nib to effectively overwrite the original version. Thankfully, everything is revision controlled, so you should be able to recover the original versions. But straightening out your workarea and the repository is not fun. If I get a chance, I'll write up an email demonstrating exactly how much fun it isn't.

- CVL.app is an excellent CVS GUI. Check it out; see SoftTrak at www.stepwise.com to find the latest version. Even with a good GUI, it is a wise idea to understand what is going on under the covers. CVL (and others) basically drive the command line cvs by stuffing various permutations of arguments and executing the command line binary via, say, NSTask.

- Project Builder's SCM integration is almost very very cool. At this point, I use it to view differences between my workarea and repository, but I use the command line to take care of all actual read/write operations. It will likely get better in future releases.

good luck,
b.bum

---

* if we were really starting from scratch, I would do:

bbum% cvs -t -d borg.codefab.com:/some/path/cvsroot/ init

... to initialize the repository. I could then check out the CVSROOT directory....

[localhost:~] bbum% cvs -d borg.codefab.com:/some/path/cvsroot/ checkout CVSROOT
cvs server: Updating CVSROOT
U CVSROOT/checkoutlist
U CVSROOT/commitinfo
U CVSROOT/config
U CVSROOT/cvswrappers
.....

...and add the objects.nib specification to cvswrappers...

[localhost:~] bbum% cd CVSROOT
[localhost:~/CVSROOT] bbum% tail cvswrappers
# -k expansion mode value: b, o, kkv, &c
#
# and value is a single-quote delimited value.
# For example:
*.gif -k 'b'
*.tiff -k 'b'
*.jpeg -k 'b'
*.icns -k 'b'
objects.nib -k 'b'
*.rsrc -k 'b'
[localhost:~/CVSROOT] bbum% cvs commit -m 'Added an incomplete set of binary specs for Cocoa development.'
cvs commit: Examining .
Checking in cvswrappers;
/some/path/cvsroot//CVSROOT/cvswrappers,v <-- cvswrappers
new revision: 1.2; previous revision: 1.1
done
cvs server: Rebuilding administrative file database

You may also want to edit the cvsignore file and make sure it contains a reasonable set of files to ignore. Keep in mind that the ignore behavior is different between add and import-- one of the wonderful little quirks of CVSs ultra inconsistent design and implementation.

On Tuesday, June 26, 2001, at 01:58 AM, Stefan M. van den Oord wrote:

Thought cvswrappers sort of / kind of work and are included with OSX,
do not use them unless you absolutely have to.

Indeed today I discovered that the /Developer/Tools/cvswrappers doesn't work
with my Linux box (which has CVS 1.11.1). I understand the explanation about
avoiding tar-wrappers (I didn't feel to good about that anyway). But what
exactly should be done instead? Ian suggested adding objects.nib as a
binary, but I understand that EOModels need something as well?

I would greatly appreciate it if somebody could come up with a cvswrappers
that solves the same problems as /Developer/Tools/cvswrappers does, but that
also works with CVS 1.11.1.

Kind regards,

Stefan


--
Stefan M. van den Oord
email@hidden


  • Prev by Date: Re: PB widget
  • Next by Date: Re: Send action when textDidChange
  • Previous by thread: Re: [semi-OT] ADC Sherlock Plugins
  • Next by thread: Cocoa Template Type
  • Index(es):
    • Date
    • Thread