April 14, 2010

About Surround SCM Rollbacks

Surround SCM
The ability to rollback changes is a basic functionality that any software configuration management tool should have. Surround SCM provides more than one way to rollback changes. You can rollback a file to any prior point in time and you can also choose to rollback a promote or a rebase. The one thing I always like to point out is that rollbacks do not erase anything. If you have a file and you roll it back to a previous version, Surround SCM does not erase the current version. Rather, it creates a new version whose contents will be identical to the version that you rolled back to. You could almost think of a rollback action as a new check in. This concept is not something that users sometimes realize. A common question that will come into our support group is something like this: “I recently promoted a change from my Workspace branch to our Mainline branch. I did a rollback to an earlier version in my Workspace branch but when I try to do a rebase it tells me there is nothing to Rebase.” The user is trying to do a rebase as a way to re-apply the changes. However, this will not work. The error message the user receives is expected. Let's take a closer look. Surround SCM’s branching engine only applies new changes to your branches when a promote and rebase are performed. Surround uses common ancestor detection and some internal flagging mechanisms that allow the system to always know the difference between new changes to a branch and pre-existing changes to a branch. As I mentioned, when Surround performs a rollback (either a file rollback or promote and rebase rollback) the previous version history is not discarded, so when a promote and rebase are performed after a rollback Surround still detects the earlier changes and will not apply the same set of changes a second time. Let's use our old friend foo to help us explain this. A file exists called foo that is identical between the Mainline and a Workspace branch. The original contents of the file will be called A and so looking at the two branches I can say the file contents are A, A (Mainline, Workspace). The user checks in a new change (B) to the Workspace instance of the file. Now we can say, between the Mainline and Workspace, the file contents are A, A + B. The files are now different between the Mainline and Workspace. However, when the user tries to perform a rebase, Surround will show no new changes because the contents known as A already exist in both locations. The new change (B) is promoted to the Mainline. Now the file is identical again in both locations A +B, A + B. The user performs a rollback in the Workspace and now the file contents are A + B, A + B – B. It appears that a newer file exists in the Mainline since a Diff shows just the contents of A in the Workspace and A + B in the Mainline. When a rebase is performed Surround will still say no new changes. This is because both changes A and B are still present in the Workspace branch. Change B cannot be reapplied a second time. This is what Surround sees; A + B, A + B – B and of course changes A and B are already present in the Workspace foo.h file. If the user wants to get this file back to the pre-rollback contents then ‘another‘ rollback must be performed. The file contents now look like A + B, A + B – B + B resulting in no differences between the Mainline and Workspace. (The file history will show 1, 2, 3, 4 for the add, checkin, rollback to version 1, rollback to version 2). To summarize:
  • Surround does not discard any history information, even during rollbacks.
  • Surround does not allow changes to be re-merged more than once (I call this merge memory).
  • As a result, a rollback will not result in pre-existing changes being re-applied during promote and rebase.
The merge memory feature is one of the outstanding benefits of Surround SCM, as it prevents any changes you make from being merged multiple times. Compare this to a system that does not keep track of these merge points and would allow the accidental reapplication of an old change, which may have a negative result like undoing a bug fix.