עבודה עם מספר מאגרים מרוחקים ב Git במקביל

19/09/2020
git

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

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

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

1. ה Setup

בשביל הדוגמה ניקח את גיטהאב בתור השרת שלנו ונבנה שני פרויקטים: אקרא לראשון multiple-repos-demo-1 ולשני multiple-repos-demo-2. אצלי במשתמש אלה הלינקים לפרויקטים:

  1. https://github.com/ynonp/multiple-repos-demo-1

  2. https://github.com/ynonp/multiple-repos-demo-2

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

git clone git@github.com:ynonp/multiple-repos-demo-1.git
cd multiple-repos-demo-1
echo 'print("Hello world")' > app.py

git add .
git commit -m 'initial commit'
git push

2. עבודה עם מספר מאגרים מרוחקים

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

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

git remote -v
origin  git@github.com:ynonp/multiple-repos-demo-1.git (fetch)
origin  git@github.com:ynonp/multiple-repos-demo-1.git (push)

קל לראות שהפרויקט שלי מחובר למאגר יחיד ובצד שמאל המילה origin מציינת את שם המאגר המרוחק.

נחבר את המאגר השני עם הפקודה:

git remote add secondary git@github.com:ynonp/multiple-repos-demo-2.git

ונוודא שהכל הצליח עם:

git remote -v
origin  git@github.com:ynonp/multiple-repos-demo-1.git (fetch)
origin  git@github.com:ynonp/multiple-repos-demo-1.git (push)
secondary       git@github.com:ynonp/multiple-repos-demo-2.git (fetch)
secondary       git@github.com:ynonp/multiple-repos-demo-2.git (push)

בשביל לדחוף את הקומיט למאגר השני אני יכול להשתמש פשוט ב push:

git push secondary master

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

3. מה עושים כשהמאגר השני התעדכן

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

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

git clone git@github.com:ynonp/multiple-repos-demo-2.git
cd multiple-repos-demo-2
echo new file > readme.md
git add .
git commit -m 'add new file'
git push

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

git log

commit 0d44abd1fefc5ffcaf853ba76abbf909abde7511 (HEAD -> master, secondary/master, origin/master)
Author: ynonp <ynonperek@gmail.com>
Date:   Fri Sep 18 10:58:46 2020 +0300

    initial commit

בשביל לקחת את הקומיט מהמאגר השני אני יוצר ענף מקומי שיעקוב אחר הענף master מהמאגר השני:

git checkout -b secondary-master --track secondary/master

והפלט:

Branch 'secondary-master' set up to track remote branch 'master' from 'secondary'.
Switched to a new branch 'secondary-master'

עכשיו נשים לב ל git log:

git log

commit 0d44abd1fefc5ffcaf853ba76abbf909abde7511 (HEAD -> secondary-master, secondary/master, origin/master, master)
Author: ynonp <ynonperek@gmail.com>
Date:   Fri Sep 18 10:58:46 2020 +0300

    initial commit

מה קורה כאן? אני רואה שיש לי ענף חדש שעוקב אחר secondary/master, אבל נראה כאילו יש בו רק קומיט אחד.

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

git pull secondary

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

git log

commit 8ebd0fca5eb2e6482d740518a8dc90e6c5288ba5 (HEAD -> secondary-master, secondary/master)
Author: ynonp <ynonperek@gmail.com>
Date:   Fri Sep 18 11:09:29 2020 +0300

    add new file

commit 0d44abd1fefc5ffcaf853ba76abbf909abde7511 (origin/master, master)
Author: ynonp <ynonperek@gmail.com>
Date:   Fri Sep 18 10:58:46 2020 +0300

    initial commit

ויכול לחזור לענף הראשי שלי כדי למזג אותו ואז לדחוף אותו למאגר הראשון:

git checkout master

Switched to branch 'master'
Your branch is up to date with 'origin/master'.

git merge secondary-master

Updating 0d44abd..8ebd0fc
Fast-forward
 readme.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 readme.md

git push origin

Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 277 bytes | 277.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:ynonp/multiple-repos-demo-1.git
   0d44abd..8ebd0fc  master -> master

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

בהמשך כדי לקבל עדכונים ממאגר origin אני משתמש ב pull על ענף master שלי, ובשביל לקבל עדכונים ממאגר secondary אני משתמש ב pull על ענף secondary-master שלי.

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