Skip to content

עצי עבודה של Git לעבודה על כמה ענפים במקביל

עצי עבודה של Git לעבודה על כמה ענפים במקביל

המקור באנגלית פורסם ב־2026-05-16T20:16:22.751+03:00. המאמר המקורי באנגלית

מהדורה לימודית מתוקנת. תאריך הבדיקה הטכנית מול מקורות ראשוניים: 2026-10-28. דוגמאות הקוד לא הודרו ולא נבדקו בזמן ריצה. תאריך הפרסום המקורי באנגלית נשמר; המהדורה בעברית משתמשת בתאריך הפרסום שלה בפועל, ולא בתאריך המקור באנגלית.

עצי עבודה של Git

עבודה על כמה ענפים
בו־זמנית

git worktree add ../feature

הקשרים המוצגים בתרשים
  • main
    • feature-auth
    • hotfix-ssl

תכונת Git מתקדמת · פיתוח מקביל · הפרדת ענפים

התרשים המקורי (רשות, מוגדל)

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

עצי עבודה של Git לעבודה על כמה ענפים במקביל

התרשים המקורי באנגלית

🌿 תכונות מתקדמות של Git

עצי עבודה של Git

עבודה על כמה ענפים בתיקיות נפרדות, תוך צמצום הצורך ב־stash או בהחלפת עותק העבודה הנוכחי מקור

N+1
ענפים
בו־זמנית
פחות
פעולות
stash
משותפת
היסטוריית .git
בין עצי העבודה
מובנה
בליבת Git
מאז גרסה 2.5

מבוא: הבעיה שעצי עבודה של Git פותרים

תרחיש נפוץ הוא עבודה באמצע מימוש תכונה בענף feature/auth-refactor, ופתאום מגיעה הודעה: ״תקלה קריטית בסביבת הייצור, צריך תיקון בדחיפות!״ עומדות בפניכם שתי אפשרויות:

  1. לשמור את השינויים ב־stash, להחליף ענף, לתקן את התקלה, ליצור commit, לדחוף, לחזור לענף המקורי ולשלוף את ה־stash, בתקווה שלא יהיו התנגשויות
  2. לשכפל שוב את המאגר כולו לתיקייה שנייה ולעבוד במקביל

שתי האפשרויות מסורבלות. עצי עבודה של Git מספקים פתרון מובנה ונוח: אפשר לבצע checkout לכמה ענפים בו־זמנית בתיקיות נפרדות, החולקות את אותו מאגר .git ואת אותה היסטוריה.

🗂️ איך פועלים עצי עבודה

📁
my-repo/ (main)
.git/ ← ההיסטוריה המלאה
src/
package.json
ענף: main
←
📁
my-repo-hotfix/
.git ← קישור ל־.git הראשי
src/ (גרסאות התיקון הדחוף)
ענף: hotfix/critical-fix
📁
my-repo-feature/
.git ← קישור ל־.git הראשי
src/ (גרסאות התכונה)
ענף: feature/new-ui

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

פקודות בסיסיות

מנהלים עצי עבודה באמצעות פקודות git worktree. אלה הפקודות העיקריות:

bash: פקודות git worktree חיוניות
# Illustrative commands: not executed or runtime-tested.
# Choose one operation at a time in an authorized test repository.
# Existing branch (must not already be checked out elsewhere):
git worktree add ../my-repo-hotfix hotfix/critical-bug

# Or create a different worktree and a new branch from local main:
git worktree add -b feature/new-payment ../my-repo-payment main

# Detached review of a real commit; replace COMMIT_SHA with a verified hash:
git worktree add --detach ../my-repo-review COMMIT_SHA

# Inspect registered worktrees:
git worktree list
# Illustrative paths/commit abbreviations, not actual command output:
# /home/example/my-repo          a1b2c3d [main]
# /home/example/my-repo-hotfix   b2c3d4e [hotfix/critical-bug]

