Amos Shapira schrieb:
On 19/07/07, *Dirk* <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>> wrote:
But after I have introduced some more enhancements to the converter, I
have another idea:
One could write a "PreConversion Hook" in the sence of
MergeParentdata,
RemoveTemporaryCheckIns, MergeUnpinPinData or BuildComments and check
for these types of activities. With some tricks one could figure
out the
best timstamp and modify the conversion database. With these types of
hooks you can do almost anything to the database, that can be changed
without an in depth knowledge about the logical structure.
So what you area suggesting (and I'm not familiar with the code beyond
a cursory look a few weeks ago) is to leave the input file alone but
fake the timestamp via a hook so the rest of vss2svn will think it is
the better one?
If you can do some development work in perl, I would go for option 2. If
you are not familar with PERL, but familiar with C++ I would go for
modifying ssphys. If you are familar with a hexeditor, have a look at
the 010 Editor [1], you can modify the timestamps yourself. I have
attached a template file for the 010 Editor that can decode the phyiscal
files. This template file is from my first experiments with decoding the
archive.
I'm sorry, that I have very little time currently to do some
programming. Otherwise I would help with option 2. Until then I can only
help you with information.
Dirk
[1] http://www.sweetscape.com/010editor/
<cid:part1.02090807.00080101@nogga.de>
//--------------------------------------
//--- 010 Editor v1.3.2 Binary Template
//
// File:
// Author:
// Purpose: decodes general SourceSafe files like (aaaaaaaa)
//--------------------------------------
typedef struct {
long size;
char type[2];
short checksum;
} HEADER;
enum <ushort> ACTION {
Labeled = 0,
Created_Project = 1, //??
Added_Project = 2,
Added_File = 3,
Destroyed_Project = 4,
Destroyed_File = 5,
Deleted_Project = 6,
Deleted_File = 7,
Recovered_Project = 8,
Recovered_File = 9,
Renamed_Project = 10,
Renamed_File = 11,
// missing action 12,
// missing action 13
Shared_File = 14,
// missing action 15
Created_File = 16,
Checked_in = 17,
// missing action 18
RollBack = 19,
ArchiveVersions_File = 20,
ArchiveVersions_Project = 21,
Archive_File = 22,
Archive_Project = 23,
Restore_File = 24,
Restore_Project = 25,
// missing known actions: branches, archives, restores
};
typedef struct {
short flags; // 00 = item, 01 == project
char name[34]; // short name
long nsmap; // offset into the names.dat
} SSNAME;
typedef struct {
long previous; // previous ProjectEntry
ACTION action;
short version;
time_t date;
char user[32];
char label[32];
// offset zum nächsten EL record
long offsetToNextRecordOrComment2;
// After a rollback activity:
// this was a offset to the next FD record,
// and another time it was the files size
// Dies schient immer der comment zu sein. Im Falle eines Labels ist es der
LabelComment
long offsetToComment1; // MC record
// Länge der comments
short lengthComment2;
short lengthComment1;
} PROJENTRY;
typedef struct {
SSNAME name;
char physical[9];
} DUMMY_ACTION;
typedef struct {
int empty;
} CREATED_PROJECT_ACTION;
typedef struct {
SSNAME name;
char physical[9];
} DELETED_PROJECT_ACTION;
typedef struct {
SSNAME name;
char physical[9];
} RECOVERED_PROJECT_ACTION;
typedef struct {
SSNAME newName;
SSNAME oldName;
char physical[9];
} RENAMED_PROJECT_ACTION;
typedef struct {
SSNAME name;
char physical[9];
} RECOVERED_FILE_ACTION;
typedef struct {
SSNAME name;
char physical[9];
} DELETED_FILE_ACTION;
typedef struct {
SSNAME name;
short padding;
char physical[9];
} DESTROYED_FILE_ACTION;
typedef struct {
SSNAME name;
char physical[9];
} ADDED_FILE_ACTION;
typedef struct {
SSNAME name;
char physical[9];
} CREATED_FILE_ACTION;
typedef struct {
SSNAME newName;
SSNAME oldName;
char physical[9];
} RENAMED_FILE_ACTION;
typedef struct {
char srcPathSpec[260];
SSNAME name;
short padding1;
short pinnedToVersion;
short padding2; // Pinned?
char physical[10];
} SHARED_FILE_ACTION;
typedef struct {
SSNAME name;
char physical[9];
} ADDED_PROJECT_ACTION;
typedef struct {
char padding[8];
char checkInSpec[260];
} CHECKED_IN_ACTION;
typedef struct {
SSNAME name;
char physical[10];
char parent[10];
} ROLLBACK_ACTION;
typedef struct {
SSNAME name;
char physical[10];
char unknown2[12];
short version;
char targetFile[252];
} ARCHIVE_VERSIONS_ACTION;
typedef struct {
SSNAME name;
char physical[10];
short dummy;
char filename[264];
} ARCHIVE_ACTION;
typedef struct {
SSNAME name;
char physical[10];
short dummy;
char filename[264];
} RESTORE_ACTION;
typedef struct {
short type; // 1 Project, 2 File
short numberOfRecords;
// This is the last name that was given to the item
SSNAME name;
short firstVersion;
char fileExt[2]; // .A or .B
// offsets for records
int i1; // first EL Header
int i2; // last EL oder FD HEader
int i3; // size of the file
} DH;
typedef struct {
char dummy4[20];
// 0x00 initial
// 0x02 == binary
// 0x04 == store only latest revision
// 0x41 == checked out
// 0x20 == shared
short flag;
char shareSrcSpec[10];
unsigned long offsetBFRecord;
unsigned long offsetPFRecord; // offset to the last PF record in der Liste
short numberOfBranches;
short numberOfReferences; // Reference count for the item
unsigned long offsetCFRecord1; // file checked out, ptr to CF record
unsigned long offsetCFRecord2; // file not checked out, ptr to CF record
int unknown1; // changes after checkin
char dummy5[8];
// diese scheinen immer Paare zu bilden, nach einem Checkin ändert sich
// der d11, d21
// d12 == d22 == d32
short d11;
short d12;
short d21;
short d22;
short d31;
short d32;
char dummy6[4];
// dito wie dxx, jedoch zum ersten mal nach einem Checkin
short e11;
short e12;
short e21;
short e22;
short e31;
short e32;
char dummy7[200];
short numberOfItems; // including projects
short numberOfProjects; // number of subprojects
} DH_ITEM;
typedef struct {
char dummy4[20];
char parentSpec[34]; // of last checkout
char dummy7[226];
char parentPhys[9];
char dummy8[3];
short numberOfItems; // including projects
short numberOfProjects;
} DH_PROJECT;
typedef struct {
char user[32];
char padding[4];
// zusammen 260?
char CheckOutFolder[256];
char padding2[4];
char computer[32];
// zusammen 260
// char parentSpec[80];
// char fileSpec2[60];
// char padding3[120];
char parentSpec[260];
char comment[13];
char padding4[51];
// initial alles 0
// Check Out: flag1=01, flag2=40, flag3=00
// Check In : flag1=00, flag2=00, flag3=10
char flag1;
char padding5;
char flag2;
char padding6[8];
char flag3;
int numberOfVersions;
} CF;
typedef struct {
long previous;
char parent[10];
short padding;
} PF;
typedef struct {
int dummy;
} MC;
typedef struct {
int command; // 01 copy, 00 replace, 02
long start;
long end;
} FD;
typedef struct {
long previous;
char branch[10];
short dummy2;
} BF;
char fileHeader[0x34];
local long currentPos = 0;
local long len;
local long count = 0;
while (!FEof())
{
HEADER h;
currentPos = FTell ();
if (h.type == "DH")
{
DH dh;
if (dh.type == 1)
DH_PROJECT project;
else
DH_ITEM item;
}
else if (h.type == "CF")
{
CF cf;
}
else if (h.type == "PF")
{
// Zeigt auf einen weiteren Share (ProjectFolder?)
PF pf;
}
else if (h.type == "FD")
{
// forward delta?? oder file delta
FD fd;
}
else if (h.type == "BF")
{
// forward delta?? oder file delta
BF bf;
}
else if (h.type == "MC")
{
// einfacher String mit Länge h.size
len = h.size;
// char string[len];
}
else if (h.type == "EL")
{
PROJENTRY r;
if (r.action == Created_File)
{ CREATED_FILE_ACTION a; }
else if (r.action == Added_File)
{ ADDED_FILE_ACTION a; }
else if (r.action == Created_Project)
{ CREATED_PROJECT_ACTION a; }
else if (r.action == Added_Project)
{ ADDED_PROJECT_ACTION a; }
else if (r.action == Deleted_Project)
{ DELETED_PROJECT_ACTION a; }
else if (r.action == Recovered_Project)
{ RECOVERED_PROJECT_ACTION a; }
else if (r.action == Renamed_Project)
{ RENAMED_PROJECT_ACTION a; }
else if (r.action == Checked_in)
{ CHECKED_IN_ACTION d; }
else if (r.action == Shared_File)
{ SHARED_FILE_ACTION a; }
else if (r.action == Recovered_File)
{ RECOVERED_FILE_ACTION a; }
else if (r.action == Deleted_File)
{ DELETED_FILE_ACTION a; }
else if (r.action == Destroyed_File)
{ DESTROYED_FILE_ACTION a; }
else if (r.action == Renamed_File)
{ RENAMED_FILE_ACTION a; }
else if (r.action == RollBack)
{ ROLLBACK_ACTION a; }
else if (r.action == ArchiveVersions_File)
{ ARCHIVE_VERSIONS_ACTION a; }
else if (r.action == ArchiveVersions_Project)
{ ARCHIVE_VERSIONS_ACTION a; }
else if (r.action == Archive_File)
{ ARCHIVE_ACTION a; }
else if (r.action == Archive_Project)
{ ARCHIVE_ACTION a; }
else if (r.action == Restore_Project)
{ RESTORE_ACTION a; }
else if (r.action == Restore_File)
{ RESTORE_ACTION a; }
else // if (r.action == Checked_in)
{ DUMMY_ACTION r2; }
}
else if (h.type == "DH")
{
}
else
Warning ("unknown header %s", h.type);
FSeek (currentPos + h.size);
}
Warning ("%d EL Header", count);
_______________________________________________
vss2svn-users mailing list
Project homepage:
http://www.pumacode.org/projects/vss2svn/
Subscribe/Unsubscribe/Admin:
http://lists.pumacode.org/mailman/listinfo/vss2svn-users-lists.pumacode.org
Mailing list web interface (with searchable archives):
http://dir.gmane.org/gmane.comp.version-control.subversion.vss2svn.user