Perforce: merge/integrate a release stream to the parent virtual stream - merge

I have a main stream and a child virtual stream (say ProjVirt whose parent is Main). I created a release stream say rel1.0 from the ProjVirt stream - so that the changes can migrate from rel1.0 to ProjVirt.
Even the graph view shows the green merge arrow going from rel1.0 to ProjVirt (saying a merge is possible), but I cannot merge the changes from rel1.0 to the parent virtual stream. I keep getting the following warning:
p4 merge -c 324065 -S //depot/rel1.0 -P //depot/ProjVirt -s //depot/Main/myProj/...
no files opened
1 warning reported
No target file(s) in both client and branch view.
What am I doing wrong?

I am not sure that p4 merge take a -s parameter according to this documentation
p4 merge -c 324065 -S //depot/rel1.0 would merge from parent to child (this is the default direction).
If you want to merge in the other direction, you have to use the reverse syntax -r :
p4 merge -c 324065 -r -S //depot/rel1.0
I don't think you need anything else as target, because p4 can deduce the parent stream automatically from your stream config.
I think the original error message was due to the fact that changelist 324065 has no file in parent stream, but rather files in rel1.0. And since you were merging from parent, p4 found no file to merge.

Related

Get all changelists (excluding user) between "mainline" and branch

Background
I have a "mainline" depot and a "beta" branch in Perforce (using simple branches: no streams, etc).
I would like to merge the latest code from "mainline" to my "beta" branch. I have to do this about once every day, and there are about 100+ commits/submissions to the "mainline branch" every day.
Normally, I would do something like so:
p4 integ //prod/mainline/... //prod/beta/...
cd $(p4 where //prod/beta/... | cut -d ' ' -f3 | sed 's/\.\.\.$//g')
p4 resolve ./...
Problem
However, we have an annoying hourly build process that updates version numbers in various Makefiles, build scripts, etc; that updates version/branch numbers, and is checked in to Perforce using a "dummy" account (i.e. dummy_user) by our build servers. This is done across all branches, causing any merge operation to have arbitrary conflicts.
This version number submission now prevents my p4 integ/p4 resolve operation from completing cleanly, and I have to hand-merge all of these files affected by the "version number update operation". I would like to just have to hand-merge actual code changes, rather than this version number nonsense.
Question
Is there a way to p4 integ a set of change-lists not yet present in the branch (but present in main/another-branch), excluding a user? I could always do something like:
for i in $(p4 changes //prod/mainline/... | grep -v dummy_user | cut -d ' ' -f2)
do
p4 integ //prod/mainline/...#${i},${i} //prod/beta/...
done
However, I don't have an automated way to get a list of all change-lists that:
Exist in mainline...
But haven't yet been merged/integrated into beta...
And aren't authored by dummy_user.
How can I accomplish this?
Sounds like you've found a solution that works for you, but FWIW here's what I'd do:
0) Make a branchspec since that makes this next part easier:
p4 --field "View=//prod/mainline/... //prod/beta/..." branch -o prod-main-beta | p4 branch -i
1) Ignore the robo-commits (I assume you want to just leave these things alone):
p4 -Ztag -F #=%change% ichanges -u dummy_user -b prod-main-beta | p4 -x - integ -b prod-main-beta
p4 resolve -ay
p4 submit -d "Begone, robo-cruft!"
2) Do the "real" integrate. If you find yourself still having to pick around the "dummy" changes, try the -Rs option -- that might give you more merges to do but it will bend over backwards to make sure those merges don't include anything you've already integrated.
p4 integ -b prod-main-beta [-Rs]
p4 resolve [-am]
p4 submit
Optional 3) Improve your build tooling so that the version info is located in a dedicated file, and other build files link to it. Then you can exclude your version file from your branch specs, or just always ignore changes to it without having to cherry-pick, or whatever. Here's a real-world example: https://swarm.workshop.perforce.com/files/guest/perforce_software/p4/2015-1/Version

