Is it possible to create a patch using a set of changelists? - perforce

Problem: 2 projects shared trunk and were updating some of the same files. Now one project needs to be released, so a new branch was created from a checkpoint before the projects started.
I have a list of just my changelist numbers from the mainline. Using that I can generate a list changed files and diff output using a script with a series of 'p4 describe #' commands.
Can I reformat that output and apply it to the new branch somehow?

Response to the title: "Is it possible to create a patch using a set of changelists?"
Yes.
p4 diff2 -u //path_to_your_sources/...#cln_minus_1 //path_to_your_sources/...#cln > /tmp/cln.patch.
You can then use /tmp/cln.patch as input to the patch utility. Here, 'cln' is the submitted change list number that you want to create a patch for.

I've just spent two hours struggling with this. Using cygwin patch, I had to munge the paths until they were recognised.
In the end, the magic incantation looked like this (broken across lines):
p4 diff2 -u //depot/foo/main/...#100003 //depot/foo/main/...#100000 |
sed 's#//depot/#E:/Source/#g' |
sed '/^+++\|---/s#/#\\#g' |
patch
That is:
Use p4 diff2 to get a unified diff (-u) of part of the depot between the two revisions that I care about. The second changelist is the one before the first one I want, otherwise it's not included in the diff.
Use sed to change the //depot/ to E:/Source/, which is where my workspace lives.
Change forward slashes to double backslashes (this seems to make it work).
Pipe the results through patch.
Cygwin patch is smart enough to check files out of Perforce, but I'm not sure how to get it to do it silently. It prompts with Get file 'e:\Source\foo\whatever' from Perforce with lock?.
This is with p4 version 2010.1, a fairly recent installation of Cygwin, running on PowerShell.
Oh, and after this, patch wrote out Unix-style line endings, so I used u2d to fix those up.

