0Pricing
AI Agents · 강의

커밋 기록 및 변경 내용 분석

커밋 기록을 순회하고 변경된 파일을 추출하며 변경 내용을 요약합니다.

커밋 기록 및 변경 내용 분석은(는) CoddyKit의 무료 AI Agents 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Agents 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.

커밋 기록을 분석하는 이유

커밋 기록은 에이전트에게 매우 유용한 정보의 원천입니다. 무엇이 언제, 누구에 의해 변경되었는지를 보여 주기 때문입니다. 에이전트는 커밋 기록을 사용해 변경 로그를 생성하고, 코드 검토 요약과 개발자 활동 보고서를 작성하며, 위험 요소를 감지하고(릴리스 직전에 이루어진 대규모 변경 등), 코드베이스의 발전 과정을 파악합니다.

from github import Github
import os

g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')

# Get recent commits on the default branch
commits = repo.get_commits()
print(f'Total commits: {commits.totalCount}')

# Preview the last 5
for commit in commits[:5]:
    print(f'{commit.sha[:8]} | {commit.commit.author.name}')
    print(f'  {commit.commit.message.split(chr(10))[0][:60]}')
    print(f'  {commit.commit.author.date.date()}')

기간으로 커밋 필터링하기

since 및 until 매개변수를 사용해 특정 날짜 범위의 커밋을 가져옵니다. 두 매개변수 모두 Python datetime 객체를 받습니다. 이는 주간 또는 월간 활동 보고서를 생성하는 기본 도구입니다.

import datetime
from github import Github
import os

g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')

# Last 7 days of commits
now = datetime.datetime.utcnow()
last_week = now - datetime.timedelta(days=7)

recent_commits = repo.get_commits(
    since=last_week,
    until=now
)

print(f'Commits in last 7 days: {recent_commits.totalCount}')

# By specific author
author_commits = repo.get_commits(
    since=last_week,
    author='alice'  # GitHub username
)
print(f'Alice\'s commits last week: {author_commits.totalCount}')

# On a specific branch
branch_commits = repo.get_commits(
    sha='feature/new-api',
    since=last_week
)

커밋 통계: 추가 및 삭제

각 커밋 객체에는 변경된 모든 파일의 additions, deletions, total 변경 횟수가 포함된 stats 속성이 있습니다. 이를 통해 변경 규모를 빠르게 파악할 수 있습니다.

from github import Github
import os

g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')

commit = repo.get_commit('abc12345sha')

# Overall stats
print(f'SHA: {commit.sha[:8]}')
print(f'Message: {commit.commit.message[:80]}')
print(f'Author: {commit.commit.author.name}')
print(f'Date: {commit.commit.author.date}')
print(f'Additions: +{commit.stats.additions}')
print(f'Deletions: -{commit.stats.deletions}')
print(f'Total changes: {commit.stats.total}')

# Large commit warning
if commit.stats.total > 500:
    print('WARNING: Large commit — careful code review needed')

커밋에서 변경된 파일 나열하기

commit.files는 커밋에서 변경된 각 파일에 해당하는 File 객체의 목록입니다. 속성에는 filename, status(추가됨/수정됨/삭제됨/이름 변경됨), additions, deletions, patch(변경 내용 텍스트)가 있습니다.

from github import Github
import os

g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')
commit = repo.get_commit('abc12345sha')

print(f'Files changed: {len(commit.files)}')

for f in commit.files:
    print(f'  [{f.status.upper():<8}] {f.filename}')
    print(f'    +{f.additions} -{f.deletions}')
    if f.previous_filename:  # for renamed files
        print(f'    Renamed from: {f.previous_filename}')

# Find changed Python files
python_changes = [
    f for f in commit.files
    if f.filename.endswith('.py')
]
print(f'\nPython files changed: {len(python_changes)}')

변경 내용(패치) 텍스트 구문 분석하기

file.patch에는 통합 변경 형식이 들어 있습니다. +로 시작하는 줄은 추가된 줄이고, -로 시작하는 줄은 삭제된 줄이며, 접두사가 없는 줄은 문맥 줄입니다. 이를 구문 분석해 분석할 추가된 줄을 추출할 수 있습니다. 예를 들어 새 비밀 값, TODO 주석 또는 안티 패턴을 찾을 수 있습니다.

def extract_added_lines(patch):
    if not patch:
        return []
    added = []
    for line in patch.split('\n'):
        if line.startswith('+') and not line.startswith('+++'): 
            added.append(line[1:])  # strip the '+' prefix
    return added

def scan_for_secrets(added_lines):
    import re
    PATTERNS = [
        (r'api[_-]?key\s*=\s*["\'][^"\']{20,}', 'potential API key'),
        (r'password\s*=\s*["\'][^"\']{6,}', 'potential hardcoded password'),
        (r'sk-[a-zA-Z0-9]{20,}', 'potential OpenAI key'),
        (r'ghp_[a-zA-Z0-9]{36}', 'potential GitHub token'),
    ]
    findings = []
    for i, line in enumerate(added_lines, 1):
        for pattern, label in PATTERNS:
            if re.search(pattern, line, re.IGNORECASE):
                findings.append({'line': i, 'type': label, 'preview': line[:80]})
    return findings

