Git - חלק 5

בחלק החמישי של סדרת Git אסביר כיצד rebase באמת עובד, ונכיר כלי חדש הנקרא rebase אינטראקטיבי (המאפשר לבצע מגוון מניפולציות על commits). ומשם נמשיך להכרה עמוקה של כלי אחר ושימושי הנקרא stashing.

אני מזכיר שוב, חלק זה הנו המשך ישיר של החלק הקודם, נמשיך מאותו המקום, עם אותן הדוגמאות וכ’ו. בנוסף, מכיוון שהסדרה הזו מהווה מעין יומן מסע, גם הפוסט הזה יחולק לשניים, שני חלקים של שאלות ותשובות וסיכום ביניים.

 

Rebase

בחלק הקודם (4) דיברנו על rebase, הגיע הזמן קצת להרחיב את הדיבור עליו. למי שלא זוכר מה rebase עושה, הוא פשוט הולך ל commit הזהה האחרון בין 2 הענפים שאותם רוצים למזג, מעביר את כל ה commit מהענף החדש עד אותו commit זהה לאזור זמני, לאחר מכן הוא לוקח את כל ה commit מהענף המקורי שאתו אנחנו רוצים למזג ומבצע אותם ואחריהם מבצע את ה commit מהאזור הזמני. הדוגמה של בוב ואליס מהחלק הקודם מדגימה את זה היטב, וגם יצרתי תמונה שבה ה commit של אליס מופיע בסופו של דבר לפני ה commit האחרון של בוב בענף של בוב, והתמונה מסבירה מה הולך שם, אבל זה לא מה שבאמת קורה והגיע הזמן להבהיר את הדברים לעומק.

אם ניקח לדוגמה 2 ענפים, הראשון master והשני dog. מאוד מפתה להבין את rebase כפעולה הלוקחת את כל ה commit השונים מ master ומעבירה אותם לענף של dog (אחרי ה commit המשותף) ואז מבצעת את ה commit החדשים שהיו בענף dog (מחזירה אותם מהאזור הזמני לענף dog), (בעצם אותה פעולה שהדגמתי באיור של בוב ואליס). אך באמת מה שקורה הוא שאחרי שהעברנו את ה commit מענף dog לאזור הזמני, הדבר הבא שעשינו הוא לשנות את ענף dog שיצביע לאחרי ה commit האחרון בענף dog, ואז הרצנו מחדש את ה commit מהאזור הזמני בענף dog (ניתן לראות המחשה של לפי ואחרי פעולת ה rebase בתמונה משמאל).

בנקודה מסוימת כשתעבדו עם git אתם כנראה תתיקלו בסיטואציה בה אתם רוצים לעשות שוב את ה commits באותו הענף שאתם עובדים עליו, לשנות אותם באיזו שהיא צורה. כאן נכנסת לסיפור תצורה שונה של rebase עם הפקודה ‘git rebase -i HEAD~3’ כשה i מסמלת את המילה interactive (אינטראקטיבי), בדוגמה לפקודה שכתבתי אנחנו רוצים לשנות את השלושה commits האחרונים (כותבים HEAD תילדה 3, והכוונה ל3 commits לפני ה HEAD הנוכחי). כשנלחץ על אנטר, יפתח לנו עורך ובתוכו script (תסריט) של ה rebase. אתם יכולים לחשוב על ה script הזה כעל פקודות שעומדות לרוץ ברגע שנשמור ונצא מהעורך.

בתמונה משמאל (המציגה את העורך שיפתח) ניתן לראות שאנו משתמשים בפקודה pick לכל אחד מה commit שלנו (בהמשך נעבור על שאר הפקודות). אז נגיד ששמרנו ויצאנו מהעורך, מה הוא יבצע? קודם כל הוא יעביר את שלושת ה commit האלו לאזור זמני, לאחר מכן הוא יריץ כל אחת מהפקודות ב script שלנו. במקרה שלנו אנו משתמשים במילת המפתח pick, ולכן הוא יריץ מחדש כל commit, ובעצם לא יקרה כלום, כי הוא החזיר אותם לענף בדיוק באותו הסדר.

