Repository Footprint Analysis

Repository Footprint Analysis: TestSampleA

This analysis combines insights from the Git object database history (git-sizer) and the current working directory state to identify performance bottlenecks and bloat.

Overall Risk Level: CRITICAL

The repository exhibits severe bloat in its Git history (19.7 GiB total blob size) and critical structural issues with extremely large trees (32.6k entries in a single directory). These factors will significantly degrade Git performance, increase clone times, and impact CI/CD pipeline efficiency.

Git Database Bottlenecks

  • Blobs Total Size: 19.7 GiB CRITICAL
    The cumulative size of all file versions stored in the repository's history is extremely large. This indicates that many large files, or files that change frequently, have been committed over time, leading to a bloated history. Each change to a large file adds its full size to the repository's historical footprint.
  • Trees Maximum Entries: 32.6 k CRITICAL
    A single directory, identified as force-app/main/default/email/Apttus__ApttusTempEmailTemplates, contains an excessive number of entries. This is a major performance bottleneck for Git, as operations like checkout, status, and diff become very slow when traversing such large directories.
  • Number of Files in Biggest Checkout: 522 k HIGH
    The largest historical checkout contained over half a million files. While the current working directory has slightly fewer, this indicates a history of very large codebases or numerous small files, contributing to overall repository complexity and slower operations.
  • Maximum Blob Size: 8.12 MiB MEDIUM
    Individual files of this size, particularly if they are text-based and change frequently, contribute significantly to the overall blob size and repository bloat. The working directory scan confirms these are primarily Salesforce profile XMLs.

Working Directory Bloat

The current working directory scan reveals that the vast majority of disk space is consumed by XML files, specifically large Salesforce profile metadata.

  • .xml files: 1.17 GB (95% of total size) CRITICAL
    This file type dominates the repository's footprint.
  • Salesforce Profile XMLs: ~8.1 MB each CRITICAL
    The top 10 largest files are all .profile-meta.xml files, each around 8.1 MB. These files are notorious for growing very large and changing frequently, leading to massive Git history bloat as identified by git-sizer.
    File Size
    /force-app/main/default/profiles/Read Only System Integration.profile-meta.xml8.18 MB
    /force-app/main/default/profiles/Read Only System Integration Login User.profile-meta.xml8.18 MB
    /force-app/main/default/profiles/Informatica System Integration.profile-meta.xml8.17 MB
    /force-app/main/default/profiles/CRM Integration API Only with IPs %28DO NOT USE%29.profile-meta.xml8.17 MB
    /force-app/main/default/profiles/Admin.profile-meta.xml8.17 MB
    /force-app/main/default/profiles/Analytics Cloud Integration User.profile-meta.xml8.16 MB
    /force-app/main/default/profiles/Sales Insights Integration User.profile-meta.xml8.15 MB
    /force-app/main/default/profiles/CRM Team Administrator.profile-meta.xml8.15 MB
    /force-app/main/default/profiles/B2BMA Integration User.profile-meta.xml8.15 MB
    /force-app/main/default/profiles/SalesforceIQ Integration User.profile-meta.xml8.15 MB
  • .asset files: 44.7 MB MEDIUM
    While significantly smaller than the XMLs, this category is the second largest by total size. Review these assets to ensure they are appropriate for Git and not excessively large binaries.
  • Apttus__ApttusTempEmailTemplates directory CRITICAL
    This directory is flagged by git-sizer for having an extremely high number of entries (32.6k). This suggests a large number of small files, possibly temporary or generated, which severely impacts Git's tree traversal performance.

Actionable Remediation

Addressing these issues requires a multi-pronged approach focusing on metadata decomposition, selective ignoring, and potentially historical cleanup.

1. Salesforce Profile Decomposition (Immediate & High Impact)

The large profile XMLs are the primary cause of bloat. Decompose them into smaller, more manageable files. This is a critical step for Salesforce DevOps.

  • Strategy: Use Salesforce CLI or a specialized tool to break down each .profile-meta.xml file into individual components (e.g., object permissions, field permissions, Apex class access, Visualforce page access).
    sfdx force:source:retrieve -m Profile:Admin -o <output_directory> --json
    Then, use a tool or script to convert the retrieved profile into its decomposed format. Many Salesforce DevOps platforms and community tools offer this capability.
  • Impact: Instead of an 8MB file changing for a single permission update, only a small, specific permission file will change. This drastically reduces blob size growth and improves Git performance.

2. Manage Apttus__ApttusTempEmailTemplates Directory

The directory force-app/main/default/email/Apttus__ApttusTempEmailTemplates with 32.6k entries is a major bottleneck.

  • Investigation: Determine if these are truly temporary, generated, or legacy email templates.
  • Exclusion (if temporary/generated): If these files are not essential for version control or are generated during builds, add them to .forceignore:
    # Ignore temporary or generated Apttus email templates
    force-app/main/default/email/Apttus__ApttusTempEmailTemplates/
  • Cleanup (if legacy/unneeded): If they are legacy and no longer used, remove them from the repository.
  • Organization (if needed): If they are legitimate and needed, explore ways to organize them into subdirectories to reduce the number of entries in a single tree.

