שאלה לגבי ענפים ב-GITHUB
-
@ps כבר התחלתי לכתוב שיעור שלם על הנושא...
GIT זו מערכת לא קלה או פשוטה. זה אחת מהטענות העקריות נגדה.
(לשם כתיבת השיעור הייתי צריך ללמוד בעצמי איך דברים עובדים, לא שלפתי מידיעות קודמות.)
אבל בגדול אתם צודקים, אין צורך ללמוד את כל הפינות האפלות ולהבין בדיוק מה קורה כאשר אתה עובד לבראנצ' אחר בלי לעשות commit. פשוט עובדים נכון, ועושים commit לפני שעוברים לענף אחר.אולי אם אני יקבל תמונה ברורה אני אעלה את השיעור... (בעצם כבר מחקתי, אבל זה טוב להבין קצת גם מה קורה מאחורי הקלעים בגיט, כי ה"קלעים" דקיקים בגיט למדי ובלי להבין נופלים במכשולים...)
-
הקדמה
במערכת גיט יש שלוש אזורים שבהם מופיעים כל הקבצים של הפרוייקט.
- ב-repository (כאן נמצאים לא רק הקבצים אשר ישנם פה עמנו היום אלא כל ההיסטוריה שלך מתחילת הפרוייקט)
- ה-staging area (ידוע גם כ-index). מיד אחרי checkout זה משקף את ה-commit שעשית עליו checkout. אחרי stage נוספים פה השינויים שעליהם עשית stage. בעת commit כל מה שנמצא פה ייכנס ל-commit החדש.
- working directory - סביבת העבודה. כאן נמצאים הקבצים שעליהם אתה עובד.
פקודת
git checkout
הרעיון שלו הוא לשנות את אזור 3 (- סביבת העבודה) לשקף את המצב של אחד מהאזורים 1 או 2 (ה-staging area או ה-working directory)- במקרה של
git checkout <file>
בלי לציין בראנצ' או commit, התוצאה היא ש-<file>
באיזור 3 ישקף את<file>
באיזור 2, זו פעולה הרסנית זה ידרוס את כל השינויים שבאזור 3. - במקרה של
git checkout <branch> <file>
התוצאה היא ש-<file>
באיזור 2 ו-3 ישקף את מצב ה-<file>
באיזור 1 (בתוך<branch>
). זו פעולה הרסנית, זה ידרוס את השינויים שבאיזור 2 ו-3. - במקרה של
git checkout <branch>
בלי לציין שם של קובץ, זו פעולה לא הרסנית, הפעולה תצליח רק אם הוא לא הורס כלום.
א) זה משנה את הבראנצ' הנוחכי ל-<branch>
ב) זה דורס את הקבצים באיזור 2 ו-3, אבל רק אם זה לא יהרוס את השינויים המקומיים, ולכן התוכנה עוברת על כל הקבצים, אם יהיה אובדן של שינויים אז כל הפעולה נכשלת. לכל קובץ התוכנה בודקת כדלהלן:- אם בתוך איזור 1, יש שוויון בין הקבצים של הבראנצ' הקודם לבראנצ' הנוחכי או שהקובץ לא קיים בבראנצ' החדש, לא קורה כלום, כלומר מכיון שלא נדרש שום דריסה, תמצא את איזור 2 ו-3 כמו מקודם עם כל השינויים המקומיים (אלה שעשית להם stage ואלה שלא עשית להם stage), ופעולת commit ישמור את השינויים לבראנצ' החדש.
- אם קובץ לא קיים בבראנצ' הקודם, אז הפקודה מוסיפה את הקובץ לאיזור 2 ו-3
- אם הקובץ קיים בשני הבראנצ'ים (הקודם והנוכחי) אבל בתוך איזור 1 אין שוויון ביניהם, אז נבדקים שינויים מקומיים.
- אם אין שינויים מקומיים - הקובץ נעתק לתוך איזור 2 ו-3.
- אם יש שינויים מקומיים, אז נבדקים שוויון איזור 2 של הקודם לאיזור 1 של הנוכחי, במקרה שהם שווים, לא קורה כלום, אם הם לא שווים הפעולה נכשלת. (אני לא מסביר למה זה כך כי אין לי כח, אבל אחרי מחשבה אני מבין את ההגיון בזה).
נ.ב. לא מצאתי את זה מתועד בצורה זו, אבל כך הבנתי מתוך נסוי... אם היה לי כח הייתי מסתכל בקוד המקור, התיעוד הסמכותית ביותר...
-
עכשיו מצאתי את האלגוריתם שבודק שלא נהרסים שינויים על ידי ה-checkout.
https://git-scm.com/docs/git-read-tree#_two_tree_merge
אוףףף, למה עשו את זה כל כך מסובך הראש שלי מתפוצץ
ועיין עוד: https://stackoverflow.com/a/44166981/8997905
-
כדאי לעבוד עם תוכנת קליינט גרפית לגיט (Sourcetree, Fork). כי אז רואים את כל העץ והענפים מול העיניים.
בעת שינוי ומעבר לבארנץ אחר, רואים מיד מה קרה ולאיפה הלכו השינויים - אלה שנשמרו ואלה שלא נשמרו.
מניסיון שלי הייתי אומר שכ 80% מהשאלות בGit נעלמות כשרואים את העץ בצורה מוחשית.
טיפ לעת מצוקה:
git reflog
יציג את כל השלבים האחרונים שבוצעו (Commit, Checkout וכן הלאה), ללא קשר למיקומם בעץ. ניתן לתפוס את המזהה של השלב הרצוי ולעבור אליו (checkout). -