rebase אינטראקטיבי משנה כל commit אחרי זה שציינתם, אז אם לדוגמה נכתוב ‘git rebase -i HEAD’ אז commits אחרי ה HEAD, הרי ה HEAD זה ה commit האחרון שלנו, אז במקרה הזה יפתח לנו שבעצם לא עושה כלום (לא יהיה כל commit בעורך). אך אם נכתוב ‘^git rebase -i HEAD’ אנחנו בעצם אומרים ל rebase ללכת להורה של ה commit האחרון, או ה commit הלפני אחרון, ולכן בעורך יהיה לנו commit אחד בלבד.

אז כעת, בואו נשתמש ב rebase על מנת לבצע מניפולציה על ה commits.נניח שכתבנו בשורת הפקודה ‘git log –oneline’ ושמנו לב שסדר השתי commits האחרונים אינו נכון (בטעות עשינו את הפעולות הפוך), בואו נחליף את הסדר של שלהם. דבר ראשון נכתוב ‘git rebase -i HEAD~3’. דבר מעניין שיש לשים לב אליו, הוא שכשאנו מריצים פקודת ‘git log’ הוא מראה לנו את סדר ה commit מהחדש לישן, וכשאנו מריצים את הפקודה ‘git rebase’ וקופצים לעורך, העורך מראה לנו את ה commit מהישן לחדש (הפוך). אז במקרה שלנו, אנחנו רק רוצים להחליף את הסדר של ה commits, וכל מה שאנחנו צריכים לעשות כדי שזה יקרה הוא להחליף את הסדר של ה commits בתוך העורך (ע”י כתיבם הפוך). לאחר מכן, אם נשמור ונצא מהעורך המערכת תריץ מחדש את ה commits בסדר שפירטנו ב script, וכשנריץ ‘git log –oneline’ נראה שאותם ה commits (במקרה שלנו השתיים האחרונים) הוחלפו במקומתיהם. אז מה קורה כשאנו יוצאים מה script של ה rebase? המערכת לוקחת את ה commits לאזור זמני, ואז מבצעת אותם בסדר אותו פירטנו ב script.

מה אם אנחנו חוזרים ל commits ושמים לב שהשתמשו בתיאור לא טוב או לא נכון ל commit כלשהו? ה rebase האינטראקטיבי יכול לעזור לנו גם בזה. כדי לתקן את התיאור פשוט נריץ מחדש את פקודות ה rebase שלנו ובתוך העורך אנחנו רק צריכים לשנות את את התיאור של אחד מה commits ע”י כתיבת ‘reword eb7d5a0 Actually, this is bla bla’ (במקום ‘pick eb7d5a0 Actually, this is bla bla’ שכתבתי בתמונה ממעלה). לאחר שנשמור ונצא מהעורך, יפתח לנו עורך נוסף בו נוכל לעורך את התיאור עצמו. וכשנשמור נצא גם מהעורך הזה, המערכת תריץ מחדש את ה commits מה scrpit (ז”א תריץ את ה2 הראשונים אותו הדבר - ללא שינוי, כי שם הייתה רק פקודת pick, ובשלישי תריץ אותו שוב עם שינוי התיאור).

דרך נוספת בה אנחנו יכולים לבצע מניפולציות על commits ב rebase האינטראקטיבי, הוא לחלק commit אחד לשתיים (אולי היה בו יותר מידי קוד, והאמת היא שהוא צריך להיות מחולק לשניים ואולי אפילו שלושה commits). בשביל לבצע את זה, נשנה ב commit שאנחנו רוצים לפצל את מילת המפתח מ pick ל edit, אם ניקח שוב כדוגמה את ה commit האחרון אז נכתוב ‘edit eb7d5a0 Actually, this is bla bla’. כשנשמור ונצא מהעורך, המערכת תריץ מחדש את כל ה commits מהאזור הזמני, כשהיא תגיע ל commit שאותו צריך לעורך היא תחזיר אותו לשורת הפקודה עם ההודעה שניתן לראות בתמונה משמאל. אם היינו רוצים להוסיף דברים ל commit הנ”ל, היינו יכולים להוסיף אותם לאזור ההיערכות ואז להשתמש ב ‘git commit –amend’ (כמו שמוצע בפלט) כדי לצרף אותו ל commit הנ”ל, ואז להשתמש ב ‘git rebase –continue’. אך מה שאנחנו רוצים הוא רק לפצל את ה commit, אך לקוד הנ”ל כבר בוצע commit, לכן הדבר הראשון שאנחנו צריכים לעשות הוא לכתוב ‘^git reset HEAD’ (למי שלא זוכר, הפקודה תחזיר את ה HEAD (או את הסמן אם תרצו) ל commit אחד אחורה (אחד אחורה בגלל ה”גזר” = ^)) ובעצם תעזוב את השינויים בכלל (שלא כמו ב reset –soft הפקודה אינו מחזירה את השינויים לאזור ההיערכות) בנוסף, למי שזוכר, אם היינו עושים hard –reset, המערכת הייתה מוחקת את השינויים גם מאזור ההיערכות, ז”א הם היו נמחקים גם מהתיקייה). לכן כעת, נוסיף את הקבצים שאנחנו רוצים ב commit הראשון לאזור ההיערכות (עם פקודת add) ונבצע להם commit, לאחר מכן נוסיף לאזור ההיערכות את הקבצים שאנחנו רוצים ב commit השני ואז גם להם נבצע commit. לאחר שסיימנו לפצל את commits, או בעצם לעזוב את השינויים בתיקיה, ולהוסיף אותם לאזור ההיערכות בפעמים נפרדות ולבצע להם commit בפעמים נפרדות, נריץ את הפקודה ‘git rebase –continue’ כדי שהמערכת תמשיך להריץ את שאר הפקודות מה script שב rebase שכתבנו בהתחלה.

