32

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)

Luke Girvin
  • 13,221
  • 9
  • 64
  • 84
orange
  • 720
  • 3
  • 11
  • 27
  • What are you trying to accomplish with this? There's probably a better way of accomplishing your goal. – Daniel Mann Jan 14 '14 at 23:47
  • @DanielMann, I'm trying to take the shelf i get and apply to another branch. I don't want a baseless merge, too many files tagged as merge. – orange Jan 14 '14 at 23:52

5 Answers5

96

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.

Lee Richardson
  • 1,061
  • 7
  • 8
  • 9
    @orange: why don't you make this the correct answer? It solves your problem. – floquet22 Feb 24 '16 at 08:30
  • I just found a workflow using Git-TFS that allows you to do this. I'll post an answer tomorrow hopefully. It's not 100% what the person is asking for, but it doesn't involve such a wonky workflow. – Greg Burghardt Jul 07 '16 at 20:57
5

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).

Daniel Mann
  • 57,011
  • 13
  • 100
  • 120
3

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
zumalifeguard
  • 8,648
  • 5
  • 43
  • 56
  • Thanks! I used this approach but created a new workspace for it just to make sure I didn't accidentally mix anything up in my regular workspace. Then used TFS Power Tools (`tfpt unshelve /migrate`) to unshelve the shelveset to a different workspace/branch. – xr280xr Sep 10 '19 at 15:02
1

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
Greg Burghardt
  • 17,900
  • 9
  • 49
  • 92
1

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.

Easwar
  • 11
  • 1