views:

34

answers:

1

Does anyone have code (preferably that runs on Win32) that will display a history of all file renames and moves that have occured in a Perforce branch?

+1  A: 

Since you didn't give a lot of information about your environment, I made the following assumptions:

  • You are on Windows, but willing/able to install Ruby and the p4ruby API
  • You are running Perforce version 2009.1 or newer (I actually implemented support for previous versions of Perforce as well, it's just a little ambiguous, see below).

With that said, let's look at what we want: All renames and moves of files within a branch. The P4 knowledge-base tells us that a rename (and a move, for that matter) consists of

  • open for edit
  • move file
  • submit

and is designated as a 'move/add' operation in the change. I have hacked a little Ruby script, which looks at all changes (p4 changes //branch/...) of the given branch, and for each change looks (p4 describe @change) whether there is a 'move/add' operation and emits the file.

#!/usr/bin/env ruby

require 'P4'

branch = ARGV[0]

p4 = P4.new
p4.connect

begin
  p4.run_changes("-i", branch).each do |change|
    p4.run_describe(change["change"]).each do |c|
      files = c["depotFile"]
      files.each do |f|
        if c["action"][files.index(f)] =~ /move\/add/
          puts "File #{f} was RENAMED in change #{c["change"]} (original: #{c["fromFile"][files.index(f)]})"
        end
        if c["action"][files.index(f)] =~ /integrate/
          # TODO find a corresponding delete in the same changelist, which would
          # this mark as a 'move' for P4 versions prior 2009.1
          puts "File #{f} was INTEGRATED in change #{c["change"]}"
        end
      end
    end
  end

rescue P4Exception
  p4.errors.each { |e| $stderr.puts(e) }
  raise
end

p4.disconnect

C:\> ruby p4report.rb //some/perforce/branch/...

Some more notes:

  • Provided as is, roughly tested, use at your own risk
  • Depending on the number of changes for the branch this could take a while, it's not very elegant to list all changes and then examine each change, i.e. do not use on the root of your depot (//depot/...)
  • The TODO in the code clearly says it: For Perforce prior 2009.1 a rename was done by integrate followed by delete (see knowledge-base). I've added support to find the integrate action, but left the rest as an exercise to the reader. As it is right now, you wouldn't see a difference between a normal branching operation and a 'branch-and-delete' operation.

Any suggestions about how to make that easier are welcome.

jhwist