Cherry-pick
git cherry-pick מעתיק commit ספציפי מ-branch אחד אל ה-branch הנוכחי. השם בא מהדימוי של "לקטוף דובדבן" - לבחור בדיוק את מה שאתם רוצים.
מתי להשתמש?
- תיקון באג ב-feature branch שצריך גם ב-main דחוף
- העברת commit אחד מ-branch ניסוי ל-branch אמיתי
- "צ'יפ" של commit מ-PR שעוד לא התקבל
- Hotfix שצריך גם ב-release branch ישן
פקודה בסיסית
git cherry-pick a3f5c2d
git ייצור commit חדש ב-branch הנוכחי שלכם עם אותם השינויים של a3f5c2d. ה-SHA של ה-commit החדש יהיה שונה.
מספר commits
# commit אחד
git cherry-pick a3f5c2d
# מספר commits
git cherry-pick a3f5c2d b8e7f1a c9d2e3b
# טווח (לא כולל את הראשון)
git cherry-pick a3f5c2d..c9d2e3b
# טווח (כולל את הראשון)
git cherry-pick a3f5c2d^..c9d2e3b
דגלים שימושיים
git cherry-pick -x <commit> # מוסיף "(cherry picked from commit ...)" להודעה
git cherry-pick -e <commit> # פותח עורך לעריכת ההודעה
git cherry-pick -n <commit> # רק staging, בלי commit אוטומטי
git cherry-pick --signoff <commit> # מוסיף Signed-off-by
כשיש קונפליקט
cherry-pick יכול להיכשל אם ה-commit נוגע בקוד שכבר השתנה ב-branch הנוכחי. הזרימה זהה ל-merge:
git cherry-pick a3f5c2d
# CONFLICT (content): Merge conflict in src/login.js
# פותרים את הקונפליקט ידנית, מסמנים
git add src/login.js
# ממשיכים
git cherry-pick --continue
# או מבטלים
git cherry-pick --abort
דוגמת זרימה: hotfix ל-release ישן
# מצב: גילית באג ב-v1.0 שתיקנת ב-main
# צריך להחזיר את התיקון גם ל-release/v1.0
# 1. מוצאים את ה-commit של התיקון ב-main
git log --oneline | grep "fix login"
# a3f5c2d Fix login race condition
# 2. עוברים ל-release branch
git switch release/v1.0
# 3. cherry-pick של התיקון
git cherry-pick a3f5c2d
# 4. אם הקוד שונה - פותרים קונפליקט, ממשיכים
git add .
git cherry-pick --continue
# 5. דוחפים
git push origin release/v1.0
הבעיה עם cherry-pick
cherry-pick יוצר שני commits עם אותו תוכן אבל hash שונה. זה יכול לסבך merges עתידיים:
main: A───B───C───D───E
\
release/v1.0: F───G───D' (D' = cherry-pick של D)
אם בעתיד תנסה למזג release/v1.0 ל-main, git ינסה להוסיף את D' ל-main - שכבר יש בו את D. בדרך כלל git חכם מספיק לזהות את זה, אבל לפעמים נוצרים קונפליקטים מיותרים.
מסקנה: cherry-pick הוא כלי שימושי, אבל לא ה-default. אם אפשר לעשות merge - עדיף.
דוגמה: cherry-pick של מספר commits עוקבים
# רוצים את 3 ה-commits האחרונים מ-feature/auth
git switch main
git cherry-pick feature/auth~2..feature/auth
# זה מעתיק 3 commits: feature/auth~2, feature/auth~1, feature/auth
דוגמה: cherry-pick רק עם staging
# רוצים לקחת commit אבל לערוך אותו לפני ה-commit החדש
git cherry-pick -n a3f5c2d
# עכשיו השינויים ב-staging אבל אין commit
git status
# עורכים, מוסיפים שינויים, מבצעים commit
git commit -m "Adapted login fix from main"
בדקו את עצמכם
נסו לענות לבד לפני שאתם פותחים את התשובה.
-
מה עושה
git cherry-pick <hash>?הצגת התשובה
תשובה ב. שימושי להעביר תיקון באג אחד לענף אחר.