You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Perforce中按指定文件类型生成自定义格式的修订次数Top10文件列表?

Sure thing! You can absolutely get that custom-formatted list of your most-changed files in Perforce by pairing the p4 filelog command with some simple scripting to parse and reformat its output. Here's how to do it for both Unix-like shells (bash/zsh) and Windows PowerShell:

Unix-like Shell (Bash/Zsh) Solution

This script will fetch all files of your target type, count their revision history, sort them by change count, and output the top 10 in your desired format:

# Define your target file type (e.g., *.java, *.py)
TARGET_TYPE="*.java"

# Fetch file logs, count revisions, sort, and format output
p4 filelog -l //.../${TARGET_TYPE} | awk '
    # Track the current file and reset revision count when a new file is found
    /^\/\// {
        if (filename != "") {
            print revisions, filename
        }
        filename = $0
        revisions = 0
    }
    # Increment revision count for each recorded change
    /^\.\.\. #/ {
        revisions++
    }
    # Print the last file's data when done
    END {
        if (filename != "") {
            print revisions, filename
        }
    }
' | sort -nr | head -10 | awk '
    # Print header and separator
    BEGIN {
        print "# rank filename revisions"
        print "-------------------------------------"
    }
    # Format each line with rank, filename (stripped of depot path), and revision count
    {
        # Use $2 instead of substr(...) if you want the full depot path instead of just the filename
        print NR, substr($2, index($2, "/")+1), $1
    }
'

Windows PowerShell Solution

If you're working on Windows, this PowerShell script accomplishes the same goal:

# Set your target file type
$targetType = "*.java"

# Fetch raw file log output
$logData = p4 filelog -l "//.../$targetType"

$currentFile = $null
$revisionCount = 0
$fileRevisionList = @()

# Parse the log data to count revisions per file
foreach ($line in $logData) {
    if ($line -match '^//') {
        # Save the previous file's data if we have one
        if ($currentFile -ne $null) {
            $fileRevisionList += [PSCustomObject]@{
                FilePath = $currentFile
                RevisionCount = $revisionCount
            }
        }
        $currentFile = $line
        $revisionCount = 0
    }
    elseif ($line -match '^\.\.\. #') {
        $revisionCount++
    }
}

# Add the last file's data to the list
if ($currentFile -ne $null) {
    $fileRevisionList += [PSCustomObject]@{
        FilePath = $currentFile
        RevisionCount = $revisionCount
    }
}

# Generate the formatted output
Write-Host "# rank filename revisions"
Write-Host "-------------------------------------"
$rank = 1
$fileRevisionList | Sort-Object -Property RevisionCount -Descending | Select-Object -First 10 | ForEach-Object {
    # Extract just the filename (remove depot path) - use $_.FilePath to keep full path
    $fileName = $_.FilePath.Substring($_.FilePath.LastIndexOf('/') + 1)
    Write-Host "$rank $fileName $($_.RevisionCount)"
    $rank++
}

Quick Notes

  • Full Path vs. Filename: If you want to display the full Perforce depot path instead of just the filename, modify the final formatting step in either script to use the full file path string instead of stripping it.
  • Performance: For very large codebases, fetching logs for all files at once might be slow. If this is an issue, you can first get a list of files with p4 files //.../${TARGET_TYPE} and process them individually (though this will take more total requests to the Perforce server).

内容的提问来源于stack exchange,提问作者henrik

火山引擎 最新活动