ניהול גירסאות

selalerer

New member
זה רק שלב הלמידה שארוך יותר.

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

selalerer

New member
אני עובד עם vim בשוליים, אז לא ממש יכול לומר.

אני לא מכיר את הכלי מספיק טוב.
 
לעשות revert ב svn אתה צריך אינטרנט ושרת וזה לוקח זמן

בgit זה שניה בלי אינטרנט
לעשות compare אותו סיפור
לעשות branch
אני אשכרה זוכר שעבדתי בפרוייקט גדול של svn ולא עשיתי branch אפילו פעם אחת כי זה היה תהליך של שעה!
 

user32

Well-known member
מנהל
תהרגו אותי על דברי הכפירה אבל אני לא מצליח להבין את הקונספט

אודה ולא אבוש, יצא לי לעבוד עם GIT בצורה שטחית ביותר. למעשה, יותר אנסתי את GIT והשתמשתי בו כאילו הוא SVN


אני אשאל כמה שאלות ותענו לי כי אני באמת לא לגמרי מבין.

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

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

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

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

משתמש122

New member
למה git כ"כ נהדר ?

אז אתייחס לנקודה שהעלית - למה לך לעבוד ברגע נתון על יותר מבראנצ' אחד:
&nbsp
ראשית, עליך להסכים לטענה האומרת ש-commit/patch צריכים להיות אטומיים ככל האפשר. כלומר ללא ההכרה בכך, שום כלי ניהול תצורת קוד לא יעזור לך, שכן הניהול יהיה מסובך יותר.
&nbsp
שנית, ברגע נתון אני עובד על באג אחד בבראנצ' X. סיימתי לעבוד עליו.
את הפצ' שמתקן את הבאג שלחתי לקוד ריוויו. תהליך שיכול להיארך בין מספר דקות לימים.
&nbsp
והנה אני עובר ברגע לבראנצ' Y כדי לעבוד על באג נוסף, בלתי תלוי בבאג הראשון. תוך כדי העבודה קיבלתי הערות לגבי התיקון לבאג הראשון. אני יכול בקלות לחזור לבראנצ' הראשון, להתייחס להערות ולשלוח פצ' חדש ושוב לחזור לבראנצ' השני ולהמשיך לעבוד באין מפריע על הבאג השני.
&nbsp
אם אני אעבוד על שני הבאגים באותו הבראנצ', הרי שאני יוצר תלות שאינה הכרחית בין שני התיקונים ובמידה והבאג השני יזכה לריוויו מהיר יותר ולאישורו, אהיה חייב להמתין או לאישור הראשון או לשלוח את הפצ'ים מחדש באופן בלתי תלוי.
&nbsp
הסיפור מסתבך כאשר אתה עובד על מוצר שלו יש מספר גרסאות ואותו התיקון צריך להיכנס למספר בראנצ'ים.
git מאפשר לך לבצע cherry-pick מבראנצ' אחד שבו התיקון כבר הוכנס אל הבראנצ'ים הנוספים.
&nbsp
המעבר בין בראנצ'ים הוא מהיר. יצירת הבראנצ'ים מהירה מאוד.
עריכת פצ' ספציפי (נניח מספר 26) בתוך סדרה של ~50 פצ'ים (סיפור אמיתי) היא פשוטה למדי.
&nbsp
git לא מהווה תחליף לכתיבת קוד ראוי או לביצוע קוד ריוויו או לוודא שהפצ' שלך אכן עובד כהלכה.
אבל הוא יאפשר לך למצוא בזמן קצר מאוד את האשמים במחדלי הקוד ע"י git blame.
&nbsp
וה-merge יכול להיות כואב גם כאן אם שני אנשים עבדו על אותם קבצים באותן שורות.
אבל זה גם המחיר של חוסר תקשורת בתוך צוות, ניהול פרטני וכו' וכו'.
&nbsp
בנוסף, אם אני וחבר צוות נוסף מפתחים את אותו הפיצ'ר למשל, נוח יהיה לנו לעבוד עם בראנצ' המשותף לשנינו בלבד, מבלי ששאר המפתחים אף יידעו עליו (כלומר לא מזהמים את מה שנבחר לכהן כ-repository הראשי).
&nbsp
אבל הכל מתגמד בעיני לעומת המהירות עבודה איתו.
 