לפעמים דווקא ניתקל בבעיה ההפוכה, שניים או שלושה commits שבאמת היו צריכים להיות אחד. אז אנחנו צריכים דרך בה נוכל לאחד אותם יחדיו, אז במקרה שלנו, בואו נאחד שוב את ה commits שעכשיו פיצלנו. הפעם נריץ את הפקודה ‘git rebase -i HEAD~4’ (בגלל שפיצלנו את ה commits הפעם ה commit האחרון שאנחנו רוצים הוא הרביעי) והפעם בעורך נציין איזה commit אנחנו רוצים למחוץ/לאחד ל commit שלפניו, נעשה זאת עם הפקודה squash (שימו לב לכך שאתם צריכים לשנות את הפקודה מ pick ל squash ל commit השני כדי שיואחד לזה שמעליו). ברגע שנשמור ונצא מה script, יפתח לנו עורך נוסף (ניתן לראות בתמונה משמאל) שיראה לנו את התיאור של ה commit הראשון והתיאור של ה commit השני (שאנחנו עומדים למחוץ לראשון). העורך, כמו שניתן לראות בתמונה, מבקש ממנו להכניס את התיאור של ה commit החדש, המאוחד, ולכן נחליף את התיאור של ה commit הראשון בתיאור שאמור להיות ל commit המאוחד. וכמובן כשסיימנו, נשמור ונצא מהעורך.

מאחורי הקלעים, ברגע שאנחנו כותבים את הפקודה ‘git rebase -i HEAD~4’ המערכת לוקחת את הארבעה commits ומעבירה אותם לאזור זמני, ולאחר מכן לוקחת כל commit בנפרד ומריצה אותו לפי ה script על ציר הזמן (הענף), כשהמערכת מגיע לפקודת ה squash, היא לוקחת את אותו ה commit וממזגת אותו (merge) עם ה commit האחרון (ונותנת לו תיאור חדש).

שאלות ותשובות

כמו תמיד, החלק של השאלות והתשובות אינו תחליף לתרגול, אם אין לכם פרויקט שאתם יכולים/רוצים לשתף, צרו תיקייה ובתוכה קובץ טקסט פשוט ותתרגלו. אין תחליף לתרגול אישי במחשב שלכם עם שורת הפקודה. הלמידה הטובה ביותר מגיעה דרך האצבעות, אז כתבו את הפקודות בעצמכם, גם אם אתם לא זוכרים, תנסו, ומקסימום תסתכלו בתשובות. אך תכתבו אותן בעצמכם ואל תתפתו להשתמש ב copy/paste, אחרי כתיבת הפקודה פעם, פעמיים, שלוש זה יגיע.