3. Review and Exclude Other Bloat

  • .asset files: Review the content of .asset files. If they are large binary files (e.g., images, PDFs) that are not frequently updated or are better managed outside of Git (e.g., in a CDN or Salesforce Static Resources directly without versioning in Git), consider excluding them if appropriate for your workflow.
  • General .forceignore Best Practices:

    Ensure your .forceignore file is comprehensive. Common exclusions include:

    # Ignore temporary files and directories
    .sfdx/
    .sf/
    .vscode/
    .DS_Store
    *.log
    *.bak
    *.tmp
    
    # Ignore specific metadata types if not managed in Git
    # Example: If profiles are fully decomposed and you only manage specific permissions
    # force-app/main/default/profiles/*
    
    # Ignore specific large files or directories identified
    # force-app/main/default/email/Apttus__ApttusTempEmailTemplates/
    

4. Historical Cleanup (Post-Decomposition)

After decomposing profiles and managing the email templates, the Git history will still contain the large blobs. To reclaim space and improve historical performance, a history rewrite is necessary. This is a destructive operation and requires careful planning, communication, and coordination with all repository users.

  • Tool: Use git filter-repo (recommended over git filter-branch for performance and safety).
  • Process:
    1. Decompose profiles and commit changes.
    2. Identify and remove the original large profile XMLs from history. This involves scripting git filter-repo to remove specific file paths that contained the large profiles before decomposition.
    3. Identify and remove the large Apttus__ApttusTempEmailTemplates directory from history if it was determined to be ignorable.
    4. Force push the rewritten history. All users will need to re-clone the repository.

    Example (conceptual, requires careful testing):

    # Install git-filter-repo if not already installed
    # pip install git-filter-repo
    
    # Clone a fresh copy of the repository for filtering
    git clone --mirror <your-repo-url> <repo-name>.git
    cd <repo-name>.git
    
    # Example: Remove specific large profile files from history
    # This assumes you have already decomposed them and committed the decomposed versions.
    # The paths here should be the *original* paths of the large files.
    git filter-repo --path force-app/main/default/profiles/Read Only System Integration.profile-meta.xml --invert-paths --force
    git filter-repo --path force-app/main/default/profiles/Read Only System Integration Login User.profile-meta.xml --invert-paths --force
    # ... repeat for all large profile files ...
    
    # Example: Remove the problematic email templates directory from history
    git filter-repo --path force-app/main/default/email/Apttus__ApttusTempEmailTemplates/ --invert-paths --force
    
    # After filtering, push the rewritten history (requires force push)
    git remote set-url origin <your-repo-url> # Reset URL if it was changed
    git push --force --all
    git push --force --tags
    

    WARNING: This is a highly impactful operation. Ensure all team members are aware, have backed up their work, and are prepared to re-clone the repository.

Copado Pipeline Impact

Improving the posture of this Git repository by reducing bloat and clearing bottlenecks will have a profound positive impact on Copado Source Format Pipeline jobs (Copado Functions):

  • Faster Git Operations:
    • git clone / git fetch: Significantly reduced time for Copado agents to clone or fetch changes from the repository, especially for fresh environments or new pipeline executions. A 19.7 GiB history is extremely slow to transfer.
    • git checkout: Faster switching between branches and preparing the working directory for deployment, as Git will process fewer, smaller files and fewer entries in large directories.
  • Improved Metadata Processing Performance:
    • sfdx force:source:pull / sfdx force:source:deploy: When profiles are decomposed, changes to permissions will result in much smaller metadata payloads. This means faster retrieval and deployment times, as Salesforce CLI and the Metadata API will process fewer and smaller XML files.
    • Reduced API Call Volume: Smaller metadata changes often translate to fewer API calls or faster processing per call, especially for complex metadata types like profiles.
  • Enhanced Pipeline Reliability:
    • Fewer Timeouts: Large repositories and slow Git operations are common causes of pipeline timeouts. Reducing bloat will make pipelines more robust.
    • Reduced Disk Usage: Smaller repository size means less disk space consumed on Copado agents, preventing potential disk full errors and improving overall system stability.
  • Optimized Copado Functions Execution:
    • Copado Functions that interact with the Git repository (e.g., for diffing, merging, or deploying) will execute much faster and more reliably due to the underlying Git performance improvements.
  • Overall Efficiency:

    The cumulative effect will be a dramatic reduction in overall pipeline execution times, leading to faster feedback loops, more frequent deployments, and a more agile Salesforce development process.

Historical Object Analysis (git-sizer)