Get latest transaction ID for AccuRev stream

I want to find out what the ID was of the latest transaction that changed a stream.
I figured I could use accurev hist -s NameOfStream -t now -fx, but I am not sure if this would also show changes that I get from upstream.
Let's assume I have the following tree in AccuRev:
MyDepot
StreamA
StreamA1
StreamA2
StreamB
In case I promote a change from StreamB to MyDepot, that also affects StreamA and its children, I want to see the transaction when calling accurev hist -s StreamA1 -t now -fx. Does this happen or do I need a different command?
Update: I checked and the hist command only shows transactions that occured in the specific stream I mentioned and not any upstream changes.
How can I detect a change in a stream with a single command, without having a local workspace?
You can't do it with Accurev alone but I wrote a python script that can. It is a part of my Accurev to Git conversion tool which you can find here:
https://github.com/NavicoOS/ac2git
If you clone that repository all that you need is the accurev.py script and its deep-hist sub-command. Use ./accurev.py -h and ./accurev.py deep-hist -h to see the usage.
Example use:
./accurev.py deep-hist -p MyDepot -s MyStream -t 20-highest
This will recursively run the accurev hist command on the stream and its parents and will print out the result. It shows you all the transactions that have the potential to change your stream. Not all of these transactions listed will have changed your stream, but you can use accurev diff -v MyStream -V MyStream -t 19-20 to see if your stream has changed at transaction 20 and applying to list of returned transactions should give you only the transactions that have changed something in your stream.

Listing perforce changes in one branch, but not another; when there are deletions

