[cvsnt] Re: Remove old files from the repository?

John Cole john.cole at uai.com
Fri Jun 10 15:21:45 BST 2005


I had a similar question a few months ago and was able to follow the
directions to use WinCVS, but this only operated on a single file at a time.
Since I wanted to operate on all exe, dll, and ocx files, I wrote a NAnt
(http://nant.sf.net) script to parse the log output and delete all non-taged
files.  You could modify this to work with a date range instead.

It isn't fast and I've only run it on our test server, so use it at your own
risk :-)

John Cole
-----------------------------------------------------
<project name="DeleteFromCVS" default="main">

	<target name="main">
		<foreach item="File" property="filename">
		<in>
			<items>
				<include name="**/*.exe" />
			</items>
		</in>
		<do>
			<property name="cvs.dir"
value="${path::get-directory-name(filename)}" />
			<property name="cvs.file"
value="${path::get-file-name(filename)}" />
			<echo message="${cvs.dir}  -  ${cvs.file}" />
			<call target="cvs.delete" />
		</do>
	</foreach>
	</target>


	<target name="cvs.delete">
		<exec program="cvs" 
			workingdir="${cvs.dir}"
			commandline="log &quot;${cvs.file}&quot;" 
			output="temp.txt"/>

		<echo message="${cvs::get-non-sig('temp.txt')}" />
		
		<foreach item="String" in="${cvs::get-non-sig('temp.txt')}"
delim="|" property="rev">
			<echo message="cvs admin -o ${rev} ${cvs.file}
${cvs.dir}" />
			<exec program="cvs" 
				workingdir="${cvs.dir}"
				commandline="admin -o ${rev}
&quot;${cvs.file}&quot;" 
				/>
		</foreach>
	</target>
	
	<script language="C#" prefix="cvs">
		<code><![CDATA[
			[Function("get-non-sig")]
			public static string GetNonSigRevisions(string
pLogFile) {
				StreamReader sr = new
StreamReader(pLogFile);
				string line;
				Regex re0 = new Regex("^symbolic names:$");
				Regex re1 = new Regex("^\t(.*):(.*)$");
				Regex re2 = new Regex("^revision (.*)$");
				Regex re3a = new Regex("^branches:
(.*);$");
				Regex re3b = new
Regex("^----------------------------$");
				int mode = 0;
				string lastrev = "";
				System.Collections.Hashtable tags = new
System.Collections.Hashtable();
				System.Collections.Hashtable revs = new
System.Collections.Hashtable();
				while ((line = sr.ReadLine()) != null) {
					switch(mode) {
						case 0:  // find the
symbolic names switch to mode 1
	
if(re0.IsMatch(line)) {
								mode = 1;
							}
	
//Console.WriteLine(string.Format("Mode={0}", mode));
							break;
						case 1:	// read all of the
names and then switch to mode 2
	
if(re1.IsMatch(line)) {
								Match m =
re1.Match(line);
								if (!
tags.ContainsKey(m.Groups[2].ToString().Trim())) {
	
tags.Add(m.Groups[2].ToString().Trim(), m.Groups[1].ToString().Trim());
								}
	
//Console.WriteLine(line);
							} else {
								mode = 2;
	
//Console.WriteLine(string.Format("Mode={0}", mode));
							}
							
							break;
						case 2: // read in the
revision, switch to mode 3 to look for a branch point
	
if(re2.IsMatch(line)){
								Match m =
re2.Match(line);
								if
(NewBranch(m.Groups[1].ToString(), lastrev)){
									if
(! tags.ContainsKey(m.Groups[1].ToString().Trim())) {
	
tags.Add(m.Groups[1].ToString().Trim(), "tip");
									}
								}
								
								if (!
tags.ContainsKey(m.Groups[1].ToString().Trim())) {
	
revs.Add(m.Groups[1].ToString().Trim(), m.Groups[1].ToString().Trim());
								}
	
//Console.WriteLine(string.Format("{0} {1}", line,
NewBranch(m.Groups[1].ToString(), lastrev)));
								lastrev =
m.Groups[1].ToString();
								mode = 3;
							}
							break;
						case 3:	// look for branch
or end of rev log
	
if(re3a.IsMatch(line)){
								Match m =
re3a.Match(line);
								if (!
tags.ContainsKey(lastrev)) {
	
tags.Add(lastrev, "branch");
								}
								
								if
(revs.ContainsKey(lastrev)) {
	
revs.Remove(lastrev);
								}
	
							}
							
							
	
if(re3b.IsMatch(line)){
								mode = 2;
							}
							break;
					}
					
					
				}
				sr.Close();
	
				string ret = "";
				foreach (DictionaryEntry d in revs) {
					if (ret.Length > 0) ret += "|";
					ret += d.Value.ToString();
	
//Console.WriteLine(string.Format("{0} {1}", d.Key.ToString(),
d.Value.ToString()));
				}
	
				return ret;
			}
			
			public static bool NewBranch(string pV1, string
pV2){
				// this relies on the log appearing in order
				string [] a = pV1.Split('.');
				string [] b = pV2.Split('.');
				bool ret = false;
				if (a.Length == b.Length) {
					for (int i = 0; i < a.Length - 1;
i++ ) {
						if(a[i] != b[i]){
							ret = true;
						}
					}
					// check to see if this is the first
revision of a branch
					if (a[a.Length - 1] == "1"){
						ret = true;
	
//Console.WriteLine(string.Format("first revision {0}", pV1));
					}
						
						
				} else {
					ret = true;
				}
				
				return ret;
				
			}

		]]></code>
	</script>	
</project>
-----------------------------------------------------


> BEAUCHAMP, MICHAEL J. wrote:
>> I have a large web app with about 10,000 files (and growing).  For legal
>> reasons, my company wants to remove files or versions of files
>> (revisions) that are more than 2 years out of date. So far the only
>> thing I've found is the admin -o command and option, but aside from
>> being dangerous, I can't figure out a way to do more than one file at a
>> time in WinCVS. 
> 
> I haven't looked at it, but is the WinCVS method a script?  If it is, 
> then you could wrap it with a call for each file in your repository.

-------------------------------------
This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you have received this email in error please notify the system manager. This message contains confidential information and is intended only for the individual named. If you are not the named addressee you should not disseminate, distribute or copy this e-mail.



More information about the cvsnt mailing list