Git - חלק 2

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

 

diff command

אז נניח שאליס הגיעה לעבודה, היא נמצאת ב repo המקומי שלה (מקומי, בפרויקט קיים, אצלה במחשב), ואתמול היא עשתה כמה שינויים בקובץ LICENSE, היא רוצה להמשיך אך לא זוכרת מה היו השינויים שעשתה. כדי לראות את השינויים האלו, יש לכתוב את הפקודה git diff, הפלט של הפקודה יהיה השינויים שאינם נמצאים באזור ההיערכות, ז”א שינויים שביצענו בקבצים שהמערכת עוקבת אחריהם, אך לא ביצענו להם עדיין add מחדש (כדי לכלול את השינויים). את השורה הישנה תראו עם מינוס (-) בתחילתה, ואת השורה החדשה ניתן לראות עם פלוס (+) בתחילתה.

$ git diff
diff --git a/License b/License
index 7e4922d..442669e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2014 nirgn
+Copyright (c) 2014 nirgn

אם נוסיף את הקובץ (LICENSE) לאזור ההיערכות (עם הפקודה git add LICENSE), ולאחר מכן נריץ שוב את הפקודה git diff, לא יודפס כלום. מכיוון שכל השינויים שהיו נוספו לאזור ההיערכות. אך אם נרצה לראות את השינויים באזור ההיערכות, נשתמש בפקודה git diff -staged. ונקבל את אותו הפלט שקיבלו מקודם.

 

מה אם התחרטנו?

כעת, אם נכתוב git status נראה כי ישנו קובץ ששונה, נוסף לאזור ההיערכות, ובעצם מוכן ל commit. אך מה אם לא רצינו להוסיף את הקובץ LICENSE לאזור ההיערכות. נגיד ואליס עדיין לא סיימה לערוך אותו והוסיפה אותו מוקדם מידי, מה אז? כדי להוריד קבצים מאזור ההיערכות אנו משתמשים בפקודה git reset HEAD nameOfFile (החליפו את nameOfFile בשם הקובץ), אז בואו נריץ אותה על הקובץ שלנו git reset HEAD LICENSE. כמובן שעכשיו אנחנו צריכים להתייחס ל elephant in the room, ה HEAD. ה HEAD מתייחס ל commit האחרון (בענף הנוכחי (או ציר הזמן אם תרצו) שבו אנו נמצאים, עד כה קיים רק ענף אחד בשבילנו, master, עדיין לא נגענו באפשרויות נוספות בנושא).

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

$ git status
# On branch master
# Changed but not updated:
#    (use "git add <file>.." to update what will be comitted)
#    (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified:    LICENSE

בואו נעצור שנייה, ונחזור טיפה אחורה. נגיד שאליס עשתה שינוי בקובץ README.txt, כדי לבצע לו commit היא תצטרך קודם כל להוסיף אותו לאזור ההיערכות, ז”א שעליה לכתוב 2 פקודות. הראשונה: git add README.txt והשניה: "git commit -m "Modify readme file, אך יש דרך קיצור שבה אנחנו יכוליף להוסיף את הקובץ לאזור ההיערכות ולבצע commit בפקודה אחת: "git commit -a -m "Modify readme, אך שימו לב, בפקודה הזו אנו מבצעים commit אך ורק לקבצים שאנו כבר עוקבים אחריהם. כך שאם אנחנו רוצים להוסיף קובץ חדש, נצטרך לעשות זאת בדרך הארוכה יותר, להוסיף אותו לאזור ההיערכות ולבצע commit.

 

Reset

עד כה דיברנו על המצב בו התחרטנו לאחר שהוספנו קובץ לאזור ההיערכות, או אפילו התחרטנו על עריכת הקובץ מלכתחילה. אך מה אם ערכנו את הקובץ, הוספנו אותו לאזור ההיערכות, ביצענו commit, ואז התחרטנו! רצינו להוסיף איזה שינוי שאמור להיות כלול בתוך ה commit שעכשיו ביצענו. למזלנו יש את הפקודה ^git reset –soft HEAD הפקודה תבטל את ה commit האחרון ותחזיר כל השינויים מה commit הזה אל אזור ההיערכות. בחלק א’ הסברנו כי ה HEAD מתייחס ל commit האחרון (בענף הנוכחי, בו אנו נמצאים), אך כאן ישנו גם הסימן ^, הסימן הזה אומר: ל commit שלפני האחרון. ואם נריץ לאחר מכן שוב את הפקודה git status נראה כי כל השינויים כרגע, באזור ההיערכות (לפני הביטול של ה commit האחרון. אם היינו מריצים git status לא היינו מקבלים דבר, כי לא בוצעו שינויים מה commit האחרון, זה שהעלינו עכשיו, אך משום שביטלנו אותו וחזרנו commit אחד אחורה, ישנם שינויים), כעת ניתן לערוך את הקבצים, להוסיף חדשים וכ’ו, ולבצע commit מחדש.