Perforce will let you cherry-pick changelists for integration, which may be easier than trying to generate and apply a patch. Perforce will keep track of what revisions you've integrated where, which may make future integrations easier.
Let's assume you used to have one trunk:
//depot/mycode/trunk
And you checked in all of your changes there. You branched trunk at some point in the past to:
//depot/mycode/rel
And you have a list of changelists on trunk to merge. From a client spec that maps rel, integrate each changelist:
p4 integrate //depot/mycode/trunk/...#1234,1234 //depot/mycode/rel/...
where 1234 is the changelist number. Resolve after each integration. You may also wish to build, test, and commit your integrations at various checkpoints during your integration, if you can identify good points to do so. (Perforce can handle multiple integrations per commit, but if you make a mistake you'll need to revert to the last version checked in and redo the intermediate integrations and resolves.)

p4 describe -S -du <CL number>
is the shorter and most concise command, in my opinion.

Related

How can I partially integrate a file in Perforce?

I have a file on another branch which contain a change I would like to integrate. But it contains other changes too which I don't want to integrate yet.
How can I integrate the file only partially?
I first integrated and resolved the file as usual, then I did a "p4 edit" on the file after that to remove the changes I don't want to go in yet. "p4 opened" said that the file is opened for edit, so I thought the commit will submitted as an edit not an integration. I was wrong! It still updated the integration history! So if I attempt to integrate the rest of the changes later the perforce will say "all revisions integrated", and the only way to resolve the problem is integrating by disregarding the integration history, which is painful to resolve.
How can I avoid this next time?
EDIT:
To clarify I mean there are multiple changes in a single revision of file and I want to integrate only a part of it.
(edited to reflect that the question is about partially integrating a revision, not integrating a single revision of a file)
Since a revision is the smallest atom of change in Perforce's metadata, you won't be able to record that a subset of a revision was integrated -- and since you don't want to record that the entire revision was integrated (thereby "ignoring" the rest of the revision for future integrations), rather than doing this as an integrate, I'd do it as an edit:
p4 edit target
p4 print -o theirs source#n
p4 print -o base source#n-1
p4 merge3 base theirs target > target
rm base theirs
(edit target)
p4 submit
Another option would be to initially open the file for integrate and then clear the resolve record by reverting (use the -k flag to keep local changes) and reopening for edit:
p4 integrate source#n,n target
p4 resolve
p4 revert -k target
p4 edit target
In general if there are multiple independent changes you're making to a file such that you might want to be able to cherry-pick and/or track them independently at a later date, submitting them as independent changelists will make that much much much easier. Shelving can help with this if you realize only after making a big change that it'd make more sense as a series of smaller changes -- shelve your big change, revert some parts, submit the smaller change, then unshelve the big change and continue.

Will the Perforce command "p4 copy" keep revision info?

dear all,
I am using the Perforce Windows x64 GUI 2014.1888424. Per my test, the answer is NO. It will use the assigned revision number.
I found the "integrate" and "branch" commands also don't keep the revision info.
Are these commands designed to behavior like this?
PS: I know that rename/move will keep the revision info.
Would you please give me any hint? Thank you very much!
You didn't describe precisely what test you did, so I'm speculating slightly, but: the Perforce integrate, copy, and merge commands do preserve the overall revision history of the file.
However, many of the commands which display file history do not display the full history by default; you have to specify additional commands to instruct the server to output the history across integrations.
For example, compare the output of
p4 filelog -i
versus
p4 filelog
or
p4 changes -i
versus
p4 changes
for your experiments.
The -i flag tells the server that you want to see the history of the file from prior to the integration or copy from its previous location. Here's how it's described in 'p4 help filelog':
The -i flag includes inherited file history. If a file was created by
branching (using 'p4 integrate'), filelog lists the revisions of the
file's ancestors up to the branch points that led to the specified
revision. File history inherited by renaming (using 'p4 move') is
always displayed regardless of whether -i is specified.
Note that, as you've observed, renaming is indeed handled differently than integ/copy/merge.
As for myself, when I am studying the history of a file, I tend to nearly always use the P4V tool and its supremely powerful Revision Graph and Time Lapse View tools. These tools know how to navigate all sorts of complex integration history, and make studying the history of a file much easier.

perforce: create a local backup of current pendinglist

in perforce, i have a pending list with some changed files. now i want to revert to the base, but without loosing my changes, so i want to back them up somewhere. like saving the DIFFs of each file. at a later time, i want to restore those changes and continue my work.
is this possible? if so, how?
thanks!
there is no need for external tools at all, assuming you are on a unix machine (or have a proper cygwin setup under Windows, haven't tested it.) The only caveat is that Perforce's p4 diff produces an output that is slightly incompatible with patch, therefore you need it to point to your unix diff-command. In your client-root you can do
P4DIFF=/usr/bin/diff p4 diff -du > pending-changes.patch
optional (if you want to revert the open files from the command-line, otherwise use p4v):
p4 revert `p4 opened|awk -F\# '{print $1}'`
Later you would open the files for edit (can be automated by extracting the affected files from the patchfile pending-changes.patch and then:
patch < pending-patches
Depending on your path-layout in your client-root, you have to use the -p#num option of patch to get the patch applied cleanly.
You should be able to do a shelve. It's a way of saving a changelist for future editing. The link below is a Python add-in for Perforce that implements shelve. Also, I know that Practical Perforce has a couple of ways to shelve current changes without an external script. I don't have the book in front of me but I'll try to update this question tonight when I do.
http://public.perforce.com/wiki/P4_Shelve
Linked to from P4Shelve, is P4tar which looks very useful, and does the operations on the client, rather than branching on the server.
Certainly I'll be looking into doing similar things soon.
See also this question:
Sending my changelist to someone else without checking in.
It's basically the same thing.
Create a branch of these files in some appropriate location
Check out the branch versions of the files you have edited
Copy the edited files over from the trunk and submit them
Revert the files on the trunk
Now you've got those "diffs" you wanted safely archived. When your ready to apply those changes later on, just integrate them back into the trunk.
This is what the Python script, that Brett mentioned, does. This is the way to do it manually without any special tools.

Can I integrate checked out files into a different branch on perforce

We were working on a design, and for that we created the skeleton of the classes in our main branch. Now, we are starting to code, and for that we got a new branch. So, it would be nice if I can move all the new files in the main branch into the new branch. However, I cannot check them in yet. So, is it possible to integrate the checked out changelist? Thanks.
The Perforce support web site explains how to do this: Perforce Knowledge Base: Branching work in progress. It would be nicer if it was a single step that didn't require running eight different commands.
Since release 2013.1, the way to branch work in progress is to shelve the work and unshelve it on the branch. In detail:
Shelve your outstanding changes:
$ p4 shelve ...
Change 182535 created with 10 open file(s).
Shelving files for change 182535.
edit //info.ravenbrook.com/project/mps/master/code/arenavm.c#26
# etc.
Unshelve them on the branch (using the -b option, which maps the file name through a branch specification):
$ p4 unshelve -b mps/branch/2013-06-05/diag -s 182535
... //info.ravenbrook.com/project/mps/branch/2013-06-05/diag/code/arenavm.c - must resolve //info.ravenbrook.com/project/mps/master/code/arenavm.c#=182535 before submitting
# etc.
Resolve any merges resulting from the unshelve, using p4 resolve -as to quickly do the "safe" ones, and then doing the rest with p4 resolve as usual.
$ p4 resolve -as
//gdr-peewit/info.ravenbrook.com/project/mps/branch/2013-06-05/diag/code/arenavm.c - copy from //info.ravenbrook.com/project/mps/master/code/arenavm.c
# etc.
$ p4 resolve
No file(s) to resolve.
(The example output is from a real use case I ran just now.)
I never found a way to do that within perforce, but you can at least partially automate it.
Usually when I had to do something like that I'd check out the files in the branch I want to move things to, then use WinMerge to diff the branches and copy the changes over. Once that's done you can revert the changes in the original branch and check them in in the new branch.
It's not the best solution (no automatic checkout/add/delete of files on the new branch), but was the fastest method I came up with.
Not really.
You can of course simply open the files for edit in the new branch, and manually copy the changed files from the workspace of your main branch to the new branch's workspace. This is probably the easiest way if it just a few files.
Here are a few scripts that can be handy if a larger number of files are involved.
E.g., with the P4Shelf script you can create an archive of all your changed files, and later automatically open them in any branch with the changes restored.
Also, check out some other nifty scripts for Perforce by Jim Tilander.
To rephrase Gareth Rees' answer above in simple terms,
p4 unshelve -b target_branchspec -s changelist
:)
The easy answer is - no you can't. A quick perusal of the Perforce docs didn't come up with a ready cite for this, unfortunately, but in my experience any attempt to pull the rug out from under the Perforce server will result in your changes being lost which will leave you an unhappy camper.
Make a back up, create a new work area on the new branch, and re-apply your changes, perhaps using the diff/merge strategy outlined in Herms answer.

Determining the last changelist synced to in Perforce

A question that occasionally arises is what is the best way to determine the changelist that you last synced to in Perforce. This is often needed for things like injecting the changelist number into the revision info by the automatic build system.
I recommend the opposite for automatic build systems: you should first get the latest changelist from the server using:
p4 changes -s submitted -m1
then sync to that change and record it in the revision info. The reason is as follows. Although Perforce recommends the following to determine the changelist to which the workspace is synced:
p4 changes -m1 #clientname
they note a few gotchas:
This only works if you have not submitted anything from the workspace in question.
It is also possible that a client workspace is not synced to any specific changelist.
and there's an additional gotcha they don't mention:
If the highest changelist to which the sync occured strictly deleted files from the workspace, the next-highest changelist will be reported (unless it, too, strictly deleted files).
If you must sync first and record later, Perforce recommends running the following command to determine if you've been bit by the above gotchas; it should indicate nothing was synced or removed:
p4 sync -n #changelist_number
Note that this method doesn't work if a file is added in a changelist (n-1) and then deleted in the very next changelist (n). p4 changes -m1 #clientname and p4 changes ...#have both return n-3 and p4 sync -n #n-3 will say "file(s) up-to-date."
Just to answer this myself in keeping with Jeff's suggestion of using Stackoverflow as a place to keep technical snippets....
From the command line use:
p4 changes -m1 #<clientname>
And just replace with the name of your client spec. This will produce output of the form:
Change 12345 on 2008/08/21 by joebloggs#mainline-client '....top line of description...'
Which is easily parsed to extract the changelist number.
You may try finding the maximum change number in the output of the "p4 files" command. The working directory should not contain post-sync commits, though. This is just a tad better than
p4 changes -m1 "./...#have"
as the latter seems to run on the server and may fail on big source trees due to "MaxResults" limits.
$ p4 changes -m1 "./...#have"
Request too large (over 850000); see 'p4 help maxresults'.
$ p4 -G files "./...#have" | python c:/cygwin/usr/local/bin/p4lastchange.py
Files: 266948
2427657
where p4lastchange.py is based on the code from the Using P4G.py From the Command Line presentation by J.T.Goldstone, Kodak Information Network/Ofoto, April 15, 2005.
#! /usr/bin/env python
import sys, os, marshal
if os.name == "nt":
# Disable newline translation in Windows. Other operating systems do not
# translate file contents.
import msvcrt
msvcrt.setmode( sys.stdin.fileno(), os.O_BINARY )
lastcl = 0
num = 0
try:
while 1:
dict = marshal.load(sys.stdin)
num = num + 1
for key in dict.keys():
# print "%s: %s" % (key,dict[key])
if key == "change":
cl = int(dict[key])
if cl > lastcl:
lastcl = cl
except EOFError:
pass
print "Files: %s" % num
print lastcl
p4 changes -m1 #clientname which is the "recommended" way to do it for my client takes about 10 minutes
this is what I use:
p4 cstat ...#have | grep change | awk '$3 > x { x = $3 };END { print x }'
for the same client takes 2.1 seconds
If you are using P4V you can do this graphically:
In the Dashboard tab (View->Dashboard) choose a folder and you will see a list of changelists that the folder isn't yet updated with. Note the lowest number (in the highest row).
Make sure that in the Workspace Tree you have selected the same folder as previously in the Dashboard. Then go to the History tab (View->History) and scroll down to the number noted previously. The number just below that number is the number of your current changelist.
You could also use the cstat command:
p4 help cstat
cstat -- Dump change/sync status for current client
p4 cstat [files...]
Lists changes that are needed, had or partially synced in the current
client. The output is returned in tagged format, similar to the fstat
command.
The fields that cstat displays are:
change changelist number
status 'have', 'need' or 'partial'
For a serious build (one that is being prepared for testing), explicitly specify the desired label or changelist number, sync to label, and imbed it in build artifacts.
If a changelist (or label) is not given, use p4 counter change to get the current change number, and record it. But you still need to sync everything using that change number.
I don't think you can achieve exactly what you want, because in general, an entire workspace isn't synced to a particular changelist number. One can explicitly sync some files to older revisions, and then a single changelist number is meaningless. That's why a fresh sync is required to ensure that a single changelist number accurately represents the code version.
Regarding the comments: Yes, my answer is intended for use by configuration managers preparing a build to give to QA. Our developers don't normally sync as part of a build; they do a build prior to submitting—so that they can make sure their changes don't break the build or tests. In that context, we don't bother to embed a repository label.
With your approach, you are making the assumption that your whole workspace was synced to head at the time of your last changelist submission, and that changelist included all of your open files. It's too easy to be mistaken in those assumptions, hard to detect, and horribly expensive in terms of lost time. On the other hand, solving the problem is easy, with no drawbacks. And because a changelist number can be explicitly specified, it doesn't matter what revision you need or how quickly the codebase is changing.
For the whole depot (not just your workspace/client)
p4 counter change
does the job, just telling the last changelist.
The best I've found so far is to do your sync to whatever changelist you want to build and then use changes -m1 //...#have to get the current local changelist (revision).
p4 sync #CHANGELIST_NUM
p4 changes -m1 //...#have | awk '{print $2}'
Gives you the changelist number that you can the use wherever you want. I am currently looking for a simpler way than p4 changes -m1 //...#have.
I am not sure if you got the answer you needed but I had a similar problem. The goal was to write in our logger the specific version of the project. The problem was that while we are making our own makefile, the overall build system is controlled by our configuration management. This means that all the solutions which say "sync to something then do something" don't really work and I didn't want to manually change the version whenever we commit (a sure source for errors).
The solution (which is actually hinted in some of the answers above) is this:
in our makefile, I do p4 changes -m1 "./...#have"
The result for this is Change change_number on date by user#client 'msg'
I simply create the message into a string which is printed by the logger (the change number is the important element but the other is also useful to quickly decide if a certain version contains changes you know you made yourself without going to perforce to check).
Hope this helps.

Resources