Diff multiple files in perforce across a revision range - perforce

I'd like to diff a bunch of lines across several revisions. Like, I'd like to see a.c, b.c, and c.c from changelist X to changelist Y.
p4 diff2 a.c#X a.c#Y (where X & Y are changelist numbers) seems to work, but only sometimes. Specifically, if a.c is non-existent at X, I don't get a diff. I'd like to be able to get the diff (even though it'll be the whole file with only adds) anyways.
To get the bigger picture: I have several files, across several commits, and I'd like to merge the diffs of these files in these commits, to basically say "this is a diff of what changed in this set of files during this set of changelists"

If I understand your problem right, p4 diff -f ... should be your friend.
From the p4-help:
The -f flag forces a diff for every file, regardless of whether
they are opened or if the client has the named revision.
This can be used to verify the client contents.
(see p4 help diff on the command line).

Related

How do remove a particular change number in perforce?

I have a perforce client which synced to a particular change number. I want to remove changes for a particular change number.
eg. lets say I have a function in a file.
void printnames() { //M
printf("John\n"); //M
printf("Joseph\n"); //N
printf("Harry\n"); //M
printf("Mary\n"); //N
}
where M and N denote the latest change numbers which added/modified these lines. I want to remove change number N(or if I may say - unsync change number N).
Is it possible to do that, and what would be the steps? (I want to this for Perforce). I know I can manually p4 edit the file, but that's not what I am looking for.
p4 sync #(N-1)
p4 sync -k #(N)
p4 reconcile
And then optionally (if there are changes after N you want to sync to your workspace, which will be necessary if you want to submit the change that undoes N):
p4 sync
p4 resolve [-am]

Is `#=n` revision specifier the same as `#n,n` in Perforce file specifications?