$ git status
# On branch master
# Changes to e committed:
# (use "git reset HEAD <file>.." to unstage)
#
# modified:    README.txt

דרך נוספת לבצע שינויים ב commit, היא להשתמש בפקודה amend, כך שאם לדוגמה רצינו להוסיף עוד קובץ בשם toDo.txt ל commit האחרון שלנו, נכתוב "git commit -amend -m "Modify readme & add toDo.txt, הפקודה, כמו שאמרנו, תוסיף את הקובץ ל commit האחרון ואפילו כתבנו הודעת commit חדשה שדרסה את הקודמת ומתראת את השינויים מחדש ב commit האחרון.

אך יש עוד שתי פקודות שימושיות:

  • ^git reset -hard HEAD - בניגוד ל soft שמבטלת את ה commit האחרון אך שמה את השינויים שלו באזור ההיערכות, זאת מבטלת את השינויים לגמרי.
  • ^^git reset -hard HEAD - הפקודה כבר מוכרת לנו, אך באה להמחיש שבמידה ונרצה לבטל את שתי ה commit האחרונים, פשוט נוסיף עוד caret.

 

GitHub ושאר העולם

עד כה אליס עבדה על ה repo (המאגר) המקומי, אצלה במחשב. אבל מה אם היא רוצה להעלות את הפרויקט ל GitHub או ל Google Code או סתם לשרת של החברה כדי שבוב, חבר צוות, יעבוד על הגרסה העדכנית הכוללת את השינויים שביצעה. כאן נכנסות לתמונה הפקודות pull / push.

New Repository

בעצם מה שאנחנו עושים זה מעלים את הקוד ל repo אחר, מרוחק. או במילים אחרות remote repository. לכן הפקודות יהיו על בסיס git remote.

לפני שנמשיך, ארצה לדבר מעט על GitHub. כדי להעלות את הקוד שלכם ל GitHub, עליכם דבר ראשון להירשם. לאחר שנרשמתם, עליכם לפתוח repo ב github, אז לחצו על ה+ ואז על New repository. לאחר מכן יפתח לכם טופס כמו שזה שלמטה. ב Repository name נכתוב את שם המאגר, וב Description נכתוב את תיאור המאגר/פרויקט.

Description

מתחת ל Description ישנה אופציה כדי לבחור האם ה repo יהיה פומבי (כולם יוכלו לראות, לקרוא, לבצע fork וכד’) או repo פרטי (יש לציין כי רק חשבונות משודרגים, שעולים כסף, יכולים לפתוח repo פרטי). מתחת לזה יש אפשרות ליצור קובץ README ל repo באופן אוטומטי. ב Add .gitgnore אנו נתאר את הז’אנר של הפרויקט שלנו וב Add a license נבחר ברישיון שתחתיו הפרויקט יהיה (זה בעצם יתאר מי, למה, כמה, איך וכד’ אנשים אחרים יוכלו לעשות לקוד שהעלינו) (לא ניכנס לזה כרגע, מכיוון שזה לא קשור ל git אולי בפוסטים אחרים).

Repository URL

לאחר שיצרנו את ה repo, נקבל מ GitHub כתובת URL שתהיה הכתובת של ה repo שלנו, ולכתובת הזאת נדחוף את הקבצים. כדי לדחוף את הקבצים, נצטרך להריץ את הפקודה --..git remote add origin https://github. בואו נראה מה הפקודה אומרת: המילה add היא הראשונה שאנחנו לא מכירים, היא בעצם אומרת שאנחנו מוסיפים remote חדש. origin הוא השם של ה remote, אנחנו יכולים לתת לו כל שם, אך מקובל לקרוא ל repo, מאגר, הראשי שלנו, זה שכל האנשים משתמשים בו כ origin. ולבסוף יש לנו את הכתובת של ה repo (החליפו את הנקודות בהמשך הכתובת שלכם).