| Name                         | Value     | Level of concern               |
| ---------------------------- | --------- | ------------------------------ |
| Overall repository size      |           |                                |
| * Commits                    |           |                                |
|   * Count                    |  6.02 k   |                                |
|   * Total size               |  1.89 MiB |                                |
| * Trees                      |           |                                |
|   * Count                    |  68.1 k   |                                |
|   * Total size               |   668 MiB |                                |
|   * Total tree entries       |  10.3 M   |                                |
| * Blobs                      |           |                                |
|   * Count                    |   296 k   |                                |
|   * Total size               |  19.7 GiB | **                             |
| * Annotated tags             |           |                                |
|   * Count                    |     0     |                                |
| * References                 |           |                                |
|   * Count                    |  2.55 k   |                                |
|     * Branches               |     1     |                                |
|     * Remote-tracking refs   |  2.55 k   |                                |
|                              |           |                                |
| Biggest objects              |           |                                |
| * Commits                    |           |                                |
|   * Maximum size         [1] |   569 B   |                                |
|   * Maximum parents      [2] |     2     |                                |
| * Trees                      |           |                                |
|   * Maximum entries      [3] |  32.6 k   | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
| * Blobs                      |           |                                |
|   * Maximum size         [4] |  8.12 MiB |                                |
|                              |           |                                |
| History structure            |           |                                |
| * Maximum history depth      |  1.15 k   |                                |
| * Maximum tag depth          |     0     |                                |
|                              |           |                                |
| Biggest checkouts            |           |                                |
| * Number of directories  [5] |  21.4 k   | **********                     |
| * Maximum path depth     [6] |     9     |                                |
| * Maximum path length    [6] |   229 B   | **                             |
| * Number of files        [7] |   522 k   | **********                     |
| * Total size of files    [8] |  1.27 GiB | *                              |
| * Number of symlinks         |     0     |                                |
| * Number of submodules       |     0     |                                |

[1]  052ce9fcc2545ddf52edc42c7444cf0b458e2f95 (refs/remotes/origin/promotion/P53781)
[2]  0e220e4cdd89922286b1f3211b7949c6cc37e17c (refs/remotes/origin/SIT)
[3]  e3a906db27f2ab94897e5433f350ce581fc495a0 (refs/remotes/origin/STAGING:force-app/main/default/email/Apttus__ApttusTempEmailTemplates)
[4]  63156b34fd1c2e25f7de952874ee0b5b0e879816 (74be18dac43b8487b975ba52613b1da7f5660a47:force-app/main/default/profiles/Read Only System Integration.profile-meta.xml)
[5]  71e316bf42678950abf16bde25816bea3d28efc6 (refs/remotes/origin/STAGING^{tree})
[6]  1636eacab735d68a0150f6ef8f340c5d15db9983 (refs/remotes/origin/SIT^{tree})
[7]  8e54ddb45eb26eab9ccd2a24e76e3d1f7a8be4bf (8bdd1e18f4edb836f0a91494dd008a6f12e983d2^{tree})
[8]  84590f0b227b3e6b6c50c824438d9f1af0e83d5f (refs/remotes/origin/promotion/P52015^{tree})

Working Directory Physical Footprint

{
  "totalSizeBytes": 1225876718,
  "fileCount": 479529,
  "extensionMap": {
    "No-Extension": 5044,
    ".md": 1251,
    ".json": 2343,
    ".xml": 1173593770,
    ".auradoc": 2516,
    ".cmp": 204112,
    ".js": 1221190,
    ".css": 44976,
    ".design": 3798,
    ".svg": 44311,
    ".app": 1118,
    ".evt": 880,
    ".tokens": 8,
    ".callCenter": 17689,
    ".crt": 4683,
    ".channelLayout": 2901,
    ".cls": 4585504,
    ".component": 101587,
    ".asset": 44758660,
    ".datacategorygroup": 20350,
    ".dwl": 939,
    ".email": 154228,
    ".html": 443280,
    ".networkBranding": 10,
    ".page": 99522,
    ".pathAssistant": 25509,
    ".scf": 44787,
    ".site": 424864,
    ".trigger": 66213,
    ".apex": 444,
    ".soql": 231
  },
  "largestFiles": [
    {
      "file": "/force-app/main/default/profiles/Read Only System Integration.profile-meta.xml",
      "size": 8182612
    },
    {
      "file": "/force-app/main/default/profiles/Read Only System Integration Login User.profile-meta.xml",
      "size": 8180860
    },
    {
      "file": "/force-app/main/default/profiles/Informatica System Integration.profile-meta.xml",
      "size": 8177429
    },
    {
      "file": "/force-app/main/default/profiles/CRM Integration API Only with IPs %28DO NOT USE%29.profile-meta.xml",
      "size": 8174366
    },
    {
      "file": "/force-app/main/default/profiles/Admin.profile-meta.xml",
      "size": 8173991
    },
    {
      "file": "/force-app/main/default/profiles/Analytics Cloud Integration User.profile-meta.xml",
      "size": 8168279
    },
    {
      "file": "/force-app/main/default/profiles/Sales Insights Integration User.profile-meta.xml",
      "size": 8158640
    },
    {
      "file": "/force-app/main/default/profiles/CRM Team Administrator.profile-meta.xml",
      "size": 8153892
    },
    {
      "file": "/force-app/main/default/profiles/B2BMA Integration User.profile-meta.xml",
      "size": 8153576
    },
    {
      "file": "/force-app/main/default/profiles/SalesforceIQ Integration User.profile-meta.xml",
      "size": 8152324
    }
  ]
}