TweetFollow Us on Twitter

Version Control on a Budget

Volume Number: 22 (2006)
Issue Number: 10
Column Tag: CVS

Version Control on a Budget

A Non-Developers Introduction to CVS

by Jose R.C. Cruz

Introduction

When working on a computer-based project, you often rely on some form of version control system to keep track of all work and changes made to your project files. Such a system allows you to create official archives of your project and provide you with an isolated local copy that you can work on. It also allows you and other participants to coordinate your contributions to the project.

This article will introduce you to the basic concept of version control using the open-source tool, CVS. This tool is preinstalled in all versions of MacOS X, and is accessed via the Terminal application located in the /Applications/Utilities directory.

The Concurrent Versioning System

What is CVS?

The Concurrent Versions System (CVS) is an open-source software tool that provides centralized version control on POSIX-compatible systems. It is originally developed from an earlier versioning system call the Revision Control System (RCS), which can manage changes, made to individual files, but not to whole projects.

The source code to CVS was released for public distribution in June 1986. An improved version of the tool was released on April 1989 under the GNU Public License. The version of CVS that comes installed in MacOS X is version 1.10 (for OS X 10.3.9), and version 1.11.18 (for OS X 10.4).

Advantages and disadvantages of CVS

One notable advantage of CVS is that it is available for a wide variety of operating systems. It is also one of the few version control systems that behave consistently across platforms. For example, CVS can store and maintain its project archives on a Linux server, while providing local copies of its archives for MacOS X and Windows XP users.

Another advantage of CVS is that it works independently of your project environment. For instance, you can use CVS to maintain archives of your XCode project as well as your Adobe GoLive web pages. Some might find this lack of tight integration to be a hindrance however. But, if your project environment is scriptable, you can always use your favorite scripting tool to integrate CVS with your environment.

Finally, CVS is much more forgiving than most commercial packages. In fact, these commercial packages use concepts and procedures similar to that of CVS. Once you have mastered using CVS, your learning curve would be less steep, when you upgrade to a commercial and more sophisticated system.

The biggest disadvantage of CVS is that it is originally designed to manage text files. Its support for binary file formats is rudimentary at best. Files such as spreadsheets, JPEGs, etc., are often stored in their entirety, causing the project archive to slowly grow to unmanageable sizes. However, this limitation is not unique to CVS. Many commercial packages provide limited support, if any at all, for binary files.

Another disadvantage is that CVS is designed to handle ASCII text files. It has problems dealing with Unicode and non-ASCII files. However, this limitation is being addressed in the open-source tool, Subversion, which is being developed as a potential successor to CVS.

Yet another (though minor) disadvantage of CVS is that it is still primarily a command-line tool. If you are more comfortable working with a point-and-click system, there are a number of free and open-source solutions that provides a graphical user interface to CVS. A notable example is the MacCVSClient X application, which is written by J. Bullmann, and available at the URL:

<http://www.heilancoo.net/MacCVSClient>

Preparing the Repository

The CVSROOT environment variable

Before using CVS, you first have to set the CVSROOT environment variable. This is used to store the default location of the CVS repository. This article assumes that you are using bash as your shell environment. You can find out which shell you are using by launching the Terminal application and typing printenv SHELL at the command prompt. If you are not using bash, type man "shell_name" at the command prompt for instructions on how to configure your own shell environment.

First you need to create the shell startup file, .bash_profile in the root of your home directory. Use your favorite text editor to create this hidden file. Some recommended editors are BBEdit, Smultron, emacs, and the venerable vi. Insert the following script at the beginning of the file and then restart the Terminal application.

# Start of CVS configuration
CVSROOT = /Users/Shared/Projects
export CVSROOT
#..end of CVS configuration

This script tells CVS to store its repository in /Users/Shared/Projects. Every CVS command thereafter will affect the project archives stored at this location.

You can always assign your own directory path for your CVS repository. Alternatively, you can override the default location by using the -d global option whenever you type a CVS command.

Creating and configuring the repository

After setting the CVSROOT variable, type cvs -init to initialize the repository. Once successful, CVS will create a directory named CVSROOT at the location specified by its environment variable. It will also populate the directory with a number of files (Table 1Table 1Table 1) that are used to configure the repository.



Table 1. List of common CVSROOT files.