When I want to compute a list of changes in one branch but not an older branch, I do something like this:
diff -u \
<( p4 changes -s submitted -i #OLD_BRANCH_LABEL ) \
<( p4 changes -s submitted -i #NEW_BRANCH_LABEL ) | grep ^+'
NOTE: These are automatic labels containing a view and a revision, but I can also put in the view paths #REVISION
which gives a good answer when both labels are actually in the same view, and good answers generally.
But I find that I get some poor results in this case:
If a commit #A adds a file to MAIN_BRANCH, and commit #D removes the file (and makes some other change), followed by commit #F which forks a NEW_BRANCH, I find that the MAIN_BRANCH contains both commits #A and #D, but NEW_BRANCH contains commits #D and #F
The NEW_BRANCH does not contain commit #A
So my p4 changes recipe above insists that the mainline contains #A which is not in the branch, or in other words was made since the branch, even though it is not in the mainline any more than it is in the branch.
An obvious but unwieldy fix would be to take another fork of MAIN_BRANCH at the point I want to compare, knowing that #A would be excluded again in the same way.
If this were git, I would use git-merge-base or something to find a common point and remove that from the changes of both branches, but perforce branching is too flexible, being just another integration.
Are there any ways that I can convince perforce that NEW_BRANCH does contain #A? (for the branch fork #F occurred after #A was committed).
Or to get perforce to ignore changes whose files are entirely deleted, that WOULD be ignored if a branch were made?
The command p4 interchanges does exactly what you are after, if I read your question correctly.
'p4 interchanges' lists changes that have not been integrated from
a set of source files to a set of target files.
Have a look at p4 help interchanges for the full description. The command does take indirect integrations into account, too.

mercurial hg partial checkin

It is a very simple and stupid question,
I am working on 2 tasks and modified 2 sets of files in the code.
Now when I type 'hg ci', it checks in all the files. Can I remove certain files from the checkin i.e. do checking for only one task?
If I remove the files in the 'check in message' will they be removed from the checkin
Thanks for all the answers
This seems like a big flaw, My use case is very simple and general. Most of the time dev are working on various tasks , some are ready , some are not, bug fixes etc.
Now the only simple solution seems to be multiple local repos or clones
Use hg ci <files>... to commit only certain files in your working directory.
If you want to pick file by file you can use the record command. It ships with mercurial, but you have to turn it on if you want to use it by putting: record= in the [extensions] section of your ~/.hgrc.
It goes hunk by hunk, but you can answer for a whole file:
y - record this change
n - skip this change
s - skip remaining changes to this file
f - record remaining changes to this file
d - done, skip remaining changes and files
a - record all changes to all remaining files
q - quit, recording no changes
? - display help
I'll point out that if you're committing some files but not others it's certain that you've not run your test suite on the one change without the other, but maybe that doesn't apply in your case.
This isn't possible with mercurial out of the box. As have been suggested there are several ways of selecting what files you want to commit. To get this function via the commit message template, you would need an extension or a shell script wrapping the commit command. Here's one way to do that:
[alias]
ci = ! hg-partial-commit
hg-partial-commit:
#!/bin/sh
# partial commit
edit=$(mktemp ${TMPDIR:-/tmp}/$(basename $0).XXXXXXXXXXXX)
filelist=$(mktemp ${TMPDIR:-/tmp}/$(basename $0).XXXXXXXXXXXX)
logmessage=$(mktemp ${TMPDIR:-/tmp}/$(basename $0).XXXXXXXXXXXX)
cleanup="rm -f '$edit' '$filelist' '$logmessage'"
trap "$cleanup" 0 1 2 3 15
(
echo user: $(hg debugconfig ui.username)
echo branch: $(hg branch)
hg parents --template 'parent: {rev}:{node|short} {author} {date|isodate}\n'
echo
echo 'Enter commit message. Select files to commit by deleting lines:'
hg status 'set:not unknown()' | sed -e 's/^/#/'
) | sed -e 's/^/HG: /' >"$edit"
${VISUAL:-${EDITOR:-vi}} "$edit"
egrep -v '^HG:' "$edit" >"$logmessage"
egrep '^HG: #' "$edit" | cut -c8- >"$filelist"
hg commit -l "$logmessage" "listfile:$filelist"
$cleanup
The real problem here is the fact that you're doing changes related to different tasks jumbled together. Mercurial has a few ways you can keep things separate.
Task Branches
Suppose you've been working on a task and you've checked in a few times since you last pulled, but things aren't ready to share yet.
o----o----B----o----o----o
Here, B is the revision where you started your changes. What we do is (after making sure our current changes are checked in):
> hg update -r B
<do our work on the other task>
> hg commit
We've now created a new branch with the changes for this task separated from the changes for our original task.
o----o----B----o----o----o
\
----o
We can do this for as many different tasks as we want. The only problem is that sometimes remembering which branch is which can be awkward. This is where features like bookmarks come in useful. A bookmark is a tag which moves forward as commits are made so that it always points at the head of a branch.
Mercurial Queues
MQ adds the ability to work on changes incrementally and move between them by pushing and poping then off a stack (or "Queue" I guess). So if I had a set of uncommitted changes that I needed to split up I'd:
> hg qrecord taska
> hg qrecord taskb
> hg qrecord taskc
I'd use the record extension (or more likely the crecord extension) to select which parts of files I want to select.
If I needed to go back to taska and make some changes:
> hg qpop; hg qpop # pop two off the queue to go back to task a
<Do changes>
> hg qrefresh # update task a with the new changes
When I want to turn the queue into normal changesets:
> hg qpush or hg qpop # get the changes I want converted onto the queue
> hg qfinish -a # converts mq changes to normal changesets
There's other methods too, but that will do for now.
You will unavoidably have to either specify the files that you want to add or the files you want to leave out. If you have a lot of files, as you indicate above, the following steps will simplify the procedure (I'm assuming a UNIX-ish system here, Windows would be slightly different).
First, generate a list of changed files:
hg status -mard -n >/tmp/changedlist.txt
The -mard options will list all files that were modified, added, removed, or delated. The -n option will list them without the status prefix so that all you have is a raw list of files.
Second, edit /tmp/changedlist.txt with your favorite text editor so that it contains only the files you wish to commit.
Third, commit these files:
hg commit `cat /tmp/changedlist.txt`
You will be able to review the files to be committed before actually performing the commit.
Alternatively, you can add more files to a commit incrementally by using
`hg commit --amend file...`
Here, hg commit --amend will not create a new commit, but add the new files to the existing commit. So, you start out with committing just a couple of files, then incrementally adding more until you are done. This still requires you to type all of them in.
For yet another alternative, you can use Mercurial Queues to split a commit in more sophisticated ways, but that's a bit more of an advanced topic.

Copy files to a new branch and keep the changelist history in P4V

I have a branch in my depot that I want to copy to a parallel location that does not currently exist in the depot. (i.e. I currently have \depot\rev6.2... and I need to create another branch at \depot\rev6.2b...) There are 2 things I would like to also happen:
First, I need the changelist history from rev6.2 to copy over to rev6.2b. When I have tried using the integrate feature, I have a new branch in the depot, but the history is blank (only 1 entry from the CL I submitted to create the branch).
Second (if possible) I would like to find a quick way so that if new changes are made in rev6.2, I can easily apply them to the rev6.2b branch as well.
I am a pretty basic P4V user (2011.1), so the more details the better. Thanks in advance for any help!!
You need to enable branch history. Click the icon I've circled in red, and select "Follow Branch Actions" in the dropdown.
Regarding your second question, if you want to bring over changes from the original branch, you can just run integrate a second time. Perforce tracks the integration history, so it knows when the branch was created, and what changes have been integrated since then (if any).
Perforce keeps all the integration history, as others already mentioned so everything from the 'rev6.2b' branch will have it's history traced to the 'rev6.2' branch. The P4V Revision Graph shows all of this history visually. On the command line the 'p4 filelog' or 'p4 filelog -i' commands, for example:
$ p4 filelog //depot/rev6.2b/...
//depot/rev6.2b/bar
... #1 change 12179 branch on 2016/02/25 by super1#super2015.2 (text) 'copy'
... ... branch from //depot/rev6.2/bar#1
//depot/rev6.2b/foo
... #1 change 12179 branch on 2016/02/25 by super1#super2015.2 (text) 'copy'
... ... branch from //depot/rev6.2/foo#1
The output shows the files in rev6.2b were branched from rev6.2 directory.
I am not sure which version and OS of the Perforce server and P4V client you are using but here is some feedback.
Regarding if new changes are made in rev6.2, to easily apply them to the rev6.2b branch also you can use a change-commit trigger to do that.
You could create a branchspec that has a view that maps all the changes from 'rev6.2' to 'rev6.2b' and then use the branch spec in the copy or integ command.
See Admin Guide: Change-commit Triggers
https://www.perforce.com/perforce/doc.current/manuals/p4sag/chapter.scripting.html#scripting.triggers.submits.commit
EXAMPLE BRANCHSPEC
Here is a view of a branch spec named 'master6.2copy'
View:
//depot/rev6.2/... //depot/rev6.2b/...
EXAMPLE
Here is *.bat file showing the content of a trigger script. (This is not an official Perforce script, just an example that can be tweaked.)
The first line below can also be instead:
p4 -p localhost:1666 -u myuser -c mywksp copy -b master6.2copy
#echo off
::
:: Example: The following change-commit trigger is an MS-DOS batch file
:: This trigger fires only after a changelist submission on a master directory
::
:: Add the following line to your triggers table:
::
:: copymaster change-commit //depot/rev6.2/... "/home/user/scripts/copyrev6-2.bat"
p4 -p localhost:1666 -u myuser -c mywksp integ -b master6.2copy
p4 -p localhost:1666 -u myuser -c mywksp resolve -at
p4 -p localhost:1666 -u myuser -c mywksp submit -d "rev6.2 copy to rev6.2b after changelist"
exit 0
Hope this helps!