How do I split a large changelist in P4 - perforce

I have a very large changelist (~40,000 files) and I need to split it into several smaller changelists so I can view the files contained. I am aware that I can adjust my p4 preferences to show more files in a changelist, but I need to run commands against the files in the changelist, and when I run the command it hangs and doesn't complete after 18 hours.
I'm running the 2012.2 P4 server.
The command I'm running is:
C:>p4 -u some_user -c some_client revert -k -c 155530 //...
Thanks

If you want to move files into a separate changeset, you could do:
p4 reopen -c default //some/subdirectory/...
p4 change
The above would move a portion of the files into the "default" changeset and then create a new changeset from them. Or, if you have another changeset to use already, you could of course do:
p4 reopen -c NEW_CLN //some/subdirectory/...
directly.
If the files you want to split out aren't nicely contained within a subdirectory, a more general approach would be to do:
p4 -ztag opened -c OLD_CLN | grep depotFile | cut -d ' ' -f 3 > files.txt
to get a list of files opened in that changeset. Then edit that file so that only files you want to remove from the changeset are listed, and then do:
p4 -x files.txt reopen -c NEW_CLN
The above calls p4 reopen -c NEW_CLN using each of line from files.txt as an argument.

Related

Git Diff and Copy

I am wanting to run a Static Code Analysis (PMD) report against the files that have been added or modified as part of a pull request on bitbucket. The files that have been modified etc are available locally within the pipeline image, however I need to do a git diff to identify the changes ONLY between the source branch (pulling from) and the target branch (to be merged into). I will then be executing the PMD CLI (with rulesets etc) against a directory that will contain only the "changed files" to highlight any issues with those files specifically as part of the change.
I basically want to copy out the files indicated in the git diff result. I hope this provides some more context.
I have tried finding some examples and done testing however I am just not getting it right due to my lack of understanding on these crazy linux commands :)
So far I have the below command, but results in an empty folder.
git diff --name-only --pretty $BITBUCKET_PR_DESTINATION_BRANCH $BITBUCKET_BRANCH | xargs -i {} cp {} -t ~/branch-diff/
xargs might have problems will a number of files - argument would be too big. I Propose something like
for name in $(git diff --name-only --pretty $BITBUCKET_PR_DESTINATION_BRANCH $BITBUCKET_BRANCH); do cp $name ~/branch-diff/; done
As a result you will have all these files in one directory (without directory tree). Other question is that is it really what you need.
Firstly, the issues with your current solution:
xargs doesn't play nicely with filenames which have spaces in. You may not have that problem now, and you can work around it, but it's better to just avoid this if possible.
cp does not build a directory tree - which you can trivially verify - so it wouldn't do what you asked anyway.
git does not produce pathnames relative to the current path, but to the working tree base.
The filenames produced by git diff $BITBUCKET_PR_DESTINATION_BRANCH $BITBUCKET_BRANCH don't even have to exist in your working tree, but only in (at least one of) the branches.
If there's a diff between the two versions of a file, you haven't said which one you want copied!
A functional script using standard file tools would look something like:
#!/bin/bash
# diffcopy.sh
#
DESTDIR="$1"
BRANCH1="$2"
BRANCH2="$3"
# so relative paths match git output
SRCDIR="$(git rev-parse --show-toplevel)"
# choose the branch whose files we want to copy
git checkout "$BRANCH2"
# make the output directory
mkdir -p "$DESTDIR"
# sync the changed files
rsync -a --files-from=<(git diff --name-only "${BRANCH1}".."${BRANCH2}") "$SRCDIR" "$DESTDIR"
# restore working copy
git checkout -
There may be a better way to do this purely in git, but I don't know it.
If you have the GNU variant of cp and xargs, you can do this:
git diff --name-only -z $BITBUCKET_PR_DESTINATION_BRANCH $BITBUCKET_BRANCH |
xargs -0 cp --target-directory="$HOME/branch-diff/" --parents
This does not spawn a cp per file, but copies as many files as possible with one cp process. By specifying --target-directory, the destination can come first on the cp command, and xargs can paste as many source file names at the and of the cp command as it likes. --parents keeps the directory names of the source files.
The -z in git diff separates file names by a NUL character instead of line breaks, and the -0 of xargs knows how to take the NUL separated path list apart without stumbling over whitespace characters in file names.

Is it possible to use a P4 command to `Mark for Delete` every file that is "missing"?

