Git — סנכרון מול GitLab
לבדוק אם ה-clone שלי ישן (fetch)
Section titled “לבדוק אם ה-clone שלי ישן (fetch)”git fetch מוריד commits ומעדכן את origin/* בלי לגעת בקבצים שלך. בטוח תמיד.
git fetchgit status -sbgit log --oneline HEAD..origin/maingit rev-list --left-right --count HEAD...origin/mainהפלט של rev-list: שני מספרים, <ahead> <behind>. 0 1 = יש commit אחד ב-remote שאין אצלך. 1 1 = התפצלות.
איך מוודאים: ## main...origin/main [behind 1] ב-status -sb, והשורה HEAD..origin/main מציגה את ה-commit של ה-CI.
למשוך שינויים לפני עריכה: pull
Section titled “למשוך שינויים לפני עריכה: pull”git pullאם הוא מסרב: git stash, git pull, git stash pop (ראה undo).
טבלה: fetch, pull ו-merge --ff-only
Section titled “טבלה: fetch, pull ו-merge --ff-only”| פקודה | מה עושה | מתי |
|---|---|---|
git fetch | מוריד, מעדכן origin/*, לא נוגע בקבצים | להסתכל לפני החלטה |
git pull | fetch + merge לתוך ה-branch הנוכחי | ברירת מחדל כשהכול נקי |
git merge --ff-only origin/main | מתקדם רק אם אפשר "להזיז מצביע"; אחרת נכשל | כשרוצים בדיקה שאין התפצלות |
git pull --rebase | fetch + הצבת ה-commits המקומיים מעל ה-remote | כשיש commit מקומי ורוצים היסטוריה ישרה |
הגדרה קבועה שמונעת merge commits בטעות: git config --global pull.ff only.
merge --ff-only נכשל (diverged)
Section titled “merge --ff-only נכשל (diverged)”הסימפטום: fatal: Not possible to fast-forward, aborting. או Your branch and 'origin/main' have diverged.
git fetchgit status -sbgit log --oneline --graph --all -10git log --oneline origin/main..HEADgit log --oneline HEAD..origin/mainorigin/main..HEAD = commits שלך שלא נדחפו. HEAD..origin/main = commits שלהם שלא משכת. הסיבה כתובה בפלט של git עצמו (שורה 2 של status: have 1 and 1 different commits each).
אפשרויות הטיפול, לפי מה שרואים ב-origin/main..HEAD:
| המצב | הפעולה |
|---|---|
| ה-commit התועה לא נחוץ | git reset --hard origin/main (ראה סכנה למטה) |
| ה-commit שלך נחוץ | git pull --rebase, ואז git push |
| רוצה לשמור אותו בצד | git branch backup לפני כל reset |
git branch backupgit reset --hard origin/mainאיך מוודאים: git status -sb מציג ## main...origin/main נקי, git log --oneline -3 זהה ל-GitLab.
ה-push נדחה: rejected (non-fast-forward)
Section titled “ה-push נדחה: rejected (non-fast-forward)” ! [rejected] main -> main (non-fast-forward)hint: Updates were rejected because the tip of your current branch is behindפירוש: ב-GitLab יש commits שאין אצלך. לא לתקן עם --force. משוך, ואז דחוף:
git pull --rebasegit push--rebase מניח את ה-commits שלך מעל מה ש-CI כתב. אם יש קונפליקט: תקן את הקבצים, git add <FILE>, git rebase --continue. לוותר: git rebase --abort.
איך מוודאים: git push מסתיים ב-main -> main ללא rejected, ו-git status -sb נקי.
למה אסור --force כאן (ומה זה --force-with-lease)
Section titled “למה אסור --force כאן (ומה זה --force-with-lease)”אם באמת חייבים לשכתב branch שלך (למשל אחרי commit --amend על branch שדחפת):
git push --force-with-lease origin <BRANCH>--force-with-lease נכשל אם מישהו (כמו ה-CI) דחף מאז ה-fetch האחרון שלך. שימוש: רק על branch פרטי, אף פעם על main של gitops. protected branch ב-GitLab ממילא חוסם force.
לדחוף branch ספציפי או commit ספציפי (HEAD:main)
Section titled “לדחוף branch ספציפי או commit ספציפי (HEAD:main)”git push origin <BRANCH>git push origin HEAD:<BRANCH>git push origin <SHA>:refs/heads/<BRANCH>השורה השלישית דוחפת commit נתון כ-branch חדש. מצב detached HEAD (undo) דוחפים רק עם HEAD:<BRANCH>.
לוודא ש-GitLab באמת קיבל (unpushed = invisible)
Section titled “לוודא ש-GitLab באמת קיבל (unpushed = invisible)”git fetchgit status -sbgit ls-remote origin <BRANCH>git rev-parse HEADאיך מוודאים: ה-sha מ-ls-remote זהה ל-git rev-parse HEAD, ואין ahead ב-status.
כתובות: SSH מול HTTPS
Section titled “כתובות: SSH מול HTTPS”| שימוש | כתובת |
|---|---|
| clone ידני עם key | git@<GITLAB_HOST>:<GROUP>/<REPO>.git |
| CI / Argo עם token | https://oauth2:${TRIDENT_GIT_TOKEN}@<GITLAB_HOST>/<GROUP>/<REPO>.git (ה-token ממשתנה CI, אף פעם לא ערך גלוי) |
פירוט ב-ssh. לשנות כתובת של remote קיים: git remote set-url origin git@<GITLAB_HOST>:<GROUP>/<REPO>.git.