Convert p4 move to p4 integrate - version-control

Is there a simple way to convert a (large) list of p4 moves to p4 integrates? There are a lot of pending modifications to the moved files, so just reverting and instead integrating isn't an option.
Perforce won't let you just revert the deleted file (which would leave the desired integration behind).

Even if Perforce allowed it, reverting the deleted files wouldn't leave an integration behind, it would leave an add behind. A move operation consists of adding (not integrating) the file(s) to the new location and then deleting them from the old. If you think about it, integrating files to a new location and then deleting them from their original location makes no sense. The purpose of an integration is to maintain a relationship between two sets of files.
As far as I know, Perforce provides no "one click" mechanism to do what you want, but it's not too difficult:
Copy the files you've modified to a temporary directory
Revert your file moves
Integrate the files and then open them for edit in their new location
Copy the changed files from the temporary directory into the new location and submit them

Related

How can I do a stream copy/merge of only a subdirectory in Perforce?

I'm using P4V. I work in a subdirectory (eg code/jorge) and other people work in another subdirectory (eg art/) that I never deal with. Additionally I have a stream where I do my personal work. Every so often I need to merge changes from the main line to my stream, and copy them back up. However, the files in art/ are large binaries and Perforce spends a long time thinking about them even though I've not touched them. Is there any way to have perforce merge/copy my directory (code/jorge) without it spending time trying to merge art/? Can I tell P4V to merge/copy only the code directory?
Related but not identical question: Perforce streams, exclude files from merge/copy
If you don't touch those files, it might be easier to not include them in your stream at all rather than manually exclude them every time you do a merge.
I.e. if your stream Paths currently says:
share ...
maybe it should instead be:
share code/jorge/...
or, if you need the art for builds but never need to modify it, you might consider doing something like:
import art/...
share code/...
I am not sure this is the recommended option but you can actually merge without using the "Stream to Stream" option but the standard "Specify source and target file" options, even if you are in a stream depot.
So you can select any subdirectory as your source like 'dev/code/jorge' and the same subdirectory as destination like "main/code/jorge' and it will only consider that directory. We do it routinely in my team because we have a big mono repo and have not taken the time to setup multiple depots when we migrated to Perforce.

When diffing folders, how can I detect moved or renamed files?

I am comparing two folders using a diff tool. I have tried a few different diff tools, but right now I'm using WinMerge. There are many files which show as unique to the right or left side, for example:
On the right we have: /bar/some_organized_characters.txt
On the left we have: /foo/some_similar_organized_characters.txt
The text file may have slight variations, but it's mostly similar. I would expect a tool to exist in most merge/diff tools which could tell you that these files are likely the "same" (meaning they have the same base), but the file has been moved, renamed, and slightly modified.
What I'm specifically trying to do is a "vendor merge." We have some customized software, and we want to merge the changes from a recent official release with the changes we have made. Many files have moved in the latest official release, and finding every move/rename by hand is difficult.
use a version control tool to check for changes. Simply commit the structure as an initial commit. Then overwrite the structure with the new version and commit that. The patch view will show you moved items. I've been able to do this with Git very easily. These tools are made to see how something has changed and will dig into the contents of the file. In fact, in git, you can set the threshold of what percentage of changes in a file constitutes a move and change, vs a delete and create.
I don't think this is possible with diff (I couldn't find it in the manpage).
However git diff detects this by default and can create patches that are applied with git apply in a similar way to patch. You can use it on arbitrary directories, not just repos, with --no-index (see Diffing between two entire directories/projects in hg or git?).

Does Visual Source Safe really lack renaming functionality?