# Inspect and preserve work before removal; run outside the target directory:
git -C ../my-repo-hotfix status --short
git worktree remove ../my-repo-hotfix
# If removal refuses, inspect the cause. Do not add --force automatically.

# Preview stale administrative records, then prune only after inspection:
git worktree prune --dry-run
# git worktree prune

# Alternative operation for a STILL-EXISTING worktree (not after removing it):
# Ensure the destination parent exists and the target is not in use.
# git worktree move ../my-repo-hotfix ../archives/hotfix-example

דוגמה מעשית: תיקון דחוף בלי לפגוע בעבודה על תכונה

bash: תהליך מלא לתיקון דחוף באמצעות עצי עבודה
# Bash workflow outline; runtime-untested, not a single paste-and-run script.
# Begin in the feature worktree; choose unused absolute paths.
cd "$HOME/my-repo" || exit 1
repo=$(git rev-parse --show-toplevel) || exit 1
hotfix="$HOME/my-repo-hotfix"
# local main must be an appropriate, verified base for this fix.
git worktree add -b hotfix/login-null-check "$hotfix" main || exit 1
cd "$hotfix" || exit 1

# Edit only the intended file, inspect, then commit and push when authorized:
vim src/auth/login.ts
git diff -- src/auth/login.ts
git add -- src/auth/login.ts
git commit -m "fix: handle null user on login redirect"
git push origin hotfix/login-null-check

# STOP: create/review/merge the PR through the repository's normal process.
# Do not additionally merge or push main locally after a remote PR merge.
# Only after confirming the PR is merged and the hotfix worktree is no longer needed:
cd "$repo" || exit 1
git -C "$hotfix" status --short
git worktree remove "$hotfix"  # refuses unsafe removal; inspect any refusal
# Optional: after verifying reachability of its commits in the relevant branch:
# git branch -d hotfix/login-null-check
# A squash/rebase merge may cause -d to refuse. Do not force-delete blindly.
# The original feature worktree was not switched or reset.

שימוש מתקדם: CI/CD, סקירות קוד ובדיקות מקבילות

bash: דפוסי שימוש מתקדמים
# Independent Bash patterns; all runtime-untested.
# Trusted repository code only: tests/builds can execute scripts.
repo=$(git rev-parse --show-toplevel) || exit 1

# Pattern 1: review a verified remote-tracking ref without checking out its branch.
# Refresh the intended ref separately if needed; use a unique unused path.
git worktree add --detach /tmp/review-pr-example origin/feature/payment-v2
# Inspect code first; only run it if trusted and authorized.
# Return outside the review tree before cleanup:
cd "$repo" || exit 1
git worktree remove /tmp/review-pr-example

# Pattern 2: detached checkout avoids main already checked out elsewhere.
git worktree add --detach /tmp/test-main-example main
# Prepare dependencies separately; use separate ports/databases for concurrent tests.
(cd /tmp/test-main-example && npm test) &
first=$!
(cd "$repo" && npm test) &
second=$!
wait "$first"; first_status=$?
wait "$second"; second_status=$?
printf 'Test exit statuses: %s %s\n' "$first_status" "$second_status"
# Inspect generated files before a separate cleanup step; never force-remove.

# Pattern 3: release branches must exist and not be checked out elsewhere.
git worktree add "$HOME/releases/v2.1" release/2.1
git worktree add "$HOME/releases/v2.0" release/2.0
patch_file="$HOME/patches/example-reviewed-fix.patch"  # illustrative, not a CVE
# Review the patch and changed files in EACH tree; commit only intended paths.
git -C "$HOME/releases/v2.1" apply --check "$patch_file"
git -C "$HOME/releases/v2.1" apply "$patch_file"
git -C "$HOME/releases/v2.1" diff
# Repeat review/apply explicitly for v2.0; then stage specific files and commit.

