שלום אורח התחבר

הבלוג של ינון פרק

טיפים קצרים וחדשות למתכנתים

מעדיפים לקרוא מהטלגרם? בקרו אותנו ב:@tocodeil

או הזינו את כתובת המייל וקבלו את הפוסט היומי בכל בוקר אליכם לתיבה:

גיט אולי מפורסמת בתור מערכת לניהול גירסאות אבל האמת שהיא עושה הרבה יותר מזה. בין השאר גיט יכולה להריץ קוד באופן אוטומטי על הקבצים שלכם כדי לשמור קוד נקי במאגר ולהקל על שיתוף מאגרים בין מתכנתים. בפוסט זה נדבר על gitattributes דרכו אפשר להגדיר תהליכים אלה ונראה כמה דוגמאות שיעזרו להבין איפה להשתמש בהם.

המשך קריאה...

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

המשך קריאה...

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

המשך קריאה...

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

תשע שנים אחרי ועדיין לא עבר לו, וגם אני כבר מזמן מכור.

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

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

מתכנתים רבים מגיעים ללמוד גיט ומחפשים איך לבצע בגיט את ה-3 פקודות שהם מכירים ממערכת ניהול הגירסאות הקודמת שלהם או דרך Tutorials של "למד את עצמך גיט בעשרים דקות". זה עובד אבל רק חלקית. כשאתם לומדים תוך כדי עבודה ומדלגים על הבסיס התיאורטי וה Best Practices יהיו דברים חשובים שתחמיצו ויהיו דברים שוליים שתקחו יותר מדי ללב.

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

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

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

אני בטוח שתהנו מהקורס ומקווה שתבחרו להצטרף. אם אתם מנויים לאתר יכולים כבר עכשיו להיכנס ולראות את התכנים. אם לא יכולים להצטרף כמנויים או לרכוש רק קורס זה בתשלום חד-פעמי. זה הקישור לקורס עם הסילבוס המלא וכפתור הצטרפות:

https://www.tocode.co.il/bundles/git

נתראה שם, ינון

מר חשדני האמיץ הכניס בטעות את הסיסמא הסודית של בסיס הנתונים ל Git Respository של הפרויקט שלו. מהר מאוד הוא קלט שזה לא היה רעיון טוב ומחק את הקובץ עם הסיסמא. האתגר שלכם- חפשו את הסיסמא במאגר והזכירו למר חשדני שלא כל כך פשוט למחוק מידע רגיש מרגע שנכנס למאגר גיט.

את תיקיית הפרויקט עם מאגר הגיט אפשר להוריד מהקישור:

http://www.tocode.co.il/system/uploads/git-ex.zip

ואת הסיסמא שמצאתם שימו כאן בהערות למטה (אבל אל תספרו איפה היתה שלא לקלקל לאחרים).

בהצלחה!

אז היה אתמול וובינר יחסית גדול על גיט ואני רוצה לסכם חלק מהטכניקות והרעיונות שהוצגו שם.

המשך קריאה...

אני אוהב את git stash. זה מאוד נוח כשאני באמצע עבודה על משהו ואז צריך לשנות קונטקסט בגלל תקלה דחופה במקום אחר פשוט לזרוק את הכל הצידה ולדעת שאפשר יהיה לחזור לאותו מצב. הרצף הזה למשל עובד ממש טוב:

[1]
$ git checkout -b new-router
$ # ... work work work
$ # oh no - production error, must fix something in master

[2]
$ git stash
$ git checkout master
$ # fix and deploy

[3]
$ git checkout new-router
$ git stash pull

הפקודות ב [1] יוצרות בראנצ' חדש בשביל העבודה על איזשהו פיצ'ר, ואז באמצע העבודה יש לנו שינויים בקבצים שלא הספקנו לעשות להם קומיט. הפקודה git stash זורקת הצידה את השינויים האלה ומחזירה אותנו לקומיט האחרון של הבראנצ'. בצורה כזו לא צריך לעשות קומיט לדברים לא שלמים שאנחנו יודעים שעוד רגע נחזור אליהם. ובאמת אחרי התיקון הפקודות ב [3] מחזירות אותנו לבראנצ' להמשך פיתוח ומוציאות מהארון את השינויים שלא עשינו להם קומיט.

