Convert changeset(s) to shelveset

12.9k views Asked by At

Is it possible to create a shelveset from the diff of two versions of one branch just by some operations in tfs/tfpt?

e.g. create a shelveset from (changeset 2013 -> changeset 2034)

5

There are 5 answers

1
Daniel Mann On BEST ANSWER

No, it's not possible. Changesets and shelvesets are different things, with different purposes. You could probably write a plugin to do what you're after (retrieve changeset, check out the files, shelve the files).

2
Lee Richardson On

It is possible to create a shelveset from a changeset with some limitations. I needed to rollback a change from a branch to remove it from a release but it wasn't in any other branch either so I wanted to keep the change in a shelveset. I achieved this as below:

  • Rollback the changeset and check in the rollback.
  • Rollback the rollback changeset. This gives me a set of pending changes containing the original change.
  • Shelve the pending changes.

You could apply this technique to the case described in the question but it would be a lot of manual effort as it would have to be repeated for every changeset. It would also generate a lot of mess in TFS as you would have to check in the rollbacks of the rollbacks too.

0
Greg Burghardt On

While this solution doesn't involve a pure TFS solution, it doesn't involve mucking with the TFS changeset history like Lee Richardson's answer does.

You can use Git-TFS to clone a TFS repository or branch, then create a new branch from a previous commit (TFS check-in), reapply changes from a newer commit and post that as a shelveset:

  1. Look in the git log for the commit before the one you want to create a changeset for:

    $ git log --oneline
    
    AAAAAAA Newest commit
    BBBBBBB The commit for which I want a shelveset
    CCCCCCC The commit where I will create a new branch from
    
  2. Create a new branch from the commit that occurs before the one you want to retroactively create the shelveset for:

    $ git checkout -b CCCCCCC
    
  3. Checkout the changes from the commit for which you want to create the shelveset for:

    $ git checkout BBBBBBB -- .
    
  4. Commit these staged files:

    $ git commit -m "Committing stuff for a retroactive shelveset that does X, Y and Z."
    
  5. Create the shelveset:

    $ git tfs shelve my_retroactive_shelveset HEAD
    

Advantages

  • This keeps the TFS changeset history clean without requiring you to revert a changeset, create a shelveset to un-revert the previously reverted changeset.

  • Since the shelveset was created from a branch in Git, you can delete that branch and still keep your Git-TFS history clean as well.

Disadvantages

  • It's not a pure TFS solution
1
zumalifeguard On

It's not impossible. Technically speaking you can do it, although you may not want to. I'll let the reader decide.

You may want to do this in a new workspace.

  1. Get the Changeset in question (new code)
  2. Move all the source to temp folder. (don't move the $tf folder). Source tree should now be empty.
  3. Get the previous Changeset.
  4. Mirror copy the new code on top of the old
  5. Do a Reconcile.

Now you can create the Shelveset.

If you are able to focus to a particular folder, then it will go faster, and you can automate it. Here's example command lines that will do this. I just tried it and it worked for me.

In this example, I point to a folder from the root called "Src". Change it your root folder.

md tmpws
cd tmpws
tf vc workspace /new /noprompt tmpws /location:local /permission:private

tf vc get "$/Src" /version:C2222 /recursive /noprompt

cd ..
md tmp
move "tmpws\Src" tmp

cd tmpws
tf vc get "$/Src" /version:C1111 /recursive /noprompt  /force /overwrite

cd ..
robocopy "tmp\Src" "tmpws\Src" /mir

tf vc reconcile /promote /adds /deletes /diff /recursive /noprompt

tf vc shelve /replace /noprompt mychange 

tf vc undo "$/Src" /recursive /noprompt
tf vc workspace /delete tmpws

cd ..
rmdir /q /s tmp
rmdir /q /s tmpws
0
Easwar On

Each commit will create a shelveset. So we can find a shelveset created while the commit was initiated. That will have exact same changes. We dont need to create new shelveset.