שאלות: אז אתם עובדים על הענף שלכם כבר כמה ימים, וקלטתם שאתם צריכים למשוך כמה commits מענף ה master. אתם יכולים לעשות merge אבל זה יצור commit לא ברור. השתמשו ב rebase כדי למשוך את ה commits האלו לענף שלכם. אוקי, בואו נתכונן למזג את הענף שלכם, אך קודם כל סדרו קצת את ה commits שלכם. השתמשו ב rebase אינטראקטיבי כדי לערוך את ה4 commits האחרונים שלכם. שמתם לב שה commit של הבדיקות מגיע אחרי ה commit של השינויים עצמם. בואו נחליף בין שתי ה commits האלו כדי שיראה שקודם כתבנו את השינויים. להלן התמונה עם תוכן העורך של ה rebase (לנוחות כתבתי רק 2 commit, אם זה היה המשך ישיר לסעיף הקודם היו צריכים להיות 4 commits בעורך). כשערכתם את ה commits, שמתם לב שהתיאור של commits של הבדיקות, קצת מעורפל, שנו את התיאור של אותו commit. להלן התמונה עם תוכן העורך. לאחר שכתבתם את מילת המפתח לעריכת התיאור ב rebase האינטראקטיבי, נפתח חלון חדש. כאן אתם משנים את תיאור ה commit. להלן התמונה עם תיאור העורך. הפעם ישנם 3 commits בעורך, אחד מהם אנחנו צריכים לפצל. אמרו ל git להפסיק ב commit עם התיאור “Add unicorn” כדי שנוכל לארגן אותו מחדש. להלן תמונה עם תוכן העורך. מצוין, git הפסיקה ב commit עם התיאור “Add unicorn”. הדבר הראשון שאנחנו צריכים זה להזיז אחורה את ה HEAD ל commit לפני האחרון, כדי שהשינויים ב commit האחרון יחזרו לאזור ההיערכות. הוספנו את השינויים לאזור ההיערכות ועשינו commit (כמובן כשתי הוספו ושתי commits). כל מה שנשאר זה לתת הוראה ל rebase להמשיך. לחזור ל rebase. טעות שלי! לא היינו צריכים לפצל את ה commits האלו, בואו נאחד אותם מחדש. להלן התמונה עם תוכן העורך. אחרי שאמרתם ל git לאחד בין ה commits, נפתח עורך נוסף כדי לאפשר לכם לכתוב תיאור ל commit החדש. להלן התמונה עם תוכן העורך.

תשובות: הפקודה: ‘git rebase master’. הפקודה: ‘git rebase -i HEAD~4’. התמונה של העורך של ה rebase לאחר העריכה. התמונה של העורך של ה rebase לאחר העריכה. התמונה של העורך של ה rebase לאחר העריכה. התמונה של העורך של ה rebase לאחר העריכה. הפקודה: ‘^git reset HEAD’. הפקודה: ‘git rebase –continue’. התמונה של העורך של ה rebase לאחר העריכה. התמונה של העורך של ה rebase לאחר העריכה.

סיכום ביניים

אז ראינו כיצד פקודת ה rebase באמת עובדת, ולמדנו על כלי חדש בשם rebase אינטראקטיבי, למדנו לבצע איתו מגוון פעולות כגון שינוי של סדר ה commits, עריכת התיאור שלהם, ואף פיצול ואפילו מיזוג של commit. הייתי ממליץ כעת לקחת הפסקה קטנה לתרגול ה rebase האינטראקטיבי, לראות שהכל יושב טוב, אם ישנו משהו שעדיין אינכם מרגישים איתו בנוח, חזרו לקרוא את הפסקה, תשאלו בתגובות, ותנסו לחפש עוד מידע בגוגל (השתדלו לא להמשיך הלאה אם משהו אינו יושב טוב).

Stashing

בואו נניח שאתם עובדים על פיצ’ר חדש בענף נפרד, והגעתם לחצי ה commit כשהבוס מצלצל ואומר לנו שישנה בעיה קריטית עם ענף ה master, צריך לתקן אותה בדחיפות ולבצע commit לתיקון. אז כעת אנחנו צריכים לחזור לענף master, אבל אני בדיוק באמצע כתיבת מתודה כלשהי בענף הפיצ’ר, וכבר כמעט סיימתי אותה. כמובן שאנחנו לא יכולים לבצע לה commit באמצע הדרך.. כאן נכנס לתמונה stash.

