Folder Rename and VaultHistoryItem
Moderator: SourceGear
-
- Posts: 5
- Joined: Tue Aug 31, 2010 3:01 pm
Folder Rename and VaultHistoryItem
Hello,
We are having a problem when parsing through the Vault history items supplied by the API.
The issue we are having resolves around renamed folders.
It appears that renaming a folder at a given point in time pushes that folder name change back through the past history, obliterating the history of the original folder name.
Here are the steps taken in Vault to recreate an example case:
In a given repository:
Create a folder named NewFolder
Inside that folder we add a file named NewFile.txt and Check it in
We rename that file from NewFile.txt to code.txt
We rename the folder NewFolder to Source.
resulting in the following folder/file structure... Source/code.txt
Now, through the API, we get a list of all the VaultHistoryItems using ProcessCommandHistory.
What we find when looping over these items is, that when we come to the item with a VaultHistoryType of Renamed (170), for the rename of "NewFolder/NewFile.txt" to "NewFolder/code.txt", the item details are thus:
Name = "parentfolders/Source/code.txt"
HistoricName = "parentfolders/Source/code.txt"
MiscInfo1 = "code.txt"
MiscInfo2 = "NewFile.txt"
This is somewhat bewildering, as at the time of the file rename, the folder it was in was named NewFolder, not "Source". "Source" is the name of the folder in the future! Is this the intended behavior?
When we view the history in the vault client, we also notice that any reference to "NewFolder" is now renamed "Source", from the point that the folder was created to the point that it was ACTUALLY renamed, it is listed as "Source".
Is this a bug?
Is there any way to get the actual path at the point in time that file was renamed?
We are having a problem when parsing through the Vault history items supplied by the API.
The issue we are having resolves around renamed folders.
It appears that renaming a folder at a given point in time pushes that folder name change back through the past history, obliterating the history of the original folder name.
Here are the steps taken in Vault to recreate an example case:
In a given repository:
Create a folder named NewFolder
Inside that folder we add a file named NewFile.txt and Check it in
We rename that file from NewFile.txt to code.txt
We rename the folder NewFolder to Source.
resulting in the following folder/file structure... Source/code.txt
Now, through the API, we get a list of all the VaultHistoryItems using ProcessCommandHistory.
What we find when looping over these items is, that when we come to the item with a VaultHistoryType of Renamed (170), for the rename of "NewFolder/NewFile.txt" to "NewFolder/code.txt", the item details are thus:
Name = "parentfolders/Source/code.txt"
HistoricName = "parentfolders/Source/code.txt"
MiscInfo1 = "code.txt"
MiscInfo2 = "NewFile.txt"
This is somewhat bewildering, as at the time of the file rename, the folder it was in was named NewFolder, not "Source". "Source" is the name of the folder in the future! Is this the intended behavior?
When we view the history in the vault client, we also notice that any reference to "NewFolder" is now renamed "Source", from the point that the folder was created to the point that it was ACTUALLY renamed, it is listed as "Source".
Is this a bug?
Is there any way to get the actual path at the point in time that file was renamed?
Last edited by jeffcarefusion on Fri Sep 03, 2010 2:09 pm, edited 1 time in total.
Re: Folder Rename and VaultHistoryItem
The history item is building names from folders as they currently appear in the tree. This is used to associate history items to the correct folder and used if a GET is used to retrieve an object at that particular time when mapped to the current tree.
Using ProcessCommandTxDetail() with the transaction which created the history would send back VaultTxDetailHistoryItem.ItemPath1 and VaultTxDetailHistoryItem.ItemPath2 which should provide the exact paths of the items as they occurred at that particular point in time.
Using ProcessCommandTxDetail() with the transaction which created the history would send back VaultTxDetailHistoryItem.ItemPath1 and VaultTxDetailHistoryItem.ItemPath2 which should provide the exact paths of the items as they occurred at that particular point in time.
Jeff Clausius
SourceGear
SourceGear
-
- Posts: 5
- Joined: Tue Aug 31, 2010 3:01 pm
Re: Folder Rename and VaultHistoryItem
Thank you Jeff, however I am still running into problems.
Here is what we are trying to do. We need to migrate one of our projects out of Vault and into another source control system, Mercurial. We are trying to do this and also retain the substantial history found in Vault (years). This means we need to walk through the Vault history and perform adds/deletes/renames.. etc as they occur and commit those changes into the other system.
Previously our approach was to call 'ServerOperations.ProcessCommandHistory', get an array of VaultHistoryItem. I found some code here in the forums that did this. I then iterate the VaultHistoryItems and group them by TxId. Then for each transaction group, I perform each operation as specified by the HistItemType property, rolling through each item, until finally committing that "transaction set". This seemed to work great until we noticed the issues mentioned previously regarding folder renaming.
After your post, I reworked the code to get an array of VaultTxHistoryItem through 'ServerOperations.ProcessCommandVersionHistory'.
I then use your recommendation and call ProcessCommandTxDetail() for each transaction, get a TxInfo object, and from that a list of VaultTxDetailHistoryItems. However, say for an add/create operation, if I attempt to do a GetOperation with the path found in ItemPath1, I receive an exception telling me that path does not exist.
(using the previously posted example if I attempt to do a get on "NewFolder/NewFile.txt", I receive an error that that path does not exist, presumably because currently in vault, NewFolder has been renamed to Source.)
I guess what it boils down to, is what is the appropriate approach through your API to get the history list, and recreate each transaction set walking forward through time. Is this possible?
Here is what we are trying to do. We need to migrate one of our projects out of Vault and into another source control system, Mercurial. We are trying to do this and also retain the substantial history found in Vault (years). This means we need to walk through the Vault history and perform adds/deletes/renames.. etc as they occur and commit those changes into the other system.
Previously our approach was to call 'ServerOperations.ProcessCommandHistory', get an array of VaultHistoryItem. I found some code here in the forums that did this. I then iterate the VaultHistoryItems and group them by TxId. Then for each transaction group, I perform each operation as specified by the HistItemType property, rolling through each item, until finally committing that "transaction set". This seemed to work great until we noticed the issues mentioned previously regarding folder renaming.
After your post, I reworked the code to get an array of VaultTxHistoryItem through 'ServerOperations.ProcessCommandVersionHistory'.
I then use your recommendation and call ProcessCommandTxDetail() for each transaction, get a TxInfo object, and from that a list of VaultTxDetailHistoryItems. However, say for an add/create operation, if I attempt to do a GetOperation with the path found in ItemPath1, I receive an exception telling me that path does not exist.
(using the previously posted example if I attempt to do a get on "NewFolder/NewFile.txt", I receive an error that that path does not exist, presumably because currently in vault, NewFolder has been renamed to Source.)
I guess what it boils down to, is what is the appropriate approach through your API to get the history list, and recreate each transaction set walking forward through time. Is this possible?
Re: Folder Rename and VaultHistoryItem
If you want to know what is happening, then looking at transaction details for a repository would be the way to go. It would let you know what happened and where at that particular time.
History on the other hand is set to provide you with a view of things as they would appear to someone used to Visual SourceSafe. That would not be my recommendation on how to get a look at things on a tx by tx basis.
HTH
History on the other hand is set to provide you with a view of things as they would appear to someone used to Visual SourceSafe. That would not be my recommendation on how to get a look at things on a tx by tx basis.
HTH
Jeff Clausius
SourceGear
SourceGear
-
- Posts: 5
- Joined: Tue Aug 31, 2010 3:01 pm
Re: Folder Rename and VaultHistoryItem
Jeff. I'm not sure I'm understanding.
I need to not just see what happened and where, but I need to actually GET the files out of vault into a local directory, in the correct state at that point in time, so that I can commit them to the other system. When I attempted to do this with vault paths I got out of the transaction details, I received errors that that path does not exist in vault, because (I think), as mentioned in previous posts, the folders had been renamed.
Is there any sample code you can point me to that deals with Transaction Details on the repository, rather than history items?
I need to not just see what happened and where, but I need to actually GET the files out of vault into a local directory, in the correct state at that point in time, so that I can commit them to the other system. When I attempted to do this with vault paths I got out of the transaction details, I received errors that that path does not exist in vault, because (I think), as mentioned in previous posts, the folders had been renamed.
Is there any sample code you can point me to that deals with Transaction Details on the repository, rather than history items?
Re: Folder Rename and VaultHistoryItem
Within ProcessCommandTxDetail() returns an array of VaultTxDetailHistoryItems.
For a rename operation, VaultTxDetailHistoryItems.ItemPath1 will be the path to the renamed object, and VaultTxDetailHistoryItems.ItemPath2 would be the name it was renamed to at the time of that transaction (not the current path). If you want additional info, HistoryItems may have additional info. However in the case of rename it just has the entries for object ids and what the old/names would be.
For a rename operation, VaultTxDetailHistoryItems.ItemPath1 will be the path to the renamed object, and VaultTxDetailHistoryItems.ItemPath2 would be the name it was renamed to at the time of that transaction (not the current path). If you want additional info, HistoryItems may have additional info. However in the case of rename it just has the entries for object ids and what the old/names would be.
Jeff Clausius
SourceGear
SourceGear
-
- Posts: 5
- Joined: Tue Aug 31, 2010 3:01 pm
Re: Folder Rename and VaultHistoryItem
Thank you for your reply. Unfortunately I was sidetracked for a period of time on another project so I did not get a chance to respond.
This is still not working for me. I am going to try to explain exactly what I am doing, the steps I take to create my sample repository, and include the code I am using to get the items out of vault. Hopefully with this information you can tell me Yes or No if what I want to do with your API is even possible. Here goes.
Ok, as stated previously, I need to recreate an entire vault repository history step by step in a different source control system. For the purpose of this post, lets just disregard the other system and the operations required therein.
The crux of what what I need to do is get files and folders out of vault and into a local directory for each revision or history step, as they appeared at that point in time one at a time. . Every move, every change, every rename, everything exactly as they happened in Vault. So I need the file in the correct folder with everything named correctly and whatever changes were included in that revision as it actually appeared at that point in time.
Here is what I have done locally as a "test repository"
In vault, I have a path $/Sandbox/jeff/ .
To this folder I add a new folder called "VaultSimpleTest". ( $/Sandbox/jeff/VaultSimpleTest )
In this folder I add another folder and call it "FolderA" ( $/Sandbox/jeff/VaultSimpleTest/FolderA )
Inside FolderA, I add a file named "FileOne.txt" ( $/Sandbox/jeff/VaultSimpleTest/FolderA/FileOne.txt )
I then rename FolderA to FolderB. ( $/Sandbox/jeff/VaultSimpleTest/FolderB)
The repository tree in Vault looks like this:
History by revision on the folder $/Sandbox/jeff/VaultSimpleTest looks like this:
History by Item on the folder $/Sandbox/jeff/VaultSimpleTest looks like this:
Now here is the problem. In the code I will go over below, when for example, I attempt to retrieve the file "$/Sandbox/jeff/VaultSimpleTest/FolderA/FileOne.txt" @ Version 1. I receive an error from vault stating that it does not exist. If while Debugging, I change this path to "$/Sandbox/jeff/VaultSimpleTest/FolderB/FileOne.txt", then it gets the file fine. However the path I find in the history items I am working with do not supply me with that path, only the FolderA path, which was the valid path at that point in time but for whatever reason Vault has retroactively renamed the folder.
I've worked the code down into a really simple demo application in C# (.net 3.5) whose source can be found here:
http://dl.dropbox.com/u/78912/VaultGetDemo.zip *
In pseudocode here is what I am doing.
Login to vault.
Set the working folder to a local folder on my filesystem.
Setup my GetOptions, Recursive, Overwrite=True etc.
Get VaultTxHistoryItem array from ServerOperations.ProcessCommandVersionHistory
For each VaultTxHistoryItem, i call ProcessCommandTxDetail with the corresponding transaction id, this gives me a TxInfo.
For each VaultTxDetailHistoryItem in TxInfo I examine each of the VaultTransactionHistoryItem's in it's HistoryItems array.
For each of these items I examine the HistItemType member to determine what operation was performed for that history step.
For a history type of Added (10), I perform a GetOperations.ProcessCommandGetVersion operation with the repository path found in the VaultTxDetailHistoryItem.ItemPath1, VaultTxDetailHistoryItem.Version, and the GetOptions I built previously. **
Continue this until all history items have been examined for each transaction
**For the purposes of this demo, I am not handling any other HistItemTypes as they are not needed to demonstrate the issue.
So, here is what happens.
Login fine.
Get history items fine.
Attempt to get $/Sandbox/jeff/VaultSimpleTest/FolderA fails, no object was found
Attempt to get $/Sandbox/jeff/VaultSimpleTest/FolderA/FileOne.txt, no object was found.
Of note here is that if I create a similar repository but do not perform the rename of FolderA to FolderB, then this all works just fine. It is the fault of the renaming that I am unable to get history items that have a renamed folder in their path.
So this is where I am stuck. I cannot figure out how to get items where any folder in it's path has been renamed, into the appropriate folders they should be in as they appeared at that date and time.
Is it possible? Is it just not possible to do it item by item like I need to?
*demo app operation: Fill in the text fields with the details to your vault server & repository an hit the Get History button. Operation logging will appear in the listbox marked Output.
This is still not working for me. I am going to try to explain exactly what I am doing, the steps I take to create my sample repository, and include the code I am using to get the items out of vault. Hopefully with this information you can tell me Yes or No if what I want to do with your API is even possible. Here goes.
Ok, as stated previously, I need to recreate an entire vault repository history step by step in a different source control system. For the purpose of this post, lets just disregard the other system and the operations required therein.
The crux of what what I need to do is get files and folders out of vault and into a local directory for each revision or history step, as they appeared at that point in time one at a time. . Every move, every change, every rename, everything exactly as they happened in Vault. So I need the file in the correct folder with everything named correctly and whatever changes were included in that revision as it actually appeared at that point in time.
Here is what I have done locally as a "test repository"
In vault, I have a path $/Sandbox/jeff/ .
To this folder I add a new folder called "VaultSimpleTest". ( $/Sandbox/jeff/VaultSimpleTest )
In this folder I add another folder and call it "FolderA" ( $/Sandbox/jeff/VaultSimpleTest/FolderA )
Inside FolderA, I add a file named "FileOne.txt" ( $/Sandbox/jeff/VaultSimpleTest/FolderA/FileOne.txt )
I then rename FolderA to FolderB. ( $/Sandbox/jeff/VaultSimpleTest/FolderB)
The repository tree in Vault looks like this:
History by revision on the folder $/Sandbox/jeff/VaultSimpleTest looks like this:
History by Item on the folder $/Sandbox/jeff/VaultSimpleTest looks like this:
Now here is the problem. In the code I will go over below, when for example, I attempt to retrieve the file "$/Sandbox/jeff/VaultSimpleTest/FolderA/FileOne.txt" @ Version 1. I receive an error from vault stating that it does not exist. If while Debugging, I change this path to "$/Sandbox/jeff/VaultSimpleTest/FolderB/FileOne.txt", then it gets the file fine. However the path I find in the history items I am working with do not supply me with that path, only the FolderA path, which was the valid path at that point in time but for whatever reason Vault has retroactively renamed the folder.
I've worked the code down into a really simple demo application in C# (.net 3.5) whose source can be found here:
http://dl.dropbox.com/u/78912/VaultGetDemo.zip *
In pseudocode here is what I am doing.
Login to vault.
Set the working folder to a local folder on my filesystem.
Setup my GetOptions, Recursive, Overwrite=True etc.
Get VaultTxHistoryItem array from ServerOperations.ProcessCommandVersionHistory
For each VaultTxHistoryItem, i call ProcessCommandTxDetail with the corresponding transaction id, this gives me a TxInfo.
For each VaultTxDetailHistoryItem in TxInfo I examine each of the VaultTransactionHistoryItem's in it's HistoryItems array.
For each of these items I examine the HistItemType member to determine what operation was performed for that history step.
For a history type of Added (10), I perform a GetOperations.ProcessCommandGetVersion operation with the repository path found in the VaultTxDetailHistoryItem.ItemPath1, VaultTxDetailHistoryItem.Version, and the GetOptions I built previously. **
Continue this until all history items have been examined for each transaction
**For the purposes of this demo, I am not handling any other HistItemTypes as they are not needed to demonstrate the issue.
So, here is what happens.
Login fine.
Get history items fine.
Attempt to get $/Sandbox/jeff/VaultSimpleTest/FolderA fails, no object was found
Attempt to get $/Sandbox/jeff/VaultSimpleTest/FolderA/FileOne.txt, no object was found.
Of note here is that if I create a similar repository but do not perform the rename of FolderA to FolderB, then this all works just fine. It is the fault of the renaming that I am unable to get history items that have a renamed folder in their path.
So this is where I am stuck. I cannot figure out how to get items where any folder in it's path has been renamed, into the appropriate folders they should be in as they appeared at that date and time.
Is it possible? Is it just not possible to do it item by item like I need to?
*demo app operation: Fill in the text fields with the details to your vault server & repository an hit the Get History button. Operation logging will appear in the listbox marked Output.
Re: Folder Rename and VaultHistoryItem
I see your local client instance tree cache is the latest and greatest, and you are passing a historical path to retrieve the file. The server looks up the old path, and spits back the file is invalid because the path is not the current path to the item.
I don't know if the API could handle this case as I believe it always assumes you are working with the current tree, not with paths that existed X transactions ago.
What if you somehow processed moves / renames to "derive" the current path? To be honest, I don't know if that would work or not, but it might be something that solves your problem.
I don't know if the API could handle this case as I believe it always assumes you are working with the current tree, not with paths that existed X transactions ago.
What if you somehow processed moves / renames to "derive" the current path? To be honest, I don't know if that would work or not, but it might be something that solves your problem.
Jeff Clausius
SourceGear
SourceGear
-
- Posts: 5
- Joined: Tue Aug 31, 2010 3:01 pm
Re: Folder Rename and VaultHistoryItem
I've also considered that Jeff, I'm not sure if that would work or not, just thinking about it makes my head kind of hurt. Also, I've found that attempting to get a deleted file does not work either, so even if the above worked for moves/renames, I'm not sure how to get around the problem with deleted files.jclausius wrote: What if you somehow processed moves / renames to "derive" the current path? To be honest, I don't know if that would work or not, but it might be something that solves your problem.
** edit.. thinking more on this, maybe if I knew some file was deleted in the future, I wouldn't really care too much about getting each revision throughout it's history, for the purposes of this project anyways. I'll have to talk that over with some people here. Thanks!
Re: Folder Rename and VaultHistoryItem
I know this is old but I thought I would add my 2 cents in case anyone else came across this. You could get the version of the parent folder using GetOperations.ProcessCommandGetVersion() I think. I use GetOperations.ProcessCommandGetVersionToLocationOutsideWorkingFolder() personally and it works except it ignores GetOptions and does not delete files, so I have to start with an empty directory for each version.