Search code examples
unity-game-engineperforce

How to correctly undo a bad commit in P4V (Perforce)?


Ok, so I am using Perforce P4V to back up my work for a Unity project. One of my teammates checked in some changes to the metafiles which broke everything. No problem though right? That's the whole point of using P4. We can just revert that. Only... revert didn't work?

The behavior I am seeing is File A was changed in changelist 1 File B was changed in changelist 2, File C And A were changed in changelist 3

Let's say Changelist 3 contains the bad change I clicked on changelist 2 in my history, then clicked get revision, and checked the Force Operation box. changelist 2 being the last known good state what I expected to happen was to have all of my files restored to the state I was in when changelist 2 was submitted.

Instead, file C was reverted, but File A was not. It's like, since file A didn't change in changelist 2 it didn't bother to get that version.

So I am in a state where all of the unity metafiles are maimed and all prefab references are broken.

When that didn't work I tried using get a revision to go back to the most current state. Then using Backout. That similarly didn't work, metafiles still maimed. I then tried selecting the last known good state and rolling the entire project folder back to that state. Again, didn't work. But then again, I may have maimed my project so badly at that point that nothing would have worked.

The only way I have found that appears to correctly be reverting the files and restoring the broken links is manually selecting each file or folder and reverting it to the last good commit, which is different for each file/folder since they were added and changed in different commits.

What I don't understand is why the force get revision didn't do that on its own. Or what the "correct" way to undo a bad commit is.

I even tried deleting the entire assets folder then using get revision force to pull an entirely new copy from the server using the last known good commit. This appeared to work perfectly once, but when I tried to repeat it to verify my results it went back to losing all of the meta file links. The only dependable way of getting back into a good state appears to be manually force getting each file and folder to the individual last known good commit.

I have consigned myself to having to manually fix my blunder this time, but I'd really appreciate help to know how to do this the right way for the future.


Solution

  • Use the p4 undo command.

    p4 undo @BADCHANGELIST
    p4 submit
    

    That's all there is to it!

    (There is a similar operation in P4V called "Back Out" -- I have encountered difficulties using this and prefer using the command line because it's easier, but YMMV.)

    Note that p4 undo and p4 revert are entirely different commands! Many people get confused about this because git calls its "undo" command git revert, but a p4 revert is not the same as a git revert (it's more like git reset --hard). You can't use p4 revert to undo something that's already submitted; it's only for reverting your pending work to the latest submitted state from the depot.

    I'll see if I can explain what went wrong with what you attempted:

    Let's say Changelist 3 contains the bad change I clicked on changelist 2 in my history, then clicked get revision, and checked the Force Operation box. changelist 2 being the last known good state what I expected to happen was to have all of my files restored to the state I was in when changelist 2 was submitted.

    Instead, file C was reverted, but File A was not. It's like, since file A didn't change in changelist 2 it didn't bother to get that version.

    IIRC when you click on a changelist and use it to sync in P4V, it defaults to doing p4 sync @CHANGE,CHANGE rather than p4 sync @CHANGE -- as you've observed, this is very unhelpful if you're trying to "roll back" to an earlier state across the entire workspace. You can probably fix this by clicking checkboxes in the sync dialog somewhere. I believe if you click on a changelist in the "Folder History" view it uses the path (p4 sync path/...@CHANGE) which should work better.

    Once you've managed to sync the workspace to the older state, if you want to make that state permanent, you need to open the files for edit ("check out" in P4V), sync to schedule a resolve ("get latest" in P4V), resolve (which is also "resolve" in P4V, make sure you accept your workspace version (P4V might call this "accept target", I'm not sure), and then submit. Again, I recommend just using p4 undo so you can skip all of those manual steps.