Jazz Forum Welcome to the Jazz Community Forum Connect and collaborate with IBM Engineering experts and users

Resolving path of IVersionable in selected state

 How to get path of file which isn't in newest version but is a part of previous changelist in RTC scm.

All I could achieve so far is this:

IFileItemHandle fileItemHandle = (IFileItemHandle) IFileItem.ITEM_TYPE.createItemHandle(change.afterState().getItemId(), change.afterState().getStateId());
file = versionableManager.fetchCompleteState(fileItemHandle, monitor);

if (file instanceof IFolder) {         
    IFolder folder = (IFolder) file;         
    relativePath = getFilePath(file, workspaceConnection.configuration(changeSet.getComponent()), monitor);
    fileName = folder.getName();      
} else {
    relativePath = getFilePath(file, workspaceConnection.configuration(changeSet.getComponent()), monitor);    
    fileName = ((FileItem) file).getName();     
}

Where getFilePath is:

private String getFilePath(IVersionableHandle folder, IConfiguration config, IProgressMonitor monitor, Boolean searchInHistory) throws TeamRepositoryException {
    List lst = new ArrayList<IVersionableHandle>(), ancestors;
    lst.add(folder);
    if (searchInHistory) {
        ancestors = config.determineAncestorsInHistory(lst, monitor);
    } else {
        ancestors = config.locateAncestors(lst, monitor);
    }

    return getFullPath(ancestors);
}

private String getFullPath(List ancestor) throws TeamRepositoryException {
    String directoryPath = "";
    for (Object ancestorObj : ancestor) {
        IAncestorReport ancestorImpl = (IAncestorReport) ancestorObj;
        for (Object nameItemPairObj : ancestorImpl.getNameItemPairs()) {
            INameItemPair nameItemPair = (INameItemPair) nameItemPairObj;
            String pathName = nameItemPair.getName();
            if (pathName != null && !pathName.equals("")) {
                directoryPath = directoryPath + "\\" + pathName;
            }
        }
    }
    return directoryPath;
}

Unfortunately it doesn't work perfectly. If filename is changed in following changelists like on this example:

Changelist 1:     
add file: src/newFile.java

Changelist 2:     
modify file: src/newFile.java

Changelist 3:     
rename file: src/newFile.java -> src/newFile_rename.java

The relative path resolved in first changelist would be:

src/newFile_rename.java

instead of

src/newFile.java

How to make it works good?

1

1 vote



2 answers

Permanent link
Just an observation, if I create three change sets, create file, modify file and then rename file, The summary shown in the pending changes view shows the original name in the first change set but the new name in the other two change sets. I'd expect only the final change set would show the new name.

Pending Changes view

1 vote


Permanent link
IFileItemHandle fileItemHandle = (IFileItemHandle) IFileItem.ITEM_TYPE.createItemHandle(change.afterState().getItemId(), change.afterState().getStateId());
You're asking for the after state. It seems you're getting the state of the file from changelist 3(maybe you mean change set) after the rename.

Check that you are fetching the correct state.

1 vote

Comments
I think I wasn't clear enough. This code refers to first changelist where there is no beforeState (new file added), that's why I'm using afterState().

For each specified item, retrieves the sequence of name-item pairs that leads to that item in the configuration starting at a root folder.

The javadoc for #determineAncestorsInHistory() retrieves the path segments as defined in the configuration. Since you're using the configuration that includes the file rename, that's the path that you get.

I recommend after you fetch the after state to use #getParent() and resolve the paths that way to get the path as it was when the change was made.

file = versionableManager.fetchCompleteState(fileItemHandle, monitor);
file.getName() // the filename before the rename
file.getParent() // parent folder handle, go up the tree to retrieve the other path segments

I've tried to use Mark Byrd's code which I've found here (method getParent3): https://jazz.net/forum/questions/94927/how-do-i-find-moved-from-location-for-a-movedreparented-item-using-rtc-4-java-api

This code is going through all parents of item and collecting their names. Unfortunately it doesn't work either.

Can you explain what does not work with it? It appears to have worked for him and the code looks reasonable (aside from path segments would be from the configuration used to fetch the parents). The filename would be correct as far as I can tell.

Maybe this example I posted in my question is not as good as I thought before. Let me show you a better one:

Changeset 1: add src/test/directory/filename.java
Changeset 2: modify src/test/directory/filename.java
Changeset 3: reparent src/test/directory -> src/test/directory_new
Changeset 4: reparent src/test -> src/test_new
While trying to resolve path of file from first changeset I'm getting path: src/test_new/directory_new/filename.java insead of src/test/directory/filename.java.

You're getting the path as it is in the configuration you used to fetch the item's parent folder.

 I don't understand what do you mean by this. IConfiguration object is based on component which contains all of those files. If I'm doing it wrong could you please give me some hint how to do it right? Mark's solution doesn't work for me at all. 

The IConfiguration describes the state of the component. The one you're using includes the all of the change sets. This means the path for that file in the configuration is src/test_new/directory_new/filename.java. Mark's solution doesn't handle this as it seems to take the file's true name but the path comes from the most recent configuration.