Amongst these files, the cvswrappers file is the one that tells CVS how to store each project file. By default, CVS will convert the line ending characters found in each file to a form appropriate for the host system. It will also attempt to expand any keywords that it finds in each file. However, these behaviors can corrupt a purely binary file. . As created, cvswrappers contains only comments. . Take a look at the all-text cvswrappers to customize it for your needs. You need to update the cvswrapper file if you plan to store binary files in your project archive. If, for example, you want to include JPEG and GIF files to your archive, add the following lines to the file.

   *.jpg -k 'b' -m 'COPY'
   *.gif -k 'b' -m 'COPY'

These will tell CVS to store these binary files in their entirety.

Adding a project

You should now have a working CVS repository. To add your project to the repository, navigate to the location of your project directory by typing cd "project_directory_location" at the Terminal prompt. Then use the import command to add your website project to the repository.

cvs import -m ""short description of your project""- 
   "archive_name" "user_name" "release_tag"

Note: tThat entire command line is typed as a single line. The - character is there only to indicate the continuation of the line.

For example, if your website project directory is in

   /Volumes/Users/myHome/SitesmySit, te

type cd /Volumes/Users/myHome/Sites at the Terminal prompt. Then use the import command to add your website project to the repository.

cvs import -m ""short description of your project""- 
   "archive_name" "user_name" "release_tag"

Note that entire command line is typed as a single line. The - character is there only to indicate the continuation of the line.

So using the above example, you would Then, archive your website project by typing

cvs import -m "My website project"-
   " mySite Sites myName version_1_0

at the prompt.

CVS will then generate a series of messages as it parses each and every file and subdirectory in your project directory, as while creating it creates the project archive. When successful, your project will be stored in the same directory as CVSROOT under "archive_name" (Figure 1Figure 1Figure 1). However, iIf you decided not to continue with this archive, use the Finder to navigate to the directory where CVSROOT is stored. Then delete the "archive_name" directory by dragging it to the Trash and choosing Empty Trash from the Finder menu.



Figure 1. Structure of a CVS repository.

Working with the CVS Project

The CVS version number

CVS uses an internal version number system to keep track of which project file has been modified or branched. In its basic form, a CVS version number consists of at least two fields of the non-zero positive number, with each field delimited by a period (ASCII 0x2e). The format assumed by the version number is

   "project_number"."revision_number"[."branch_number"]

CVS increments the "revision_number" field each time you checked in a modified file back into the archive. However, when you create a branch off a specific file, CVS adds a "branch_number" for that branch. It then updates the field each time you checked in a modified version of that branched file. Additional "branch_number" fields are also added whenever you append new branches to that same file.

The "project_number" field remains mostly unchanged throughout the project. In fact, you must avoid interfering with the internal version system to prevent any orphan files or branches. If you want to assign your own version number to the project archive, use the cvs tag command, which will be covered later on.

Checking out a project or file

Now that you have a project archive in the CVS repository, you first have to check outretrieve a copy of that archive for you to work on. You do this by typing cvs checkout "project_name" at the Terminal prompt. Alternatively, if you want to check out a specific project file, type cvs checkout "project_file_path", where "project_file_path" is the directory path of the file with respect to the main project directory.

CVS will then create a local copy of the project or file on your present working directory. Each directory in this copy will be accompanied by a CVS subdirectory, which is used to store information about your local copy (Figure 3Figure 2Figure 2).



Figure 2. Structure of a checkout CVS project.

Once you have checked out your local copy, your username is automatically added to the CVS log. Other people working on the same project archive as you are, will be aware of your presence. So, if you are done with your local copy, type cvs release "project_name" at the Terminal prompt. CVS will first check and prompt you, if you have any modified files in your copy. Once you answered YES to the prompt, it will no longer keep track of your copy. It will also remove you from its user log.

So, using the website example, you would type cvs checkout Sites, to retrieve a copy of your website project from the repository. The project directory, Sites, will then be created in your present working directory, and it will contain at least one CVS subdirectory. Once you are done making changes to your website, type cvs release Sites to inform CVS to cease keeping track of your local copy.

Adding a new file or directory

Suppose you have created a new file or directory in your local copy, and you want to add it to the project archive. To do so, type cvs add "new_directory_path" at the Terminal prompt. Now unlike most commands, CVS does not automatically execute the add command. Instead, it queues the request into its command buffer. This ensures the integrity of your project archive by giving you a chance to cancel the request.