# Pattern 4: separate CI script, run only with a verified CI_COMMIT_SHA.
# Generated/untracked files may make cleanup refuse; preserve and inspect them.
ci_worktree_build() (
  repo=$(git rev-parse --show-toplevel) || exit 1
  : "${CI_COMMIT_SHA:?Set a verified commit hash}"
  build_dir=$(mktemp -d "${TMPDIR:-/tmp}/ci-worktree.XXXXXX") || exit 1
  git worktree add --detach "$build_dir" "$CI_COMMIT_SHA" || exit 1
  cleanup() {
    cd "$repo" || return
    git worktree remove "$build_dir" ||
      printf 'Cleanup refused; inspect retained worktree: %s\n' "$build_dir" >&2
  }
  trap cleanup EXIT
  cd "$build_dir" || exit 1
  npm ci && npm run build && npm test
)
# Calling ci_worktree_build executes repository scripts; not called here.

⚠️ כללים ומגבלות חשובים

🚫 אין לבצע checkout כפול

בדרך כלל Git מונע ביצוע checkout של אותו ענף בשני עצי עבודה בו־זמנית. כך נמנעים עדכונים מתנגשים של אותו ענף. הודעת השגיאה הרגילה היא: fatal: 'feature/x' is already checked out מקור

📦 מאגר אובייקטים משותף

כל עצי העבודה חולקים מסד אובייקטים אחד של .git. פעולות Git כמו fetch, log ו־blame יכולות לגשת להיסטוריה המשותפת, אך חלק מההפניות נפרדות לכל עץ. פקודות שבוחנות את קובצי העבודה או את האינדקס עשויות להחזיר תוצאות שונות. מקור

🔧 תמיכה בסביבות פיתוח

פתחו כל תיקייה כפרויקט נפרד בעורך. פרטי השילוב תלויים בעורך ובגרסה, ולכן יש לבדוק את התצורה שלכם. ב־VS Code, Remote - Containers הוא שם ישן של הרחבה; שם המוצר הנוכחי הוא Dev Containers. יש לבדוק את התנהגות הקונטיינר ועץ העבודה בתצורה שנבחרה. מקור

💾 נפח אחסון

עצי עבודה אינם משכפלים את תיקיית האובייקטים של .git, אך כל עץ זקוק לקובצי העבודה שלו ועשויים להיות בו תלויות ותוצרי בנייה נפרדים. הנפח הנוסף תלוי במאגר ובכלים; דוגמת 500MB ו־100–200MB במקור לא הייתה תוצאת מדידה. מקור

עצי עבודה לעומת החלופות

⚖️ השוואה בין עצי עבודה לגישות אחרות

גישה החלפת הקשר נפח אחסון עבודה מקבילה מתאים במיוחד ל־
git worktreeללא החלפת עותק העבודה הנוכחיאובייקטים משותפים וקבצים נוספים✅ עבודה מקבילה אמיתיתמשימות מקבילות באותו מאגר
git stash⚠️ מעבר מלאללא עותק עבודה שני❌ עבודה סדרתית בלבדצורך קצר וזמני
שכפול שניעותק עבודה נפרדאחסון מאגר נפרד✅ עבודה מקבילה אמיתיתניסויים מבודדים
commit זמני של עבודה ומעבר ענף⚠️ מעבר מלאללא עותק עבודה שני❌ עבודה סדרתית בלבדכאשר stash אינו פתרון נקי

כתיבת סקריפטים לעבודה יעילה עם עצי עבודה

bash: פונקציות עזר במעטפת לעצי עבודה
# Bash-only educational helpers; runtime-untested.
# Review before adding to shell configuration. No settings changed by this article.
gwt-review() {
  local branch="$1" repo dir
  repo=$(git rev-parse --show-toplevel) || return
  git check-ref-format --branch "$branch" >/dev/null || return
  git fetch origin "refs/heads/$branch" || return
  dir=$(mktemp -d "${TMPDIR:-/tmp}/review-worktree.XXXXXX") || return
  git worktree add --detach "$dir" FETCH_HEAD || return
  printf 'Reviewing at: %s\n' "$dir"
  cd "$dir" || return
}