You would need the configuration that represents the state of component for your file state (ie. get a configuration without change sets 2-4 if you're looking at change set 1). The Java plain client API doesn't expose the ability to manipulate a configuration to show the path that you want. I think your best shot is taking your workspace and discarding change sets 2-4 before asking the configuration for the path segments.

I've noticed that there is an issue in RTC UI Client with resolving historical file path. Path of files with changed ancestors is not good. I believe that you have some kind of class to resolve that pathes without discarding changesets (at least scm tool you provided somehow know how to move files and resolve its old path well). Here is some screens where you can see the problem in RTC UI.

Changelists Adding new file reparent directory reparent directory (2)

I don't know what you're trying to illustrate with your screenshot. Are you highlighting that the file paths are inconsistent? I only see two files in your screenshots and the files aren't the same so I don't know what to look at.

I'm sorry you're right this screenshots tells nothing at all. Let me make another examples. This one should be ok.



Here you can see list of changeSets where (oldest changeset is on the bottom of the list) new file is added, and other two is rename of this file parent directories. I'll show now details of this changesets.

To make everything clear I've put original path to the changeset comment and as you can see it's totally different than the one which is resolved by RTC itself.

Here is other two to show you how directories was changed:


I hope this explanation is clear enough.


 

I see what's happening now. The folder names are resolved using whatever configuration you have picked. By default, it uses one of your repository workspaces that you have in Pending Changes. If the configuration of that workspace has the folder renamed, then that's what the name is resolved as. Change Summary (new in 4.0.1) view allows you to select a different stream or repository workspace to use for resolving paths.

I think I know where we can find answer for this problem, but not sure if it can be used in this particular situation. I've found that RTC UI is able to show repository files in specific stateId (file situation in selected changeSet). Right click on specific changeSet and selecting "repository files" give us ability to look at file situation after this changeSet. Maybe this is a good place to look for answer for this problem? 


Here is screenshot with repository files after my first changeSet:
 
Is it possible to do it using Plain Java API only?

The Repository Files view constructs a configuration that has the changes up to the point of that change set. You can do the same with the plain Java API but there isn't direct API to help you construct that configuration. I don't know how practical it would be to implement it yourself with the limited API available.

But is it possible to construct that kind of configuration object?


What about command line client for RTC's scm? To be honest I don't really know how to use it to update sources to apply new changesets (scm accept doesn't work for me) . Anyway is command line client able to resolve path correctly during update (of update is possible)?

If you're trying to update content on your disk, why are you not using the accept APIs in IWorkspaceConnection? You say the command line's 'scm accept' doesn't work. What happens when you try to use it?

If your file is in a specific baseline or snapshot, you could use 'scm list remotefiles' to get that path.

I'm not interested in updating sources for applying changesets. I'm only interested in displaying what was changed during every changeset applied to repository. 


About the command line issue... After checking out using: lscm load -r "https://rtcserver.com" workspace and making some changes in repository, when I'm trying to update sources I've checked out using: lscm accept -r "https://rtcserver.com" --flow-components -v command I'm still getting "Workspace unchanged.". The reason I'm trying to use command line client is that to make sure if it can resolve path and it's not just removing and checking out all files again.

I see. In the work item you opened (265025), you had said "I'm working with RTC Java Plain API to checkout and update sources stored in my local machine." and "update sources stored in my local machine" sounded to me like you wanted to update the content on your disk. It seems that isn't what is actually desired here. My mistake.

The accept command is for changing the content of your sandbox to reflect the change sets you have accepted. Yes, it knows the paths on the disk so that it can update the right files and folders. I am not sure what this has to do with what you want since you seem to want to know the path of a versionable when a change set happened when this information is not stored in the change set.

Updating sources is irrelevant for me now. Now I'm only focused on obtaining right file path. 


About scm command line client... The only reason I've mentioned this is that I'm not sure if it can update sources and wont get lost with file pathes after many reparenting. This is important for me to test it by myself on my own test cases where I'm sure my script fails on resolving pathes.

Updating sources is irrelevant for me now. Now I'm only focused on obtaining right file path. 


About scm command line client... The only reason I've mentioned this is that I'm not sure if it can update sources and wont get lost with file pathes after many reparenting. This is important for me to test it by myself on my own test cases where I'm sure my script fails on resolving pathes. 

 Updating sources is irrelevant for me now. Now I'm only focused on obtaining right file path. 


About scm command line client... The only reason I've mentioned this is that I'm not sure if it can update sources and wont get lost with file pathes after many reparenting. This is important for me to test it by myself on my own test cases where I'm sure my script fails on resolving pathes.

Sorry I didn't see this earlier, I just answered this same question on stack overflow.

The specific file state can only tell you the name of the file, not the containing folders.

You need to find the configuration that represents your workspace at the time of the changeset.   This might not actually exist, so you will have to settle for the closest one and then need to consider the other changes that happened after your change.

You do this starting at IFlowNodeConnection.changeHistory() and calling IChangeHistory.previousHistory until you find the change history that contains your changeset in IChangeHistory.recent.  Once you find it, the IChangeHistory.configuration is the first configuration after your change and it includes all the changes in recent().

1 vote

showing 5 of 23 show 18 more comments

Your answer

Register or log in to post your answer.

Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.

Search context
Follow this question

By Email: 

Once you sign in you will be able to subscribe for any updates here.

By RSS:

Answers
Answers and Comments
Question details
× 10,930
× 1,202

Question asked: May 07 '13, 4:43 a.m.

Question was seen: 7,914 times

Last updated: May 28 '13, 11:55 a.m.

Confirmation Cancel Confirm