עד לפה נראה לי שהכרתם ועכשיו לטיפ: מסתבר שהרבה פעמים אנחנו נתקעים ב [2] הרבה יותר זמן ממה שחשבנו. כשחוזרים אחרי יומיים להמשך עבודה לא תמיד זוכרים איפה היינו. מה שיותר גרוע לפעמים באמצע העבודה על [2] דברים יותר חמורים קורים ושוב צריך לשים קוד חצי אפוי ב stash. וכמו כל ארון אחסון זמני ככל שה stash גדל כך קשה יותר למצוא בו את הדברים שלכם.

מסתבר שאפשר להוסיף הודעה ל git stash, לראות את ההודעה הזו ואף לחפש שינויים לפי מילות מפתח בהודעות.

הפקודה:

$ git stash save 'started writing CSS for the new router but big production bug stopped me'

תשמור את השינויים בצד יחד עם ההודעה.

הפקודה:

$ git stash list

תציג את כל השינויים השמורים בצד עם ההודעות שלהם. הפקודה:

$ git stash list stash^{/big}

תציג את כל השינויים שההודעה שלהם כוללת את המילה big ולסיום הפקודה:

$ git stash apply stash^{/big}

תיקח את השינויים מהסטאש החדש ביותר שההודעה שלו כוללת את המילה big לתוך הקוד בתיקיית העבודה שלכם.

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

אה ושלא נשכח היום בעשר יש וובינר עם טיפים לגיט. נדבר שם בעיקר על בראנצ'ים ושיטות עבודה ועדיין אפשר להצטרף בקישור:

https://www.tocode.co.il/workshops/43

למתכנתים וותיקים שעבדו עם כלי ניהול גירסאות בעבר אמור לקחת בדיוק עשר דקות למצוא את שתי הפקודות החשובות בגיט: checkout ו commit. עוד כמה שעות של עבודה ואתם כבר שולטים גם ב add ו clone ואולי אפילו ב diff ויכולים להמשיך לעבוד כאילו אתם עדיין עם SVN. עד שמתחילות הצרות.

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

סיבה שניה היא פוטנציאל הרווח. כי אם אתם עובדים בגיט כמעט בטוח שאתם יכולים להפיק יותר מהכלי אם תדעו לעבוד נכון עם בראנצ'ים, לשלב ביניהם ולהזיז קוד בין הבראנצ'ים השונים. ואם תכירו טוב את ההבדל בין ה Staging Area, ל Local Repository ול Remote Repository תוכלו להשתמש בצורה חכמה יותר בכל אחד.

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

הרשמה בחינם בקישור:

https://www.tocode.co.il/workshops/43

השבוע דיברתי עם אליעזר במפגש תרגול git ועברנו על בראנצ'ים ועל הפקודה git branch -f שלדעתי עוזרת לעשות קצת סדר בקשר בין בראנצ'ים לקומיטים.

הבלבול מתחיל כבר כשפותחים פרויקט חדש:

$ git init
$ git log
fatal: your current branch 'master' does not have any commits yet

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

$ echo 1 > demo.txt
$ git add .
$ git commit -m 'commit 1'
$ echo 2 > demo.txt
$ git commit -a -m 'commit 2'
$ git log
localhost:project ynonperek$ git log
commit cd877d58a9885372b9b6ff93c77dabcff8b58052 (HEAD -> master)
Author: ynonp <ynonperek@gmail.com>
Date:   Thu May 3 08:23:51 2018 +0300

    commit 2

commit 85f0794fe33b4718dce3f02b480a119261d64115
Author: ynonp <ynonperek@gmail.com>
Date:   Thu May 3 08:23:40 2018 +0300

    commit 1