stash מאפשר לנו לקחת כמה קבצים, שלא בהכרח מכילים commit מלא, ולאחסן אותם באזור זמני כדי שנוכל לשחזר אותם מאוחר יותר. אז אם נריץ את הפקודה ‘git stash save’ המערכת תיקח את הקבצים שעדיין לא הושלמו בענף הפיצ’ר ותשמור אותם באזור זמני, ובנוסף תשחזר את המצב של ה commit האחרון. כך שאם נריץ אחריה ‘git diff’ נראה שלא היו שינויים, ואם נריץ ‘git status’ נראה שלא בוצע commit לכולם בענף הפיצ’ר שלנו. אז עכשיו אנחנו יכולים לעבור בבטחה לענף ה master (עם הפקודה ‘git checkout master’) ולעשות את השינויים הנדרשים (אנחנו יכולים למשוך שינויים ‘git pull’, לבצע commits, ולדחוף את השינויים חזרה ‘git push’).

כעת, כשאנחנו מוכנים לחזור לעבוד על ענף הפיצ’ר שלנו, נחזור אליו עם הפקודה ‘git checkout feature’ ולאחר מכן נריץ את הפקודה ‘git stash apply’. הפקודה תגרום להרצה מחדש של השינויים שהחבאנו (בעזרת הפקודה ‘git stash save’) קודם לכן באזור הזמני. כעת אם נריץ ‘git diff’, נראה את השינויים שביצענו (המתודה החצי גמורה).