I'm using Visual Source Safe at a new job and it hasn't been too bad... then I renamed a file.
I clicked through the warning prompts not really paying attention realized that by renaming the file I lost all of my history. Is this really the case? I can't believe VSS doesn't support renaming.
I refactor lots of code and not having a renaming work properly really bites.
Thanks for the answers. I guess VSS does have renaming functionality, just not in Visual Studio. What a dealbreaker though, switching apps to rename a file in source control? :/
It's possible to do this in SourceSafe, but it requires a bit of manual intervention:
First, make sure the file you want to rename is checked in.
In SourceSafe, right-click the file and select Rename from the menu (or alternatively, simply press F2), then rename the file.
This only renames the file within SourceSafe. You will have to check out the renamed file to your working folder and then delete the original file from your working copy to complete the rename.
If you view the file's history (right-click, then Show History, or altenatively, Ctrl-H), you will see that all of its history is intact. Note, however, that SourceSafe will refer to the file by its new name in all of the history entries for the file. The actual rename is tracked at the project folder level. If you view the history of the folder that contains the renamed file, you'll see a history item indicating that the file was renamed from oldname to newname.
Addendum: A note on retrieving older versions of renamed files from history
Joe White commented on this answer that SourceSafe doesn't honor the original filename when you do a Get on an older version of a renamed file. This is true, if you are getting the older version from the File History viewer.
However, if you do a Get of an older version of your code (before the rename) from the parent folder's history viewer, SourceSafe will correctly use the original filename when it puts the files in your working folder.
The reason for this behavior goes back to the fact that SourceSafe tracks renames at the parent folder level and not at the per-file level.
It doesn't matter.
Once you've seen your SourceSafe "database" corrupted through no action of your own, SS could produce daily rainbows and unicorns, but they'd eventually morph into festering sea creatures of random bytes, unrecoverable by man.
Get away from Source Safe. It was a noble effort by Microsoft to get people into the idea of source control, but I've twice (in 2 years, same data store, 3 people working against it) seen it die an unrecoverable death.
Get into svn, tfs, anything else! Tell your higher-ups that you're playing with fire every time you check in. You may be as lucky as I was on the project before the failed one, or you could just end up... relying on your backup strategy...
VSS has a rename feature which maitains history
File > Rename (I am positive that this maitains history)
but its been a long time since I've used it

Moving folder in SVN, having a bit of trouble

