[p4] Changing file case in perforce, using a windows server

Robert Cowham robert at vizim.com
Fri Aug 13 14:22:19 PDT 2010


The problem with integrate/delete is that any deletes create discontinuities
in the version history.

This creates problems when you do a "catchup" from main (where the "rename"
happened) to the child branch before "publishing" back to main.

So you risk missing integrations unless you use the -Di flag to the
integrate command for all "catchups":

         -Di     If the source file has been deleted and re-added,
                 will attempt to integrate all outstanding revisions
                 of the file, including those revisions prior to the
                 delete.  Normally 'p4 integrate' only considers
                 revisions since the last add.

While for small numbers of users this is not a problem (just tell them to do
it, make sure they have integrated all outstanding branches or do it for
them...), with lots of users it is almost impossible to enforce in any
sensible way. Especially if there are many branches already exsiting which
may be integrated back to your mainline at any point in time, and may
contain months of work.

So depends on your sitation...

Robert

P.s. for anyone interested, here is a simple (but dangerous - requires
P4PORT=1999 to be available!!!) test script which demonstrates the
problem...

#!/usr/local/bin/ruby
#--
#---------------------------------------------------------------------------
----
#++
#
#= Introduction
#
#== Name:   text_case_rename_rename.rb
#
#== Author:     Robert Cowham  <robert at vizim.com>
#
#== Description 
# 
#       Runs test cases for case sensitivy fixing proposal.
#
#== Requires
#     Ruby
#     P4Ruby
#
#== Note
#
#     Assumes being run on Unix with case sensitive p4d in path or
alternatively
#    Windows.
#
#   Assumes following dir structure:
#       /some/dir
#                       /p4root - where p4d is running for location of
journal etc
#                      /client - directory where this script runs
#   See also hard coded P4PORT values, and the use of OBLITERATE between
runs to reset things!!.
#   RUN AT YOUR OWN RISK!!!!!!
#
#--
#---------------------------------------------------------------------------
----
#++

require "P4"
require 'test/unit'
require 'ftools'

class TestCaseFix < Test::Unit::TestCase

    # Note WE ASSUME THAT NO ONE ELSE IS USING THIS P4D SERVER!!!!!
    def setup
        @orig_file = "A/FILE"
        @new_file = @orig_file.downcase
        @temp_rename_file = "r/file"
        @branch_file = "b/FILE"
        @p4root = "../p4root"
        
        @p4 = P4.new
        @p4.debug = 1
        @p4.port = '1999'
        @p4.client = 'test_ws'
        @p4p = P4.new
        @p4p.port = '1999'
        @p4p.client = 'test_ws'
        @p4.connect
        @p4p.connect
        cl = @p4.fetch_client
        cl["Root"] = `pwd`
        print @p4.save_client(cl)

        remove_file(@orig_file)
        remove_file(@orig_file.downcase)
        remove_file(@temp_rename_file)
        remove_file(@branch_file)
    end
   
    def remove_file(path)
        print @p4.run_obliterate("-y", "//depot/%s" % path).inspect
        if File.exists?(path)
            File.chmod(0644, path)
            File.delete(path)
        end
    end
 
    def write_file(path, contents)
        key = path.downcase
        File.mkpath(File.dirname(path))
        file = File.open(path, "w")
        file.write(contents.join("\n") + "\n")
        file.close
    end

    def submit(desc)
        c = @p4.fetch_change
        c['Description'] = desc
        print @p4.save_submit(c).inspect
        print "\n"
    end

    def test_rename_rename
        # This test does a rename to a temp file and then renames back
again.
        write_file(@orig_file, ["A", "B", "C", "D", "E"])
        @p4.run_add(@orig_file)
        submit("V1")

        @p4.run_edit(@orig_file)
        write_file(@orig_file, ["A1", "B", "C", "D", "E"])
        submit("V2")

        @p4.run_integ(@orig_file, @branch_file)
        submit("integ")

        # This is an edit that won't be included in the branched file
        @p4.run_edit(@orig_file)
        write_file(@orig_file, ["A1", "B1", "C", "D", "E"])
        submit("V3")

        # Here we rename the original file and then rename it back
        @p4.run_integ(@orig_file, @temp_rename_file)
        @p4.run_delete(@orig_file)
        submit("V4 renamed")

        # First note that a rename back needs the -f flag
        begin
            @p4.run_integ(@temp_rename_file, @new_file)
        rescue
            assert(@p4.warnings[0] =~ /all revision\(s\) already
integrated./)
        end
        result = @p4.run_integ("-f", @temp_rename_file, @new_file)
        print result.inspect
        assert_equal(result[0]['action'], 'branch')
        assert_equal(result[0]["fromFile"], "//depot/#{@temp_rename_file}")
        @p4.run_delete(@temp_rename_file)
        submit("V5 renamed back")

        print @p4p.run_filelog("//depot/...").inspect

        @p4.run_edit(@new_file)
        write_file(@new_file, ["A1", "B1", "C", "D1", "E"])
        submit("V6")

        # Now make a change on branched file and integrate it back
        @p4.run_edit(@branch_file)
        write_file(@branch_file, ["A1", "B", "C1", "D", "E"])
        submit("Edit on branch")

        # Do "catchup" - which fails due to deleted revision and interrupted