# --- demo ---
patch = (
    '@@ -1,2 +1,3 @@\n'
    ' def connect():\n'
    '+    api_key = "sk-abcdefghijklmnopqrstuvwx"\n'
    '+    password = "hunter2222"\n'
)
added = extract_added_lines(patch)
print('Added lines:', added)
for finding in scan_for_secrets(added):
    print(finding)

작성자별 활동 집계하기

개발자 활동 보고서를 만들려면 작성자별로 커밋을 그룹화합니다. 일정 기간 동안 작성자별 커밋 수, 추가 및 삭제된 줄 수, 수정된 파일 수를 계산합니다. 이는 팀 회고와 PR 할당 결정을 내릴 때 유용합니다.

import datetime
from collections import defaultdict
from github import Github
import os

g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')

last_month = datetime.datetime.utcnow() - datetime.timedelta(days=30)

author_stats = defaultdict(lambda: {'commits': 0, 'additions': 0, 'deletions': 0, 'files': set()})

for commit in repo.get_commits(since=last_month):
    author = commit.commit.author.name
    author_stats[author]['commits'] += 1
    author_stats[author]['additions'] += commit.stats.additions
    author_stats[author]['deletions'] += commit.stats.deletions
    for f in commit.files:
        author_stats[author]['files'].add(f.filename)

print('Author Activity (last 30 days):')
for author, stats in sorted(author_stats.items(), key=lambda x: -x[1]['commits']):
    print(f'{author}: {stats["commits"]} commits, +{stats["additions"]} -{stats["deletions"]}, {len(stats["files"])} files')

커밋에서 변경 로그 생성하기

변경 로그 에이전트는 두 태그 또는 날짜 사이의 커밋을 읽고, 기존 커밋 형식에 따라 유형(feat/fix/chore)별로 그룹화한 다음 형식이 지정된 변경 로그를 생성합니다. 각 커밋의 설명 품질을 높이려면 LLM을 사용합니다.

import re
import datetime
from github import Github
import os

g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')

def get_commits_since_tag(repo, tag_name):
    try:
        ref = repo.get_git_ref(f'tags/{tag_name}')
        tag_sha = ref.object.sha
        tag_commit = repo.get_commit(tag_sha)
        since = tag_commit.commit.author.date
        return list(repo.get_commits(since=since))[:-1]  # exclude the tag commit
    except Exception:
        return []

def parse_conventional_commit(message):
    match = re.match(r'^(feat|fix|chore|docs|test|refactor|perf|style)(\(.+?\))?: (.+)', message)
    if match:
        return match.group(1), match.group(3)
    return 'other', message.split('\n')[0][:60]

commits = get_commits_since_tag(repo, 'v1.2.0')
by_type = {'feat': [], 'fix': [], 'other': []}
for c in commits:
    msg = c.commit.message
    ctype, desc = parse_conventional_commit(msg)
    by_type.get(ctype, by_type['other']).append(desc)
print(f'Parsed {len(commits)} commits')

고위험 커밋 식별하기

고위험 커밋은 규모가 크거나, 중요한 파일(인증, 결제, 보안)을 수정하거나, 릴리스 직전에 만들어진 커밋입니다. 에이전트는 이러한 커밋을 메인 브랜치에 병합하기 전에 추가로 면밀히 검토하도록 표시할 수 있습니다.

import datetime
from github import Github
import os

g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')

CRITICAL_PATHS = [
    'src/auth', 'src/payment', 'src/security',
    'config/', '.env', 'Dockerfile', 'requirements.txt'
]

def is_high_risk(commit):
    reasons = []

    # Large change
    if commit.stats.total > 300:
        reasons.append(f'Large change: {commit.stats.total} lines')

    # Touches critical files
    for f in commit.files:
        for path in CRITICAL_PATHS:
            if f.filename.startswith(path):
                reasons.append(f'Touches critical: {f.filename}')
                break

    return reasons

now = datetime.datetime.utcnow()
for commit in repo.get_commits(since=now - datetime.timedelta(days=1)):
    risks = is_high_risk(commit)
    if risks:
        print(f'HIGH RISK: {commit.sha[:8]} - {commit.commit.message[:50]}')
        for r in risks:
            print(f'  - {r}')

두 커밋 비교하기

repo.compare(base, head)를 사용해 두 참조(브랜치, 태그 또는 커밋 SHA) 사이의 변경 내용을 가져옵니다. 이 메서드는 두 지점 사이의 통합 통계, 커밋 목록 및 변경된 파일 목록이 포함된 Comparison 객체를 반환합니다.

from github import Github
import os

g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')

# Compare two branches
comparison = repo.compare('main', 'feature/new-api')

print(f'Commits ahead: {comparison.ahead_by}')
print(f'Commits behind: {comparison.behind_by}')
print(f'Status: {comparison.status}')  # ahead/behind/identical/diverged
print(f'Total commits in diff: {len(comparison.commits)}')
print(f'Files changed: {len(comparison.files)}')