user32

Well-known member
מנהל
כן, זה נחמד

בדרך כלל אפשר להסתפק בchange lists אבל אני מבין מה שאתה אומר. בSVN באמת לפעמים אתה נאלץ ליצור "גרסה בצד" בצורה מסורבלת כשאתה במקביל על שינויים גדולים ולא רוצה שישפיעו זה על זה. למרות זאת, בעיניי זה מצב לא רצוי. שני מפתחים שעובדים על branch משותף? אני לא מת על הרעיון אבל יכול לראות את זה עובד.
בפרוייקט הבא אני אנסה את GIT בצורה יותר רצינית גם מבחינה מתודולוגית. כלומר, אם משתמשים בזה רק בשביל לעשות קומיט לbranch אחד אז באמת זה לא שונה מSVN או כל דבר אחר. אז אני אחכה להזדמנות לתת לזה הזדמנות...
 
דוגמא מאצלנו - למה צריך branch

יש לנו מוצר קיים. מדי פעם מוצאים באג שצריך לתקן. יש לו branch משלו.
יש לנו את הגירסא הבאה של המוצר ששם יש פיתוח של דברים שלא נמצאים בגירסה הקיימת. יש branch בשביל זה.
אם אתה באמצע פיתוח ופתאום אתה מקבל מייל שחייבים לתקן את הבאג של התוכנה הישנה, פשוט עוברים branch.
git checkout store_version
ותוך שניה יש לך את כל הקוד של הגירסא הישנה.
תיקנת את הבאג - שיחררת את המוצר - עכשיו אתה רוצה לmarge אותו לגירסה החדשה
&nbsp
ועוד דוגמה מהשרוול, נניח שאומרים לך שצריך לבדוק שינוי בתשתיות, אבל רק לבדוק אם זה שווה את המאמץ.
אז מה אתה עושה?
יוצר branch ועובד על זה שבוע,
בנתיים כולם מתקדמים עם הגירסה הרגילה, ואתה עושה את עבודת התשתית במקום אחר.
בsvn במקרה הזה פשוט לא היית עושה commit במשך שבוע, ואז לך תמצא את הידיים והרגליים.
&nbsp
ועכשיו למשהו אחר לגמרי - נניח ומצאת באג ואתה לא יודע מתי הוא נכנס. אתה רוצה לחזור אחורה בזמן. בsvn זה תהליך מייגע שמצריך עבודה של השרת
בgit זה משהו פשוט שלוקח שניות בלי שרת ובלי נעליים
 

משתמש122

New member
נשמע בדיוק כמו אותה חוויית משתמש אצלנו

אני זוכר גם זמני עבודה מאוד-מאוד ארוכים עם svn
 

user32

Well-known member
מנהל
כן, זה מצב שקורה

