کار با Remote و GitHub
حالا که Git محلی را یاد گرفتیم، وقت آن است که به دنیای متصل برویم. در این فصل یاد میگیریم چطور با GitHub کار کنیم: ساخت ریپازیتوری، اتصال SSH، push، pull، fetch و مفاهیم remote.
حالا که Git محلی را یاد گرفتیم، وقت آن است که به دنیای متصل برویم. در این فصل یاد میگیریم چطور با GitHub کار کنیم: ساخت ریپازیتوری، اتصال SSH، push، pull، fetch و مفاهیم remote.
Remote چیست؟
Remote نسخهای از ریپازیتوری شماست که جای دیگری نگهداری میشود – معمولاً روی GitHub، GitLab یا یک سرور.
┌─────────────────┐ ┌──────────────────┐
│ Local Repo │ ←────→ │ Remote Repo │
│ (your computer)│ │ (GitHub server) │
└─────────────────┘ └──────────────────┘
↑
git push / pull / fetch
یک پروژه میتواند چند remote داشته باشد. معمولترین نام: origin
ساخت ریپازیتوری در GitHub
روش ۱: ابتدا در GitHub، سپس clone
- به github.com بروید
- روی + در بالا سمت چپ → New repository
- Repository name:
todo-app - توضیحات (اختیاری)
- Public یا Private
- تیک Add a README file را بزنید
- Add .gitignore (Python، Node، …)
- Choose a license (MIT متداول)
- Create repository
# Clone روی سیستم خود
git clone https://github.com/USERNAME/todo-app.git
cd todo-app
# remote خودکار به نام origin اضافه میشود
git remote -v
# origin https://github.com/USERNAME/todo-app.git (fetch)
# origin https://github.com/USERNAME/todo-app.git (push)
روش ۲: اول local، بعد به GitHub
# شروع از پروژه local
mkdir my-project
cd my-project
git init
echo "# My Project" > README.md
git add .
git commit -m "Initial commit"
# در GitHub repo بسازید (بدون README و .gitignore - چون از قبل دارید)
# اضافه کردن remote
git remote add origin https://github.com/USERNAME/my-project.git
# تعیین branch اصلی
git branch -M main
# اولین push
git push -u origin main
احراز هویت با SSH Key
HTTPS هر بار password میخواهد. SSH key راحتتر و امنتر است:
۱. ساخت SSH key
# Linux/Mac/Git Bash در ویندوز
ssh-keygen -t ed25519 -C "you@example.com"
# اگر سیستم قدیمی است که ed25519 را پشتیبانی نمیکند:
ssh-keygen -t rsa -b 4096 -C "you@example.com"
# Enter file: (Enter بزنید برای پیشفرض ~/.ssh/id_ed25519)
# Enter passphrase: (میتوانید خالی بگذارید یا رمز اضافی بدهید)
۲. افزودن کلید به ssh-agent
# شروع agent
eval "$(ssh-agent -s)"
# افزودن کلید
ssh-add ~/.ssh/id_ed25519
۳. کپی کلید عمومی
# Linux
cat ~/.ssh/id_ed25519.pub
# سپس copy کنید
# Mac
pbcopy < ~/.ssh/id_ed25519.pub
# Windows (Git Bash)
clip < ~/.ssh/id_ed25519.pub
۴. افزودن به GitHub
- GitHub → Settings → SSH and GPG keys
- New SSH key
- Title: نام دستگاه (مثلاً “Work Laptop”)
- Key: کلید عمومی را paste کنید
- Add SSH key
۵. تست اتصال
ssh -T git@github.com
# Hi USERNAME! You've successfully authenticated, but GitHub does not provide shell access.
تغییر URL از HTTPS به SSH
# بررسی URL فعلی
git remote -v
# origin https://github.com/USERNAME/repo.git
# تغییر به SSH
git remote set-url origin git@github.com:USERNAME/repo.git
# تأیید
git remote -v
# origin git@github.com:USERNAME/repo.git
git clone – دانلود یک repository
# Clone از HTTPS
git clone https://github.com/django/django.git
# Clone از SSH
git clone git@github.com:django/django.git
# Clone با نام پوشه دیگر
git clone https://github.com/django/django.git my-django
# Clone فقط یک branch خاص
git clone --branch develop https://github.com/USER/repo.git
# Shallow clone (فقط commitهای اخیر - برای پروژههای بزرگ)
git clone --depth 1 https://github.com/torvalds/linux.git
# Clone یک ریپو با همه submoduleهایش
git clone --recurse-submodules https://github.com/USER/repo.git
دستورات Remote
# لیست remoteها
git remote
# origin
# با URL
git remote -v
# origin git@github.com:USER/repo.git (fetch)
# origin git@github.com:USER/repo.git (push)
# اطلاعات کامل یک remote
git remote show origin
# افزودن remote جدید
git remote add upstream https://github.com/ORIGINAL/repo.git
# تغییر URL
git remote set-url origin git@github.com:USER/new-repo.git
# تغییر نام
git remote rename origin github
# حذف remote
git remote remove upstream
git push – فرستادن به Remote
# push branch فعلی به remote
git push
# اگر branch محلی tracking نشده با remote (اولین push)
git push -u origin main
# -u یعنی: این branch را با origin/main link کن، تا دفعات بعدی فقط git push بزنیم
# push همه branchها
git push --all
# push همه tagها
git push --tags
# push با یک branch به branch دیگر در remote
git push origin local-branch:remote-branch-name
# حذف branch روی remote
git push origin --delete feature-old
# force push (خطرناک!)
git push --force
git push --force-with-lease # کمی امنتر
git push --force تاریخچه remote را بازنویسی میکند و کار همکاران را خراب میکند. فقط روی branchهای شخصی استفاده کنید. --force-with-lease امنتر است چون اول چک میکند کسی push نکرده باشد.
git fetch vs git pull
این دو متفاوتاند. تفاوت را بدانید!
git fetch
تغییرات remote را فقط دانلود میکند، اما در branch محلی شما merge نمیکند:
git fetch origin
# تغییرات remote در origin/main مینشینند
# اما main محلی دستنخورده میماند
# حالا میتوانید چک کنید چه تغییری آمده
git log main..origin/main # commitهای جدید در remote
git diff main origin/main # تغییرات
git log --oneline --graph --all # نمایش گرافیکی
# اگر راضی بودید، merge کنید
git merge origin/main
git pull
git pull = git fetch + git merge (یا rebase) – یعنی دانلود + ادغام در یک قدم:
git pull origin main
# = git fetch origin && git merge origin/main
# با rebase بهجای merge
git pull --rebase origin main
# تنظیم default
git config --global pull.rebase true # همیشه rebase
git config --global pull.rebase false # همیشه merge (default)
git config --global pull.ff only # فقط fast-forward
git fetch را بیشتر استفاده کنید تا قبل از ادغام، تغییرات را ببینید. git pull سریع است اما گاهی غافلگیرتان میکند.
Tracking Branches
وقتی git push -u میزنید، branch محلی به remote متصل میشود:
# بررسی tracking
git branch -vv
# * main a3f4b2c [origin/main] Latest commit
# feature b2c3d4e [origin/feature: ahead 2] Add new feature
# ahead 2: شما 2 commit جلوتر از remote هستید
# behind 3: شما 3 commit عقبترید
# diverged: هر دو طرف تغییرات جداگانه دارند
# تنظیم tracking
git branch --set-upstream-to=origin/main main
git branch -u origin/main
# حذف tracking
git branch --unset-upstream
جریان کاری روزمره
# 1. شروع روز - گرفتن آخرین تغییرات
git switch main
git pull
# 2. ساخت branch جدید
git switch -c feature/add-search
# 3. کار + commit
echo "..." > search.py
git add .
git commit -m "feat: add search functionality"
# 4. push به remote (اولین بار)
git push -u origin feature/add-search
# 5. ادامه کار - commitهای بعدی
git add .
git commit -m "fix: handle empty search query"
git push # حالا فقط git push کافی است
# 6. در GitHub: Pull Request باز کنید (فصل بعد)
Conflict هنگام pull
git pull origin main
# Auto-merging app.py
# CONFLICT (content): Merge conflict in app.py
# 1. حل conflict (مثل فصل قبل)
nano app.py
# 2. add و commit
git add app.py
git commit # پیام merge آماده میشود
# 3. push
git push
گزینه: rebase بهجای merge
git pull --rebase origin main
# اگر conflict شد:
# 1. حل کنید
git add resolved-file.py
# 2. ادامه rebase
git rebase --continue
# یا لغو
git rebase --abort
Protected Branches
در GitHub میتوانید branchهای مهم را محافظت کنید (Settings → Branches):
- Require pull request before merging: نمیتوان مستقیم push کرد
- Require approvals: حداقل N نفر تأیید کنند
- Require status checks: تستها قبول شوند
- Require signed commits
- Require linear history: نه merge commit
- Restrict who can push
مثال کامل: همکاری روی پروژه
# --- روز اول ---
# 1. Clone پروژه تیم
git clone git@github.com:team/project.git
cd project
# 2. ساخت branch فیچر
git switch -c feature/user-profile
# 3. توسعه
# ...
git add .
git commit -m "feat: add user profile page"
git push -u origin feature/user-profile
# 4. در GitHub: Pull Request باز کنید
# 5. منتظر review
# --- روز دوم - تغییرات review ---
# اعمال feedback
git add .
git commit -m "fix: address review comments"
git push
# --- روز سوم - main تغییر کرده ---
# همگامسازی
git switch main
git pull
git switch feature/user-profile
git merge main # یا git rebase main
# (حل conflict اگر هست)
git push
# --- بعد از merge شدن PR ---
git switch main
git pull
git branch -d feature/user-profile # حذف local
git push origin --delete feature/user-profile # حذف remote (یا GitHub خودکار حذف میکند)
چند Remote
سناریو: شما fork یک پروژه را clone کردهاید و میخواهید با اصلی هم sync باشید:
# Clone از fork خود
git clone git@github.com:YOUR-USERNAME/django.git
cd django
# remote اصلی پروژه را اضافه کنید (به عنوان upstream)
git remote add upstream https://github.com/django/django.git
git remote -v
# origin git@github.com:YOUR-USERNAME/django.git (fetch)
# origin git@github.com:YOUR-USERNAME/django.git (push)
# upstream https://github.com/django/django.git (fetch)
# upstream https://github.com/django/django.git (push)
# گرفتن تغییرات از اصلی
git fetch upstream
git switch main
git merge upstream/main # یا git rebase upstream/main
git push origin main # بهروز کردن fork شما
بهترین شیوهها
- SSH بهجای HTTPS (راحتتر، امنتر)
- قبل از شروع کار:
git pull - قبل از push: یک
git pullدیگر برای جلوگیری از conflict - هرگز روی main کسی دیگر force-push نکنید
--force-with-leaseبهجای--force- main را protected کنید در پروژههای تیمی
- commitها را زود push کنید (backup در GitHub)
- secrets را push نکنید! (.env در .gitignore)
- اگر اشتباهاً secret push شد: rotate کنید + git filter-branch یا BFG
جمعبندی
- Remote نسخهای از repo روی سرور است
- SSH key برای احراز هویت بهتر از HTTPS
git clone: کپی یک repo از remotegit push: ارسال commitهاgit fetch: دانلود + بدون mergegit pull: fetch + merge- Tracking branch: link بین local و remote
- Protected branches: امنیت در پروژههای تیمی
- چند remote: برای fork و upstream
در فصل بعد، Fork و Pull Request – راه استاندارد همکاری در پروژههای open-source.