כדי לקבל רשימה של כל ה remote שה repo המקומי שלנו מכיר (אלה שהכנסנו במהלך הזמן), נשתמש בפקודה git remote -v. אל תשכחו שעדיין לא דחפנו את ה repo שלנו ל GitHub, ה remote האלו הם מעניין סימניות (bookmarks). אז כעת, נדחוף את ה repo שלנו בעזרת הפקודה git push origin master. שימו לב שאנו מפרטים את שם ה repo המרוחק (origin) ואת הענף (ציר הזמן אם תרצו) אליו נרצה לדחוף (master). ומכיוון שאנו משתמשים ב GitHub, המערכת תרצה את שם המשתמש שלנו והסיסמה (כדי לוודא שאנו מורשים לדחוף ל repo הזה).

אם נרענן כעת את הדף ב GitHub נראה שהמערכת מציגה את הקבצים החדשים, ובנוסף ישנו כפתור ה Network (בעמודה של התפריט בצד ימין, אחד לפני האחרון, מעל ההגדרות) שם נוכל לראות את הענפים ואת כל ה commit שביצענו ביחד עם התיאור של כל commit, מי ביצע אותו וכד’, או בקיצור תחליף לכתיבת git log בשורת הפקודה.

אז דחפנו את ה repo שלנו ל GitHub (או כל שרת אחר), אבל אנחנו עובדים בצוות, ואנחנו לא היחידים שעושים שינויים, אז איך אנחנו מושכים חזרה את ה repo המרוחק כדי לעדכן את ה repo המקומי שלנו? בעזרת הפקדה git pull (כמובן שתהיו עם שורת הפקודה בתוך ה repo המקומי שלכם).

נחזור קצת אחורה, מקובל שהשם המרכזי של ה repo המרוחק (remote) יהיה origin, אך זה לא אומר שיכול להיות לנו כמה כאלה. לדוגמה origin כמובן, ואולי גם test שבו אנו מריצים את הבדיקות שלנו, וכ’ו. בנוסף, ראינו את הפקודה להוספת remote (הפקודה <git remote add<name> <address), אך בשביל להסיר remote, הפקודה שונה: <git remote rm <name. וכדי לסכם את הכל, נחזור גם על הפקודה איתה אנו דוחפים את הקוד ל remote והיא ``<git push -u<branch`, אם שמתם לב בפקודה המקורית אותה כתבנו למעלה לא היה u- וזה נכון, מכיוון שאתם לא חייבים להוסיף אותה. ה u- תשמור את השם והענף של ה remote כדי שפעם באה שתרצו לדחוף קוד לשרת תוכלו לכתוב רק `git push` (ללא שם ה remote והענף).

 

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

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

שאלות

  1. נוסף קובץ חדש לאתר, כתבו פקודה שתראה לכם את כל השינויים שהיו מאז ה commit האחרון.
  2. ישנו קובץ חדש בשם contactPage.html, הוסיפו אותו לאזור ההיערכות .
  3. חבר שלכם לצוות עצר ליד העמדה שלכם ומעוניין לראות את הדף החדש, הראו לו.
  4. חכו! חבר שלכם לצוות מעדכן אתכם שהלקוח בסוף אינו מעוניין בדף הזה, הורידו אותו אותו מאזור ההיערכות.
  5. ביצענו שינויים בדף הראשי, index.html, מכיוון שהמערכת כבר עוקבת אחרי הקובץ הזה, פשוט הוסיפו אותו שוב לאזור ההיערכות ובצעו לו commit (בפקודה אחת).
  6. אופס! שכחנו להוסיף עוד דף בשם map.html שה index מקשר אליו, והאמת שהוא צריך להיות באותו ה commit ביחד עם ה index.html. תקנו זאת (הדף חדש, המערכת אינה עוקבת אחריו).
  7. חכו רגע! החלק של ה map.html התבטל, החזירו אותו לאזור ההיערכות.
  8. עזבו, כל הפרויקט התבטל, בטלו את השינויים ב index.html ואת map.html.
  9. בכל זאת, משהו נשאר מהפרויקט, חבר שלכם לצוות שלח לכם את הכתובת של ה repo המרוחק (remote) והוא: git@example.com:example.git. הוסיפו את הכתובת ככתובת של ה origin במאגר.
  10. סיימתם להיום, נשאר רק לדחוף את הקוד ל remote repo (השתמשו ב u- בפקודה כדי שלא תצטרכו לכתוב את הכל שוב בפעם הבאה)..

תשובות

  1. הפקודה: git diff.
  2. הפקודה: git add contactPage.html.
  3. הפקודה: git diff -staged.
  4. הפקודה: git reset HEAD contactPage.html.
  5. הפקודה: ``“git commit -a -m “Modify index.html`.
  6. מכיוון שמהערכת אינה עוקבת אחרי הדף יש צורך קודם כל להוסיפו לאזור ההיערכות עם הפקודה: git add map.html. ונוסיף את הדף ל commit הקודם עם הפקודה: "git commit -amend -m "Modify index.html & add map.html.
  7. הפקודה: ^git reset -soft HEAD.
  8. הפקודה: git checkout - index.html map.html.
  9. הפקודה: git remote add origin git@example.com:example.git.
  10. הפקודה: git push -u origin master.

 

