The Command Line, the File, and the Wardrobe

Recently, I’ve been working with a command file parsing feature of the Version Control command line. The command line has the option to pass in a file containing multiple commands to easily repeat the same set of operations, including both standard version control commands and working directory switching. Input can also be read from the command line if no filename is provided.

Why command files?

A command file performs multiple operations using the same connection to the application tier. In addition, only one instance of the tf application is opened, thus incurring the startup costs of a managed application only once. This reduces overhead and has a significant impact for a series of a few dozen commands. For longer series of commands, the gain is even more substantial.

How do I use a command file?

The command file switch is the "@" character, either followed by a file name if you wish to perform a previously saved set of commands ("tf @scriptfile.tfc") or by itself if you want input read from stdin ("tf @"). In either case, Version Control commands are not prefixed by tf.

What can they do?

It is important to note that command files are by default non-interactive. Many commands, such as undo, default to interactive mode when run from the command line. However, the /noprompt flag can be used to bypass warning messages and simply revert all files. In command files, /noprompt is assumed to be on unless the special command file command "setnoprompt" is set to false (i.e. "setnoprompt off" within a command file). Insert "setnoprompt on" to change the default back to /noprompt.

The command file parsing accepts a few more commands than standard command line Version Control commands do. The current working directory can be changed throughout the script with cd or chdir. Use "setnoprompt" to toggle the current prompting default behavior. Begin a line with "rem" to insert a comment to the command file. On a line by itself, write "exit” or "quit" to explicitly terminate the command file parsing.

Command files accept arguments, as well, permitting the same file to be used in a variety of circumstances. Within the file, %1 will be replaced with the first argument, %2 with the second, and so forth. Any number of such arguments may be used.

A sample command file

Suppose that one of the build engineers makes a new branch of the current source tree at the end of every development push. She might have the following command file which accepts three input parameters. The file might be run with

    tf @BuildProject.tfc GalacticExplorer 2.3 c:\projects

where BuildProject.tfc is a text file containing

    cd %3    workspace /new /server:TFSServer %1BuildWorkspace%2    get %1 /recursive    branch %1 %1V%2    checkin /comment:”This is build v%2 of %1”    label %1Build%2 /comment:”%1 Build %2” %1V%2    workspace /delete %1BuildWorkspace%2

This would create the workspace GalacticExplorerBuildWorkspace2.3. It then gets the GalacticExplorer project, branches off the new version in GalacticExplorerV2.3, and labels the new version. For each new build, she simply runs the command file with the project name, and the new build’s version number and local directory.

Command files are also useful for grouping a set of commonly used functions. For instance, one user might write a command file to undo all changes on a test subdirectory, check in all changes, and then get all files for the updated project.