Recently, one of the junior developers made a check-in to a large MVC SOA C# application, to both the client and service side, which makes the project unbuildable. Their check-in added spurious dependencies as well as removed required files, with something like 900 files in the project affected.
In order to keep the project moving forward, I was instructed by management to simply obtain the project from the changeset prior to this check-in in TFS and and then apply all changesets after the bad check-in going forward, since we though a release would be urgently needed.
As the weeks have passed, however, this approach is getting untenable. Is there a way to do one of these two things in TFS?
Either
remove a changeset from TFS without removing the changesets that come after it?
or
Automatically get all of the changesets in TFS for a solution except for one specific changeset.
remove a changeset from TFS without removing the changesets that come after it?
According to the document Roll back changesets:
A changeset is a permanent part of the history of your
version-controlled items and cannot be undone or removed. However,
you can roll back the effects of one or more changesets.
So, we could not remove one specify changeset. Just like James said, we could roll back the bad changeset. But it will also remove the changesets that come after it. As workaround, you can check the Changeset details for that specify changeset. Then ask that the junior developers remove his code, then check in the delete changeset.
Automatically get all of the changesets in TFS for a solution except
for one specific changeset.
There is way to find and view a TFS changeset by comment text:
tf history $/ -r | ? { $_.comment -like '*findme*' }
Check the this thread for some more details.
But there is no such out of box method to exclude one specific changeset in the text, we need to write our scripts like, batch, powershell to except it from the text.
Hope this helps.
Related
I'd like to see what changesets were merged to create a changeset on a branch in the history. This doesn't seem to be straight forward. I've tried to use the Track Changeset functionality, but I can't seem to see anything useful. I would also like it if I could do this from the command line so that I could potentially script a way to pull out appropriate changesets separately.
Edit
Ok, seems that using Timeline Tracking, I can get the changesets from the Track Changes feature. Now is there a way to do this from the command line?
Using Tracking Changeset window is the right way to View where and when changesets have been merged.
For the overview and some meaning of the elements in tracking changeset window, you could refer above link. And switch to timeline view will make the result more directly,clearly.
Afraid you could not do this through command line. There is a Merges Command, but could not specific a single changeset.
However, you could use TFS API to achieve this, take a look at below two similar questions:
Find changeset id parent of a branch in tfs
Is there a way to find out the source changeset from which a particular branch was created in TFS?
The answer contains a link to a blog post which contains many details, including TFS API and a custom command-line tool.
It has recently happened that a coworker, after completing some minor changes to the Stable branch of our solution, accidentally checked-in some of his unfinished work on the Development branch as well. TFS bundled it all up as a single changeset.
While the mistake was easily detected and fixed, I feel like I am missing something critical here. Why would TFS's "Pending changes" page allow you (and, worse, offer by default) to create a single changeset containing everything you've done on every branch?
It seems to me that a changeset should consist of changes to one and only one branch, so you can more effectively manage/merge/rollback them as necessary, without affecting other branches. If you have been working on multiple branches at the same time, upon checking-in it should ask you to insert multiple descriptions, and create multiple changesets as a result.
Assuming my reasoning is at least valid (if not necessarily universal), is there a way to configure TFS so that users may not check-in changes to more than one branch at a time?
EDIT: Failing that, I would appreciate a way to at least set the 'Pending Changes' page to put all changed files by default in the 'Excluded' section, so users will need to manually include them before checking in (which would help them notice any accidental changes).
Best practice: A developer can check in pending changes limited to a given folder/branch by right-clicking the folder, choosing "Check in pending changes". For that check-in action, the "Pending Changes" view will temporarily "exclude" any changes made outside of that folder/branch until you complete the check-in.
Can it be prevented: Per Microsoft, there is a premade Check-in Policy option known as "Enforce check-in to only contain files that are part of current solution". This may work for you, assuming you use "Solutions".
Why is this allowed: I suppose it's just how TFS was designed. I'd suspect it's to do with the treatment of branches as folders, and allowing check-in's across folders leaks into allowing check-in's across branches.
I can think of some scenario where this could be useful, like applying a critical fix on both release and main branches and merge is not an option.
What you can do to minimize the risk is to reduce the scope of developer workspaces as suggested by Jesse in Check-in each project separately?.
We have a branch called "Main". In July 2012 I created a new branch from this called "Phase 3" for the next version of our project. We have been working on this since then, but from time to time some other changes get applied to Main.
In May this year we performed a merge from Main to Phase 3 with some of those changes, and that was all fine.
Between then and now, we upgraded our TFS server from 2008 to 2012 update 3. (I wasn't involved with the "upgrade" but I believe it was an install on a new server with some kind of backup/restore of the data.) We've bit had any other issues with this.
Last week I tried to perform another merge from Main to Phase 3. I chose "selected changesets" because we have done a serious amount of rework in our phase 3 branch so merging changes across is quite difficult - so I wanted to do them bit by bit.
However, I was surprised to see that Visual Studio was trying to merge across changes from July 2011 - a good year before the branch was made (the very first changes made to this part of our project in fact.)
Oddly enough, if I view the history of the phase 3 solution I can expand it and see all these changes. So TFS appears to know that they have already applied.
I tried to merge some of the earlier changes across to see what would happened. The only changes it included were to do with items that had been renamed or deleted. For example, we had renamed our solution so TFS wanted to branch and merge a copy of the SLN with the old name. Or we had some images that had been subsequently deleted in both branches, but not at the time of this new merge.
So I backed this out and tried to merge everything across from May this year - i.e. just before our last merge across. This carried over a hideous number of changes - all sorts of things including regular merge/edit type changes. So I backed that out too!
We had created another branch from Phase 3. I have been able to merge between the two branches OK. I think it was created about a week before the TFS upgrade. But it's not experiencing the issue.
We have other branches that were taken from Main. These are experiencing the issue in that TFS is wanting to apply changes that it has already made.
I am using VS2012 update 3 to do the merge. I also tried VS2010 just in case but that does the same. Also a colleague has tried it and confirmed the same symptoms.
I don't think it helps that our phase 3 is so vastly different to main that merging anything across is really difficult.
Does anyone know how I can best resolve this? I'm a little worried about doing something I might regret later on!
I encountered similar problems when upgrading from TFS 2008 to TFS 2010. The issue is probably due to partially merged changesets. I.e. some of the files in the changeset have been merged, some haven't. Or it could be a branch move / rename situation. See the answer here for details of why a branch rename can cause this problem
In TFS 2008 if you attempted a merge, then unchecked files from the pending changes list. TFS assumed that you didn't want to merge the file ever again and on subsequent merges you wouldn't see those files.
In TFS 2010 or higher, the behaviour changes. If you uncheck files from the pending changes, on the next merge TFS will attempt to merge those files again. I think TFS 201x has the correct behaviour but its a pain that MS didn't highlight the change in behavior.
To check if this is the case, run the following from the command line
tf merge $/tp/main $/tp/phase3 /recursive /candidate
The /candidate switch tells TFS to give you a list of changesets it wants to merge without performing the merge. If you see any changesets in the list that have a * next to them, these are partially merged.
To fix it you have 2 choices.
Merge the files and resolve the conflicts, it might be worth merging on a changeset by changeset basis rather than trying to do them all at once. This will probably be a bit painful but once it's done it's done.
If you're confident that the phase 3 branch is correct then you can Merge using the command prompt. If you use tf merge $/tp/main $/tp/phase3 /version:c123~c456 /recursive /discard where c123 represents the oldest changeset you want to ignore and c456 represents the most recent changeset you want to ignore. The /discard switch tells TFS to update the merge history so that it thinks the merge has been done, but it won't actually perform the merge. This should remove the partially merged changesets from your list of candidates
If you opt for option 2 then you should do some analysis to make sure that you really don't want to take the partially merged changesets.
If you get to the point where merging is too difficult, or you just don't trust it.. then the only practical option is the "stomp over it with a new changeset". ie - do the merge manually outside of TFS and then commit your new, fixed changeset. then, kill the old branch and start again.
Not an ideal situation to be in, but your source integrity is paramount. Hopefully starting from a fresh branch will prevent issues like this in the future.
Is it possible to view history and compare with shelvesets? We are investigating the possibility of using shelvesets instead of check-ins. From our initial investigation it seems we cannot view history like we do for check-ins.
We are using Visual Studio 2010/TFS 2010.
From http://msdn.microsoft.com/en-us/library/ms181403(v=vs.90).aspx
Section: The Difference Between Changesets and Shelvesets:
Unlike a changeset, a shelveset is a non-versioned entity. If you or another user unshelve the items of which a shelveset consists, edit several files, and reshelve the shelveset, Team Foundation does not create a new version of the items for future comparison and maintains no record of who revised the items, when, or in what manner. The original shelveset is completely replaced.
So, no, you can't review history. I am unsure on methods of comparing shelvesets. You should also read that entire section (The Difference Between Changesets and Shelvesets) as each item in it is a strong argument to not use shelvesets in the place of changesets.
I also cannot think of any reason why using shelvesets instead of changesets would be desirable, maybe you can list the reasons why you all were exploring this path. Just think about not being able to track changes, that alone should be a deal breaker (of course, shelvesets not even being versioned should just about do it)..
Like it says on the link posted by dugas, shelvesets are built more for...well, shelving things. For example, on the project I am working on right now, I did a shelveset for some refactoring changes I was in the middle of because something unrelated broke and I needed the code back to the original non error-filled version. I also use it for when I'm in the middle of attempting something and want to have a backup but I don't want to check in code just yet.
There's no versioning on shelvesets, but it is possible to compare code in a workspace, to the code in a shelveset, without pulling the shelveset files.
Pull the versions of files you want to compare the shelveset contents to, into a workspace
open the solution in that workspace
File >> Source Control >> Unshelve Pending Changes...
find the desired shelveset and bring up its details
On each file in the Shelveset Details window, you can right-click and select Compare >> With Workspace Version...
TFS will pull the shelveset file to a temporary location, show the diff, and then (?) clean up the temp file after you're done.
You'll be comparing the shelveset file contents, to the contents of the files on the local disk in this workspace. If changes were made to both files, the compare won't be able to tell and will indicate all those changes. However, you can compare the selveset version to its original (Compare >> With Unmodified Version..), to see all the changes that were made just to the shelveset file. You can also find out the changeset that was the base for the shelveset file (Properties..), and see what changes were added to the workspace version since that common base changeset.
There's no tree compare though, and this may require the TFS power tools to work.
P.S> I don't recomment trying to use shelvesets in place of checkins like this. If there's one thing I've learned over the years, it's not to fight Microsoft's designed-in workflows -- you do things their way, or you find a different tool. Microsoft doesn't intend you to use shelvesets this way (they want you to use changesets and a branch), and if you try, you'll constantly be fighting Microsoft's designed-in workflow.
You can use shelvesets for peer code-review before committing them to the repository ... and also for parking commits before going through a gated build process.
They are not suitable for anything other than "quick shelving" of work - use branching if you want to have multiple parallel work streams.
We are planning to move from StarTeam to TFS for source control and are in the midst of refining our ALM procedures. Maybe I am misunderstanding something about how labels work in TFS, but it appears that you can apply a label to files by Changeset. I am trying to create a label on only the files/versions in the specific changeset.
I have attempted to do this like so:
1) Main Menu -> Source Control -> Apply Label
2) 'New Label' dialog appears
3) Leave path as is (Dev Branch)
4) Select 'Changeset' from 'Version' dropdown, enter my changeset #
5) Click Create.
... which results in the entire branch getting labeled. The changeset may be 1 - 100s of files, so individually labeling files is not practical.
We do this all the time in starteam: label changesets related to features, then move a build label up onto the labeled changeset. Am I missing something fundamental? (Thanks for any guidance)
Note the name... you are labeling by changeset not labeling a changeset.
Labeling in TFS is like marking a point in time. So when you label by changeset you are basically saying this is what my source control looked like at this point in time.
It sounds more like you area saying you want to be able to find a set of changes (changeset) not everything at the point in time that changeset was made.
You could pick a branching strategy that would allow you to branch by feature. The downside of this is that it will involve a lot of merging.
Another options would be to link the changesets for any specific feature to a work item and then you will have a list of changesets that you will want to merge up once you have completed that feature. In 2008 this can be a little troublesome because merging changesets that are not sequential can be more time consuming than necessary. (meaning there are changesets in between on that branch not that the changeset numbers are sequential)
Fortunately, you can try out different branching strategies and as long as you think it through it isn't to tough to switch if you don't like how you were doing it.
In TFS2010 I tested adding lables to a changeset and I am seeing the same behavior you reported.
When reviewing a changeset it will only contain the files that were checked in.
When reviewing a label that was created on the same changeset it will contain all of the files in the branch, with each file showing the changeset version of the last check-in.
I don't know why it works this way.