שני שימושים הגיוניים ל git stash

26/01/2022

הרבה זמן לא הבנתי את git stash. הרי למה לזרוק את כל השינויים שלי ל stash כשאני יכול לעשות להם קומיט ל branch זמני חדש? מה אני מרוויח מלשים אותם במקום שבו רק יהיה לי יותר קשה למצוא אותם?

אז אם גם אתם לא מהמשתמשים הכבדים של גיט סטאש הנה שני מצבים שבהם כן כדאי להכיר אותו ולהשתמש בו-

1. אם בפרויקט מוגדר commit hook

אני יודע, קומיט הוקס הם חשובים כדי לוודא שהקוד עובד כמו שצריך או כל מיני דברים כאלה, אבל לפעמים הם יכולים להיות מאוד מציקים - למשל אם יש לי קומיט הוק שמוודא שהקוד עובר eslint, ואצלי הקוד עדיין לא עובר eslint אבל בכל זאת צריך לשים אותו בצד, אז אני כבר לא יכול לעשות קומיט ל branch זמני וללכת לעשות דברים אחרים כי ה commit hook יחסום אותי.

במצבים כאלה stash הוא פיתרון מעולה כי הוא מדלג על pre-commit hook. אנחנו זורקים את השינויים ל stash עם:

$ git stash -u

מקבלים תיקיית עבודה נקיה, יכולים לתקן באג או לעבוד על פיצ'ר אחר, וכשרוצים לחזור לאיפה שהיינו מפעילים:

$ git stash pop --index

המתג -u גורם לשליחת כל הקבצים ל stash כולל אלה שעדיין לא התווספו לגיט, והמתג --index אחרי pop גורם לשיחזור גם של ה Staging Area כך שאם עשיתם add לכמה קבצים אז אחרי החזרה מה stash לא תצטרכו לעשות להם add שוב.

2. אם יש לי קובץ גדול בתיקיה

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

במילים אחרות נניח שסטטוס נותן לי את הסיטואציה הבאה:

On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   src/App.js

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        buggy-data.db

הקובץ buggy-data.db מייצג dump של בסיס הנתונים עם מידע שגורם לבאג במערכת שלי ואני מנסה לתקן אותו. זה קובץ בינארי גדול ואני צריך אותו רק בשביל הבדיקות והתיקונים. באמצע העבודה אני צריך לעבור לעבוד על פיצ'ר או באג אחר.

אם אני עכשיו יוצר קומיט חדש בענף חדש לצורך התיקון ומכניס אליו גם את buggy-data.db, קובץ זה יידחף לשרת המרכזי בפעם הבאה שאעשה push ויישמר במאגר הגיט לנצח. אם אני מוותר על buggy-data.db בקומיט הזמני ומשאיר אותו פשוט בתיקיית העבודה הוא עלול להפריע לי בתיקון הבאג בענף החדש. אני יכול להכניס אותו ל .gitignore אבל לא בטוח שאני רוצה לשנות את gitignore בשביל משהו כל כך זמני.

סטאש שוב מסתמן בתור הפיתרון הקל במצב הזה. מפעילים:

$ git stash -u

והקובץ הגדול נעלם לסטאש יחד עם השינוי שהתחלתי לעשות. הפעלה עתידית של git push לא תשלח את הקובץ הגדול למאגר המרכזי ובהפעלה עתידית של gc הוא יימחק מתיקיית .git, או אם רוצים מיד אחרי ה git stash pop למחוק אותו אפשר להריץ:

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc

מכירים עוד מקרים שבהם git stash הוא הפיתרון הטוב ביותר? מוזמנים לשתף בתגובות.