כל פעם שנכתוב ‘git stash save’, המערכת דוחפת את ה stash הספציפי הזה (השינויים שעכשיו רצינו להחביא) ל”סליק המחסנית” (התרגום שלי לעברית לוקה בחסר, באנגלית: stash stack). זו היא בעצם מחסנית של stash. אם נכתוב את הפקודה ‘git stash list’ המערכת תדפיס לנו רשימה של כל ה stash שהחבאנו. בתמונה משמאל ניתן לראות דוגמה להדפסה הזו (WIP מסמל Work In Progress). שימו לב כי ה stash אינו commit, ולכן המערכת מציגה לנו את ה commit האחרון לפני שביצענו stash. בנוסף, לכל stash ניתן שם (לדוגמה “{stash@{0”), המאפשר לנו להתייחס לכל אחד באופן ספציפי, אם נרצה ליישם את ה stash השני, נכתוב ‘{git stash apply stash@{1’, ורק השינויים מה stash הספציפי הנ”ל ייושמו בקוד שלנו. אם לא נכתוב stash ספציפי (כמו שעשינו בפסקה למעלה עם הפקודה ‘git stash apply’), אז stash מס’ 0 (הראשון) יישום כברירת מחדל. ולבסוף, כשנריץ את הפקודה ‘git stash apply’ המערכת תיישם את השינויים מה stash, אך היא לא תוציא (pop) אותו מהרשימה. כדי לזרוק אותו מהרשימה, נכתוב לאחר מכן ‘git stash drop’.

ישנם כמה קיצורי ברירות מחדל שכדאי לדעת, לדוגמה אנחנו יכולים לכתוב ‘git stash’ וזה בדיוק כמו לכתוב ‘git stash save’. כמו שכבר הזכרנו אם נכתוב ‘git stash apply’ זה בדיוק כמו לכתוב ‘{git stash apply stash@{0’. גם ‘git stash drop’ הוא בדיוק כמו לכתוב ‘{git stash drop stash@{0’. ולבסוף יש את הפקודה ‘git stash pop’ שהיא בדיוק כמו לכתוב ‘git stash apply’ ולאחריה ‘git stash drop’.

בדיוק כמו שאנחנו ממזגים ענפים ונתקלים בקונפליקטים בקובץ מסוים, ניתן להיתקל בקונפליקט גם כשמריצים ‘git stash apply’. בתמונה משמאל ניתן לראות דוגמה לקונפליקט בו המערכת לא הצליחה לשנות/לערוך את הקובץ המקומי (index.html), והיא מבקשת מאיתנו לבצע commit לשינויים שלנו או לבצע להם stash, לפני שאנחנו מנסים להריץ את הפקודה stash apply. מה שבעצם התבצע זה כלום. המערכת לא ביצעה את השינויים מה stash והיא אומרת לנו, חכה רגע! זה לא יעבוד עד שלא תחזור חזרה ותבטל את השינויים שעשית (ניתן לבצע בעזרת הפקודה ‘git reset –hard HEAD’) או שתבצע להם commit, או שאפשר לבצע להם stash (מה שאומר שהם לא יהיו בענף הזה, אך בניגוד ל reset, אנחנו לא מוחקים אותם אלה מעבירים אותם לאזור זמני).

גם כשנכתוב את הפקודה ‘git stash pop’ (זוכרים, פקודה משולבת ל apply ואז drop) יכולים להיווצר לנו קונפליקטים, נפתור אותם כמו שתיארנו בפסקה למעלה, אך שימו לב כי זה לא מבצע drop באופן אוטומטי, וזה בגלל שאולי פשוט נרצה לבצע hard reset ואז לבצע שוב את הפקודה pop, אז המערכת לא מניחה שאתם רוצים למחוק את ה stash הזה. אז כמובן שאם ניתקל בקונפליקט נרצה לחזור לרשימת ה stash (בעזרת ‘git stash list’), ולהיפטר מה stash ידנית (בעזרת ‘git stash drop’ או ה stash הספציפי).

אז בואו נניח שאליס עובדת על איזה קוד, ויש לה שינויים שהיא רוצה לבצע להם commit ושינויים שהיא רוצה לבצע להם stash בשביל commit מאוחר יותר. אם אליס תריץ ‘git stash save’ המערכת תחביא את כל הקוד שהיא כתבה ועדיין לא ביצעה לו commit (הקוד השונה מה commit האחרון), והרי זה לא מה שאליס התכוונה. במקום זאת נכתוב ‘git stash save –keep-index’, מה שהפקודה תבצע היא תשמור את הקבצים שבאזור ההיערכות, באזור ההיערכות, ואת שאר הקבצים היא תחביא. כך שלפני הרצת הפקודה, על אליס להוסיף את הקוד שהיא רוצה לשמור לאזור ההיערכות. לאחר מכן היא יכולה לבצע commit לקוד, ולבסוף לשחזר את החצי השני של הקוד שהוחבא (עם ‘git stash pop’).

עד כאן המערכת החביאה קבצים שהיא כבר מכירה, כבר עוקבת אחריהם, ובדוגמה בפסקה שלעיל ביצענו commit לקבצים לא מוכרים למערכת (ע”י הוספה שלהם לאזור ההיערכות) אך לא דיברנו על החבאת קבצים חדשים, שהמערכת לא מכירה. מה עם אליס רוצה לבצע commit לחלק מהקוד, ולחלק השני לבצע stash, אך החלק השני הנ”ל אינו מוכר למערכת, הוא קובץ חדש. כדי להחביא קבצים שהמערכת אינה עוקבת אחריהם, קבצים חדשים, נכתוב ‘git stash save –include-untracked’.

כשיש לנו כמה stash ברשימה, לפעמים קשה להבחין בינהם ולהבין איזה מבניהם אנו רוצים. ובשביל זה קיימות עוד אופציות להרצת פקודת list. כגון: ‘git stash list -stat’ שתגרום למערכת להדפיס את כל ה stash ביחד עם השינויים בהם (רשימה של הקבצים עם הקוד המוחבא, וכמה שורות נוספו/הוסרו). והאמת שאנחנו יכולים להשתמש בכל אופציה שהיינו משתמשים עם הפקודה ‘git log’ (עליהן דיברנו בחלק הקודם, 4). אם נרצה מידע על stash ספציפי נכתוב ‘{git stash show stash@{0’ (וכמובן קיים קיצור כדי לראות את ה stash האחרון ע”י כתיבת ‘git stash show’). אך ניתן לבצע עוד דבר בשביל להבדיל בין ה stashים ברשימה, ניתן להוסיף הודעה/תיאור ל stash ע”י כתיבת השמירה של ה stash כך ‘“git stash save “Add bla bla to index’ וכשנריץ ‘git stash list’ במקום לראות את ה SHA של ה commit האחרון והתיאור שלו נראה את התיאור שכתבנו.

בנוסף, ה stash יכול לשמש גם כגיבוי, אם ביצענו stash לקוד בענף ה feature, ובטעות מחקנו את הענף (עם הפקודה ‘git branch -d feature’), עדיין נוכל לשחזר את הקוד מה stash. כתיבת הפקודה ‘{git stash branch newFeature stash@{0’ תיצור ענף חדש בשם newFeature ותשחזר אליו את הקוד מ {stash@{0. שימו לב שהוא יוציא את ה stash לאחר מכן, ז”א יבצע לו pop. ולבסוף, מה אם יש לנו כמה stash ברשימה ואנחנו כבר לא צריכים אותם, לא הגיוני לבצע לכל אחד ואחד מהם drop, זה יותר מידי עבודה. במקום נכתוב ‘git stash clear’ והפקודה תנקה לנו את הרשימה של ה stash.

שאלות ותשובות

כמו תמיד, החלק של השאלות והתשובות אינו תחליף לתרגול, אם אין לכם פרויקט שאתם יכולים/רוצים לשתף, צרו תיקייה ובתוכה קובץ טקסט פשוט ותתרגלו. אין תחליף לתרגול אישי במחשב שלכם עם שורת הפקודה. הלמידה הטובה ביותר מגיעה דרך האצבעות, אז כתבו את הפקודות בעצמכם, גם אם אתם לא זוכרים, תנסו, ומקסימום תסתכלו בתשובות. אך תכתבו אותן בעצמכם ואל תתפתו להשתמש ב copy/paste, אחרי כתיבת הפקודה פעם, פעמיים, שלוש זה יגיע.

שאלות: אתם לא מוכנים לבצע commit על מה שאתם עובדים כרגע, אבל צריך לבצע תיקון מהיר בענף master. החביאו את השינויים שלכם כדי שתוכלו לעבור זריז ל master, לעדכן ולבצע את התיקונים הנדרשים. בדיוק סיימתם לבצע את התיקונים ב master. עכשיו אתם מוכנים להמשיך את העבודה שהתחלתם בענף feature. לפני זה הדפיסו רשימה של ה stash, כדי שנוודא שאנחנו מחזירים את ה stash הנכון. מצוין. ה stash שלכם הוא הראשון ברשימה, ({stash@{0), החזירו אותו. אחרי ששחזרתם את ה stash שלכם, תנקו אותו מהרשימה. יש עוד stash שהייתם רוצים לשחזר (שוב, הוא בראש הרשימה), שחזרו אותו. אופס! יש קונפליקט בקבצים. אין בעיה, ממילא רק ניסתם דברים. בצעו hard ריסט כדי לחזור ל commit האחרון. עכשיו אחרי שחזרתם ל commit האחרון, נסו שוב לשחזר את ה stash אך הפעם זרקו אותו מהרשימה באותה הפקודה. אתם צריכים שוב להחליף ענפים, אך הפעם כמה מהשינויים שלכם מוכנים ל commit. בצעו stash לכל הקבצים שלא באזור ההיערכות, ועזבו את הקבצים שבאזור ההיערכות כדי שתוכלו לבצע להם לאחר מכן commit. החבאתם דברים כל היום. כעת, יש להם די הרבה קטעי קוד מוחבאים, ואתם לא בטוחים איזה מהם אתם צריכים. הדפיסו את המידע של כל ה stash. כמעט סיימתם את העבודה בענף feature, אבל הצוות רוצה שתבצעו commit למה שסיימתם עד כה. החביאו את החלק שלא סיימתם והוסיפו תיאור ל stash בשביל הנוחות (לדוגמה: Add bla method). עכשיו כשביצעתם commit לחלק המרכזי של העבודה שלכם (בענף feature). צרו ענף חדש בשם bla ותשחזרו אליו את הקוד מה stash האחרון, בפקודה אחת.

תשובות: הפקודה: ‘git stash save’. הפקודה: ‘git stash list’. הפקודה: ‘git stash apply’. הפקודה: ‘git stash drop’. הפקודה: ‘git stash apply’. הפקודה: ‘git reset –hard HEAD’. הפקודה: ‘git stash pop’. הפקודה: ‘git stash save –include-untracked’. הפקודה: ‘git stash list –stat’. הפקודה: ‘“git stash save “Add bla method’. הפקודה: ‘{git stash branch bla stash@{0’.

סיכום

בחלק החמישי למדנו על פקודת ה rebase האינטראקטיבי (כיצד לסדר commits, עריכת התיאור שלהם, פיצול ומיזוג של commits). בנוסף למדנו על כלי ה stashing שעוזר לנו להחביא קטעי קוד (כיצד לשמור את קטעי הקוד מוחבאים ולאחר מכן לשחזר אותם, כיצד לזרוק את ה stash, כיצד לראות את הרשימה של ה stash, התעסקנו עם כל מיני צורות תצוגה של רשימת ה stash, ואף שמירה של חלק מקטע הקוד השונה). כמו תמיד, אם ישנם שאלות אשמח לעזור בתגובות.