סיכום ביניים

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

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

 

שיתוף פעולה

URL

שיתוף פעולה בפרויקטים בין אנשים הוא דבר חשוב, הוא קורה כל הזמן, אם זה כצוות שעובד על אותו הפרויקט, ואם זה כפרויקט קוד פתוח שאנשים שונים תורמים חלקים שונים, מתקנים באגים וכד’. אז בואו נניח שבוב שעובד ביחד עם אליס בצוות, רוצה עותק של ה repo על מנת להתחיל לעבוד על פיצ’ר חדש בפרויקט. כיצד הוא יכול להשיג עותק כזה? פשוט לבצע שיבוט (clone) של ה repo. אם אתם משתמשים ב GitHub לדוגמה, גשו לעמוד של הפרויקט, ובחרו code, למטה קצת מעל ה “Download ZIP” יש קוביית טקסט שהכותרת שלה היא “HTTPS clone URL” (ניתן לראות דוגמה בתמונה משמאל). על מנת לשבט את ה repo אנחנו צריכים את הכתובת שלה, וזה מה שהשגנו כעת. בשביל לשבט נכתוב <git clone <URL (את ה URL ביחד עם הסוגרים המשולשים החליפו בכתובת של repo שהעתקתם).

הפקודה תיצור repo (מאגר) מקומי, אצלכם במחשב, בשם ה repo ממנו שיבטתם את הפרויקט (אם ברצונכם לשנות את השם של ה repo אתם יכולים להשתמש בפקודה git clone <URL> newName, בעצם פשוט עשו רווח אחרי ה url של ה repo אותו אתם משבטים וכתבו את השם שברצונכם לתת ל repo המשובט והמקומי שלכם).

ברגע שעשינו שיבוט (clone) ל repo. המערכת (git) עושה 3 דברים: הראשון – מורידה את כל ה repo לתיקייה במחשב שלכם (בשם ה repo ממנו שיבטתם או בשם שנתתם). השני – מוסיפה לפרויקט המקומי ששיבטנו, remote חדש בשם origin, שמצביע ל URL ממנו שיבטנו (זוכרים כיצד ניתן לבדוק את זה? ע”י הפקודה git remote -v). והשלישי – המערכת תגדיר את הענף הראשי (כנראה יהיה master) ותכוון את ה HEAD שלנו להיות ב commit האחרון.

New Branch

 

ענפים ומיזוגם

