"העלות מוקדם, העלות הרבה" הוא מנטרה פופולרית בפיתוח תוכנה בשימוש ב Git. על ידי עיצוב כך, נותן בטחת שכל שינוי מתעד בצורה טובה, מעודד שיתוף פעולה, ומקל לעיתים קרובות לעקבות אחר ההתפתחות של הפרויקט. עם זאת, זה יכול גם להוביל ליתר מדי עלויות.
זה המקום בו חשובות העלויות של סוקאסינג העלויות (squashing commits). סוקאסינג העלויות הוא תהליך של שילוב עודות עלויות בתוך עודות אחת מאחדת, בעלת תוכנית אחת).
לדוגמה, נאמר שאנחנו עובדים על תכונה של טופס כניסה, ויצרנו את הארבעה העלויות הבאות:
אחרי שהפונקציית הזו תיגמר, עבור הפרוייקט הכללי, ההגיעות האלה הן יותר מדי פרטניות. אין לנו צורך בעתיד לדעת שנתקענו בבאג שנתקלנו בו בזמן הפיתוח. כדי לוודא שההיסטוריה ברחבי העמוד הראשי תהיה נקיה, אנחנו מדברים את ההגיעות האלה להיות בתווך הגיעה אחת:
איך לדבר את ההגיעות ב Git: רעבאס אינטראקטיבי
השיטה המקובלת ביותר לדבר הגיעות היא בעזרת רעבאס אינטראקטיבי. אנחנו מתחילים בו בשימוש בפקודה:
git rebase -i HEAD~<number_of_commits>
החל בהחלף <מספר_ההגיעות>
בעזרת המספר של ההגיעות שאנחנו רוצים לדבר.
במקרה שלנו, יש לנו ארבעה הגיעות, אז הפקודה היא:
git rebase -i HEAD~4
הבצעת הפקודה הזו תפתח מערכת העריכה האינטראקטיבית של הקומאנד:
החלק העליון מציג את ההגשות, בעוד שהחלק התחתון מכיל תגובות על איך לדבר על ההגשות.
אנחנו רואים ארבעה הגשות. עבור כל אחד מהם, עלינו להחליט על איזה פקינס לבצע. אנחנו מתייחסים לפקינסים pick
(p
) ו squash
(s
). כדי לדבר על ארבעה הגשות בפקין אחד, אנחנו יכולים לבחור את הראשון ולדבר על שלושה השארים.
אנחנו יוצרים את הפקינסים על-ידי שינוי את הטקסט שמקדם את כל ההגשה, בעיקר בעיקר משנה את הפקינס pick
ל s
או squash
עבור ההגשות השנייה, השלישית והרביעית. כדי לערוך את השינויים האלה, אנחנו צריכים להכנס למצב "הוסף" במערך הציונים על-ידי לחיצה על המקש 'i' על המקלדת:
אחרי לחיצת i
, תווית -- INSERT --
תظפה בתחתית, מציגה שאנו נכנסנו למצב ההוספה. עכשיו, אנחנו יכולים להזיז את הסמן בעזרת המקשים הסוגים האלה, למחוק תווים ולהקליד כמו בעורך טקסט רגיל:
ברגע שנוכל להיות רוצים מהשינויים, עלינו לצאת ממצב ההכנסה על ידי לחיצה על המקש Esc
על המשטח. השלב הבא הוא לשמור על השינויים ולצאת מהעורך. כדי לעשות זאת, אנחנו לחיצה קודם על :
כדי להודיע לעורך שאנחנו רוצים לבצע פקודה.
בתחתית העורך, אנחנו רואים סימן סימן ספירלי :
שמבקש מאיתנו להכניס פקודה. כדי לשמור על השינויים, אנחנו משתמשים בפקודה w
, שעוצבה עבור "כתיבה". כדי לסגור את העורך, אנחנו משתמשים בq
, שעוצבה עבור "סגירה". אלה הם פקודות שיכולים להיות משולבות ולהיות מקלדות ביחד wq
:
כדי לבצע את הפקודה, אנחנו לחיצה Enter
. הפעולה הזו תסגיר את העורך הקיים ותפתח אחד חדש, מעניין אתנו להזין הודעת ההגשה עבור ההגשה החדשה שנעשה. העורך יציג מסר בררן בדרך כלל שמורה מהמסרים מארבעה ההגשות שאנחנו מסדרים:
אני ממליץ לשנות את המסר כדי לשקף בצורה מדוייקת את השינויים המבצעים על ידי ההתחברויות האלה—אחרי הכל, המטרה של הדחיפה היא לשמר על ההיסטוריה נקייה וקלה לקריאה.
כדי לבוא במגע עם המאשר ולערוך את המסר, אנחנו לוחצים שוב על i
כדי להגיע למצב עריכה ולערוך את המסר לרצוננו.
במקרה זה, אנחנו מחליפים את המסר על ידי "יישמת טופס ההתחברות." כדי לצאת מהמצב העריכה, אנחנו לוחצים Esc
. אחר כך, אנחנו שומרים את השינויים על ידי לחיצה על :
, הקלדת wq
, ולחיצה על Enter
.
איך להסתכל על ההיסטוריה של ההתחברויות
בדרך כלל, להשיג את כל ההיסטוריית ההתחברויות היא מאתגרת. כדי להסתכל על ההיסטוריית ההתחברויות, אנחנו יכולים להשתמש בפקודה git log
. במקרה המוצג, לפני הדחיפה, הייצוג של פקודת git log
יראה:
לנווט ברשימת ההגשות, השתמש במקשים העליונים והתחתונים. כדי לצאת, לחצי את q
.
אנחנו יכולים להשתמש ב git log
כדי לאשר את ההצלחה של הדחיפה. בהרצתו אחרי הדחיפה, יוצג ההגשה היחידה עם המסר החדש:
שליחה של ההגשה הדחופה
הפקידה העליונה תפעל על הארכיון המקומי. על מנת לעדכן את הארכיון המרחוקי, אנחנו צריכים לשלוח את השינויים שלנו. אך בגלל ששינינו את ההיסטוריית ההגשות, אנחנו צריכים לשלוח באמצעי --force
:
git push --force origin feature/login-form
שליחת האובייקט באופן הכפוי ישחרר את ההיסטוריית ההגשות על הרשת ויעצמת את העבודה של אחרים שעובדים על העברה. זוהי מסגרת טובה לתקשר עם הצוות לפני שירת הפעולה הזו
דרך יותר בטוחה להדחיק את הגיבוי, שמפחיתה את הסיכון של השיתוף פעולה, היא לשימוש במעדף --force-with-lease
:
git push --force-with-lease origin feature/login-form
האפשרות זו מובטחת שאנחנו נהדחיק את הגיבוי רק אם הענף הרחוק לא נעדכן מאז ההגעה או השימוש האחרון שלנו.
דים ספציפיים
דמיינו שיש לנו חמש דים:
נניח שאנחנו רוצים לשמור על דים 1, 2 ו-5 ולדחוף את דים 3 ו-4.
בשימוש בהדיכה משולבת, הדים שמסמכים לדחיפה יישלבו בדי הקדם ישיר. במקרה זה, זה אומר שאנחנו רוצים לדחוף Commit4
בדרך בה הוא מתאחד עם Commit3
.
על מנת לעשות זאת, אנחנו צריכים להתחיל בסיסק אינטראקטיבי שמכיל את שני ההעלאות האלה. במקרה זה, שלושה העלאות מספקות, אז אנחנו משתמשים בפקודה:
git rebase -i HEAD~3
אחר כך, אנחנו מגדירים Commit4
ל s
כדי שיישאר עם Commit3
:
אחרי שיוצאים את הפקודה הזו ואוצרים את ההעלאות, אנחנו מבחינים שההעלאות 3 ו4 הוספו ביחד בעוד שהשאר נשאר בליבול.
סוכך מהתעדות הספציפית
בפקודה git rebase -i HEAD~3
, החלק HEAD
הוא אותו השפה הקצרה להעלאה האחרונה. התבנית ~3
משמשת כדי ל指定 אב אב של ההעלאה. לדוגמה, HEAD~1
מתייחסת להורי HEAD
.
ברבסה אינטראקטיבית, ההגיעות המתייחסות לכמה ההגיעות הקדמוניות שמובילות עד להגיעה הספציפית בהגיעה הזו בפקודה. שימו לב שההגיעה הספציפית אינה כל בין ההגיעות:
במקום שימוש ב HEAD, אנחנו יכולים ל指定 קובץ ההגיעה ישירות. לדוגמה, Commit2
יש קובץ dbf3cc118d6d7c08ef9c4a326b26dbb1e3fe9ddf
, אז הפקודה:
git rebase -i dbf3cc118d6d7c08ef9c4a326b26dbb1e3fe9ddf
יתחילה רבסה שמביאה בחשבון כל ההגיעות המועדות אחרי Commit2
. לכן, אם אנחנו רוצים להתחיל רבסה בהגיעה ספציפית ולכלול את ההגיעה הזו, אנחנו יכולים להשתמש בפקודה:
git rebase -i <commit-hash>~1
התמצת סכסוכים בזמן שליטת ההגיעות
כשאנחנו מסדרים את ההגיעות, אנחנו מאחדים מספר שינויים בהגיעה בפשוטות אחת, שעשויה להוביל לסכסוכים אם השינויים מתחתים או מתפרץים באופן משמעותי. פה כמה מהמקרים הנפוצים בהם סכסוכים עשויים להתקיים:
- שינויים מתחתיים: אם שתיים או יותר עדכונים שמוסיפים לאחדות שינו את אותן שורות בקובץ או שורות קרובות ביחד, Git אולי לא יוכל להתרגל את השינויים האלה באופן אוטומטי.
- מצב שינויים שונה: אם אחד העדכונים הוסיף את הקטע המסויים בקוד ועדכון אחר עריכה או ביטל את אותו הקטע, העדכונים האלה יכולים להוביל לסכסוכים שצריך להתמודד איתם.
- שינוי שם ועריכה: אם עדכון אחד משנה את שם הקובץ ועדכונים באחריות עריכות בשם הקובץ הישן, העדכונים האלה יכולים להבלבל את Git, גורמים לסכסוך.
- שינויים בקבצים בינריביים: קבצים בינריביים לא מתאימים טוב לכלים של שינויים בעזרת טקסטים. אם מספר הגיבורים משנים את אותו קובץ בינריבי ואנחנו מנסים לדביק אותם, עלול להיות סכסוך בגיוס כי גיט לא יכול להסיד את השינויים האלה באופן אוטומטי.
- היסטוריה מורכבת: אם להגיבורים יש היסטוריה מורכבת עם שילובים רבים, הפצת ענף או שינויים מחדש בין ההגיבורים, דביקתם יכולה להיות סכסוך בשל העצם הלא-לינארי של השינויים.
בזמן של דביקה, גיט ינסה ליישם כל שינוי בפעם בודדת. אם הוא מתקבל על סכסוך בזמן העיבוד, הוא יעצר ויאפשר לנו להתמודד עם הסכסוכים.
הקונפליקטים יהיו מסומנים עם סימני קונפליקט <<<<<<
ו >>>>>>
. כדי לטפל בקונפליקטים, עלינו לפתוח את הקבצים ולפתור ידנית כל אחד על ידי בחירת אילו חלקים של הקוד אנחנו רוצים לשמר.
אחרי פתרון הקונפליקטים, עלינו להגיע לקבצים המוגדרים בעזרת הפעולה git add
. אחר כך, אנחנו יכולים להמשיך את הרעיון בעזרת הפעולה הבאה:
git rebase --continue
עבור מידע נוסף על קונפליקטים בGit, הביטו בסיכם הלימודים הבא:איך לפתור קונפליקטים השלמה בGit.
אלטרנטיבות לדביקה עם הרעיון
הפקת git merge --squash
היא שיטה חלופית ל git rebase -i
עבור שילוב מספר התנסוכים לתנאים אחדים. הפקת זו מועילה בעיקר כשרוצים לשלב שינויים מעבר לתוך העמודה הראשית בזמן שמדברים את כל ההתנסוכים הבודדים לתנאים אחד. הנה סקירה של איך להשתמש ב git merge
עבור הדביקה:
- אנחנו ננווט לעמודה המטרתית בה אנחנו רוצים להביא את השינויים.
- אנחנו מבצעים את הפקת
git merge --squash <שם-עמודה>
במקום<שם-עמודה>
בשם העמודה המובאת. - אנחנו מבצעים את ההעלאה עם
git commit
כדי ליצור העלאה אחת שמייצגת את כל השינויים מעבר לעמודה התכלית.
לדוגמה, נאמר שאנחנו רוצים להשתל את השינויים של העמודה feature/login-form
אל תוך main
בתא אחד:
git checkout main git merge --squash feature-branch git commit -m "Implement login form"
אלה המגבלות של הגישה הזו בהשוואה ל git rebase -i
:
- רזור של שליטה:פחות שליטה על ההגיעות הבודדות. בעזרת ההתאזנה, אנחנו יכולים לבחור אילו ההגיעות להשתל, בעוד שהשלים מכריע לשלב כל השינויים לתא אחד.
- היסטוריה ביניינית: בזמן שמשתמשים בשילוב, ההיסטוריה הפרטית של העמוד התכונה נאבדת בעמוד הראשי. זה יכול להקשיש את העבודה בעיקרה בעקבות השינויים הבודדים שנעשו בזמן הפיתוח של התכונה.
- בדיקת פעם קדם-ההגעה: בגלל שהיא משלבת את כל השינויים באסם שינוי אחד, אנחנו לא יכולים לבדוק או לבצע בדיקות על כל ההגעה בנפרד לפני שילוב, בניגוד לזמן שבהדרכה מתארגנת באופן אינטראקטיבי, שבו כל ההגעה יכולה להיבדק ולהוות בסדר ספציפי.
סיכום
השלמת ההגעות הקלות והקטנות לתוך תהליך הפיתוח מעודדת שיתוף פעולה ודוקמנוסיה ברורה, אך היא גם יכולה להפריע להיסטוריית הפרוייקט. השילוב של ההגעות שוב מקבל את הממן המדיר, שומר על המילים החשובות בעוד שמונעת את רעש השינויים הקטנים המסווגים בין ההגעות.
כדי ללמוד עוד על Git, אני ממליץ על המשאבים הבאים:
Source:
https://www.datacamp.com/tutorial/git-squash-commits