MichaelPlante
MichaelPlante

Reputation: 462

p4 interchanges showing integrated changelists

My team is using a bash script that runs p4 interchanges -S $stream in order to determine which task streams still need to be copied up to their parents.

In the case of a stream that has two changelists where one undoes the other (where the cumulative diff is empty), the script is not saying that all revisions are already integrated, despite the stream having already been copied up to its parent.

Is there a way to make p4 interchanges recognize that the empty diffs do not need integration, or is there another p4 command we could be using here?

Upvotes: 0

Views: 1064

Answers (1)

Samwise
Samwise

Reputation: 71542

It depends on how you undid the changelist. If you used the p4 undo command, then p4 integrate (and by extension p4 interchanges) is able to recognize the relationship between those revisions by following the integration records created by p4 undo. If you undid it with a manual edit, then each revision looks like a new edit from the metadata perspective (which is all that integrate/interchanges considers -- actual file content inspection is delegated to resolve).

Here's an example file that (I think) demonstrates the situation you're talking about with an undone change, such that the cumulative effect is no diff:

C:\Perforce\test\undo>p4 filelog -i bar
//stream/test2/undo/bar
... #3 change 250 integrate on 2021/06/25 by Samwise@Samwise-dvcs-1509687817 (text) 'undo'
... ... undid //stream/test2/undo/bar#2
... #2 change 249 edit on 2021/06/25 by Samwise@Samwise-dvcs-1509687817 (text) 'foo'
... ... undone by //stream/test2/undo/bar#3
... #1 change 248 branch on 2021/06/25 by Samwise@Samwise-dvcs-1509687817 (text) 'foo'
... ... branch from //stream/test2/undo/foo#1
//stream/test2/undo/foo
... #1 change 236 add on 2021/01/28 by Samwise@Samwise-dvcs-1509687817 (text) 'add foo'
... ... branch into //stream/test2/undo/bar#1

As you can see, integrate and interchanges report this as nothing to do:

C:\Perforce\test\undo>p4 interchanges bar foo
bar - all revision(s) already integrated.

C:\Perforce\test\undo>p4 integ bar foo
bar - all revision(s) already integrated.

This is thanks to the undo/undone credits that you can see in the filelog. integrate can see that #3 is just the inverse of #2, so it adds them together and finds nothing to do.

Now suppose I add another edit and do a "fake undo" (this is what happens if you e.g. roll back a change with an old script or version of P4V that doesn't know about p4 undo):

C:\Perforce\test\undo>p4 edit bar
//stream/test2/undo/bar#3 - opened for edit

C:\Perforce\test\undo>echo asdfasdf >> bar

C:\Perforce\test\undo>p4 submit -d edit
Submitting change 251.
Locking 1 files ...
edit //stream/test2/undo/bar#4
Change 251 submitted.

C:\Perforce\test\undo>p4 sync bar#3
//stream/test2/undo/bar#3 - updating c:\Perforce\test\undo\bar

C:\Perforce\test\undo>p4 edit bar
//stream/test2/undo/bar#3 - opened for edit
... //stream/test2/undo/bar - must sync/resolve #4 before submitting

C:\Perforce\test\undo>p4 sync bar
//stream/test2/undo/bar#4 - is opened and not being changed
... //stream/test2/undo/bar - must resolve #4 before submitting

C:\Perforce\test\undo>p4 resolve -ay
c:\Perforce\test\undo\bar - vs //stream/test2/undo/bar#4
//Samwise-dvcs-1509687817/undo/bar - ignored //stream/test2/undo/bar

C:\Perforce\test\undo>p4 submit -d "fake undo"
Submitting change 252.
Locking 1 files ...
edit //stream/test2/undo/bar#5
Change 252 submitted.

C:\Perforce\test\undo>p4 integ -n bar foo
//stream/test2/undo/foo#1 - integrate from //stream/test2/undo/bar#2,#5

C:\Perforce\test\undo>p4 interchanges bar foo
Change 251 on 2021/06/25 by Samwise@Samwise-dvcs-1509687817 'edit'
Change 252 on 2021/06/25 by Samwise@Samwise-dvcs-1509687817 'fake undo'

What if I want to fix this after the fact? You mentioned that the stream was already copied up -- with a normal copy, there is no metadata record of this if the files were already identical (due to some sort of tricky operation like this). That is, even though integrate sees outstanding revisions, copy says "up-to-date":

C:\Perforce\test\undo>p4 copy -n bar foo
File(s) up-to-date.

In most situations this doesn't matter because you don't copy and merge in the same direction, and so copy biases toward not creating extra revisions for no good reason. In the event you do want the records to be updated so that copy and integrate agree with each other, though, you can do a copy with the -f flag, which tells it to create new revisions for the sole purpose of integration credit:

C:\Perforce\test\undo>p4 copy -f bar foo
//stream/test2/undo/foo#1 - sync/integrate from //stream/test2/undo/bar#2,#5

C:\Perforce\test\undo>p4 submit -d "recordkeeping copy"
Submitting change 253.
Locking 1 files ...
integrate //stream/test2/undo/foo#2
Change 253 submitted.

C:\Perforce\test\undo>p4 interchanges bar foo
bar - all revision(s) already integrated.

The copy -f operation will still do nothing if the files are identical and the credit is fully up to date:

C:\Perforce\test\undo>p4 copy -f bar foo
File(s) up-to-date.

so it's safe to use in non-edge cases as well.

Now, if you don't have any control over any of this, and you just want your script to not report changelists when the two streams are identical by content even if they aren't fully up to date by credit: do p4 copy -n before you do p4 interchanges, and if it reports "up to date", then for your purposes you can just treat it as p4 interchanges reporting the same thing.

Upvotes: 0

Related Questions