Why does "p4 integrate" operate on more files than "p4 interchanges" lists? - perforce-integrate

I maintain a family of branches, .../base/..., .../base-staging/..., .../base-production/.... Changes are usually made in base, reviewed, and then integrated out to base-staging and eventually base-production. Before an integration, I typically do a p4 interchanges to confirm that only expected changes will be carried forward.
Usually this works. But sometimes p4 integrate pulls over files and changes not listed by p4 interchanges. By my understanding, that shouldn't happen! What am I misunderstanding?
Details:
Ancient history:
create .../base/...
p4 integrate base/... base-staging/...
p4 integrate base/... base-production/...
make changes in .../base/... and submit
p4 interchanges base/... base-staging/...
review and approve
p4 integrate base/... base-staging/...
whoah! what are all these other listed files???
review: real changes, made well before my interchanges command, but not mentioned therein

I'm going to assume we're talking about a relatively recent server release -- on older releases "interchanges" will indeed match exactly what "integrate" lists, but in newer releases they diverge a bit in order to address the subtly different common use cases of the two commands.
One of the functions of "integrate" is to record history that ensures that future integrates behave in a predictable fashion. In some edge cases that means opening a file for integrate even though no actual changes need to be propagated to the target, so that it can be recorded that the file is up to date. A very simple example: make a change in A, ignore from A to B, merge from B to C, now merge A to C. Your expectation will typically be that integration is "transitive" such that if A->B reports nothing to do and B->C reports nothing to do then A->C will report nothing to do; if the B->C merge skips the change because it was an "ignore", though, then the A->C merge has no record that the B->C merge was ever even attempted, and it will propagate the change, violating the expectation of transitivity.
"Interchanges", however, does not record any history, and it is usually desirable for it to limit its scope to report only source changes that are not present in the target. It's therefore tuned to produce a smaller set of changes than you might get by running "integrate". The changes that are excluded from "interchanges" but included by "integrate" are typically going to be ones that do not strictly require merging, but that will probably make it easier to merge the "required" changes if they're included as well.
Using the "-Rs" flag on "integrate" will cause it to mimic the "interchanges" behavior and select the absolute minimum set of source revisions. It's briefly described in this old blog post from when it was introduced:
http://www.perforce.com/blog/101206/p4-integ-3-exciting-things-afoot

Related

Why/How can a revision graph like this be produced in perforce?

I have this revision graph from perforce and I am baffled how we managed to produce this graph. The part I find most puzzling is the part with the red square around it with revision 6 of row 2 being merged twice. The first time revision 6 is merged to revision 8 but with revision 11, I have never seen two revisions merged at the same time from separate branches. The second time revision 6 is merged like a normal merge but this file has been renamed for some time now so I don't know why the delete would suddenly get merged again. Can anyone explain the scenarios under which this can happen?
The top two rows are our trunk, the first row is our current trunk, the second row is the file before it was renamed, and the bottom row is a branch, we have many branches with the same strange merges in this branch.
A lot depends on how revision #6 was created. If you select revision 6, and open the "integrations" tab in the details pane, you can click on the source(s) of the integration(s) to reveal them in the graph.
A delete on top of a delete suggests that this file was re-added (under the old name) in some other branch, and then something unusual happened with that file that entailed the creation of an extra revision on the trunk for record-keeping purposes. The relationship between that revision and revision #12 of the "new" file may be significant -- it looks like there are effectively 5 different file variants sharing 2 different names in this history graph, and maybe there are additional variants that we can't see here.
You may also be able to get some information by clicking on the specific revision you're curious about (#10 on the bottom?) and reading the changelist description.
In general, a merge operation will propagate whatever has happened in the source that has not yet happened in the target. It does this by setting up a resolve, and in some cases the choices made during a resolve operation may negate some part of the changes made in the source and target (although the default option, where possible, will be to preserve and combine both). So the final outcome of a merge depends on its inputs, and what happened during the resolve, and the inputs in turn may be influenced by merges from elsewhere (and resolve choices made as a consequence of those merges), and so on.
Note also that not every arrow you see in a revision graph is the result of a merge -- copy has its own semantics, and a forced integrate via p4 integ -f has its own as well. (This is where reading the changelist description is useful -- hopefully the author of the change will have left some record there as to what their intent was and anything unusual they might have done, which can shortcut a lot of tedious forensic work.)