Is the #=n syntax identical to the #n,n syntax?
For example, is
p4 integ //someotherbranch/...#12345,12345 ...
identical to
p4 integ //someotherbranch/...#=12345 ...
?
To access shelved revisions you do need to use the "#=n" syntax specifically, which is handled as a special case for changelists with shelved files. Otherwise they end up being the same.
If you want to get really technical "#n,n" is syntactic sugar for "#>=n,#<=n", which is logically going to match the same set of depot revisions as "#=n" (except for the shelve special case, which involves revisions that aren't actually committed to the depot yet).

How can I list P4 changes since a specific changelist

Is there a way get the list of changelists after a particular changelist for a particular branch?
p4 changes (some flag ?) (CL#) //depot/project
This can be done with the following syntax (assuming you want to see all the changes submitted to this branch since changelist 12345 inclusive):
p4 changes //depot/project/...#12345,#head
To successfully use Perforce it is crucial to understand the intricacies of the Perforce File Specifications or filespecs. Think of it as the query language of Perforce.
For example, if you want to do something with a branch between two points you would need a filespec similar to below:
//depot/branches/branch_name/...#12345,#head specifies a range between changelist 12345 and head/latest.
//depot/branches/branch_name/...#12345,23456 specifies a range between changelist 12345 and 23456.
//depot/branches/branch_name/...#2012/08/01,#2012/08/21 specifies a range between two dates.
p4 changes "//depot/project/...#>nnn"
where nnn is your CL#.
If you're into Perforce Integration, and you need to get the next CL to Integrate (the CL right after the last one you've integrated, say #12345), try this:
p4 changes "//depot/branches/branch_name/...#>12345" | tail -1 | cut -d ' ' -f 2

How to find which changelists will be copied?

I want to be able to do a 'p4 describe' on all the changelists that will be copied upon a 'p4 copy' command. How can this be done?
I could do something like:
p4 copy -n from-branch/... to-branch/... | sed -e 's|.* ||' | xargs -n 1 p4 filelog
to find the list of changes per file and truncate the list at the point of the last branch or integrate action into to-branch (if there is one). But this could potentially take a long time. Is there a better way?
Try p4 interchanges. I like the -l and -f flags, which print the whole changelist description and list the files changed:
p4 interchanges -lf from-branch/... to-branch/...
I haven't actually used this command with p4 copy, though, so the results might be slightly different. If you're doing especially fancy integrations (cherry-picking revisions) Perforce might show a changelist as needing to be integrated even when it's already been integrated.
I think the easiest thing to do would be to create a label and tag from-branch/... at the last CL that was copied to to-branch from from-branch. Then finding out the list of CLs not copied is as easy as:
p4 changes 'from-branch/...#>copied-up-to' # where copied-up-to is the name of the dynamic label
If everything under from-branch is all tagged at the same CL, I could use a dynamic label whose Revision spec would be the last CL that was copied to to-branch from from-branch.
A script is probably the right way to go. I'd use the perl, python, or ruby API to make it more efficient and easier to maintain.
The basic outline would be:
Run p4 copy -n to get the list of candidate files
Parse out the source revisions that are being copied. For instance, each line of output has something like "branch/sync from //depot/foo.c#1,#3". For that file you'd want to know how revisions 1-3 were created.
Run p4 changes to get the changelists that affected each file (e.g. p4 changes -l //depot/foo.c#1,#3
Again, doing this using an API will be much more efficient, as you can use a single connection for all the command calls.

Showing Perforce changelists submitted since last sync

Before I sync my Perforce client in the morning, I'd like to read the diffs and log messages for any changelists that will affect me. Unfortunately, though, I can't find a simple way to list such changelists using either p4 changes or P4V. I suspect I'm missing something simple, though.
Is there a way that I can list all the changelists submitted since I last sync'ed my client? If I can get the full descriptions and diffs from previous depot revisions, as p4 describe does for a single changelist, that would be even better.
The simple answer is:
p4 changes -l "...#>have"
You need the quotes to avoid your shell doing redirection.
You can trivially iterate over the changes and call "p4 describe" on each one.
You can get a full diff by using "p4 diff2" (assuming you want a unidiff):
p4 diff2 -du ...#have ...#head
But that doesn't give you a per-changelist diff.
Beware!
p4 changes "...#>have"
does not list changelists that contain only new/added files.
Your best bet is to cache the last sync point, something like
HEAD=`p4 counter change`
if [ -f lastbuild.txt ]
then
OLDHEAD=`cat lastbuild.txt`
else
OLDHEAD=`p4 changes -m1 ...#have`
echo lastbuild.txt not found! I will guess that your last sync was #$OLDHEAD
fi
p4 changes ...#$OLDHEAD,$HEAD > changes.txt
# -snip- review changes.txt, perhaps prompt "Continue with sync to $HEAD?"
p4 sync ...#$HEAD
echo $HEAD > lastbuild.txt
With this method you will get false positives if you have submitted or cherry-pick-synced any changelists since the last time you updated the sync point cache, but it's better to list an extra changelist for review than to miss one, especially one containing all new code.
Don't try this at home
For posterity, here are a couple other things I've tried in the past that ultimately failed:
p4 changes ...#have > have.txt
p4 changes ...#head > head.txt
diff have.txt head.txt
covers the case of changelists containing all adds, but the final output falsely includes older changelists for files that are deleted at #have. Also perf can be pretty bad if you have a lot of history in the depot.
p4 sync -n ... | cut -f1 -d' ' | p4 -x- changes -m1 | sort | uniq
gets pretty close, but fails to list older changelists if a file has been edited multiple times since you last synced. It's also hitting the depot once for every file that will sync, so perf can be really poor.
The newer versions of P4V (starting with 2009.2, maybe 2009.1) have something called a Dashboard that contains several "Tasks". One of these is Changelists that have not yet been synced to your workspace.
In the menu bar go to View -> DashBoard. There is a gear icon on the right of the DashBoard tab bar that allows you to configure your options. One of these is is "Files in my workspace are not at the latest revisions." The unsynced files are organized by changelist.
Is the answer to this question at all helpful?
From what I remember you have to store the last date/time you synced and then parse the output of p4 changes -t to just display those changelists after your date.
With time you may end up building a lot of little snippets of code around your use of Perforce. It may be a good idea to bundle them all into a wrapper script that invokes p4 for you and passes commands on to it, with or without extra, custom steps.
If you're using this kind of a wrapper with discipline (ie. not invoking p4 directly) it's trivial to make it store the last change you synced to.
In a DOS batch file, you could do something like the following:
FOR /F "tokens=2 delims= " %%a IN ('p4 changes -m1') DO (SET TO_CHANGELIST=%%a)
FOR /F "tokens=2 delims= " %%a IN ('p4 changes -m1 -c <client_name>')
DO (SET FROM_CHANGELIST=%%a)
p4 changes -s submitted #%TO_CHANGELIST%,#%FROM_CHANGELIST%
It will give you the list of all p4 changelists that are between the one that was last synced on your client and the changelist that was most recently submitted.
You can replace the last line with the following if you want to get the changelist descriptions and diffs:
FOR /F "tokens=2 delims= " %%a
IN ('p4 changes -s submitted #%TO_CHANGELIST%,#%FROM_CHANGELIST%')
DO (p4 describe %%a)
I would suggest that you pipe this data to a file so it will be easier to review.

Resources