gwt-add() {
  local branch="$1" repo repo_name short_branch dir
  repo=$(git rev-parse --show-toplevel) || return
  git check-ref-format --branch "$branch" >/dev/null || return
  repo_name=$(basename "$repo")
  short_branch=$(printf '%s' "$branch" | sed 's/[/:]/-/g')
  dir="$(dirname "$repo")/${repo_name}-${short_branch}"
  # main must exist; existing branch/path names intentionally cause refusal.
  git worktree add -b "$branch" "$dir" main || return
  printf 'Worktree at: %s\n' "$dir"
  cd "$dir" || return
}

gwt-list() {
  # Use Git's own path-safe human output rather than fragile awk parsing.
  git worktree list
}

gwt-clean-reviews() {
  # Inventory only. No bulk deletion from parsed text or global wildcard paths.
  git worktree list
  printf '%s\n' 'Inspect one exact review path, leave it, then use git worktree remove PATH.'
}

עצי עבודה במאגרי monorepo ועם Node.js/npm

bash: טיפול ב־node_modules בעצי עבודה
# Alternative package-manager examples, not consecutive steps.
# Dependencies and lifecycle scripts can execute code; trusted projects only.

# npm option: create the worktree once at an unused path.
git worktree add ../my-repo-feature feature/new-ui
(cd ../my-repo-feature && npm ci)

# pnpm ALTERNATIVE, after creating a suitable worktree once:
# (cd ../my-repo-feature && pnpm install --frozen-lockfile)
# Select the manager matching the repository lockfile and supported version.
# Caches/stores may reuse downloaded content, but install time is workload-specific.
# Each worktree can have separate node_modules and build outputs.

# In the repository's .gitignore, an in-tree rule may be appropriate:
# node_modules/
# Do NOT put ../*-worktree/ or sibling paths in this repository's .gitignore:
# ignore rules cannot match files outside the repository working tree.

💡 שיטות עבודה ועצות שימושיות

📂 מוסכמת שמות
השתמשו בשמות תיאוריים: ../repo-hotfix, ../repo-review-123, ../repo-release-2.1. כך הפלט של gwt-list יהיה קריא.
🧹 ניקוי תקופתי
הריצו git worktree prune רק לאחר בדיקת הפלט של הרצת dry-run, כדי להסיר רשומות מנהליות לא תקפות ולא קובצי עבודה. קובץ בשם ~/.gitignore אינו קובץ התעלמות גלובלי אוטומטי, אלא אם core.excludesFile מפנה אליו. קובץ .gitignore של מאגר אינו יכול להתעלם מעצי עבודה אחים שנמצאים מחוץ למאגר. מקור1 מקור2
🔗 שילוב בסביבת הפיתוח
פתחו כל עץ עבודה בחלון VS Code נפרד באמצעות code /path/to/worktree, או השתמשו ב־״Open Directory״ של JetBrains כדי לפתוח סביבות פיתוח מקבילות לאותו בסיס קוד.
📍 בחירת מיקום
שמרו עצי עבודה אחים לצד המאגר הראשי: ~/projects/my-repo ← ~/projects/my-repo-hotfix. כך נמנעים מקינון עמוק ושומרים עבודה קשורה קרובה זו לזו.

סיכום

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

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

כל דוגמאות המעטפת לא נבדקו בזמן ריצה ויש להתאימן במאגר בדיקה מורשה. יצירת עצי עבודה, commits ודחיפות משנה מצב; התקנת תלויות ובדיקות עלולות להריץ קוד מהמאגר. שום דוגמה לא הורצה. הסרה כפויה הוסרה מפני שהיא עלולה למחוק קבצים שלא נשמרו ב־commit. יש לנקות מתוך תיקייה שמחוץ לעץ היעד ולעצור אם Git מסרב; בדקו ושמרו קבצים במקום להוסיף ‎--force. שמות הענפים, הגיבובים והטלאים הם להמחשה, לא הודעות אבטחה אמיתיות.

מקורות לתיקונים

Post a Comment

Previous Post Next Post