כאשר אתה לומד לקודד, במוקדם או במאוחר תלמד גם על מערכות בקרת גרסאות. ולמרות שישנם כלים מתחרים רבים במרחב זה, אחד מהם הוא הסטנדרט בפועל המשמש כמעט את כולם בענף. זה כל כך פופולרי שיש חברות שמשתמשות בשמו במיתוג שלהן. אנחנו מדברים כמובן על גיט.
בעוד ש- Git הוא כלי רב עוצמה, כוחו מוסתר היטב. ישנם כמה מושגים חיוניים שעליך להבין כדי להיות בקיאים באמת ב- Git. החדשות הטובות הן שברגע שתלמד אותם, כמעט ולא תיתקל בצרות שלא תוכל להימלט מהן.
זרימת העבודה האופיינית
בתהליך עבודה טיפוסי של Git תשתמש במאגר מקומי, במאגר מרוחק ובענף אחד או יותר. מאגרים מאחסנים את כל המידע על הפרויקט, כולל כל ההיסטוריה שלו וכל הסניפים. סניף הוא בעצם אוסף של שינויים המובילים מפרויקט ריק למצב הנוכחי.
לאחר שיבוט מאגר, אתה עובד על העותק המקומי שלך ומציג שינויים חדשים. עד שתדחוף שינויים מקומיים במאגר המרוחק, כל עבודתך זמינה רק במחשב שלך.
כשתסיים משימה, הגיע הזמן לסנכרן עם המאגר המרוחק. אתה רוצה למשוך את השינויים המרוחקים כדי לעמוד בקצב ההתקדמות של הפרויקט, ואתה רוצה לדחוף את השינויים המקומיים כדי לחלוק את עבודתך עם אחרים.
שינויים מקומיים
הכל בסדר כאשר אתה ושאר הצוות שלך עובדים על קבצים נפרדים לחלוטין. מה שלא יקרה, אתם לא תדרכו זה על זה.
עם זאת, ישנם מקרים בהם אתה וחבריך לקבוצה מציגים בו זמנית שינויים באותו מקום. וכאן בדרך כלל מתחילות הבעיות.
האם אי פעם הוצאת להורג git pull
רק כדי לראות את החששים error: Your local changes to the following files would be overwritten by merge:
? במוקדם או במאוחר, כולם נתקלים בבעיה זו.
מה שמבלבל יותר כאן הוא שאתה לא רוצה למזג שום דבר, פשוט למשוך, נכון? למעשה, משיכה היא קצת יותר מסובכת ממה שחשבתם.
כמה בדיוק עובד Git Pull?
משיכה אינה פעולה אחת. הוא מורכב מאיסוף נתונים מהשרת המרוחק ואז מיזוג השינויים עם המאגר המקומי. ניתן לבצע שתי פעולות אלה באופן ידני אם תרצה:
git fetch git merge origin/$CURRENT_BRANCH
origin/$CURRENT_BRANCH
חלק אמצעי זה:
- Git ימזג את השינויים מהמאגר המרוחק ששמו
origin
(זה ששכחת ממנו) - שנוספו ל
$CURRENT_BRANCH
- שלא נמצאים כבר בסניף המקומי שלך
מכיוון ש- Git מבצע מיזוגים רק כשאין שינויים לא מחויבים, כל פעם שאתה מריץ git pull
עם שינויים לא מחויבים עלול להכניס אותך לצרות. למרבה המזל, ישנן דרכים לצאת מהצרה בחתיכה אחת!