If you have decided to cancel the request to add the new file or directory, first move or delete the file or directory from your project directory. simply Then, type cvs remove "new_directory_path" at the Terminal prompt. This will tell CVS to remove the add request for that file or directory from its command buffer.

So, let us assume that you have added the file, hello.html, to your Sites project directory. To add that file to the project archive, type cvs add Sites/hello.html. To cancel the add request, remove the hello.html file from the Sites directory. Then type cvs remove Sites/hello.html to remove the request from the command buffer.

Updating your copy

As you work on your local copy, you may want to check your copy against the project archive periodically. Since CVS is designed from the start to support multiple users, others may have made changes that could impact your own. As you work on your local copy, you may want to check your copy against the project archive periodically. Naturally, this does not apply if you are the only one working on the project.

To check your copy against the archive, type cvs update at the Terminal prompt. You can also type cvs update --d, to include subdirectories that are present in the archive, but not in your local copy.

CVS will then scan every file in your local copy and compare their contents with those in the archive. If it comes across an unmodified local file older than the one in the archive, CVS will attempt to replace that file with the latter. If, however, it comes across one that is modified, CVS will attempt to merge the local file with the one in the archive. It will then inform you of any conflicting changes, should the merge process fail s. It will also inform you of any files or directories on your local copy that are newer or non-existent in the project archive.

Reverting to a previous version

What if you have made a mistake when editing one of your local files? What if you decided to completely discard your changes for whatever reason? You can revert to the previous version of a project file by using the cvs update command.

First you need to know which previous revision of the file you want to revert (see the cvs log command later in this article). Once you have that established, type

cvs update -j "new-revision-number" -
 -j "old-revision-number" "filename"

at the Terminal prompt to start the reversion process.

CVS will first retrieve both revisions and then perform a join operation between the two files. The joined result then replaces your local copy. At this point, you can decide if you want to commit your reverted copy back into the project archive.

Committing your changes

You have made changes to some files on your local project. You have also added new files and/or subdirectories to your project as well. After considerable testing and review on your part, you are now ready to submit your changes to the project archive.

To do so, type cvs commit -m "reason for committal" at the Terminal prompt. CVS will then scan your local project, and update any files in the archive with your changes. It will also execute any addition or removal requests that are queued in the command buffer. However, if you only want to update a single file or subdirectory in the project archive, type cvs commit -m "reason for committal" "file_or_directory_name" at the prompt.

Again, let us assume that you have changed the title of your hello.html file, and then saved your changes. To commit that modified file to the archive, type

cvs commit -m -
"Changed the title of the hello.html file" Sites/hello.html 

at the prompt.

Always make sure to provide a brief and concise reason whenever each time you use the cvs commit command. Not providing a reason for the committal action is generally frowned upon in normal practice. It compromises the change history log of your project archive as well makes it difficult for you to revert to a previous version.

Also, always pay attention to the status messages (Listing 1Listing 1Listing 1) displayed by CVS during the committal process. If CVS encountered any errors, it will immediately stop the committal process after the last successful file or directory update. To preserve archival integrity, avoid attempting further committals until you (or your project manager) has isolated and resolved the error.

You also may want to avoid executing a committal request when the project archive is being backed up or undergoing maintenance. Consult your colleagues for internal rules governing the committal process.

Listing 1. Sample output of the cvs commit command.

Checking in Sites/hellohome.html;
/Users/Shared/Projects/Sites/helloome.html,v  <--  home.htmhello.html
new revision: 1.4; previous revision: 1.3
done

Reverting to a previous version

What if you have made a mistake when editing one of your local files? What if you decided to completely discard your changes for whatever reason? You can use the cvs update command to revert to the previous version of your files.

First, you need to know which previous revision of the file you want to revert to (see the cvs log command later in this article). Once you have that established, remove the file that you want to revert from, and type cvs update -r "revision_number" "filename" at the Terminal prompt. CVS will first warn you that you are missing a file, and then promptly update your local copy with the correct file.

On the other hand, if you have already committed your changes to the archive, type

cvs update -j "new_revision_number" -
 -j "old_revision_number" "filename" 

at the prompt to start the reversion process. CVS will first retrieve both revisions and then perform a join operation between the two files. The joined result then replaces your local copy. At this point, you can decide if you want to commit your reverted copy back into the project archive.

Using the website example, if your hello.html file is at version 1.4 in the archive, but you want to revert to version 1.3, type cvs update -j 1.3 -j 1.3 Sites/hello.html to revert to the desired version.

