1

When files in a tfs workspace are moved outside of tfs (eg. through windows explorer), tfs picks these moves up as a delete and an add.

To get around this, I have a program running that monitors for changes and when a move happens I do a Workspace.PendRename with updateDisk set to false.

This works fine except that tfs adds the delete as a candidate change.

Is there anyway to remove this candidate change? It causes issues if people try and promote these changes.

By using Workspace.GetPendingChangesWithCandidates I can get the candidate change, but there doesn't seem to be anything I can do with it to remove it from the list.

Before doing the PendRename, I tried moving the file back to it's original location (File.Move) and then doing the PendRename with updateDisk set to true. This actually works well for single files, but gets complicated when folders and such are involved.

I'm hoping there's a simple way to either remove the candidate change from the list, or to even disable the candidate changes functionality altogether for certain files/folders. I tried adding the folder to the .tfignore file but that doesn't work.

Promote Candidate Changes shows deletes even though files were renamed

Zenix
  • 21
  • 6
  • 1
    Are you using a local work space? A local workspace will monitor changes on disk, so if you move a file from one directory within the workspace to another within the work space a move is detected. A move in TFS is a delete+add so the behavior you describe is intended. If you don't want your workspace to monitor changes on disk use a server workspace instead. There are some differences between local and server workspace which are described here: https://www.visualstudio.com/en-us/docs/tfvc/decide-between-using-local-server-workspace – Sander Aernouts Mar 08 '17 at 07:23
  • Sander, in TFS a move is not an add and a delete, that would lose all file history. A move in TFS is called a rename. – Zenix Mar 09 '17 at 00:15
  • Patrick, files inside the workspace are being moved without the knowledge of TFS, so TFS picks these up as a delete and an add. I would like TFS to understand that it's actually a move/rename. – Zenix Mar 09 '17 at 00:17
  • @Zenix It's the right phenomenon, when a rename is done outside of the Source Control Explorer then the change will be detected as two individual actions, ***one delete*** and ***one add***. – PatrickLu-MSFT Mar 09 '17 at 02:00

1 Answers1

1

In TFS there are two kinds of moving files. I have crated a sample for both :

Local Workspace (window exploer) directly move/drag file

  1. In the disk my workspace, I'm going to move 2.PNG to Main-branch folder

enter image description here

  1. Then we could check what TFS detects in VS. One with add(in new place), one with delete(in old place) in Promote Candidate Changes.

    enter image description here

  2. You need to check in both the add and delete ( promote first). Finally you will get what you want both server and local.

Move a file in solution explorer directly

  1. In the solution explorer , I'm going to move 1.PNG to Main folder by right click and select move.

enter image description here

  1. You will get a pending change with rename status directly and not any Promote Candidate Changes.

    enter image description here

  2. Then we could check our local workspace, you will see 1.PNG is automatically deleted in the workspace folder even though you haven't check in changes. Finally checking pending changes, everything is fine and clean. enter image description here


Back to your question: Promote Candidate Changes shows deletes even though files were renamed.

The TFS API should be using the way 2 above. Look at the parameters :

updateDisk

If true, the local disk is updated according to the pending changes; if false, the disk is not modified and changes are not acknowledged.

So if you set the updateDisk to false , the 1.PNG should still exist in the disk and TFS detect it and adding to promote Candidate Changes shows deleted. Which meets your screenshot. The solution should be change the value from false to true.