כעת, בוב מוכן לעבוד על הפיצ’ר החדש בפרויקט. כדי לעשות את זה, כדאי מאוד ליצור ענף (branch) חדש ולא לעבוד על אותו ענף שבו הפרויקט הראשי נמצא. יצירת ענף חדש (או אם תרצו ציר זמן חדש, שיוצא / מתפצל מהענף / ציר הזמן הנוכחי) (נקרא לו cat) מתבצעת ע”י הפקודה <git branch <nameOfBranch (ניסיתי לצייר בתמונה משמאל כיצד תראה יצירת הענף החדש (של בוב [: ), לאחר ה commit האחרון). אך אם נבדוק על איזה ענף אנחנו (עם הפקודה git branch), נראה שאנחנו (ה HEAD) עדיין בענף master. אז כדי לעבור לענף של ה cat נכתוב את הפקודה git checkout cat. כעת, אנחנו בעצם בציר זמן אחר, נוכל לעשות עם הפרויקט מה שאנחנו רוצים והשינויים ישמרו רק בענף cat. נוכל בכל רגע לעבור חזרה לענף(/ציר הזמן) של ה master ולראות את הפרויקט מזווית אחרת (ללא השינויים שעשינו, בנוסף, אם חברי הצוות עשו שינויים ובצעו commit לענף master, נוכל לסנכרן את הפרויקט (ע”י הפקודה git pull) ולראות את השינויים שלהם.

$ git branch cat
New Branch Commit

עכשיו כשאנחנו בענף cat, בואו ניצור קובץ txt חדש בשם cat.txt, ונכתוב בתוכו “schrodinger” (הרי החתול הזה צריך להיות שייך למישהו [; ), נוסיף אותו לאזור ההיערכות (עם הפקודה git add cat.txt), נבצע לו commit (עם הפקודה "git commit -m "Creat quantum cat). וה commit שביצענו כרגע, יתווסף לענף (/ציר הזמן) של ה cat (כי עליו ביצענו את ה commit).

עכשיו אם נכתוב בשורת הפקודה ls כדי לראות את הקבצים המופיעים בתיקייה שלנו, נראה את cat.txt, אך אם נעבור לענף הראשי (עם הפקודה: git checkout master, ונכתוב שוב ls לא נראה את הקובץ cat.txt, הוא פשוט לא קיים בענף / ציר הזמן הזה. גם אם נכתוב את הפקודה git log לא נראה את ה commit שבוצע ל cat.txt. רק כדי לבדוק שאנחנו לא משוגעים, נחזור לענף cat (בעזרת הפקודה git checkout cat, נכתוב ls ונראה את הקובץ cat.txt, גם אם נכתוב git log נראה את התיעוד של ה commit שביצענו.

Merge

 

בואו נניח שסיימנו לעשות את כל השינויים שרצינו בענף cat, ואנחנו רוצים לשלב את השינויים בפרויקט שבענף הראשי, master. אז נחזור לענף master עם הפקודה git checkout master ועכשיו כשה HEAD שלנו בענף master, נשלב לתוכו את הענף cat עם הפקודה git merge cat, ניתן לראות בתמונה משמאל הדגמה לאיך שיראו הענפים לאחר הרצת הפקודה. בנוסף, בפלט שנקבל יופיע המילים “Fast-forward”, מה זה בעצם אומר?

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

$ git merge cat
Updating 1191ceb..ab48a3f
Fast-forward
 cat.txt |    1 +
 1 file changed, 1 insertion(+)
 create mode 100644 cat.txt
Checkout to Branch Dog

 

כשסיימנו עם הענף (במקרה שלנו cat) אנחנו יכולים פשוט למחוק אותו עם הפקודה git branch -d cat. עכשיו בואו ניצור ענף (branch) חדש כדי לעבוד על פיצר שונה, נקרא לו dog, הפעם נשתמש בקיצור דרך הקיים כדי ליצור branch חדש ולעבור אליו ישר בפקודה אחת (במקום הפקודה git branch dog, ופקודה כדי לעבור אליו git checkout dog), נכתוב את הפקודה git checkout -b dog. נוסיף קובץ חדש בשם labrador.html (עם הפקודה git add dog/labrador.html, הנחנו שהוא בתיקייה dog בשביל דוגמה קצת יותר מורכבת) ונבצע לו commit. לאחר מכן נוסיף עוד קובץ חדש בשם germanShepherd.html (בעזרת הפקודה git add dog/germanShepherd.html) וגם לו נבצע commit. שימו לב בתמונה משמאל כיצד נראה ציר הזמן עכשיו (ה HEAD זז איתנו כל פעם שאנו מבצעים commit).

 

$ git checkout -b dog
Switched to a new branch 'dog'
...
$ git add dog/labrador.html
$ git commit -m 'Add Labrador'
...
$ git add dog/germanShepherd.html
$ git commit -m 'Add German Shepherd'
Fix Main JavaScript

אך באמצע שבוב עובד עם הענף dog, הוא מקבל sms מהבוס שיש באגים ב master, הם לא סובלים דיחוי וחייבים לתקן אותם במהרה. אז הוא עובר ל master (עם הפקודה git checkout master) (ניתן להריץ אח”כ git branch בשביל לוודא כי אכן עברנו ל master) לאחר מכן, בוב מושך מה remote repo (המאגר המרוחק) את המידע כדי לוודא שיש לו את הפרויקט העדכני (מי זוכר מתי פעם אחרונה הוא התעסק איתו ואם מישהו בצוות עשה שינויים מאז, עדייף להיות בטוחים מאשר להצטער) עם הפקודה git pull. שימו לב שכרגע החץ עם ה HEAD אמור להיות ב commit העדכני ביותר ב master, שלפי התמונה למעלה אמור להיות ה commit השני, ממש לפני הפיצול של dog.

 

בוב מתקן את מה שצריך לתקן, בוא נאמר main.js, ומבצע לו commit עם הפקודה ``“git commit -m “Fix main.jsודוחף את השינוי ל master ב remote (לענף master במאגר המרוחק) עם הפקודהgit push` (נניח וכבר ביצענו פעם commit עם u- כדי לשמור את הניתוב וכ’ו).

$ git checkout master
  Switched to branch 'master'
$ git branch
  admin
* master
$ git pull
...
$ git add main.js
$ git commit -m 'Fix man.js'
...
$ git push
Checkout to Branch Dog

עכשיו כשסיימנו לטפל במקרה החירום, הגיע הזמן לחזור לפרויקט שלנו בענף dog עם הפקודה git checkout dog, מסיימים את העבודה, ועוברים חזרה ל master (עם הפקודה git checkout master) כדי למזג את הפרויקט בעזרת הפקודה git merge dog. והפעם, בניגוד למיזוג עם cat, ביצענו שינויים ב master אחרי יצירת הענף החדש, dog, אז כשנמזג בין הענפים יפתח לנו עורך הנקרא VI (אם מוגדר עורך אחר כברירת מחדל הוא יפתח במקומו). העורך נראה כמו בתמונה למטה. בפתיחת העורך git אומרת לנו או קיי, עשיתי את ה commit הזה בשבילך כי אני רואה שאתה מנסה למזג בין 2 הענפים האלו, אך אם אתה צריך להיות ספציפי יותר, בבקשה תוסיף את זה להודעה שלמעלה (ניתן לראות שכתוב בה ‘Merge branch ‘dog). ניתן לערוך את ההודעה הזאת, וכשסיימנו נכתוב wq: (ה w מסמלת write וה q מסמלת quit) כדי לחזור חזרה לשורת הפקודה.

 

Recursive Merge
VI

מכיוון שמיזגנו שני ענפים עם שינויים בכל אחד מהם גיט מבצעת “מיזוג רקורסיבי” וכשזה קורה, גיט יוצרת commit בדיוק היכן שהענפים מתמזגים חזרה, לאחר מכן אם נכתוב git log נוכל לראות את ה commit שנוצר ע”י המערכת (git).

Merge made be 'recursive' strategy.
 0 files changed
 create mode 100644 dog/labrador.html
 create mode 100644 dig/germanShepherd.html

$ git log
commit 19f735c3556129279bb10a1447dc5aba1q1fa9
Merge: 5c9ed90 7980856
Aurthor: nirgn965 &lt;nirgn975@gmail.com&gt;
Date:   Thu May 12:17:51:53 2014 -0200

    Merge branch 'dog'

 

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

הגענו לחלק השני של השאלות והתשובות.

שאלות

  1. מחלקת ה IT ביצעה עדכונים למערכת ההפעלה בעמדה שלכם ומחקה את ההארד דיסק תוך כדי העדכון. שבטו (העתיקו) את ה repo של הפרויקט (נקרא לו blabla) מהכתובת https://github.com/nirgn975/blabla.git.
  2. על הדרך, תבדקו את רשימת ה remote שה repo שלנו מכיר.
  3. אנחנו צריכים להוסיף פיצ’ר חדש לפרויקט, יש לבנות אותו לפני על ענף נפרד, צרו ענף חדש בשם newBla.
  4. החליפו ענף לענף שזה עתה יצרנו.
  5. סיימנו לבצע את כל העבודה על הענף newBla, כעת אנחנו מוכנים למזג בין הענף הנל לראשי (master), בצעו זאת.
  6. כעת, צרו עוד ענף (בשביל פיצ’ר אחר וחדש) ועברו לאותו הענף (נקרא לו fin) בפקודה אחת בלבד.

תשובות

  1. הפקודה: git clone https://github.com/nirgn975/blabla.git.
  2. הפקודה: git remote -v.
  3. הפקודה: git branch newBla.
  4. הפקודה: git checkout newBla.
  5. ראשית נחזור לענף master עם הפקודה: git checkout master, ולאחר מכן נמזג עם הפקודה git marge newBla.
  6. הפקודה: git checkout -b fin.

 

סיכום

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