דלגו לתוכן

Git — סנכרון מול GitLab

לבדוק אם ה-clone שלי ישן (fetch)

Section titled “לבדוק אם ה-clone שלי ישן (fetch)”

git fetch מוריד commits ומעדכן את origin/* בלי לגעת בקבצים שלך. בטוח תמיד.

runs on: any shell
git fetch
git status -sb
git log --oneline HEAD..origin/main
git 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”
runs on: any shell
git pull

אם הוא מסרב: git stash, git pull, git stash pop (ראה undo).

פקודהמה עושהמתי
git fetchמוריד, מעדכן origin/*, לא נוגע בקבציםלהסתכל לפני החלטה
git pullfetch + merge לתוך ה-branch הנוכחיברירת מחדל כשהכול נקי
git merge --ff-only origin/mainמתקדם רק אם אפשר "להזיז מצביע"; אחרת נכשלכשרוצים בדיקה שאין התפצלות
git pull --rebasefetch + הצבת ה-commits המקומיים מעל ה-remoteכשיש commit מקומי ורוצים היסטוריה ישרה

הגדרה קבועה שמונעת merge commits בטעות: git config --global pull.ff only.

הסימפטום: fatal: Not possible to fast-forward, aborting. או Your branch and 'origin/main' have diverged.

runs on: any shell
git fetch
git status -sb
git log --oneline --graph --all -10
git log --oneline origin/main..HEAD
git log --oneline HEAD..origin/main

origin/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
runs on: any shell
git branch backup
git 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)”
runs on: any shell
! [rejected] main -> main (non-fast-forward)
hint: Updates were rejected because the tip of your current branch is behind

פירוש: ב-GitLab יש commits שאין אצלך. לא לתקן עם --force. משוך, ואז דחוף:

runs on: any shell
git pull --rebase
git 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 שדחפת):

runs on: any shell
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)”
runs on: any shell
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)”
runs on: any shell
git fetch
git status -sb
git ls-remote origin <BRANCH>
git rev-parse HEAD

איך מוודאים: ה-sha מ-ls-remote זהה ל-git rev-parse HEAD, ואין ahead ב-status.

שימושכתובת
clone ידני עם keygit@<GITLAB_HOST>:<GROUP>/<REPO>.git
CI / Argo עם tokenhttps://oauth2:${TRIDENT_GIT_TOKEN}@<GITLAB_HOST>/<GROUP>/<REPO>.git (ה-token ממשתנה CI, אף פעם לא ערך גלוי)

פירוט ב-ssh. לשנות כתובת של remote קיים: git remote set-url origin git@<GITLAB_HOST>:<GROUP>/<REPO>.git.