Skip to content

fix(assets): drop case-colliding duplicate league logos - #506

Merged
ChuckBuilds merged 1 commit into
mainfrom
claude/vibrant-rhodes-525c49
Aug 30, 2026
Merged

fix(assets): drop case-colliding duplicate league logos#506
ChuckBuilds merged 1 commit into
mainfrom
claude/vibrant-rhodes-525c49

Conversation

@ChuckBuilds

Copy link
Copy Markdown
Owner

Problem

Four league fallback logos were each tracked at two paths differing only in case:

assets/sports/mlb_logos/MLB.png  +  mlb.png
assets/sports/nba_logos/NBA.png  +  nba.png
assets/sports/nfl_logos/NFL.png  +  nfl.png
assets/sports/nhl_logos/NHL.png  +  nhl.png

Reproduce with:

git ls-files | tr 'A-Z' 'a-z' | sort | uniq -d

On Windows and default macOS the filesystem is case-insensitive, so both index entries map to a single physical file. Whichever git writes last wins, the other reports as permanently modified, and git status can never be clean — any git pull flips which one is dirty.

A fresh clone of main on Windows today:

warning: the following paths have collided (e.g. case-sensitive paths
on a case-insensitive filesystem) and only one from the same
colliding group is in the working tree:

  'assets/sports/mlb_logos/MLB.png'
  'assets/sports/mlb_logos/mlb.png'
  ... (all four pairs)

$ git status --porcelain
 M assets/sports/nhl_logos/NHL.png

For MLB/NBA/NFL both entries pointed at the same blob, so the collision was cosmetic. NHL was not:

path blob size dimensions
NHL.png e3287a787e 672455 B 1439×1621
nhl.png eaebd59425 107184 B 768×768

So which resolution the league fallback logo actually loaded depended on checkout order rather than on the code. On a fresh Windows clone of main, NHL.png on disk currently holds the 107184-byte 768×768 blob — the low-res one — even though the code asks for NHL.png.

Fix

Keep the uppercase path in each pair.

Every logo lookup uppercases the abbreviation before building a filename:

  • LogoDownloader.normalize_abbreviation()normalized = abbreviation.upper() (src/logo_downloader.py:130)
  • LogoDownloader.get_logo_filename_variations()original = abbreviation.upper(), then f"{original}.png" / f"{normalized}.png" (src/logo_downloader.py:146-159)
  • LogoHelper.normalize_abbreviation()team_abbr.strip().upper() (src/common/logo_helper.py:193-217)

There is no case-insensitive or lowercase filename lookup anywhere in the tree, and nothing in src/, test/, scripts/, or web_interface/ references a lowercase league logo by name. The uppercase name is what the code actually requests — and for NHL it is also the higher-resolution asset.

Removal used git update-index --force-remove on the literal index path, so the entry is dropped without the case-insensitive working tree deleting the survivor. git rm here would have matched case-insensitively and taken out the wrong file.

Verification

Fresh git clone of this branch on Windows (NTFS, core.ignorecase=true):

  • no collision warning
  • git status --porcelain → empty
  • git ls-files | tr 'A-Z' 'a-z' | sort | uniq -d → empty
  • assets/sports/nhl_logos/NHL.png → 672455 B, 1439×1621 ✅

No code changes; no references to the removed paths exist.


Found incidentally while running the plugin safety harness for a football-scoreboard fix. Unrelated to that change, so it was deliberately left out of that PR.

Four league fallback logos were each tracked at two paths differing
only in case:

  assets/sports/mlb_logos/MLB.png  +  mlb.png
  assets/sports/nba_logos/NBA.png  +  nba.png
  assets/sports/nfl_logos/NFL.png  +  nfl.png
  assets/sports/nhl_logos/NHL.png  +  nhl.png

On Windows and default macOS the filesystem is case-insensitive, so
both index entries map to one physical file. Whichever git writes last
wins and the other entry reports as permanently modified, so `git
status` can never be clean and any `git pull` flips which one is dirty.

For MLB/NBA/NFL the two entries pointed at the same blob, so the
collision was only cosmetic. NHL was not: NHL.png is 1439x1621
(672455 B) and nhl.png is 768x768 (107184 B), so which resolution the
league fallback logo loaded depended on checkout order rather than on
the code.

Keep the uppercase path in each pair. Every logo lookup uppercases the
abbreviation before building a filename -- LogoDownloader
.normalize_abbreviation and .get_logo_filename_variations
(src/logo_downloader.py) and LogoHelper.normalize_abbreviation
(src/common/logo_helper.py) all do -- and nothing in the tree requests
a lowercase league logo, so the uppercase name is what the code
actually asks for. For NHL that is also the higher-resolution asset.

Removed with `git update-index --force-remove` so the literal index
entry is dropped without the case-insensitive working tree deleting the
survivor.
@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (4)
  • assets/sports/mlb_logos/mlb.png is excluded by !**/*.png
  • assets/sports/nba_logos/nba.png is excluded by !**/*.png
  • assets/sports/nfl_logos/nfl.png is excluded by !**/*.png
  • assets/sports/nhl_logos/nhl.png is excluded by !**/*.png

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c55e3a59-4d9f-4416-bccd-e99b61c650f3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@ChuckBuilds
ChuckBuilds merged commit cbc540a into main Aug 30, 2026
9 checks passed
@ChuckBuilds
ChuckBuilds deleted the claude/vibrant-rhodes-525c49 branch August 30, 2026 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant