I need to append some text to the description of already existing changelist in Perforce using Java.
What would be the most efficient way to do it?
I could think of
1. CL_content = p4 change -o <changelist>
2. Then append the required text to the description
3. p4 change -i CL_content
But, it would not be suitable for very large changelists.
Any other way?
Your solution looks good. No other option to update a bulk of changelists at once.
Perforce should be able to take the load when you are doing one after other. I don't see any issues with it.
Related
Does perforce track the time and date at which changes were made to changelists? For example, updating the description text, or shelving different revisions of files into the changelist? And if so, can this information be accessed using p4 command line?
p4 changes -t will include information about the creation time of the changelist, but not the update. p4 describe doesn't seem to include any flags related to time. p4 fstat can show time information about the files in a changelist, but not the changelist itself.
No, changelists are not versioned objects (not even in the spec depot, annoyingly). The only ways to track changes to changelists are to go under the covers, e.g.:
Scrape information from the journal file (this requires some understanding of Perforce's db schema)
Add triggers on each command that might update a changelist in the ways you want to track (this requires exhaustive understanding of Perforce's command API so you don't "miss" anything that you need to trigger on).
Is there a way to view all changelists that were made in the context of a stream in perforce? I am interested in a command line way.
Similar question: suppose I have a stream and its parent. Is it possible to find the changelist that is their latest common ancestor?
If you want to see not only locally made changes but also those that are included via import, the simplest way is to switch to that stream and run the query in the context of the current client:
p4 switch STREAMNAME
p4 changes //CLIENTNAME/...
Changes made locally will usually be in the depot path that matches the stream name (e.g. //stream/STREAMNAME/...), but if you use import+ this is not necessarily so (although if you use import+ the concept of changes being made within the context of a particular stream goes out the window entirely).
Finding the changelist that is the "latest common ancestor" depends what you want to use this ancestor for and what you consider to be a "common ancestor" and even what "latest" means (the word "latest" implies most recent chronologically, but that's not necessarily the same as "closest" in terms of having the most commonality). Some general approaches that might be useful:
Use the p4 istat command to see when the last merge/copy operations happened and what the latest change was that each included.
Use the p4 changes -i command on each stream to see what changelists it includes (including integrated ancestors), and diff to find the common ancestors.
Use the p4 integrate -o command to see the merge base for each file, and get the associated changelist with p4 changes or p4 files.
Thanks to Sam Stafford for pointing this out.
First use
p4 interchanges -S <child_stream_name>
This will give you a list of the changes that have not been copied up the parent branch.
To view diffs you can either use "p4 describe" on each of the changelists in the list.
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.
Is there a way to duplicate the change list description using p4 command line when integrating from the source change list across branches ?
Details:
For e.g.
p4 integ -t -b branch_a_to_branch_b -s //my/tree/...#2425,#2425
integrates files from changelist 2425 to the default changelist in the target branch branch_b from source branch branch_a
Is it possible to create a new changelist which has the same description as the source changelist ?
Then the target integration can be done on this new changelist.
I don't know of a way to do this in one command, but it seems like it would be easy enough to script up. You might want to look at the commands p4v runs when it integrates, as it has the option to integrate to a new changelist. Then it would simply be a matter of changing the description of the new changelist to match the old one.
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.