PatrickLu-MSFT
  • 49,478
  • 5
  • 35
  • 62
  • I can't imagine this could be by design. It seems like it must be a bug, and I'm trying to find a workaround. Perhaps I didn't explain the issue clearly enough. I use Workspace.PendRename to rename a file. This goes into my pending changes. TFS then adds a delete for the original filename into my candidate changes. So TFS is adding a candidate delete for a file that's missing, even though it knows that that file has been renamed. – Zenix Mar 09 '17 at 00:19
  • @Zenix When a file is renamed correctly, the History is not "Gone", it's associated to the "old name" instead. However when **a rename is done outside of the Source Control Explorer** then the change will be detected as two individual actions, **one delete** and **one add**. You can use the "Pending Changes" window to promote these to a rename so that the history is preserved. – PatrickLu-MSFT Mar 09 '17 at 01:56
  • @Zenix More details take a look at **jessehouwing**'s answer in this question http://stackoverflow.com/questions/28990323/moving-files-lose-history-in-tfs-2013 – PatrickLu-MSFT Mar 09 '17 at 01:58
  • I need this promote to be done programatically. This is why I'm doing a PendRename with updateDisk set to false. If there's a better way then I've love to know. If there was a method PromoteAsRename( pendingDelete, pendingAdd ) that would be perfect, but such functionality doesn't seem to be exposed by the api. This is why I consider it a bug, TFS knows that the file has been renamed, but still adds a candidate delete for it. It's like telling your mother that your sister has gone to the store, and then she files a missing persons report anyway. – Zenix Mar 09 '17 at 02:15
  • @Zenix move a TFS file with c# API only needs workspace.PendRename( oldPath, newPath ); Use a "workspace.GetPendingChanges()" and "workspace.CheckIn()" methods to do it. In your case you will also need to examine your "candidate pending changes" (the ones that the TFS client has determined exist on disk) and then promote them to actual pending changes first. To use this promote to be done programatically, `Workspace.GetPendingChangesWithCandidates` is the right method check http://stackoverflow.com/questions/24970734/detect-file-delete-changes-with-tfs-api-automated-without-vs-interaction – PatrickLu-MSFT Mar 09 '17 at 02:45
  • workspace.PendRename(oldPath, newPath) doesn't work which is why I posted the question in the first place. The posts you linked unfortunately don't have any relevant information. I'm going to leave the question open in case some is able to answer it. – Zenix Mar 09 '17 at 03:11
  • @Zenix Sorry, actually your question is a bit deceptive especially the title *how to disable or remove candidate changes in TFS.* It's not related to your issue. First to say, one thing can be certain it's **not able to disable the candidate changes**. You need to promote them to actual pending changes. Did you just want to renaming File with Team Foundation Server API, and it works well with single file and not works well with multiple files. Check the code in my update which may do the trick. – PatrickLu-MSFT Mar 09 '17 at 03:56
  • The title is accurate... the issue is that tfs creates an invalid candidate delete. The PendRename works fine, the candidate delete is the problem. I would like to remove the candidate delete. Alternatively, disabling the candidate changes functionality completely would also fix the issue. I appreciate that you're trying to help, but I don't feel like you've understood the issue. The rename works fine. It sits in my pending changes like it should. but TFS also adds a candidate delete at the files original location. – Zenix Mar 09 '17 at 04:09
  • As for how to promote Excluded changes(candidate changes) with TFS API, there is a wonderful blog for your reference: [Using Local workspaces – Promote Excluded changes with TFS 2012 API](https://roadtoalm.com/2013/06/13/using-local-workspaces-promote-excluded-changes-with-tfs-2012-api/) After loop through all candidates and you could check whether have to add them (PendAdd) or Delete them (PendDelete) – PatrickLu-MSFT Mar 09 '17 at 04:15
  • @Zenix I'm not sure if it's an invaild candidate delete.(It's back to our earlier discussion. Since TFS adds a candidate delete at the files original location seems to be a right phenomenon as we talked eariler. If you don't do the delete option, there should be two edition in database simultaneously. Am I right ? And even you do the candidate delete, you still won't lose your history. It' bind with the "old name/old path") If you insist on this ,you could also promote your candiate delete to pending changes first, then delete the pending changes. Did this helps your issue? – PatrickLu-MSFT Mar 09 '17 at 04:20
  • There won't be two in the database, because I'm doing a rename. I can't promote the pending delete, because it conflicts with the pending rename. – Zenix Mar 09 '17 at 05:10
  • @Zenix Sorry to miss the updated screenshot. I think finally I got your point. Once again proved a diagram is worth thousands of words. The root cause is you are setting the updateDisk to false. Which cause the screenshot. (see my update) Your question is essentially like this [How do I tell TFS that pending file delete and add is actually a rename](http://stackoverflow.com/questions/32592050/tfs-pending-deleteadd-file-rename) Why you want TFS to understand that it's actually a move/rename ? They are using **different mechanisms** . And actually in TFS *rename* is just delete+add. – PatrickLu-MSFT Mar 09 '17 at 07:36
  • -- For example: if you rename a branch in TFS source control, you will generate a new branch with new name and delete the old branch. You could still see the old branch with "show delete items" enabled. Renaming branch will mess up the history. So usually we don't suggest to do this. If you are interested in this, you could take a look at my answer in this question:http://stackoverflow.com/questions/33653970/can-renaming-the-main-branch-in-tfvc-orphan-child-branches Also have updated my reply above for you reference. – PatrickLu-MSFT Mar 09 '17 at 07:59
  • If I simply promote the add and delete and check those in I lose file history. This makes sense, as TFS has no way of knowing that these are the same file. This is why I want to do a rename instead (which is not the same as add/delete, I'm not sure why you would think they're the same?). – Zenix Mar 09 '17 at 22:49
  • I am not talking about branches at all. – Zenix Mar 09 '17 at 22:50