גישות שונות
כשיש לך שינויים מקומיים שלא התחייבת ועדיין ברצונך לשלוף גרסה חדשה מהשרת המרוחק, מקרה השימוש שלך נופל בדרך כלל לאחד מהתרחישים הבאים. אוֹ:
- לא אכפת לך מהשינויים המקומיים ורוצים להחליף אותם,
- אכפת לך מאוד מהשינויים והיית רוצה ליישם אותם לאחר השינויים מרחוק,
- אתה רוצה להוריד את השינויים המרוחקים אך עדיין לא להחיל אותם
כל אחת מהגישות דורשת פתרון אחר.
לא אכפת לך מהשינויים המקומיים
במקרה זה, אתה רק רוצה לבטל את כל השינויים המקומיים שאינם מחויבים. אולי שינית קובץ כדי להתנסות, אך אינך זקוק יותר לשינוי. כל מה שמעניין אותך זה להתעדכן במעלה הזרם.
פירוש הדבר שאתה מוסיף שלב נוסף בין אחזור השינויים המרוחקים למיזוג. שלב זה יאפס את הענף למצבו הלא שונה, וכך יאפשר git merge
לעבוד.
git fetch git reset --hard HEAD git merge origin/$CURRENT_BRANCH
אם אתה לא רוצה להקליד את שם הסניף בכל פעם שאתה מפעיל פקודה זו, Git יש קיצור דרך נחמד מצביע הסניף במעלה הזרם: @{u}
. ענף במעלה הזרם הוא הענף במאגר המרוחק שאליו אתה דוחף ומביא אליו.
כך ייראו הפקודות הנ"ל בקיצור הדרך:
git fetch git reset --hard HEAD git merge '@{u}'
אנו מצטטים את קיצור הדרך בדוגמה כדי למנוע מהקליפה לפרש אותה.
אכפת לך מאוד מהשינויים המקומיים
כאשר השינויים הלא מחויבים שלך הם משמעותיים עבורך, ישנן שתי אפשרויות. אתה יכול להתחייב עליהם ואז לבצע git pull
, או שאתה יכול לאחסן אותם.
Stashing פירושו לשים לרגע את השינויים כדי להחזיר אותם מאוחר יותר. ליתר דיוק, git stash
יוצר התחייבות שאינה נראית בסניף הנוכחי שלך, אך עדיין נגישה על ידי גיט.
כדי להחזיר את השינויים שנשמרו בסטאש האחרון, השתמש git stash pop
בפקודה. לאחר החלת השינויים המאוחסנים בהצלחה, פקודה זו גם מסירה את התחייבות הסטאש מכיוון שאינה נחוצה עוד.
זרימת העבודה יכולה להיראות כך:
git fetch git stash git merge '@{u}' git stash pop
כברירת מחדל, השינויים מהסטאש יהיו מבוימים. אם אתה רוצה לבטל אותם, השתמש בפקודה git restore --staged
(אם אתה משתמש ב- Git חדש מ- 2.25.0).
אתה רק רוצה להוריד את השינויים מרחוק
התרחיש האחרון שונה מעט מהקודמים. בואו נגיד שאתם בעיצומו של רפקטורינג מבולגן מאוד. לא לאבד את השינויים ולא לסגור אותם הם אופציה. עם זאת, אתה עדיין רוצה שיהיו לך את השינויים המרוחקים כדי להפעיל git diff
אותם.
כפי שבוודאי הבנתם, הורדת השינויים מרחוק אינה דורשת git pull
כלל! git fetch
זה בדיוק מספיק.
דבר אחד שיש לציין הוא כי כברירת מחדל, git fetch
יביא לך רק שינויים מהסניף הנוכחי. כדי לקבל את כל השינויים מכל הסניפים, השתמש git fetch --all
. ואם תרצו לנקות חלק מהסניפים שכבר אינם קיימים במאגר המרוחק, git fetch --all --prune
יעשו את הניקוי!

קצת אוטומציה
שמעתם על גיט קונפיג? זהו קובץ שבו Git מאחסן את כל ההגדרות שהוגדרו על ידי המשתמש. הוא נמצא בספריית הבית שלך: כמו ~/.gitconfig
או ~/.config/git/config
. אתה יכול לערוך אותו כדי להוסיף כמה כינויים מותאמים אישית שיובנו כפקודות Git.
לדוגמה, כדי שיהיה לך קיצור מקביל ל git diff --cached
(שמראה את ההבדל בין הענף הנוכחי לקבצים המבוימים), הוסף את החלק הבא:
[alias] dc = diff --cached
After that, you can run git dc
whenever you wish to review the changes. Going this way, we can set up a few aliases related to the previous use cases.
[alias] pull_force = !"git fetch --all; git reset --hard HEAD; git merge @{u}" pf = pull_force pull_stash = !"git fetch --all; git stash; git merge @{u}; git stash pop"
This way, running git pull_force
will overwrite the local changes, while git pull_stash
will preserve them.
The Other Git Pull Force
Curious minds may have already discovered that there is such a thing as git pull --force
. However, this is a very different beast to what's presented in this article.
It may sound like something that would help us overwrite local changes. Instead, it lets us fetch the changes from one remote branch to a different local branch. git pull --force
only modifies the behavior of the fetching part. It is therefore equivalent to git fetch --force
.
Like git push
, git fetch
allows us to specify which local and remote branch do we want to operate on. git fetch origin/feature-1:my-feature
will mean that the changes in the feature-1
branch from the remote repository will end up visible on the local branch my-feature
. When such an operation modifies the existing history, it is not permitted by Git without an explicit --force
parameter.
Just like git push --force
allows overwriting remote branches, git fetch --force
(or git pull --force
) allows overwriting local branches. It is always used with source and destination branches mentioned as parameters. An alternative approach to overwriting local changes using git --pull force
could be git pull --force "@{u}:HEAD"
.
Conclusion
העולם של גיט הוא עצום. מאמר זה כיסה רק אחד מההיבטים של תחזוקת המאגר: שילוב שינויים מרוחקים במאגר מקומי. אפילו התרחיש היומיומי הזה דרש מאיתנו להתבונן מעט יותר לעומק במנגנונים הפנימיים של כלי בקרת הגרסאות.
לימוד מקרי שימוש בפועל עוזר לך להבין טוב יותר כיצד Git עובד מתחת למכסה המנוע. זה, בתורו, יגרום לך להרגיש מוסמך בכל פעם שאתה מכניס את עצמך לצרות. כולנו עושים זאת מדי פעם.