@@ -84,7 +84,7 @@ def commit_flag(date_str, name):
8484 return "L"
8585 return "X"
8686
87- # ---------- 파일 개수(그 날짜 스냅샷) ----------
87+ # ---------- 파일 개수(그 날짜 스냅샷; 재귀 카운트 ) ----------
8888
8989def commit_at_end_of_date (date_str ):
9090 """해당 날짜(KST 23:59:59)의 리포 스냅샷 커밋 해시 반환(없으면 빈 문자열)"""
@@ -94,33 +94,31 @@ def commit_at_end_of_date(date_str):
9494
9595def file_count_in_path_at_commit (commit , path ):
9696 """
97- 특정 커밋에서 path/ 디렉터리 '바로 아래 ' 파일(=blob) 개수와 .gitkeep 포함 여부 반환.
98- 재귀로 전체 파일을 받은 뒤, base 바로 아래만 필터링한다 .
97+ 특정 커밋에서 path/ 디렉터리 '아래 전체(재귀) ' 파일(=blob) 개수와 .gitkeep 존재 여부 반환.
98+ - git ls-tree -r --name-only {commit} -- "{ base}" 로 모든 파일을 받고 base로 시작하는 것만 필터 .
9999 """
100100 if not commit :
101101 return 0 , False
102102
103103 base = path .rstrip ("/" ) + "/"
104- # 재귀로 모든 파일 경로를 받고, base 바로 아래만 카운트
105104 cmd = f'git ls-tree -r --name-only { commit } -- "{ base } " || true'
106105 out = run (cmd )
107106 if not out :
108107 return 0 , False
109108
110- count = 0
109+ files = []
111110 has_gitkeep = False
112111 for line in out .splitlines ():
113112 name = line .strip ()
114- if not name . startswith ( base ) :
113+ if not name :
115114 continue
116- rest = name [len (base ):] # base 이후
117- if "/" in rest :
118- # 하위 디렉터리 내부는 제외 (바로 아래만 카운트)
115+ if not name .startswith (base ):
119116 continue
120- count += 1
121- if rest == ".gitkeep" :
117+ files . append ( name )
118+ if os . path . basename ( name ) == ".gitkeep" :
122119 has_gitkeep = True
123- return count , has_gitkeep
120+
121+ return len (files ), has_gitkeep
124122
125123def file_req_and_status (date_str , name ):
126124 """
@@ -185,11 +183,9 @@ def build_month_calendar(year, month, today_kst):
185183 date_str = date_obj .isoformat ()
186184 lines = []
187185 for name in NAMES :
188- # 커밋/파일 판정
189186 cf = commit_flag (date_str , name ) # 'O','L','X'
190187 cnt , req , ok = file_req_and_status (date_str , name )
191188
192- # 색상 결정
193189 if cf == "O" :
194190 dot = DOT_GREEN if ok else DOT_YELLOW
195191 elif cf == "L" :
0 commit comments