Exporting the project

Once you (and your colleagues) have finished submitting all your changes to the project archive, you should now you are now ready to export a copy of the archive for public distribution. This could mean preparing a software project for final compilation, an XML document for printing, or web pages a website for uploading.

First you prepare the project archive for exporting, by assigning it with a release tag. First, navigate to the project directory and tType cvs tag "release_tag" at the Terminal prompt, where "release_tag" would be your project's official version number. Make absolutely sure that no one is allowed to perform any committals while you are assigning the release tag. Otherwise, the wrong files may get tagged in the process.

Once you have assigned the tag, type

   cvs export --r "release_tag" -
      "export_destination" "project_archive"

at the Terminal prompt to export the project to the "export_destination" directory..

For example, if you want to export the website project, first navigate to the Sites directory by typing cd ~/Sites at the Terminal prompt. Then type cvs tag 1_0GM to assign the website with a release tag of 1.0GM.. Finally, type

cvs export -r v1_0GM /Volumes/Users/Public Sites

to export the entire website project to the directory /Volumes/Users/Public.

Make sure that your release tag contains only alphanumeric characters and/or an underscore. Also, make absolutely sure that no one is allowed to perform any committals while you are assigning the release tag. Otherwise, the wrong files may get tagged in the process.

Unlike Unlike a checked out project, an exported project does not contain the CVS subdirectories used to keep track of project changes. Any changes made to an exported project will not be committed back into the project archive. .

Furthermore, you cannot update an exported project with the latest changes from the archive. If you want to get the latest changes made to the archive, you will have to repeat the entire export procedure.

Streamlining the CVS process

Since CVS is a command-line tool, you may have noticed that using it involves a considerable amount of typing. You can reduce the amount of typing involved by using the appropriate command synonym. For example, instead of cvs checkout to check out a copy of the archive, use cvs get or cvs co. Also, instead of cvs update to run an update check, use cvs upd or cvs up.

You can get a list of other CVS command synonyms by typing cvs --help-synonym at the Terminal prompt.

You can also reduce the amount of typing by using the .cvsrc startup file (Listing 3Listing 2Listing 2) to assign the default options for each CVS command. You can use your favorite text editor to create and edit this hidden file in your home directory. Make sure to restart the Terminal application in order for the changes to take effect.

A typical CVS command line follows the format of

cvs "global_options" "cvs_command" "command_options". 

So each line in the .cvsrc file would be written down as "cvs_command" "command_options". Note that, if you have an entry of cvs "global_options" in the file, those options apply to all command sessions. You can always override these default options by adding a -f option to your CVS command.

For additional information about CVS command options, type man cvs at the Terminal prompt.

Listing 2. Sample contents of the .cvsrc startup file.

cvs --q --d "/Users/Library/Shared/Project/"
checkout --d "~/MyProject" --P
commit --l
export --f --P

Monitoring a CVS project

Tracking with sticky tags

As mentioned earlier, CVS uses an internal version number system to keep track of the files contained in your project archive. You can then specify which revision of the file you want to be updated to by using the -r command option. For example, typing

   cvs update -r 1.1 Sites/homehello.html

updates your local copy of home.html against version 1.1 of that same file in the archive.

A more flexible approach of keeping track of the archived files is through the use of sticky tags. Sticky tags enables you to tell CVS which branch or revision of the project archive you want to work on. You can use sticky tags to protect parts of your local copy from changes submitted to the archive. For example, you can tell CVS that your local copy uses version 1.2 of a specific file even though a new version of that file is available.

To set a sticky tag, type cvs checkout -r "revision_number" "project_name" when checking out a copy of the project archive. Alternatively, you can type cvs update -r "revision_number" "project_file_path" if you want to perform an update check at the specified revision.

You can also use dates as your sticky tag by using the -D command option. The format used by CVS for dates is "dd mmm yyyy" where mmm is the three-letter month abbreviation. For example, typing

   cvs update -D "15 Mar 2006" Sites/styles/defaulthello.html.css

updates your local copy of default.csshello.html to the one dated March 15, 2006 in the archive.

In either case, sticky tags permanently link your local copy to that version of the archive. Changes submitted to the archive will not appear on your local copy whenever you perform an update check. Also, for integrity reasons, you cannot commit any changes you have made until you clear all sticky tags. To do so, type cvs update -A at the Terminal prompt. Make sure to test your changes for errors and possible conflicts before submitting them to the archive, using the cvs commit command.

Tracking the differences

As you work on your local copy, you may want to check it against the project archive periodically for any potential conflicts. To display the differences between your local copy and the archive, type cvs diff "project_name" at the Terminal prompt. Alternatively, if you want to display only the differences in a specific file, type cvs diff "project_filename" instead.

In either case, CVS will parse your local copy and compare its contents against the archive. It will then display a report (Listing 5Listing 3Listing 3) showing what has changed between the two. By examining this report, you can identify any potential conflicts between your local copy and the archive.

Listing 3. Sample output of the cvs diff command.

Index: Sites/styles/default.csshello.html
===========================================================
RCS file: /Users/Shared/Projects/Sites/styles/default.csshello.html,v
retrieving revision 1.2
diff -r1.2 default.csshello.html
3c3
<       "contents of the archived revision"
---
>       "contents of the local revision"

You can also just type cvs update at the prompt to tell CVS to go ahead and update your local copy with the archive. If the archive contains changes that conflicts with your copy, CVS will mark those changes using the format shown in Listing 7Listing 4Listing 4. You then resolve the conflict by manually merging the two changes. Make sure to consult your colleagues for standard procedures on conflict resolution.

Listing 4. Format used by CVS to mark conflicting changes.

<<<<<<< "filename with conflicting changes"
   "changes in the local revision"
=======
   "changes in the archival revision"
>>>>>>> "archival_revision_number"

Tracking with logs

You can use CVS to keep track of the revision state and history of your project. The one you probably use most often is the cvs status command.

The cvs status command displays the current state of your local copy compared to the archive. It also displays the version number of your local files as well as any sticky tags you have assigned to those files. This command is normally used prior to cvs update, to give you an idea of how the update process might affect your local copy.

To display the current state of your local copy, type cvs status at the Terminal prompt. If you want to view the status of a particular file, type cvs status "project_file_path" at the prompt. In either case, CVS will generate a status log similar to the one shown in Listing 9Listing 5Listing 5. This log shows the current state of each file in your local copy, its sticky tags, and its CVS version number.

Listing 5. Sample output of the cvs status command.

===========================================================
File: news2002.htmhello.html        Status: Up-to-date
   Working revision:    1.1.1.1 Wed Mar  1 18:53:53 2006
   Repository revision: 1.1.1.1 /Users/Shared/Projects/Sites/pages/archives/news2006.htmhello.html,v
   Sticky Tag:          MkI (revision: 1.1.1.1)
   Sticky Date:         (none)
   Sticky Options:      (none)
===========================================================
File: lgp150.padfooter.html        Status: Up-to-date
   Working revision:    1.1.1.1 Wed Mar  1 18:53:53 2006
   Repository revision: 1.1.1.1 /Users/Shared/Projects/Sites/pages/mpad/lgp150.padfooter.html,v
   Sticky Tag:          MkI (revision: 1.1.1.1)
   Sticky Date:         (none)
   Sticky Options:      (none)
cvs status: Examining Sites/styles
===========================================================
File: default.css       Status: Up-to-date
   Working revision:    1.1.1.1 Wed Mar  1 18:53:53 2006
   Repository revision: 1.1.1.1 /Users/Shared/Projects/Sites/styles/default.css,v
   Sticky Tag:          (none)
   Sticky Date:         2006.03.15.08.00.00
   Sticky Options:      (none)

Another command that you can use is the cvs log command. This command allows you to display a revision history log of each file in your local copy. The log shows the location of the archived file, its current and previous version numbers, and its assigned tags. Also, for each revision, the log reveals the name of the user who worked on the file, the number of lines added or removed, and a description of what has been changed in that file. Note that, you can only use the cvs log command if you have checked out the project from the archive.

To display the revision history of a file in your local copy, type cvs log "project_file_path" at the Terminal prompt. If you want to display the revision history of the entire project, type cvs log "project_name" at the prompt. CVS will then generate a revision history log similar to the one shown in Listing 11Listing 6Listing 6.

Listing 6. Sample output of the cvs log command.

RCS file: /Users/Shared/Projects/Sites/hello.html,v
Working file: Sites/hello.html
head: 1.4
branch:
locks: strict
access list:
symbolic names:
        v1_0GM: 1.3