Integrate after Backout even files are identical

I have two branches (A and B). I changed several files in A and made a backout. When I integrate A to B also these files appear, even nothing has changed (besides files with real changes). How can I avoid that?
B is the main branch for several other branches, so for the next time a lot of integrations with several files without changes would be integrated across the depot. Any help appreciated.
I'm not sure if I'm correctly understanding you when you say "made a backout" because you also say "nothing has changed" -- usually "backout" implies making a change (i.e. you made changes that are the inverse of earlier changes).
In either case though, if when integrating A to B you do not want your changes made in A to have any effect on B, and you do not want those changes to be candidates for integration into B in the future, resolve with "-ay" (accept yours, where "yours" is the set of files you're modifying, i.e. B), and then submit. This will create a new revision which records that B is ignoring these changes in A.

Can we create Labels in perforce

I am working in a project. We use both clearcase and perforce.
As we are working on differnet builds, In clearcase we create a label for each release. Say for release "X", we create a clearcase case "Label X". Label X is having all the latest files with respect to release "X". When we finish another release say "Y", we create another label say "Label Y". Label "Y" is again having all the files for release "Y". But at any point of time we can go back to "Label X" .It means all the files will be reverted back to "Label X".
Can we do same thing in perforce? Can we create a label in perforce so at any point of time, we can go to that label which will give the files as in that label timeline.
Perforce also provide an interesting guide "Migration Planning Guide: IBM Rational ClearCase to Perforce", and mention that p4 label is not the only alternative:
Label Strategies
Both ClearCase and Perforce provide labels, which identify the versions of files that constitute a baseline. For many ClearCase users, labels are mandatory. Applying labels is time-consuming, often accounting for 30 percent or more of the time associated with creating
stable builds.
In Perforce, labels are just one way of reproducing baselines. Changelists accomplish the same goal in ways that are less taxing on the build process and faster and easier to reference than a label.
Each Perforce check-in generates a unique changelist number that reflects the state of the repository at a point in time. Any changelist can be used to describe the state
of every file in the repository, even though it affects only a small subset of the repository.
This is an oversimplication since a typical config spec is several lines or more.
Branches in Perforce are represented as directories, making it easy to combine branches and changelist numbers to represent a baseline.
Alternately, labels can refer to changelist numbers limited to an identified scope in the server, where the scope is typically a particular branch.
Yes, you can create labels in perforce.
Use p4 label to create a label specification, and then use p4 tag to tag files with a label.
You can learn more about labels in the user guide.
Imagine you have the following setup:
//depot/source/sourcefile.cpp
//depot/build/product.exe
At 8am, you check in sourcefile.cpp (now revision 2, in change list 100). The build machine starts building and at 9am, the build machine checks in product.exe, revision 2 in change list 104. Cool. Sadly, you may not have noticed, but at 8:15, someone checked in revision 3 of sourcefile.cpp in change list 103.
What are your options? If you just record the change list of the source (100) and product (104), you can sync your whole project to source and then sync further the contents of change list 104. This process is somewhat manual - you have to record two numbers and do a two step operation.
You can make a label, but sadly, labels don't allow multiple revisions so you it's not really workable.
Finally, at some point after you check in revision 104, you can create a branch. This is basically a metadata copy of the revisions you are interested in so that you can do a one click sync in the future. You can lock the branch to prevent changes.
p4 integ //depot/source/...#102 //depot/milestone1/source/...
p4 integ //depot/build/...#104 //depot/milestone1/build/...
Geeky details - you can configure files in perforce to hold a limited number of revision - for instance you might only want the last 16 revisions of product.exe. (Change the filetype to +S16). If you (or someone else does this), you the first two procedures will eventually fail because the revision has been deleted due to too many revisions. If you use the branch, your product.exe won't age out.

How to merge two checked out branches of Subversion ( Offline Merge )?

I am using Subversion with rabbit-vcs on Linux:
Under merge it shows only the option to browse my branches on online svn url
There is no option to give a offline svn folder as branch.
Since, I am pretty new to Subversion, so is it actually possible to merge 2 branches offline on svn ?
I have two branches already checked-out :
/home/user/branch1
/home/user/trunk
First of all, read this. Better yet, read this as well. Arguably, understanding merging is the most important part of knowing how to use SVN correctly (for one, you'll think thousands of times before creating a new branch :) ).
Note that you merge two committed sources into a working copy. That is, even if you specify one of the sources as a working copy it will still take its URL for merge purposes. So this is sort of syntactic sugar that a client may or may not support. The reason for it is that the merge operation needs to identify the common ancestor of the sources and merge them change by change. That information is not present in a working copy.
Note a source for some possible confusion here: in many (most?) instances the working copy argument may specify both a source to be merged and the working copy to merge into).
Here's an example of what I mean: suppose you merge S1 and S2 into W. S1 and W contain file F. S2 does not. Now, there are at least two possibilities: (1) the common ancestor S of S1 and S2 contained the file and it was deleted in S2. Then merge should delete it from W; (2) S did not contain F and it was added in S1. Then F should remain in W. The information about S in simply not present locally, so the repository has to be contacted.
To find out exactly branch URLs your offline working copies come from run svn info in branch1 and trunk.

Does perforce track deltas unique to a changeset or does it just store the whole file?

I tried to merge some work that a developer did in a working branch to a stable branch. The files a, b, and c had been changed by at least a dozen changesets since the common ancestor of STABLE and HEAD branches were separated.
I expected that since this developer changed five lines in each of file a, b, and c, that when I integrated from the HEAD to the STABLE branch, I would get his changes in my pending changset, which I could then review and commit.
Instead, it seems that it has taken every change that happened to file A, since the two were branched, and applied all of those changes that also existed in my colleague's working copy.
In other words, there seems to be no record in a perforce changeset, of what my colleague actually changed, versus what the file before contained.
If I browse the submitted changesets, I can see the difference between my colleague's version of the file, and the immediately preceding version. But then, that does not, it seems, determine what goes into the merge.
Doesn't a changeset mean, "a set of changes made between rev X and revision X+1 of a file"?
Can anybody help me understand what it means to "integrate a changeset" when in fact, what it seems is that Perforce doesn't track changes, it tracks files.
It is entirely possible that I am doing everything wrong, and would appreciate any pointer as to how it is that you can can merge accurately and safely between Perforce working branches and stable branches, without stuff that you don't want to get integrated to the stable branch getting integrated. It seems that no matter how simple the changes that actually get made in the product, the merge does not actually work for me.
Perforce does save changes to text files as deltas (binary files get saved in their entirety every time a change is submitted). It sounds like you're not properly restricting the revision range during your integration.
You say the working branch has "...been changed by at least a dozen changesets since the ...branches were separated." Let's call them changelists 1-12. If I understand you correctly you are trying to integrate the modifications made in just one of those changelists, not all of them.
During a simple integration operation Perforce will assume you want to integrate all of the changes that have been submitted since the branch was made. If you only want a subset of these changes, you have to specify a revision range. So, if you just want to integrate the changes that occurred between changelist 11 and 12, you would specify that revision range as shown in the screen capture. (Note: the revision range is inclusive, so specifying a range of 11-12, as I do in this screen shot will actually include changes in changelists 11 and 12. If you just want to integrate the changes made in changelist 12, enter 12 in both fields of the revision range.)
Just be aware that the inevitable conflicts that arise may be difficult to resolve, depending upon how far the branches have diverged and the nature of the changes.
Could you be more specific on how you did the integration? My guess is that you probably have integrated all the changes up to that changelist instead of just that changelist only. If so all you need to do is to specify the same changelist as both the upper and lower limit of the integration.
It's very easy to do in the visual client, but I'm not sure of the exact command line switch you need to use.

Resources