Exactly what is the change reported by `p4 -ztag sync ...#CLN`? - perforce

If I run p4 -ztag sync, the first printed record looks like:
... depotFile //depot/foo/bar
... clientFile /src/foo/bar
... rev 8
... action updated
... fileSize 2928
... totalFileSize 9087
... totalFileCount 1
... change 1234
All subsequent records look like:
... depotFile //depot/foo/baz
... clientFile /src/foo/baz
... rev 2
... action updated
... fileSize 2422
The change field is listed only in the first record, and it looks like it's supposed to represent the change number that I'm syncing to. If I'm syncing from an earlier change to a later change, then that does appear to be the case.
However, if I sync backward to an earlier change by doing p4 sync ...#CLN, then the reported change sometimes is not CLN but is some slightly earlier change. (And yes, CLN is a valid, submitted change that affects files under .... If I sync even further back and then sync forward using the same p4 sync ...#CLN command, then the reported change is the change number I specified.)
Why is the reported value of change different for the same p4 sync ...#CLN command, apparently dependent on whether I'm syncing forward or backward? Is this a Perforce bug? (I am using P4/LINUX26X86_64/2015.1/1126382 with P4D/LINUX26X86_64/2015.1/1240625.)

The change reported is the highest changelist associated with any revision being synced.
In some cases this may happen to be the same as the changelist specified on the command line (if any), but it will frequently be lower (although I don't think there's any way it can ever be higher).
As an example:
c:\test\changes>p4 files -a ...
//stream/dev/changes/foo#3 - edit change 23 (text)
//stream/dev/changes/foo#2 - edit change 21 (text)
//stream/dev/changes/foo#1 - add change 19 (text)
c:\test\changes>p4 have ...
//stream/dev/changes/foo#2 - c:\test\changes\foo
c:\test\changes>p4 -Ztag sync -n ...#30
... depotFile //stream/dev/changes/foo
... clientFile c:\test\changes\foo
... rev 3
... action updated
... fileSize 26
... totalFileSize 26
... totalFileCount 1
... change 23
c:\test\changes>p4 -Ztag sync -n ...#20
... depotFile //stream/dev/changes/foo
... clientFile c:\test\changes\foo
... rev 1
... action updated
... fileSize 6
... totalFileSize 6
... totalFileCount 1
... change 19
c:\test\changes>p4 -Ztag sync -n ...#10
... depotFile //stream/dev/changes/foo
... clientFile c:\test\changes\foo
... rev 2
... action deleted
... totalFileSize 0
... totalFileCount 1
... change 0
Note that when syncing #30 change 23 is reported (because it's associated with foo#3), when syncing #20 change 19 is reported (because it's associated with foo#1), and when syncing #10 change 0 is reported (because now we're removing foo from the workspace, i.e. syncing to foo#none). If we were syncing multiple files, the change reported would be the highest from among the entire group of file revisions being synced to the workspace.

Related

In perforce, is it possible to subtract the changes of one changelist from another?

