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

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'

Related

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).

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

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.

How to quickly find out the changelist deleting a line

I need to find out which changelist deleted a particular line from a file. This file is regularly updated by many people. I have 2 changelist at hand, one has the line and the other does not. The problem is, there are numerous changes in between.
Any pointer is appreciated!
[UPDATE]
I found this script, http://projects.joelinoff.com/p4tools/p4-whodunit.py, but it does not work for me:
$~/tmp/p4-whodunit.py --help
: No such file or directory
$~/tmp/p4-whodunit.py //depot/mybranch/file1
: No such file or directory
Not familiar with python, not sure what to do with it.
Use "p4 annotate -a" to find out when the line was last present; the following revision is the one that removed it.
In this example, line A was added in revision 2, and removed (replaced by B) in revision 3:
C:\test\local\dvcs\i\deltas>p4 annotate -a foo
//stream/main/i/deltas/foo#3 - edit change 50625 (text)
1-1: 1:
2-2: 1: A
3-3: 1: B
So to answer the question of "in what changelist did line A get deleted?" I can do:
C:\test\local\dvcs\i\deltas>p4 annotate -a foo | grep A
2-2: 1: A
C:\test\local\dvcs\i\deltas>p4 files foo#3
//stream/main/i/deltas/foo#3 - edit change 50625 (text)
Use P4V's Timelapse View. It will show the changelist that added the line, and the changelist that deleted the line.

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.

Resources