My p4 client version is P4/NTX64/2018.1/1705517.
I noticed that some files had accidentally been deleted in my workspace. I synced, but even so, the files did not appear.
I then ran the p4 have command and saw that it contained the missing files, and so p4 will not include those files in the sync.
Of course I can give the p4 sync command with the -f flag, but my workspace is rather large, so that would take a long time.
I then ran the flush command even with the -f flag thinking that it would correct my have list to reflect what I actually had on the filesystem of my workspace, but it didn't. What am I doing wrong?
p4 flush changes the have list to match whatever you tell it to match (if no arguments, then #head is the default). If that's not what your workspace actually contains, then the have list is now out of sync with the workspace, and future p4 sync commands will probably skip a bunch of files (exactly like you're seeing now).
The command you want is p4 clean, which syncs your workspace to match your have list. (If you have changes in unopened files, including "new" files that you haven't opened with p4 add, this will irrevocably blast them. Careful!)
If you want to open the files that don't match your have list, use p4 reconcile instead. (You can follow it up with p4 revert to discard the changes, or p4 submit to keep them permanently.)
I am very new to Perforce and just started using it.
After syncing my code using $p4 sync command i started editing a few files.
$p4 edit file1
$p4 edit file2
$p4 edit file3
These files were getting added to my default changelist. For collaborating with my team i wanted to create a changelist. For creating a changelist i ran $p4 change and removed "file1" from the changelist description. Now when i run $p4 opened. It gives an output similar to this.
//depot/... /file1 edit default change (text)
//depot/... /file2 edit default 111 (text+k)
//depot/... /file3 edit default 111 (text+k)
Now i have the following questions in my mind:
Which changelist am i currently working on is it default or 111 ??
what is the meaning of (test + k)?
When i make changes to file2 and file3 it is getting synced to changelist 111 and when i make changes to file1 it gets synced to default changelist . I am highly confused how is this happening ?
Also one more thing i am confused about is if do $p4 shelve will my changes disappear and will be reapplied only when i run unshelve command for the changelist created ?? Is this similar to git stash and git stash apply ?
It will be great if someone can answer these questions in detail. Any tutorial suggestions for Perforce will also be of great help.
Thanks in advance.
My recommendation for a Perforce tutorial is the Perforce User's Guide. Here's the section on changelists:
https://www.perforce.com/perforce/r15.1/manuals/intro/chapter.working_in_perforce.html#working_in_perforce.working_with_files.changelists
Which changelist am i currently working on is it default or 111 ??
Both! Both of these are pending changelists in your workspace.
what is the meaning of (text+k)?
The thing in parentheses is the "filetype". +k is a "filetype modifier" meaning that keywords (special words like $Id$ and $Revision$ and $Author$ in this file will be automatically expanded to appropriate values when you submit.
When i make changes to file2 and file3 it is getting synced to changelist 111 and when i make changes to file1 it gets synced to default changelist . I am highly confused how is this happening ?
Nothing is getting "synced" anywhere yet -- the pending changelists are just containers that reference the different files. When you shelve or submit, then the files associated with those changelists will get sent to the server and will be accessible by other clients. Since shelve and submit are changelist-level operations, only the files in those changelists are affected -- that's the point of having different pending changelists. You have all of the pending files in your workspace, but you can split up which ones get sent to the server at which times (it's a little like pushing different branches in git, but not -- you can do this on every operation in Perforce even when you aren't branching because each file is versioned individually rather than having the entire tree versioned as one atomic blob).
Also one more thing i am confused about is if do $p4 shelve will my changes disappear and will be reapplied only when i run unshelve command for the changelist created ?? Is this similar to git stash and git stash apply ?
No, p4 shelve only syncs the shelved change on the server with the local files in your workspace -- it doesn't in itself change your workspace. The equivalent of "stashing" would be to p4 shelve and then to p4 revert to wipe out the workspace changes. shelve on its own is a little more like doing a git push to a branch -- you keep your local copy but now it's also on the server (but not part of the "master" history). (It's not exactly the same though -- to be honest if you're brand new to Perforce I'd stick to regular old "submit" in a regular old branch since that's the basic workflow. Sharing work via shelves requires a lot more manual work since each shelf is like its own little mini-branch with no versioning.)
I've tried to shelve files today and checked the Revert checked out files after they are shelved option, and after shelving the files some files have been reverted, but some remained. It appeared that these were new files added through p4 add. Is it default behavior to not remove such files after shelving? Is there a way to remove them as part of shelving process?
What you did in P4V (shelve with reverting) is really a plain combination of two commands: shelve and revert. Behind the scenes, P4V will shelve your work (as it surely did) and then revert everything in your changelist.
Now, the revert command reverts p4 adds in such a way that they disappear from your changelist (the essence of reverting) but they remain on the local filesystem (to prevent inadvertent loss of code/data). Yes, you can argue that in this respect revert does not do a very good job of reverting your work completely, but obviously Perforce have decided to play it safe by not deleting your work.
As #Bryan Pendleton says, you can use p4 revert -w instead of plain p4 revert when you want to also delete your p4 adds from the filesystem. It's not a separate command, just a variant of p4 revert. However, there's no way to specify the -w flag (the -w behaviour) when running the "Shelve-and-Revert" combo action from P4V. (In fact, there's no way to specify -w even in the plain "Revert" action from P4V.)
I'm assuming you won't switch from P4V to the command-line (to run p4 shelve followed by p4 revert -w) just for this reason, so just remember that P4V has this little quirk and if needed, delete your local files after reverting them.
I had made changes to a file and then shelved it.
Then I deleted the file.
Now I am not able to get it back to my workspace. I tried p4 sync -f and p4 unshelve ##.
What do I do ?
p4 unshelve is the correct command.
To figure out which shelf you need to unshelve, use p4 changes -s shelved and p4 describe -S
What's probably going wrong is that when you deleted the file, you still left it "opened" in Perforce (do p4 opened to see), so first do a p4 revert to revert the file, then you can successfully unshelve the shelf and you'll get your edited version back.
In p4v, go to the depot view, select the file, then hit ctrl-shift-s (pretty sure this works in linux too) this will open an explorer window which should be where the file is located. Maybe it's going to a different directory then the one you think?
If it's not there, right click the folder, and say get this revision, and check the force checkbox
A question that occasionally arises is what is the best way to determine the changelist that you last synced to in Perforce. This is often needed for things like injecting the changelist number into the revision info by the automatic build system.
I recommend the opposite for automatic build systems: you should first get the latest changelist from the server using:
p4 changes -s submitted -m1
then sync to that change and record it in the revision info. The reason is as follows. Although Perforce recommends the following to determine the changelist to which the workspace is synced:
p4 changes -m1 #clientname
they note a few gotchas:
This only works if you have not submitted anything from the workspace in question.
It is also possible that a client workspace is not synced to any specific changelist.
and there's an additional gotcha they don't mention:
If the highest changelist to which the sync occured strictly deleted files from the workspace, the next-highest changelist will be reported (unless it, too, strictly deleted files).
If you must sync first and record later, Perforce recommends running the following command to determine if you've been bit by the above gotchas; it should indicate nothing was synced or removed:
p4 sync -n #changelist_number
Note that this method doesn't work if a file is added in a changelist (n-1) and then deleted in the very next changelist (n). p4 changes -m1 #clientname and p4 changes ...#have both return n-3 and p4 sync -n #n-3 will say "file(s) up-to-date."
Just to answer this myself in keeping with Jeff's suggestion of using Stackoverflow as a place to keep technical snippets....
From the command line use:
p4 changes -m1 #<clientname>
And just replace with the name of your client spec. This will produce output of the form:
Change 12345 on 2008/08/21 by joebloggs#mainline-client '....top line of description...'
Which is easily parsed to extract the changelist number.
You may try finding the maximum change number in the output of the "p4 files" command. The working directory should not contain post-sync commits, though. This is just a tad better than
p4 changes -m1 "./...#have"
as the latter seems to run on the server and may fail on big source trees due to "MaxResults" limits.
$ p4 changes -m1 "./...#have"
Request too large (over 850000); see 'p4 help maxresults'.
$ p4 -G files "./...#have" | python c:/cygwin/usr/local/bin/p4lastchange.py
Files: 266948
2427657
where p4lastchange.py is based on the code from the Using P4G.py From the Command Line presentation by J.T.Goldstone, Kodak Information Network/Ofoto, April 15, 2005.
#! /usr/bin/env python
import sys, os, marshal
if os.name == "nt":
# Disable newline translation in Windows. Other operating systems do not
# translate file contents.
import msvcrt
msvcrt.setmode( sys.stdin.fileno(), os.O_BINARY )
lastcl = 0
num = 0
try:
while 1:
dict = marshal.load(sys.stdin)
num = num + 1
for key in dict.keys():
# print "%s: %s" % (key,dict[key])
if key == "change":
cl = int(dict[key])
if cl > lastcl:
lastcl = cl
except EOFError:
pass
print "Files: %s" % num
print lastcl
p4 changes -m1 #clientname which is the "recommended" way to do it for my client takes about 10 minutes
this is what I use:
p4 cstat ...#have | grep change | awk '$3 > x { x = $3 };END { print x }'
for the same client takes 2.1 seconds
If you are using P4V you can do this graphically:
In the Dashboard tab (View->Dashboard) choose a folder and you will see a list of changelists that the folder isn't yet updated with. Note the lowest number (in the highest row).
Make sure that in the Workspace Tree you have selected the same folder as previously in the Dashboard. Then go to the History tab (View->History) and scroll down to the number noted previously. The number just below that number is the number of your current changelist.
You could also use the cstat command:
p4 help cstat
cstat -- Dump change/sync status for current client
p4 cstat [files...]
Lists changes that are needed, had or partially synced in the current
client. The output is returned in tagged format, similar to the fstat
command.
The fields that cstat displays are:
change changelist number
status 'have', 'need' or 'partial'
For a serious build (one that is being prepared for testing), explicitly specify the desired label or changelist number, sync to label, and imbed it in build artifacts.
If a changelist (or label) is not given, use p4 counter change to get the current change number, and record it. But you still need to sync everything using that change number.
I don't think you can achieve exactly what you want, because in general, an entire workspace isn't synced to a particular changelist number. One can explicitly sync some files to older revisions, and then a single changelist number is meaningless. That's why a fresh sync is required to ensure that a single changelist number accurately represents the code version.
Regarding the comments: Yes, my answer is intended for use by configuration managers preparing a build to give to QA. Our developers don't normally sync as part of a build; they do a build prior to submitting—so that they can make sure their changes don't break the build or tests. In that context, we don't bother to embed a repository label.
With your approach, you are making the assumption that your whole workspace was synced to head at the time of your last changelist submission, and that changelist included all of your open files. It's too easy to be mistaken in those assumptions, hard to detect, and horribly expensive in terms of lost time. On the other hand, solving the problem is easy, with no drawbacks. And because a changelist number can be explicitly specified, it doesn't matter what revision you need or how quickly the codebase is changing.
For the whole depot (not just your workspace/client)
p4 counter change
does the job, just telling the last changelist.
The best I've found so far is to do your sync to whatever changelist you want to build and then use changes -m1 //...#have to get the current local changelist (revision).
p4 sync #CHANGELIST_NUM
p4 changes -m1 //...#have | awk '{print $2}'
Gives you the changelist number that you can the use wherever you want. I am currently looking for a simpler way than p4 changes -m1 //...#have.
I am not sure if you got the answer you needed but I had a similar problem. The goal was to write in our logger the specific version of the project. The problem was that while we are making our own makefile, the overall build system is controlled by our configuration management. This means that all the solutions which say "sync to something then do something" don't really work and I didn't want to manually change the version whenever we commit (a sure source for errors).
The solution (which is actually hinted in some of the answers above) is this:
in our makefile, I do p4 changes -m1 "./...#have"
The result for this is Change change_number on date by user#client 'msg'
I simply create the message into a string which is printed by the logger (the change number is the important element but the other is also useful to quickly decide if a certain version contains changes you know you made yourself without going to perforce to check).
Hope this helps.