Suppose, I have two changelist A and B (which is on top of A).
Now, I want only the changes done in B and not the one which are included in A, i.e. B-A
Is it possible to do so?
Yes. Do:
p4 undo #A,A
p4 sync #B
This will create a new pending changelist that is "B minus A". If A and B touched the same file(s), syncing to #B will require a resolve to merge B's changes into the file (without A's changes). The merge will be set up in such a way as to make everything happen as automatically as is possible.
If there are other, later, changes to the same file(s), you will need to sync and resolve those just as you would any time you're working on an older changelist.
This is theoretically also doable in P4V (I think it's the "back out" command), but I've had bad experiences with that and do not recommend it. It's very straightforward from the command line.
Example
C:\Perforce\test\undo>p4 annotate -c foo
//stream/main/undo/foo#3 - edit change 137 (text)
135: this
136: is **CHANGE A**
135: a
137: test **CHANGE B**
135: file
Change A is #136, Change B is #137.
C:\Perforce\test\undo>p4 undo #136,136
//stream/main/undo/foo#2 - opened for integrate
... undid //stream/main/undo/foo#2
C:\Perforce\test\undo>p4 sync #137
//stream/main/undo/foo#3 - is opened and not being changed
... //stream/main/undo/foo - must resolve #3 before submitting
C:\Perforce\test\undo>p4 resolve -am
c:\Perforce\test\undo\foo - merging //stream/main/undo/foo#3
Diff chunks: 1 yours + 1 theirs + 0 both + 0 conflicting
//compy386/undo/foo - merge from //stream/main/undo/foo
C:\Perforce\test\undo>p4 submit -d "undid A"
Submitting change 138.
Locking 1 files ...
integrate //stream/main/undo/foo#4
Change 138 submitted.
Change 136 has now been undone by change 138:
C:\Perforce\test\undo>p4 annotate -c foo
//stream/main/undo/foo#4 - integrate change 138 (text)
135: this
138: is
135: a
137: test **CHANGE B**
135: file
C:\Perforce\test\undo>p4 filelog foo
//stream/main/undo/foo
... #4 change 138 integrate on 2020/02/08 by Samwise#compy386 (text) 'undid A'
... ... undid //stream/main/undo/foo#2
... #3 change 137 edit on 2020/02/08 by Samwise#compy386 (text) 'change B'
... #2 change 136 edit on 2020/02/08 by Samwise#compy386 (text) 'change A'
... ... undone by //stream/main/undo/foo#4
... #1 change 135 add on 2020/02/08 by Samwise#compy386 (text) 'test file'

In perforce, how to remove a symlink to a directory and add files in the same directory?

This can be done like this:
1. p4 delete dir,
p4 submit;
2. p4 add dir/file,
p4 submit;
Is there a way to do this in one go?
I don't want to do p4 submit in step 1 because not having that directory will break things at my end.
There does not seem to be anything preventing this:
C:\Perforce\test\dir>p4 opened
//stream/main/dir#1 - delete default change (symlink)
//stream/main/dir/bar#1 - add default change (text)
//stream/main/dir/foo#1 - add default change (text)
C:\Perforce\test\dir>p4 submit -d "presto"
Submitting change 106.
Locking 3 files ...
delete //stream/main/dir#2
add //stream/main/dir/bar#1
add //stream/main/dir/foo#1
Change 106 submitted.

how to obliterate files in folder with different revision in perforce

I have a build folder in perforce that keep tracks of all my builds but the files inside it have different revision numbers (because they are / are not affected from different builds), so in the same folder i have files with revision #1200 and other with revision #2000.
I initially was thinking to obliterate the old revisions from p4admin, since there is the option "obliterate up to revision", but in the case of this folder I'm not sure how this will behave.
There is any way in p4 for keeping only the last 2 revision of all the files in that folder? Or the only doable way is writing a script for checking each file's revision before obliterating it?
Perforce doesn't have an additive relative revision syntax, unfortunately, so you can't use #head-2 or anything like that.
The easiest way to do something like this IMO is to create a label with the #head-2 revisions, which you can do iteratively using the #< relative revision specifier on the label itself:
# start by labeling #head
C:\Perforce\test>p4 tag -l minus2 ...#head
//stream/main/0.f1#3 - added
//stream/main/1.15#4 - added
//stream/main/1.16#1 - added
//stream/main/1.17#1 - added
//stream/main/1.18#2 - added
//stream/main/2.f1#5 - added
//stream/main/2.f2#4 - added
# now replace everything in the label with the previous revision
C:\Perforce\test>p4 labelsync -l minus2 "...#<minus2"
//stream/main/0.f1#2 - updated
//stream/main/1.15#3 - updated
//stream/main/1.16#1 - deleted
//stream/main/1.17#1 - deleted
//stream/main/1.18#1 - updated
//stream/main/2.f1#4 - updated
//stream/main/2.f2#3 - updated
# now do it again, bringing us to #head-2
C:\Perforce\test>p4 labelsync -l minus2 "...#<minus2"
//stream/main/0.f1#1 - updated
//stream/main/1.15#2 - updated
//stream/main/1.18#1 - deleted
//stream/main/2.f1#3 - updated
//stream/main/2.f2#2 - updated
Now the label has all the latest revisions that I want to obliterate. I'll double-check with p4 files -a before doing p4 obliterate:
C:\Perforce\test>p4 files -a #1,#minus2
//stream/main/0.f1#1 - add change 72 (text)
//stream/main/1.15#2 - edit change 77 (text)
//stream/main/1.15#1 - branch change 73 (text)
//stream/main/2.f1#3 - integrate change 81 (text)
//stream/main/2.f1#2 - integrate change 78 (text)
//stream/main/2.f1#1 - branch change 74 (text)
//stream/main/2.f2#2 - integrate change 79 (text)
//stream/main/2.f2#1 - branch change 75 (text)
C:\Perforce\test>p4 obliterate -y #1,#minus2
//stream/main/0.f1#1 - purged
//stream/main/2.f1#2 - purged
//stream/main/2.f1#3 - purged
Deleted 4 label 24 integration 8 revision record(s).

Getting the change number of the first revision of a file in Perforce?

Is there a way to retrieve the change of the first revision of a file in Perforce? Sometimes I want to read the job description of the change that introduced a file, in order to learn what the file does, as well as to find related CRs for more information. I'm looking for something in the command line, e.g.
p4 <something> <file>
Ah, never mind, I found the subcommand I needed, p4 fstat, just after posting the question.
$ p4 fstat cama_Preempt#1
... depotFile //depot/MMA/products/CAMA/main/src/testScripts/cama_Preempt
... clientFile /ext1/acheong/CAMA/main/src/testScripts/cama_Preempt
... isMapped
... headAction add
... headType text
... headTime 1174070670
... headRev 1
... headChange 168703
... headModTime 1174070479
... haveRev 1
The headChange field shows the change number.

Perforce: How to find the original number of a change list

In perforce changelists get renumbered on submission. So for e.g. when the changelist was created it would be numbered 777 , but on submission of changelist it would get renumbered to say 790.
My question is how do I get the new CL number (790) , if I know the old CL number 777 , or vice versa ?
If you really want the original changelist number, that can be retrieved from Perforce without having to embed the original changelist number in the description. You can use the -ztag command line option to get at it. And you can only get at it through the 'changes' command (as far as I know):
d:\sandbox>p4 submit -c 24510
Submitting change 24510.
Locking 1 files ...
edit //depot/testfile.txt#2
Change 24510 renamed change 24512 and submitted.
d:\sandbox>p4 -ztag changes -m1 //depot/testfile.txt
... change 24512
... time 1294249178
... user test.user
... client client-test.user
... status submitted
... oldChange 24510
... desc <enter description here>
<saved
As pointed out, it's probably not that useful. However, I did want to note that it's possible to get at it.
The only way I can think of is adding the original changelist number as part of the changelist description field. First, you'll need a script to store the original changelist number:
#!/bin/env perl
$id = $ARGV[0];
open (CHANGE_IN, "p4 change -o $id|");
open (CHANGE_OUT, "|p4 change -i $id");
while (<CHANGE_IN>)
{
if (/^Description:/ and not /ORIGID/)
{
s/(^Description:)(.*)$/$1 ORIGID $id. $2/;
}
print CHANGE_OUT $_;
}
close (CHANGE_IN);
close (CHANGE_OUT);
Save this as origid.pl on the Perforce server with the executable bit set. Then setup a trigger with p4 triggers.
Triggers:
add_origid change-submit //depot/... /usr/bin/origid.pl %change%
Version 2012.1 of Perforce introduced the -O (capital oh) argument to p4 describe, which allows you to query a changelist by its original number (before being renumbered by p4 submit).
I find this very helpful, since I often find myself keeping notes about a changeset before it is submitted, then forgetting to note what it was renumbered to on submission.
So if I have a note talking about change 12300, I can now see what it refers to by typing:
p4 describe -s -O 12300
and having Perforce tell me:
Change 12345 by me#myhost on 2013/10/31 00:00:00
Fix that thing I wrote that note about
Affected files ...
... //Proj/MAIN/foo.c
The ztag method mentioned earlier can be used to find the old changelist number of a submitted change:
> p4 -ztag describe -s 12345 | grep oldChange
... oldChange 12300
Adding to Eric Miller's reply, because I can't comment (not enough points):
to just emit the 1 number
p4 -ztag describe $ORIG | sed -e 's/^\.\.\. oldChange //;t-ok;d;:-ok'
e.g.
OLD=$(p4 -ztag describe $ORIG | sed -e 's/^\.\.\. oldChange //;t-ok;d;:-ok')
or if you want to look up many numbers, this will output a map of new old on each line (may be useful with the "join" command). If there is no old commit, then it re-emits the new commit.
p4 -ztag describe 782546 782547 ... | sed -e '${x;p};s/^\.\.\. change //;t-keep;b-next;:-keep;x;/./p;g;G;s/\n/ /;x;d;:-next;s/^\.\.\. oldChange //;t-ok;d;:-ok;H;x;s/ .*\n/ /;x;d;'
I tried to avoid using GNU extensions to sed.
Unless you do something like Tim suggests the old change list number will be lost on submission.
Change list numbers are only temporary until you actually submit. So if you create a new change list (777 say) and then decide to delete it, the next change list you create will be 778.
It can be a bit more elegant if you use the P4 Python module.
i.e.
import P4
p4 = P4.P4()
p4.connect() # having a valid p4 workspace/connection is on you :)
c = p4.run_describe('969696') # describe a Submitted, renumbered changelist, i.e. 969696
old_pending_cl_number = c['oldChange'] # print out prior/pending CL# if this exists.
Cheers

Resources