[Cocoapsql-developer] CVS: wrapping nib and other bundles nit a good idea
Status: Alpha
Brought to you by:
alkirkus
From: Olaf v. O. <ol...@ad...> - 2002-06-01 15:00:36
|
Please read when you have nothing else to do: copy of = http://developer.apple.com/techpubs/macosx/DeveloperTools/ProjectBuilder/P= rojectBuilder. help/Contents/Resources/English.lproj/SCM/Storing_Nib_ile_Bundles.html Storing Nib Files and Other File Bundles Many files in a project are bundles, which are directories that are=20 treated as a single file. Examples include Interface Builder's .nib=20 files and TextEdit's .rtfd files. By default, CVS manages each file in=20= the package individually. So if you wanted to check out a nib file, say,=20= you would need to check out each file in the nib file bundle=20 individually. You can set up CVS to treat a file package as a wrapper.=20= CVS converts a wrapper to a tar archive when it checks the wrapper in=20 and un-tars the wrapper when it checks the wrapper out. CVS manages the=20= tar archive in the repository, instead of individual files in the=20 package. To set up CVS to handle file packages as wrappers: * The CVS administrator must add and commit a cvswrappers file to = the=20 repository's top-level CVSROOT directory. * If you're using client/server CVS, all users must place that=20 cvswrappers file at the top level of their home directories. Tip: A sample cvswrappers file is in /Developer/Tools. You can rename=20 cvswrappers to .cvswappers so it's hidden in file listings. ------------------------------------------------------------------------ =A9 2002 Apple Computer, Inc. (Last Updated March 21, 2002) But the discussion on mamasam=20 (http://cocoa.mamasam.com/MACOSXDEV/2001/06/2/8522.php) of june 2001=20 (topic =3D CVS & .nibs) I understand that "taring" is not the solution. An other comment: My setup is as follows: CVS repository located on a FreeBSD box (remotehost) CVS 1.11 (client/server) CVSROOT/cvswrappers has nothing but binary entries. =A0The only addition I've made is a binary entry for objects.nib. Mac OS X 10.0.4 (localhost) CVS 1.10 'halibut' (client/server) CVS_RSH=3Dssh CVSROOT=3D:ext:<EMAIL REMOVED>:/path/to/repository I use ssh-agent/ssh-add so that I don't have to enter my password on=20 every CVS command I open Project Builder for the command line ('open my.pbproj') so that = it gets the environment variables needed by ssh and CVS. I've had no problems working on WebObjects and Cocoa projects with this setup. =A0I didn't do anything special for eomodels. =A0The nice thing = about _not_ using tar-wrappers for things like eomodels is that you can cvs=20 diff the individual plist for an entity. I've also used CVS 1.11 to checkout/update but can't say I've ever used=20= it for an emodel/nib because I usually only use CVS 1.11 (on the FreeBSD=20 box) =A0=A0for things like documentation. =A0However, I don't think there'd = be any problem there. Works for me :) hope that helps, -- Ian P. Cardenas Computer Scientist, Software ------------------------------------------------------------------------ http://cocoa.mamasam.com/MACOSXDEV/2001/06/2/8527.php FROM: Bill Bumgarner DATE: 2001-06-26 16:37 [Taking the liberty of cross posting because this'll probably be useful to a number of folks on all three lists. =A0 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. =A0 =A0As 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. =A0The 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. =A0 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. =A0 So, I start by building a directory structure something like: FooProject/ =A0=A0 =A0 =A0 =A0README.txt =A0=A0 =A0 =A0 =A0FooApp/ =A0=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0... 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. =A0CVS takes that attitude that once something has been = added to a repository, subsequent removal should be a fully audited event. =A0As= such, it can be a pain to remove files/directories after the initial import. =A0You 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. =A0 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 <EMAIL REMOVED>'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: =A0 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*. =A0Yes, delete it. =A0This will prevent you = from continuing development in that tree of stuff. =A0 =A0A 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. =A0So: [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. =A0 (omit the -x CVS and you will see that there are differences; =A0the 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D File: objects.nib =A0 =A0 =A0 Status: Up-to-date =A0=A0 =A0Working revision: =A0 =A01.1.1.1 =A0=A0 =A0Repository revision: 1.1.1.1 /tmp/cvsroot/FooProject/FooApp/French.lproj/MainMenu.nib/objects.nib,v =A0=A0 =A0Sticky Tag: =A0 =A0 =A0 =A0 =A0(none) =A0=A0 =A0Sticky Date: =A0 =A0 =A0 =A0 (none) =A0=A0 =A0Sticky Options: =A0 =A0 =A0-kb =A0=A0 =A0Existing Tags: =A0=A0 =A0 =A0 =A0 REL_000 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= (revision: 1.1.1.1) =A0=A0 =A0 =A0 =A0 CODEFAB =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= (branch: 1.1.1) The Sticky Options indicate that the file is being handled as a binary file. =A0 The working version and branching information is fallout from doing a cvs import. =A0 As soon as you commit any file, the working revision of that file will become "1.2" (etc). =A0 This may seem odd, = but can actually be quite helpful when tracking and modifying third part sources. =A0 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. =A0However, you *must* verify that the = file hasn't been corrupted by cvs keyword expansion!!!! =A0If 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. =A0Copied original.' cvs commit: Examining . Checking in objects.nib; /tmp/cvsroot/FooProject/FooApp/German.lproj/MainMenu.nib/objects.nib,v=20= =A0<-- =A0 objects.nib new revision: 1.2; previous revision: 1.1 done Note: =A0If 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: =A0CVS keyword expansion basically substitutes various bits of information for things like $Id$ and $Log$. =A0While they sound useful, they really aren't. =A0 In particular, they pretty much guarantee that = any two revisions of a file will have differences. =A0In particular, the = $Log$ ensures that you will run into a constant stream of conflicts when updating your workarea. =A0There 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. =A0At this = point, the cvs repository is your master copy. =A0We 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. =A0 We treat workareas as totally throwaway; =A0they are not backed up and the developer is encouraged to make sure they check in working code early and often. =A0This 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. =A0Do this often; =A0more often then needed to simply = pull changes from the repository. =A0 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. =A0For 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. =A0 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. =A0Need 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 <EMAIL REMOVED>'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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D File: objects.nib =A0 =A0 =A0 Status: Locally Added =A0=A0 =A0Working revision: =A0 =A0New file! =A0=A0 =A0Repository revision: No revision control file =A0=A0 =A0Sticky Tag: =A0 =A0 =A0 =A0 =A0(none) =A0=A0 =A0Sticky Date: =A0 =A0 =A0 =A0 (none) =A0=A0 =A0Sticky Options: =A0 =A0 =A0-kb Yup; =A0commit: [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 =A0<-- =A0MyDocument.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 = =A0 <-- =A0 objects.nib initial revision: 1.1 done See the other message for a bunch of hints/tips regarding "power" use of CVS. =A0 Some final tips: - if you cp -r a NIB file (or Save As.... from Interface Builder), =A0*** MAKE SURE *** you remove the CVS directory from the COPY. =A0DO NOT = SCREW THIS UP. =A0If you do screw it up, you are in for a bit of hell undoing the problem. =A0Notably, CVS really doesn't care about directories-- the copied CVS entries will cause the contents of the .nib to effectively overwrite the original version. =A0Thankfully, everything is revision controlled, so you should be able to recover the original versions. =A0But= straightening out your workarea and the repository is not fun. =A0 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. =A0Check it out; =A0see SoftTrak at www.stepwise.com to find the latest version. =A0 Even with a good GUI, = it is a wise idea to understand what is going on under the covers. =A0CVL (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. =A0 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. =A0 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. =A0I could then check out the CVSROOT directory.... [localhost:~] bbum% cvs -d borg.codefab.com:/some/path/cvsroot/ =A0 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 # =A0-k =A0 =A0 =A0 =A0 =A0 expansion mode =A0 =A0 =A0 =A0 =A0value: b, = o, kkv, &c # # =A0and 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 =A0<-- =A0cvswrappers 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. =A0Keep 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. |