keyword substitution: kv
total revisions: 4;     selected revisions: 4
description:
----------------------------
revision 1.4
date: 2006/04/05 17:55:34;  author: kuronke;  state: Exp;  lines: +1 -1
Updated the body of hello.html
----------------------------
revision 1.3
date: 2006/04/04 19:18:45;  author: kuronke;  state: Exp;  lines: +1 -1
Added an entry to the body
----------------------------
revision 1.2
date: 2006/04/04 19:17:54;  author: kuronke;  state: Exp;  lines: +1 -1
Added an exclamation point to the title.
----------------------------
revision 1.1
date: 2006/04/04 19:03:54;  author: kuronke;  state: Exp;
Added the hello.html file
===========================================================
 RCS file: /Users/Shared/Projects/Sites/pages/booksale.htm,v
Working file: Sites/pages/booksale.htm
head: 1.5
branch:
locks: strict
access list:
symbolic names:
   MkIa: 1.5
   MkI: 1.1.1.1
   anarakis: 1.1.1
keyword substitution: kv
total revisions: 6;   selected revisions: 6
description:
----------------------------
revision 1.3
date: 2006/03/03 19:34:47;  author: user1;  state: Exp;  lines: +1 -1
Removed the conflict data
----------------------------
revision 1.2
date: 2006/03/03 19:10:13;  author: user1;  state: Exp;  lines: +1 -1
Removed irrelevant information from the booksale page
----------------------------
revision 1.1
date: 2006/03/01 18:53:53;  author: user2;  state: Exp;
branches:  1.1.1;
Initial revision
----------------------------
revision 1.1.1.1
date: 2006/03/01 18:53:53;  author: user1;  state: Exp;  lines: +0 -0
Original website project
===========================================================

Concluding remarks

The Concurrent Version System is a simple and cost-effective version control system that is bundled in every MacOS X release. It enables you and your colleagues to coordinate your contributions to the project while providing you the option to revert to a previous unaltered version of that same project. It also provides a number of features that allows you to keep track of various states of your project.

This article has only shown you the fundamental capabilities of CVS. If you are interested in learning more about the tool, especially its administrative and network features, you can consult any one of the online references listed at the end of this article.

Bibliography and References

Cederqvist, Per. Version Management with CVS. (c) 2003 Free Software Foundation. Online: <http://ximbiot.com/cvs/manual>.

Dreilinger, Sean, Moshe Bar. CVS Version Control for Website Projects. (c) 1998. Inter@active Consulting Group. Online: <http://durak.org/cvswebsites>.

Fogel, Karl. Open Source Development with CVS. (c) 1999, 2000 Karl Fogel. Online: <http://cvsbook.red-bean.com>.

Wikipedia. Concurrent Versions System. In Wikipedia, the free encyclopedia. The Wikipedia Community, Feb 2006. Online: <http://en.wikipedia.org/wiki/Concurrent_Versions_System>.


JC is a freelance engineering consultant currently residing in North Vancouver, BC. He divides his time between writing technical articles, and teaching origami to children at the local district public libraries.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