I have a project on codeplex and I'm trying to reorganise the tree structure so it makes a bit more sense and is easier to work with.
This is my current layout:
TopLevel
|-->src
|--->ProjectA //This is where all the files are held
|-->Core //plus three more folders
|-->MyProject.Core
|--->trunk
|-->src // I want to move all the folders and files in ProjectA into here
So I want to move all folders and files under ProjectA to ProjectA.Core/Trunk/src.
I checkout the whole source tree and right-clicked dragged the folders under ProjectA folder and selected "move versioned files here" into the src folder, that marked the folders in Project for deletion but the new files in src still had the green tick next to them and not the blue plus button.
After I commited the changes I had a look in the repo browser and saw that the folders hadn't been moved and were still in the ProjectA folder.
How can I move folders and the files in those folders to a different folder in subversion? Without loosing version history.
I'm using TortoiseSVN.
EDIT: Turns out it must have been codeplex, I moved my project to google code and everything works fine.
This type of reorganisation is easy to do with the Subversion command line client, which might be a viable option for you. Here's the commands that would do it (from the TopLevel directory):
svn mv src/ProjectA MyProject.Core/trunk/src/
svn ci -m "relocate ProjectA"
You can also combine both commands into one by using URLs as the source and destination, see the svn mv documentation for details.
I haven't found an easy way to do this sort of thing with TortoiseSVN, so when I need to I just use the command line client to do it.
I don't know what I was thinking when I suggested to export and import the files. I think I've been away from TortoiseSVN too long. I recall that tortoise svn actually has a really easy method of moving whole directories. It's not just obvious... but it's not clear why you can't get the result committed correctly to the repository. Presumably you did commit on the parent of all these folders.
Here's the summary:
You must select the folder and files you wish to move, and after doing so right click on the selection and drag it with the right button to the new location. You will get a context menu asking if you wish to relocate the files in the repository. This retains the history. Now your old files are marked for deletion and your new files should be marked as added. (I've found the status icons to be... not always representative of the true status). Commit this as one commit. I like to be picky and use check for modifications on the root of the checked out files, and then select exactly which changes I want to commit before doing so.
In the case of just moving one folder like this, open a window that is a parent to this folder, and another window that will be the new parent of this folder. Right click and drag all in one motion. I can't believe it takes this much text to describe a simple mouse action.
The standard strategy for dealing with nasty moves is, in the worst case, create all the new directories, move only the files from the old directories to the new directories, and then remove all of the old directories. This should get around almost any problem you encounter, and you can take shortcuts (moving entire directories and or trees) where that does work.
This will preserve history on all files. It will not preserve history on directory creations, but usually this is something you can live with, since you do have history for all of the file moves, which include the old and new directory names.

Can I safely edit a renamed file in perforce

I have a file I need to move that's already under perforce. Once moved it needs some editing - update the package, etc - appropriate to its new location. Should I submit the move changespec and then reopen it for edit, or can I do this in one go? If so, what is the appropriate sequence of events?
I have done this before in one go, but depending on your build process, I recommend against it. What I generally do is this:
Move the file.
If the move needs a change in order to compile, open it for edit and make those changes.
Submit the changes, telling perforce to reopen the files for editing.
Make the changes for path, etc., that don't cause compile errors but should be updated.
Submit those changes with an appropriate description.
If you want to, however, you could just do all your changes in step (2) above. Perforce might change the flag for the new file from integrate to add, but it still remembers the source path for the file.
Edit: Better method
I realized that I often use a different method, but the idea of "moving" the file distracted me. So, I would recommend these steps instead:
Integrate the file into the new path/name, leaving the previous file there. I am assuming that this won't break your build process.
Submit the new file, checking it out again for edit after submission.
Make the required changes to the new file, and to the project so that you are using the new file.
Submit the edits for the new file.
[Optional] You might need to check through branch specs to see if you need to map the old file into the new one in any branches.
Create a changelist for deleting the old file, and submit it sometime later.
This method allows the edits to be cleanly separated from the rename/move, while never leaving the project in a state that won't compile.
Also, why wait for step 6? Sometimes, especially on bigger projects, you might want to move a file that another person is editing. Perforce will helpfully tell you this. By waiting to delete the file, you allow your coworker(s) to finish the edits and submit without needing to move their work manually. After the edits are submitted, they can be integrated into the new file, and then the old one can be safely deleted.
Submit the move change and then reopen for edit (you could use the reopen option too).
This is much more readable to the user in the change history.
Also, recent versions of Perforce do perform checks for changes to files after resolution. So, there may be complaints editing files after some resolve operations have been completed.
I would say always submit first then edit. It is much cleaner and makes it more obvious whats happening in your repository. Then simply checkout the file in the new location and make whatever changes. This also makes it much more obvious that the changes were made in the new location and to all it to work after renaming.
Yes you can. Simply reopen for edit the branched file (i.e. the new one). In P4Win, there is a context menu for this ("re-open for edit").
"Safely" is probably an important point here. Once you rename or move the file it'll get a revision number of "1" which looks like a new file to your Perforce client. Of course, admins will be able to get its prior history, but if the editing/version history of the file is important to you it's a little harder to get the older revision.
Update: Thanks to Commodore Jaeger and Greg Whitfield for enlightening comments.
This wasn't easy to track down regarding what the One True Answer is, even from Perforce support, so I figured I'd update everyone on what we found:
Perforce stores all versions of every document in its database.
If it's saving your file as type <text> or <ktext> then it stores the diffs of one file version to another and not the entire file.
If you check out a file, make no changes to it, and then re-submit, it will save as a new version with 0 diffs. This is configurable and P4 can be set up to ignore changelist items without any actual diffs. You can force this behavior by selecting "Revert unchanged files..." before you submit a changelist.
Use "Rename/Move..." to move files in P4 so it can track them. Don't copy them using Windows Explorer and then re-add them in P4.
If you use the "Rename/Move..." function from the context menu, the "new" file will show a revision number of "1" as though it were a new file.
However, since P4 saves every function performed on a file, you can actually get to any previous revision (and even recover "deleted" files) with the CLI command p4 filelog -i
If you want to get to the revision history of a moved or renamed file and you're not an admin, you can right-click and select its "Revision Graph" which shows every version of a file even when moved between branches.
According to Perforce support, easier tracking of revision history through branch or folder moves is an oft-requested feature and is in their current roadmap.
Perforce's answer: At the moment, there isn't a way to move/rename/integrate files and still maintain the exact file history.
However, if you were to choose "Integrate..." by right-clicking on the folder that you want to share, the versions of the files of the newly branched folder and underlying files will start from revision #1, but the integration history between the branched folder and underlying files and the original folder and underlying files will remain through which you can trace the revision history of the files.