ประวัติการคอมมิตและการวิเคราะห์ส่วนต่าง
ไล่ดูประวัติการคอมมิต ดึงไฟล์ที่เปลี่ยนแปลง และสรุปส่วนต่าง
ประวัติการคอมมิตและการวิเคราะห์ส่วนต่าง เป็นบทเรียน AI Agents ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน 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 เพื่อรับการคอมมิตในช่วงวันที่ที่ระบุ ทั้งสองพารามิเตอร์รับอ็อบเจ็กต์ datetime ของ Python นี่คือเครื่องมือหลักสำหรับสร้างรายงานกิจกรรมรายสัปดาห์หรือรายเดือน
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
)สถิติการคอมมิต: การเพิ่มและการลบ
อ็อบเจ็กต์การคอมมิตแต่ละรายการมีพร็อพเพอร์ตี stats ซึ่งระบุจำนวนการเปลี่ยนแปลง additions, deletions และ total รวมจากไฟล์ทั้งหมดที่เปลี่ยนแปลง ข้อมูลนี้ช่วยให้ประเมินขนาดของการเปลี่ยนแปลงได้อย่างรวดเร็ว
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 ตามรูปแบบ conventional commit) แล้วสร้างบันทึกการเปลี่ยนแปลงที่จัดรูปแบบแล้ว ใช้ 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 — รายละเอียดระดับไฟล์ รวมถึงแพตช์ (ส่วนต่างแบบรวม)
- แยกวิเคราะห์
file.patchเพื่อสแกนบรรทัดที่เพิ่มหาข้อมูลลับ TODO หรือรูปแบบการเขียนโค้ดที่ไม่ปลอดภัย - จัดกลุ่มการคอมมิตตามผู้เขียนเพื่อสร้างรายงานกิจกรรม
- repo.compare(base, head) — ส่วนต่างระหว่างข้อมูลอ้างอิงสองรายการ เช่น สาขา แท็ก หรือค่า SHA
- ใช้ LLM เพื่อสร้างสรุปที่มนุษย์อ่านเข้าใจได้จากรายการข้อความการคอมมิต
- ทำเครื่องหมายการคอมมิตที่มีความเสี่ยงสูง ได้แก่ การเปลี่ยนแปลงขนาดใหญ่ ไฟล์สำคัญ และช่วงเวลาที่ใกล้รีลีส
เรียนรู้ AI Agents ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 60
- บทเรียน
- 239
คำถามที่พบบ่อย
บทเรียน “ประวัติการคอมมิตและการวิเคราะห์ส่วนต่าง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ประวัติการคอมมิตและการวิเคราะห์ส่วนต่าง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Agents ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ประวัติการคอมมิตและการวิเคราะห์ส่วนต่าง”
ไล่ดูประวัติการคอมมิต ดึงไฟล์ที่เปลี่ยนแปลง และสรุปส่วนต่าง คุณปฏิบัติ AI Agents ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Agents หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Agents บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “ประวัติการคอมมิตและการวิเคราะห์ส่วนต่าง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Agents นี้ได้ไหม
ได้ บทเรียน AI Agents ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ภาพรวม GitHub REST API
- การแสดงรายการและจัดการประเด็น
- ความคิดเห็นตรวจสอบ PR อัตโนมัติ
- ประวัติการคอมมิตและการวิเคราะห์ส่วนต่าง