נראה אחלה עד שחוזרים אחורה:

$ git checkout 85f0794fe33b4718dce3f02b480a119261d64115

$ git log
commit 85f0794fe33b4718dce3f02b480a119261d64115 (HEAD)
Author: ynonp <ynonperek@gmail.com>
Date:   Thu May 3 08:23:40 2018 +0300

    commit 1

$ git branch
* (HEAD detached at 85f0794)
  master

אם חשבנו על בראנצ' כספריה ועל קומיט בתור מצב עניינים בספריה ברגע נתון - מה עכשיו קרה כאן? ברור שאנחנו לא בבראנצ' master יותר, אז מה פתאום קומיט עזב את הבראנצ' שלו? ואיך חוזרים?

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

בדוגמא שלנו המדבקה HEAD היתה מחוברת לקומיט cd877. אחרי ביצוע checkout הזזנו את המדבקה HEAD לקומיט הישן יותר. המדבקה master אגב עדיין נשארה מחוברת לקומיט החדש. הנה כמה פקודות שעכשיו נראות הרבה יותר הגיוניות (ממשיכים מאותו מצב):

$ git checkout master
$ git branch
* master
$ git log
commit cd877d58a9885372b9b6ff93c77dabcff8b58052 (HEAD -> master)
Author: ynonp <ynonperek@gmail.com>
Date:   Thu May 3 08:23:51 2018 +0300

    commit 2

commit 85f0794fe33b4718dce3f02b480a119261d64115
Author: ynonp <ynonperek@gmail.com>
Date:   Thu May 3 08:23:40 2018 +0300

    commit 1

ואם קומיט לא חי בתוך בראנצ' אפשר להתחיל לעשות דברים מעניינים - כמו לעקוף את master ולבצע קומיט ישירות מתוך קומיט אחר:

$ git checkout cd877
$ echo 3 > demo.txt
$ git commit -a -m 'commit 3'
$ git log
commit ff12c93ea35fce6e1583d877458f848da796a26f (HEAD)
Author: ynonp <ynonperek@gmail.com>
Date:   Thu May 3 08:37:11 2018 +0300

    commit 3

commit cd877d58a9885372b9b6ff93c77dabcff8b58052 (master)
Author: ynonp <ynonperek@gmail.com>
Date:   Thu May 3 08:23:51 2018 +0300

    commit 2

commit 85f0794fe33b4718dce3f02b480a119261d64115
Author: ynonp <ynonperek@gmail.com>
Date:   Thu May 3 08:23:40 2018 +0300

    commit 1

פעולת git checkout הזיזה את HEAD ועכשיו כל הפעולות שלנו מתבצעות על קומיט cd877 ולא "מושכות" את master קדימה. מה שיפה שמאחר ואנחנו חושבים על בראנצ'ים כמו מדבקות קל מאוד להזיז את master לקומיט אחר. הפקודות הבאות מתקנות את המצב:

$ git branch -f master HEAD
$ git checkout master
$ git log
commit ff12c93ea35fce6e1583d877458f848da796a26f (HEAD -> master)
Author: ynonp <ynonperek@gmail.com>
Date:   Thu May 3 08:37:11 2018 +0300

    commit 3

commit cd877d58a9885372b9b6ff93c77dabcff8b58052
Author: ynonp <ynonperek@gmail.com>
Date:   Thu May 3 08:23:51 2018 +0300

    commit 2

commit 85f0794fe33b4718dce3f02b480a119261d64115
Author: ynonp <ynonperek@gmail.com>
Date:   Thu May 3 08:23:40 2018 +0300

    commit 1

הפקודה git branch -f מזיזה ברנאצ' לקומיט אחר. היא יכולה להתקיים כי קומיטים לא חיים בתוך בראנצ'ים אלא מדובר במבנה הרבה יותר גמיש ואין בעיה להזיז את הבראנצ' לקומיטים אחרים ובחזרה.

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

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

המשך קריאה...