Say I had checked in the files:
a.txt
b.txt
c.txt
I checked them all out so that I could mass edit them by dumping files from another folder:
cp -R folder-one/* folder-two/
The result is:
a.txt (updated)
b.txt (deleted)
c.txt (no changes)
Now I Revert Unchanged Files and intend to submit:
a.txt (updated)
b.txt (deleted)
But I can't because now b.txt is "missing".
Is it possible to use a P4 command to Mark for Delete every file that is "missing"?
Easiest fix is just to revert all of the files that you've opened (with the -k flag so you keep your local changes) and let reconcile figure it out from square one:
p4 revert -k ...
p4 reconcile ...

Get local location for Perforce opened files

I want to write a script to process files that have been edited. p4 opened gives a good list but it is using depot syntax. Is there a way to get the output in local syntax so I can pass the results to my script?
I am running Perforce on Linux.
p4 where will tell you where a depot file is located locally.
You'll need to take the output of p4 opened and use p4 where to translate each depot path to a local path.
This answer might provide some hints.
Edit: Also see if p4 -ztag opened suits your needs. -ztag frequently produces a more verbose, but script-friendly output.
If you just want the client syntax for the file you can use the
'p4 -Ztag opened' command such as either of the following examples:
$ p4 -Ztag opened | grep clientFile
... clientFile //admin14streams/depot/www/dev/Jam.html
... clientFile //admin14streams/depot/www/dev/Jambase.html
... clientFile //admin14streams/depot/www/dev/Jamfile.html
... clientFile //admin14streams/depot/www/dev/Jamlang.html
... clientFile //admin14streams/depot/www/dev/images/jamgraph-jam.gif
... clientFile //admin14streams/depot/www/dev/index.html
$ p4 -Ztag opened | grep clientFile | cut -d ' ' -f3
//admin14streams/depot/www/dev/Jam.html
//admin14streams/depot/www/dev/Jambase.html
//admin14streams/depot/www/dev/Jamfile.html
//admin14streams/depot/www/dev/Jamlang.html
//admin14streams/depot/www/dev/images/jamgraph-jam.gif
//admin14streams/depot/www/dev/index.html
The 'p4 where' command will give you the local file system
location if that is what you want, however.
$ p4 where //depot/www/dev/Jam.html
//depot/www/dev/Jam.html //admin14streams/depot/www/dev/Jam.html /home/bruno/myspaces/admin14streams/depot/www/dev/Jam.html
$ p4 -Ztag where //depot/www/dev/Jam.html
... depotFile //depot/www/dev/Jam.html
... clientFile //admin14streams/depot/www/dev/Jam.html
... path /home/bruno/myspaces/admin14streams/depot/www/dev/Jam.html
Hope this helps.

How do I get a count of files in a folder in Perforce?

I would like to know how many files are in any given folder/directory/branch of a Perforce depot, but I don't see a way to do this. The p4 fstat command was my first thought, but it doesn't appear to have options to return file counts. Is there a simple way to get a count of files in a folder using either the graphical or command-line client?
While the p4 fstat doesn't offer a way to obtain file counts per se, you can easily parse its output to obtain this information. Note, this works in Windows, but I would imagine it is easily modified for other OSes. Here's how you do it:
p4 fstat -T depotFile //depot/some/folder/... | find /c "... depotFile"
It can also be done with the p4 files command as thusly:
p4 files //depot/some/folder/... | find /c "//"
Use the p4 sizes -s command.
C:\test>p4 sizes -s ...
... 5 files 342 bytes
or if you want just the count:
C:\test>p4 -F %fileCount% sizes -s ...
5
(obviously the file argument can be anything else in place of ... which is the current directory)
Try this command:
p4 files //depot/dir1/dir2/... | wc -l
Explanation:
p4 files //depot/dir1/dir2/... is the command that recursively prints the files under dir2 to screen.
Pipe that through wordcount lines (| wc -l) to count the number of output lines.
This works in Linux/Unix systems, and in Windows if you're using cygwin (or some other Linux-like terminal).
Powershell method:
To count the files in a specific directory:
p4 files //depot/dir1/dir2/... | Measure-Object
Alternatively:
(p4 files //depot/dir1/dir2/...).Count
The following will give you a list of all child directories and their file counts in an object that you can view as a table, sort, export to csv, etc:
p4 dirs //depot/dir1/* | Select-Object -Property #{Name="Path";Expression={$PSItem}},#{Name="FileCounts";Expression={(p4 files $PSItem/...).Count}}

rsync and (post) process synced file

i like rsync my photos from one (linux) disc partition to an other (backup location) using an shell script.
The problem is, that I need to re-scale all photos which are saved on the backup location, for example with mogrify.
Is it possible to post-process every file, which is synced/copied by rsync?
In oder to execute mogrify on every synced file?
An other way could using rsync (only) to generate the list of files which have to be synced. Next step: run a loop to mogrify every list entry in order to output the scaled photo to the backup location.
The problem is, that I have to add all the directories and child-directories to keep the original folder structure before saving the photo.
Using rsync would handle the folder creation "on the fly".
So: is it possible to execute an command on every file synced with rsync?
rsync has a -i/--itemize-changes flag to output a resume of what it does with each file.
I suggest you to play a bit with it, I'm seeing it outputs lines like >f+++++++++ file1 for a new file, >f..T...... file1 for an unchanged file, >f.sT...... file1 for an update, etc...
Having that, you can read this output into a variable, and parse this with grep and cut:
#!/bin/bash
log=$(rsync -i rsync-client/* rsync-server/)
newFiles=$(echo "$log" | grep '>f+++++++++' | cut -d' ' -f2)
for file in $newFiles
do
echo "Added file $file"
done

Resources