# Summary of what changed
for f in comparison.files:
    print(f'  {f.status}: {f.filename} +{f.additions} -{f.deletions}')

# Compare two tags
tag_comparison = repo.compare('v1.0.0', 'v1.1.0')
print(f'Changes between v1.0.0 and v1.1.0: {len(tag_comparison.commits)} commits')

LLM 기반 커밋 요약

커밋 메시지와 파일 이름을 묶음으로 LLM에 전달하면 특정 기간에 무엇이 변경되었는지 사람이 읽기 쉬운 요약을 생성할 수 있습니다. 이는 주간 엔지니어링 요약 봇의 핵심 기능입니다.

import anthropic
import os

client = anthropic.Anthropic(api_key=os.environ['ANTHROPIC_API_KEY'])

def summarize_commits(commits, time_period='last week'):
    commit_data = []
    for commit in commits[:30]:  # limit to avoid context overflow
        commit_data.append(
            f'- {commit.commit.message.split(chr(10))[0][:80]} '
            f'(+{commit.stats.additions}/-{commit.stats.deletions})'
        )

    commit_list = '\n'.join(commit_data)
    prompt = (
        f'Summarize what happened in this codebase {time_period} '
        f'based on these commit messages. Be concise (3-5 bullet points). '
        f'Focus on user-facing changes and significant technical work.\n\n'
        f'Commits:\n{commit_list}'
    )

    response = client.messages.create(
        model='claude-opus-4-5',
        max_tokens=400,
        messages=[{'role': 'user', 'content': prompt}]
    )
    return response.content[0].text

커밋에서 민감한 파일 감지하기

보안 중심의 커밋 분석 에이전트는 민감한 파일이 실수로 포함된 커밋을 검사합니다. 예를 들면 개인 키, .env 파일, 자격 증명이 포함된 구성 파일 또는 데이터베이스 덤프가 있습니다. 알려진 민감한 패턴과 일치하는 파일 이름이 있는지 commit.files를 확인합니다.

import re
from github import Github
import os

g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')

SENSITIVE_PATTERNS = [
    r'\.env$', r'\.pem$', r'\.key$', r'id_rsa', r'credentials\.json',
    r'secret', r'password', r'\.p12$', r'keystore', r'\btoken\b'
]

def is_sensitive_filename(filename):
    for pattern in SENSITIVE_PATTERNS:
        if re.search(pattern, filename, re.IGNORECASE):
            return pattern
    return None

import datetime
last_day = datetime.datetime.utcnow() - datetime.timedelta(days=1)

for commit in repo.get_commits(since=last_day):
    for f in commit.files:
        matched = is_sensitive_filename(f.filename)
        if matched and f.status in ('added', 'modified'):
            print(f'ALERT: Sensitive file in commit {commit.sha[:8]}')
            print(f'  File: {f.filename} (matched: {matched})')
            print(f'  Author: {commit.commit.author.name}')
            print(f'  Link: {commit.html_url}')

빠른 확인: commit.files와 pr.get_files() 비교

커밋 변경 내용에 접근하는 방법에 대한 이해도를 테스트해 보세요.

커밋 기록 분석 요약

이제 에이전트가 커밋 기록을 종합적으로 분석할 수 있습니다.

  • repo.get_commits(since, until, author, sha) — 시간, 작성자 또는 브랜치로 커밋 필터링하기
  • commit.stats — 변경된 모든 파일의 추가/삭제/전체 수
  • commit.files — 통합 변경 내용이 담긴 패치를 포함한 파일별 세부 정보
  • 비밀 값, TODO 또는 안티 패턴을 찾도록 file.patch를 구문 분석해 추가된 줄 검사하기
  • 활동 보고서를 위해 작성자별로 커밋 그룹화하기
  • repo.compare(base, head) — 두 참조(브랜치, 태그, SHA) 사이의 변경 내용
  • LLM을 사용해 커밋 메시지 목록에서 사람이 읽기 쉬운 요약 생성하기
  • 고위험 커밋 표시하기: 대규모 변경 + 중요 파일 + 릴리스 임박

자주 묻는 질문

“커밋 기록 및 변경 내용 분석” 강의는 무료인가요?

네 — “커밋 기록 및 변경 내용 분석” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Agents 강의 전체를 잠금 해제할 수 있습니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.

“커밋 기록 및 변경 내용 분석”에서 뭘 배우나요?

커밋 기록을 순회하고 변경된 파일을 추출하며 변경 내용을 요약합니다. 브라우저에서 직접 실행하는 실습 코드로 AI Agents을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

AI Agents을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 AI Agents은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“커밋 기록 및 변경 내용 분석” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 AI Agents 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 AI Agents 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. GitHub REST API 개요
  2. 이슈 조회 및 관리
  3. 자동화된 PR 검토 댓글
  4. 커밋 기록 및 변경 내용 분석
← AI Agents(으)로 돌아가기