history
        result = @p4.run_integ(@new_file, @branch_file)
        assert(result[0] =~ /can't integrate from .* without -i flag/)

        # Try integrate around deleted revs flag
        result = @p4.run_integ("-Di", @new_file, @branch_file)
        print result.inspect
        print @p4.run_resolve("-am").inspect
        submit("Catchup on branch")

        # Do "publish"
        result = @p4.run_integ(@branch_file, @new_file)
        print @p4.run_resolve("-am").inspect
        submit("Publish")

        # Just for info print contents of files showing differences
        print @new_file, "\n", File.read(@new_file)
        print @branch_file, "\n", File.read(@branch_file)
        assert_equal File.read(@new_file), File.read(@branch_file)

    end
    

end

#--
#---------------------------------------------------------------------------
----
# START OF MAIN SCRIPT
#---------------------------------------------------------------------------
----
#++

def main
   require 'test/unit/ui/console/testrunner'
   Test::Unit::UI::Console::TestRunner.run(TestCaseFix)
end

if __FILE__ == $0
    main
end


> -----Original Message-----
> From: perforce-user-bounces at perforce.com 
> [mailto:perforce-user-bounces at perforce.com] On Behalf Of Robert Cowham
> Sent: 12 August 2010 22:25
> To: 'Szabo, Norbert'; perforce-user at perforce.com
> Subject: Re: [p4] Changing file case in perforce, using a 
> windows server
> 
> I did this for a client - they had many tens of thousands of 
> files in the main branch, and many branches - anything 
> involving deletes and re-adds was a non-starter.
> 
> The approach was to create a dummy changelist on the files 
> needing re-casing, and then to change the journal records so 
> that particular entries had their case fixed (and change 
> entries to start with @rv at . We then replayed the new journal 
> into the server and all was well :) 
> 
> > -----Original Message-----
> > From: perforce-user-bounces at perforce.com
> > [mailto:perforce-user-bounces at perforce.com] On Behalf Of Szabo, 
> > Norbert
> > Sent: 12 August 2010 09:20
> > To: perforce-user at perforce.com
> > Subject: [p4] Changing file case in perforce, using a windows server
> > 
> > Hi,
> > 
> > I am sure we are not the first team facing this problem - we would 
> > like to change the case of a few folders in our depots.
> > 
> > At the moment the cases of our files and folders are a bit all over 
> > the place, we came up a beautiful naming convention to sort 
> it out but 
> > we faced some issues when trying to use the "move/rename" 
> feature in 
> > p4 - it give us an error message saying something along the 
> lines of 
> > "the file already exists".
> > 
> > Just to give you an example, we would like to rename "Layers" 
> > to "layers". 
> > 
> > I am aware of this knowledge base article:
> > http://kb.perforce.com/article/850/changing-file-case
> > 
> > It is proposing deleting and re-adding files with the new 
> case which 
> > sounds like a bit of a hack... Like making integrations to 
> this branch 
> > non trivial and also, forcing everybody to get rid or their local 
> > copies and getting latest again.
> > 
> > Sounds like a lot of hassle for a simple rename operation...
> > 
> > I am wondering do you guys had any success in the past 
> tackling this 
> > problem? I am thinking along the lines of doing some server-side 
> > search&replace/rename operations. I know it can be very 
> dangerous so I 
> > would only consider it if you are aware of a reasonably trivial 
> > solution.
> > 
> > Thanks in advance!
> > 
> > Norbert Szabo
> > Bizarre Creations Ltd.
> > 
> > Ps: And please, do not propose to move our server to Linux. 
> Cheers! :)
> > 
> > 
> ______________________________________________________________________
> > This email has been scanned by the MessageLabs Email 
> Security System.
> > For more information please visit
> > http://www.messagelabs.com/email
> > 
> ______________________________________________________________________
> > 
> > _______________________________________________
> > perforce-user mailing list  -  perforce-user at perforce.com 
> > http://maillist.perforce.com/mailman/listinfo/perforce-user
> 
> _______________________________________________
> perforce-user mailing list  -  perforce-user at perforce.com 
> http://maillist.perforce.com/mailman/listinfo/perforce-user




More information about the perforce-user mailing list