ואני מסכים שזה יתרון. בכלים אחרים (SVN, perforce וכו') אני פשוט מחזיק את שני הענפים על המכונה שלי ולפעמים עושה קומיט פעמיים או קומיט לישן יותר ואז מיזוג (מזכיר שmerge קיים גם בכלים אחרים...). אני מבין שGIT עושה את זה הרבה יותר יעיל ומוכן לקבל את זה. פשוט מנקודת המבט שלי אני משתדל לא להגיע למצב שצריך לשחרר תיקונים בכמה גרסאות אבל מודע לכך שלפעמים זה מתבקש.
 

selalerer

New member
באופן טבעי כשמשהו מסובך אתה לא תשתמש בו.

אם זה סיפור לעשות branch ב-SVN אז יעשו את זה פעם בגרסה וזהו. כשזה קל, גם אם הייתרונות משניים, למה לא לעשות?
&nbsp
כשאתה ממזג branch ב-git זה לא רשומה אחת ב-log, זה מביא איתו את כל ההיסטוריה של מה שאתה ממזג. כל ה-commitים עם ההיערות שלהם.
&nbsp
יש את המצב הסטנדרטי שהוצאת כבר גירסה ללקוחות וצריך לתקן בה באגים ולמזג אותם לכל הגרסאות החדשות יותר ול-trunk. אתה ממזג את כולם אצלך על המחשב בצ'יק ושולח את זה לשרת ב-push אחד.
&nbsp
לעשות checkout ל-branch ב-git לא אומר באמת להוציא עוד עותק של כל העץ אליך ולוקח שנייה בדיוק.
&nbsp
בסופו של יום גם ב-git אתה מכניס את הכל למכונה אחת, כך שזה לא שונה (בניגוד אולי למצב בפיתוח מבוזר של פרוייקטי קוד פתוח עם forkים ש-git הומצא יותר בשביל צורת העבודה הזו).
&nbsp
&nbsp
אחת הסיבות שאני פותח branch מקומי (שבכלל אף אחד לא מכיר אותו בחברה חוץ ממני) זה שאני אוהב לעשות commitים קטנים ולשים בהערה שלהם את ההסבר של השינוי שעשיתי. לא פעם ה-commit הקטן הזה מקלקל את המוצר כמוצר. נוגע רק בנקודה מסויימת ולא באמת מתחיל ומסיים פיצ'ר. בכל זאת ההיסטוריה הזאת נוחה לי ונוחה לכל מי שקורא את הקוד וצריך להבין את השינויים שעברו על קובץ ולמה הם נעשו. ההסבר ליד ה-commit הוא יותר ממוקד והשינוי הוא יותר קטן. ה-commitים הם מקומיים כך שבכל מקרה אף אחד לא רואה אותם עד שאני מסיים את הפי'צר. אם אני לא עושה את המשימה לבד אני גם יכול להעביר את המצב ביניים הזה, ששום דבר עדיין לא עובד בו, למישהו אחר בצוות בקלות מבלי להפריע לאף אחד אחר. כשאני מסיים את הפיצ'ר, כולל למרג'ג' את השינויים של החבר צוות שעבד איתי ולבדוק, אני ממרג'ג' את זה ל-branch הראשי ועושה push ל-repository שכולם רואים.
&nbsp
&nbsp
&nbsp
כרגע אני בחברה שמשתמשת ב-SVN אבל מתגעגע
 

rj111

New member
למה לעשות branch

נניח 3 תכנתים עובדים על גרסת ה-release שתבוא בעוד חודש.
אם שלושתם לוקחים את גרסת ה-release האחרונה, משנים קבצים ועושים כל זמן מה commit, הם מכניסים שינויים לא בדוקים לגרסה הראשית ואם הם עובדים על אותם קבצים הם דורסים אחד לשני את השינויים.
מה שמקובל זה שכל אחד עושה branch לגרסה האחרונה, מבצע שינויים ועושה commit ל-branch וכשהשינויים גמורים ובדוקים, מבצעים merge בזהירות לגרסה הראשית אחד אחד בצורה טורית - לא במקביל.
 

user32

Well-known member
מנהל
זה למשל משהו שאני לא מבין

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

rj111

New member
השיטה המסורתית היא בעייתית

כל הזמן צריך לתאם אחד עם השני.
מטבע הדברים במהלך הפיתוח כל אחד עובד על מודול / קלאס נפרד ומשתדלים שהחפיפה תהיה קטנה.
כשמשה קרא למשתנה X, אהרון בד"כ לא קורא לו בשם אחר כי הוא עובד על מודול אחר.
כשכל אחד עושה branch הוא חוסך מעצמו את התאום הבלתי פוסק והעבודה מתקדמת יותר מהר. התאום נעשה כשעושים merge.
 
הנקודה הכי משמעותית לטעמי

זה משהו שבעצם ישעיהו בודניוק הזכיר בתגובה שלו ואני מאמין שספולסקי במאמר שלו (שביסמארק הביא) גם מציין, אבל חשוב להדגיש את זה שוב ושוב:
&nbsp
כשאתה עובד עם centralized version control system, זה עוזר לצוות כצוות, יש היסטוריה, מוודאים ששינויים של אחד לא דורסים את של השני וכו'. הבעיה היא שזה לא עוזר לך כמפתח. כשאתה עושה עכשיו איזה שינוי, נניח refactoring של משהו או הוספה של פיצ'ר חדש, אתה לא יכול לעשות commit תוך כדי עבודה, כי אז אתה מכניס לכולם שינויים חלקיים, לא בדוקים ואולי אפילו עדיין שוברים קומפילציה של חלק מהפרויקט. הבעיה היא שאתה כן רוצה לעשות קומיט מידי פעם כדי שתהיה לך אפשרות לחזור אחורה בהיסטוריה של העבודה הזו. התחלת את הרפקטורינג בכיוון מסוים, ואז פתאום תפסת שאולי יהיה יותר נכון ויותר טבעי לבנות את היררכיית המחלקות בכיוון שונה, אז אתה מוחק הרבה מהשינויים ומתחיל להתאים ל-design החדש שיש לך בראש. אבל אז, אופס, בעצם אי אפשר לעשות את זה כי זה ישבור משהו אחר. צריך לחזור ל-design המקורי שחשבת עליו. אה, יופי, בא נכתוב הכול מחדש כי השינויים ההם לא שמורים בשום מקום (אלא אם יש לנו מזל עם היסטוריית ה-undo של ה-IDE שלנו, ואז צריך לנסות לחזור לאט לאט ולמצוא את הנקודה המדויקת בכל קובץ או משהו...).
&nbsp
עם distributed version control system אתה עושה מידי פעם קומיטים באופן מקומי, בלי להפריע לאף אחד, אבל הנה, הכלי באמת עוזר לך אישית בעבודה, יש לך היסטוריה של העבודה המקומית שלך.
 

choo

Active member
אני אתן דוגמא איך זה עובד אצלנו:

&nbsp
(חברת מוצר, כמה עשרות אנשי פיתוח):
&nbsp
א. לכל צוות יש git repository משלו, שבו מבצעים את הפיתוח המשותף הפנימי של הצוות. בכל צוות יש "אחראי git" אחד (אחד המפתחים), שמושך שינויים מאנשים (עובדים בשיטה של pull, לא של push).
&nbsp
ב. יש git repository אחד מרכזי לחברה, עם אחראי git אחד (אחד המפתחים בחברה), שמושך קוד מה-repositories של הצוותים. אחראי ה-repositories הצותיים מושכים קוד מה-repository המרכזי ("מלמעלה") מדי פעם (לפעמים פעם ביום, לפעמים פעם בכמה ימים, לפעמים כמה פעמים ביום) ועושים merge.
&nbsp
ג. בתקופות סיום של ייצוב גרסא, עוקפים את ה-repository הציוותי, ושולחים בקשות משיכה ישר ל-repository המרכזי.
&nbsp
ד. כשאדם מפתח קוד לבד - הוא עובד מקומית אצלו. מדי פעם הוא מושך מה-repository שמעליו (ומבצע rebase) - כדי לקבל שינויים מלמעלה ולראות שהוא לא שבר את הקוד. כשהוא עשה סדרה של שינויים ש"סגורה על עצמה" ועובדת (יכול היות פעם ביום, פעם בכמה ימים, ולעיתים פעם בכמה שבועות) - הוא מושך את הקוד מלמעלה, מבצע rebase, בודק שלא שבר דברים, מתקן מה שצריך, ובסוך שולח בקשת משיכה למעלה.
&nbsp
ה. כשיש פיצ'ר שמפותח ביחד בין כמה אנשים, ודורש שינויים מסונכרנים - אחד מהם פותח אצלו branch שבו הם מפתחים את ה-feature. אותו אדם אחראי לקחת על ה-branch הזה מלמעלה כמו ב-repository הצוותי.
&nbsp
תדירות לקיחת שינויים מלמעלה נקבעת על ידי כל branch וכל repository באופן נפרד, בהתאם לצרכים שלהם ובהתאם לנוחות שלהם. מאחר ומי שמוסיף קוד חדש צריך לוודא שהוא עובד עם מה שיש למעלה - אפשר לשמור על כך שה"למעלה" יציב ועובד (פרט למקרים חריגים מאוד).
&nbsp
ו. הפיתוח מחולק ל-milestones. בזמן שמייצבים מיילסטון אחד, חלק מהאנשים כבר מתחילים לעבוד על ה-milestone הבא (נובע מגודל הצוות ביחס ליכולת למקבל פיתוח של כל "עבודת פיתוח"), ולכן פותחים עבורו branch חדש. כששולחים קוד למעלה ב-branch של מיילסטון נמוך - דואגים לבצע מיזוג שלו גם ל-branch של המיילסטון הגבוה, ושולחים אותם ביחד.
&nbsp
ז. בנוסף, בזמן ייצוב גרסא X, יש אנשים שכבר התחילו לעבוד על גרסא Y - ואז יש לה branch משלה, ואותו נוהל מיזוג כמו בסעיף הקודם.
&nbsp
אני יכול לאמר שהמודל הזה די נוח, די גמיש, ודי קל לעבוד איתו.
&nbsp
לגבי נוחות העבודה עם branch-ים מרובים - לרוב זה מתנהל די חלק (אם כי יש אנשים בודדים אצלנו שלא מרגישים נוח עם git). צריך לעבוד עם זה בצורה מאוד מתודית (אחרת אפשר לחרבש את ה-repository - ואז קשה מאוד לתקן את זה).
&nbsp
ביצוע merge בסביבה של git לרוב מהיר בהרבה מאשר ביצוע merge מקביל בסביבה של cvs, svn ואחרים. גם כשיש התנגשויות, אפשר לטפל בהן. העובדה ש-git מנהל patches ולא קבצים, אומרת שכל שינוי הוא אטומי, ולכן ביצוע revert לשינוי לא מוצלח מתבצע בפקודה אחת (במערכות האחרות צריך לבצע undo בנפרד לכל קובץ בצורה ידנית, ככל שזכור לי), ואומרת גם ששינוי לוגי אחד "נקרא" בנוחיות רבה, ללא קשר לכמות הקבצים שעליהם הוא מתפרש. זה גם אומר שאם אני מושך קוד "מלמעלה" וזה דורש ביצוע שינויים - כשאני עושה rebase אני יכול לתקן את ה-commits הישנים שלי (אלו שעוד לא שלחתי למעלה) - במקום להכניס עוד commits חדשים שבהם אני "מתקן את הקוד" - וזה מאפשר לקרוא את ההסטוריה בצורה קלה יותר. בכלל, היכולת לעקוב אחרי ההסטוריה של השינויים היא מאוד נוחה - גם לראות מי שינה מה, גם לראות מתי השתנו דברים (ואם אנשים כתבו הערות commit טובות וביצעו commits קטנים יחסית - גם להבין למה עשו את השינוי). כמות השימוש ב-git-blame ועוד יותר ב-git log -p - גדולה מאוד, ובגלל שזה עובד מאוד מהר - זה מאוד נוח. ולבסוף - זה מאפשר לבצע git-bisect שאמור להקל עלייך למצוא באיזה commit בדיוק נכנס באג מסויים למערכת (זה מאוד עוזר עבור באג מערכתי שהתגלה מאוחר, ומתקשים לדבג אותו בשיטות האחרות).
&nbsp
גם בעבודה בתוך הצוות (7-8 מפתחים) git הופך את החיים לנוחים יותר וזורמים יותר מאשר שימוש בכלים אחרים. בזמנו זה גם איפשר לי לקחת את הקוד על DoK הביתה ולעבוד חלק מהימים מהבית (כולל ביצוע commits חדשים) גם בלי חיבור vpn לעבודה. זה משהו כמעט בלתי אפשרי במערכות ניהול גרסאות שאינן מבוזרות.
&nbsp
מה שכן - מאוד עוזר אם יש אצלך מישהו שכבר עבד עם git בעבר במקום ש"יודעים מה הם עושים עם git" כדי להחליט על המתודולוגיה של השימוש ב-git - משום ש-git גמיש מדי בשביל שכל עירוב שימושים בו ייתן תוצאה קוהרנטית (למשל, עירבוב לא נכון של merge ו-rebase בין repositories שונים - יחרבש את הקוד לגמרי).
&nbsp
לקחת את git ולהשתמש בו כמו svn - מסרס את היתרונות הגדולים שלו.
 
למעלה