5 slither.io mash-ups we'd love to...
If there's one thing that slither.io has proved, it's that the addictive gameplay of Agar.io can be transplanted onto basically anything and it will still be good fun. It wouldn't be surprising if we saw other developers jumping on the bandwagon,... | Read more »
How to navigate the terrain in Sky Charm...
Sky Charms is a whimsical match-'em up adventure that uses creative level design to really ramp up the difficulty. [Read more] | Read more »
Victorious Knight (Games)
Victorious Knight 1.3 Device: iOS Universal Category: Games Price: $1.99, Version: 1.3 (iTunes) Description: New challenges awaits you! Experience fresh RPG experience with a unique combat mechanic, packed with high quality 3D... | Read more »
Agent Gumball - Roguelike Spy Game (Gam...
Agent Gumball - Roguelike Spy Game 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: Someone’s been spying on Gumball. What the what?! Two can play at that game! GO UNDERCOVERSneak past enemy... | Read more »
Runaway Toad (Games)
Runaway Toad 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: It ain’t easy bein’ green! Tap, hold, and swipe to help Toad hop to safety in this gorgeous new action game from the creators of... | Read more »
PsyCard (Games)
PsyCard 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: From the makers och Card City Nights, Progress To 100 and Ittle Dew PSYCARD is a minesweeper-like game set in a cozy cyberpunk... | Read more »
Sago Mini Robot Party (Education)
Sago Mini Robot Party 1.0 Device: iOS Universal Category: Education Price: $2.99, Version: 1.0 (iTunes) Description: -- Children's Technology Review Editor's Choice -- | Read more »
How to get a high score in every level o...
Sky Charms is an adorable match three puzzler that provides a decent challenge thanks to its creative level design. It regularly presents something new, forcing you to think on your feet. [Read more] | Read more »
Apestorm: Full Bananas (Games)
Apestorm: Full Bananas 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: ***Launch sale – limited time only!*** Fugitive Apes have taken to the skies in search of revenge after humans have... | Read more »
How to create bigger words in Spellspire
Words have power. At least they do in Spellspire,a game about blasting out magical attacks by making words out of a jumble of letters. And it's a lot of fun. But if you want to be the best, you're going to have to think tactically when you start... | Read more »

Price Scanner via MacPrices.net

15-inch 2.2GHz Retina MacBook Pro on sale for...
Amazon.com has the 15″ 2.2GHz Retina MacBook Pro on sale for $1699.99 including free shipping. Their price is $300 off MSRP, and it’s the lowest price available for this model from any reseller (and... Read more
Apple Beats Microsoft at Own Game; Amazon Pri...
First quarter seasonality combined with an overall disinterested customer base led to an annual decline of 14.7% in worldwide tablet shipments during the first quarter of 2016 (1Q16). Worldwide... Read more
Aleratec Releases Mac Software Upgrade for 1...
California based Aleratec Inc., designer, developer and manufacturer of Portable Device Management (PDM) charge/sync products for mobile devices and professional-grade duplicators for hard disk... Read more
Sale! Amazon offers 27-inch iMac, 13-inch 2.9...
Amazon has the 27″ 3.2GHz 5K iMac and the 13″ 3.9GHz Retina MacBook Pro on sale for $300 off MSRP, each including free shipping, for a limited time: - 27″ 3.2GHz/1TB HD 5K iMac (model MK462LL/A): $... Read more
Apple refurbished 13-inch Retina MacBook Pros...
Apple has Certified Refurbished 13″ Retina MacBook Pros available for up to $270 off the cost of new models. An Apple one-year warranty is included with each model, and shipping is free: - 13″ 2.7GHz... Read more
13-inch 2.7GHz/128GB Retina MacBook Pro on sa...
Take $200 off MSRP on the price of a new 13″ 2.7GHz/128GB Retina MacBook Pro (model MF839LL/A) at Amazon. Shipping is free: - 13″ 2.7GHz/128GB Retina MacBook Pro: $1099.99 $200 off MSRP Act now if... Read more
Apple refurbished clearance 15-inch Retina Ma...
Apple has Certified Refurbished 2014 15″ 2.2GHz Retina MacBook Pros available for $1609, $390 off original MSRP. Apple’s one-year warranty is included, and shipping is free. They have refurbished 15... Read more
27-inch 5K iMacs on sale for up to $150 off M...
B&H Photo has 27″ 5K iMacs on sale for up to $150 off MSRP including free shipping plus NY sales tax only: - 27″ 3.3GHz iMac 5K: $2199 $100 off MSRP - 27″ 3.2GHz/1TB Fusion iMac 5K: $1849.99 $150... Read more
What Does The Refreshed 12-Inch MacBook Tell...
A lot of commentators are complaining that Apple’s update of the 12-Inch MacBook last week is a bit of a damp squib. I don’t know what they were expecting, since it would be very unlike Apple to do a... Read more
Free Wittify Keyboard Now Available On The Ap...
A team of Harvard Business School students have announced that the Wittify Keyboard, a new app utility for iOS devices, is now available on the Apple App Store. The Wittify keyboard and application... Read more

Jobs Board

*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Solutions Consultant - Apple (United...
# Apple Solutions Consultant Job Number: 48260200 Phoenix, Arizona, United States Posted: Apr. 22, 2016 Weekly Hours: 40.00 **Job Summary** As an Apple Solutions Read more
Restaurant Manager (Neighborhood Captain) - A...
…in every aspect of daily operation. WHY YOU'LL LIKE IT: You'll be the Big Apple . You'll solve problems. You'll get to show your ability to handle the stress and Read more
Simply Mac *Apple* Specialist- Service Repa...
Simply Mac is the largest premier retailer of Apple products in the nation. In order to support our growing customer base, we are currently looking for a driven Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.