Git چیست؟ آموزش کامل Git و GitHub از صفر با پروژه عملی هوش مصنوعی

در این آموزش Git و GitHub را از صفر و به‌صورت عملی یاد می‌گیرید؛ از نصب و Commit تا Branch، Merge، Pull Request و رفع Conflict. در پایان یک پروژه API هوش مصنوعی درواره را با Git مدیریت می‌کنیم.

Share
آموزش Git و GitHub از صفر با Branch، Commit، Pull Request و پروژه عملی هوش مصنوعی

Git یک سیستم کنترل نسخه توزیع‌شده یا Distributed Version Control System است. کنترل نسخه یعنی ثبت و مدیریت تغییرات فایل‌های یک پروژه در طول زمان.

فرض کنید فایل app.py را امروز تغییر می‌دهید، فردا قابلیت جدیدی به آن اضافه می‌کنید و دو روز بعد متوجه می‌شوید تغییر جدید باعث خرابی برنامه شده است. اگر از Git استفاده کرده باشید، می‌توانید تغییرات را بررسی کنید، تفاوت نسخه‌ها را ببینید و در صورت نیاز تغییر مشکل‌دار را برگردانید.

Git برخلاف ذخیره‌سازی دستی فایل‌هایی با نام‌هایی مانند project-final-v2-new.zip، تاریخچه‌ای ساخت‌یافته و قابل جست‌وجو ایجاد می‌کند.

بر اساس کتاب رسمی Git، Git وضعیت پروژه را به‌صورت مجموعه‌ای از Snapshotها یا تصویرهای لحظه‌ای ذخیره می‌کند. هر Commit نمایانگر یک وضعیت مشخص از فایل‌های پروژه است.

چرا برنامه‌نویسان باید Git یاد بگیرند؟

Git فقط ابزاری برای تیم‌های بزرگ نیست. حتی اگر به‌تنهایی برنامه‌نویسی می‌کنید، استفاده از آن مزایای مهمی دارد:

  • ثبت تاریخچه تغییرات پروژه
  • مشاهده دقیق تغییرات هر فایل
  • بازگشت کنترل‌شده به نسخه‌های قبلی
  • آزمایش قابلیت‌های جدید بدون آسیب‌زدن به نسخه اصلی
  • همکاری هم‌زمان چند برنامه‌نویس
  • بررسی کد قبل از ادغام
  • اتصال پروژه به سرویس‌های استقرار و CI/CD
  • مستندسازی دلیل هر تغییر
  • مدیریت نسخه‌های انتشار
  • نگهداری پروژه در مخزن محلی و راه دور

در پروژه‌های هوش مصنوعی، Git برای مدیریت کد API، پرامپت‌ها، تنظیمات مدل، تست‌ها و فایل‌های پیکربندی اهمیت بیشتری پیدا می‌کند. البته فایل‌های بسیار بزرگ مانند وزن مدل‌ها، مجموعه‌داده‌های حجیم و خروجی‌های ویدئویی معمولاً نباید مستقیماً داخل مخزن Git قرار بگیرند.

تفاوت Git و GitHub چیست؟

Git و GitHub یک مفهوم نیستند.

ویژگیGitGitHub
نوع ابزارسیستم کنترل نسخهسرویس میزبانی مخزن Git
محل اجراروی کامپیوتر محلیروی سرورهای آنلاین
نیاز دائمی به اینترنتنداردبرای همگام‌سازی نیاز دارد
ذخیره تاریخچهبلهمخزن Git را میزبانی می‌کند
Pull Requestبه‌تنهایی ندارددارد
Code Reviewبا ابزارهای جانبیبه‌صورت داخلی دارد
مدیریت Issueندارددارد
GitHub Actionsندارددارد

می‌توانید بدون GitHub از Git استفاده کنید. برای مثال، تمام Commitها و Branchهای محلی بدون اتصال به اینترنت کار می‌کنند. GitHub زمانی وارد جریان می‌شود که بخواهید مخزن را آنلاین نگه دارید، با دیگران همکاری کنید یا Pull Request بسازید.

مفاهیم اصلی Git

قبل از اجرای دستورات، چهار بخش اصلی Git را بشناسید.

Working Directory

همان پوشه پروژه است که فایل‌های آن را در ویرایشگر باز می‌کنید. هر تغییری که در کد ایجاد می‌کنید ابتدا در Working Directory قرار دارد.

Staging Area

محلی واسط برای مشخص‌کردن تغییراتی است که می‌خواهید در Commit بعدی ثبت شوند. دستور git add تغییرات را به این بخش منتقل می‌کند.

Local Repository

مخزن محلی که تاریخچه Commitها را داخل پوشه مخفی .git نگه می‌دارد. دستور git commit تغییرات انتخاب‌شده را در این مخزن ثبت می‌کند.

Remote Repository

نسخه‌ای از مخزن است که روی سرویسی مانند GitHub میزبانی می‌شود. دستور git push تغییرات محلی را به مخزن راه دور ارسال می‌کند.

جریان معمول کار به این صورت است:

ویرایش فایل
    ↓
git add
    ↓
Staging Area
    ↓
git commit
    ↓
Local Repository
    ↓
git push
    ↓
Remote Repository

سه وضعیت مهم فایل‌ها در Git عبارت‌اند از:

  • modified: فایل تغییر کرده اما هنوز Stage نشده است.
  • staged: تغییر فایل برای Commit بعدی انتخاب شده است.
  • committed: تغییر در مخزن محلی ذخیره شده است.

نصب Git

نصب Git در ویندوز

نسخه ویندوز را از وب‌سایت رسمی Git دریافت و نصب کنید. تنظیمات پیش‌فرض نصب برای بیشتر کاربران مناسب است.

پس از نصب، PowerShell، Command Prompt یا Git Bash را باز کنید و نسخه Git را بررسی کنید:

git --version

نصب Git در macOS

در macOS می‌توانید ابزارهای خط فرمان Xcode را نصب کنید:

xcode-select --install

اگر Homebrew نصب است:

brew install git

نصب Git در Ubuntu و Debian

sudo apt update
sudo apt install git

سپس نسخه را بررسی کنید:

git --version

تنظیمات اولیه Git

Git برای ثبت Commit باید نام و ایمیل شما را بداند:

git config --global user.name "Your Name"
git config --global user.email "you@example.com"

نام پیش‌فرض شاخه اصلی را روی main قرار دهید:

git config --global init.defaultBranch main

برای مشاهده تنظیمات:

git config --global --list

تنظیمات --global برای تمام پروژه‌های کاربر فعلی اعمال می‌شوند. اگر بخواهید تنظیم خاصی فقط روی یک پروژه اعمال شود، داخل همان مخزن دستور را بدون --global اجرا کنید:

git config user.email "work@example.com"

پروژه عملی: ساخت API هوش مصنوعی و مدیریت آن با Git

در این پروژه یک API ساده با Python و FastAPI می‌سازیم. این API درخواست کاربر را دریافت می‌کند، آن را به API هوش مصنوعی درواره می‌فرستد و پاسخ مدل را برمی‌گرداند.

برای دسترسی به API ابتدا در درواره ثبت‌نام و کلید API ایجاد کنید. شناسه مدل موردنظر را نیز می‌توانید در صفحه مدل‌های درواره مشاهده کنید.

ساخت پوشه پروژه

mkdir darvareh-ai-api
cd darvareh-ai-api

ساختار نهایی پروژه چنین خواهد بود:

darvareh-ai-api/
├── app.py
├── requirements.txt
├── .env.example
├── .gitignore
└── README.md

ساخت محیط مجازی پایتون

در Linux و macOS:

python3 -m venv .venv
source .venv/bin/activate

در ویندوز با PowerShell:

python -m venv .venv
.venv\Scripts\Activate.ps1

فایل requirements.txt

فایل requirements.txt را ایجاد کنید:

fastapi>=0.115,<1.0
uvicorn[standard]>=0.34,<1.0
openai>=1.68,<3.0
python-dotenv>=1.1,<2.0
pydantic>=2.10,<3.0

وابستگی‌ها را نصب کنید:

pip install -r requirements.txt

فایل .env.example

این فایل قالب متغیرهای محیطی موردنیاز پروژه است و مقدار واقعی کلید API را در خود ندارد:

DARVAREH_API_KEY=YOUR_DARVAREH_API_KEY
DARVAREH_MODEL_ID=YOUR_MODEL_ID

از روی آن یک فایل .env بسازید.

در Linux و macOS:

cp .env.example .env

در PowerShell:

Copy-Item .env.example .env

سپس در فایل .env مقدار واقعی کلید و شناسه مدل انتخابی خود را قرار دهید.

فایل .gitignore

مهم است که فایل .env، محیط مجازی و فایل‌های موقت وارد Git نشوند:

.env
.env.*
!.env.example

.venv/
venv/
__pycache__/
*.py[cod]

.pytest_cache/
.mypy_cache/
.ruff_cache/

.idea/
.vscode/

dist/
build/
*.log

الگوی .env.* فایل‌هایی مانند .env.production را نیز نادیده می‌گیرد؛ اما خط !.env.example اجازه می‌دهد فایل نمونه داخل Git ثبت شود.

فایل app.py

import os
from contextlib import asynccontextmanager

from dotenv import load_dotenv
from fastapi import FastAPI, HTTPException, Request
from openai import OpenAI
from pydantic import BaseModel, Field

load_dotenv()


class ChatRequest(BaseModel):
    message: str = Field(min_length=1, max_length=8000)
    temperature: float = Field(default=0.3, ge=0, le=2)
    max_tokens: int = Field(default=800, ge=1, le=2000)


@asynccontextmanager
async def lifespan(app: FastAPI):
    api_key = os.getenv("DARVAREH_API_KEY")
    model_id = os.getenv("DARVAREH_MODEL_ID")

    if not api_key:
        raise RuntimeError("DARVAREH_API_KEY is not configured")

    if not model_id:
        raise RuntimeError("DARVAREH_MODEL_ID is not configured")

    app.state.model_id = model_id
    app.state.ai_client = OpenAI(
        api_key=api_key,
        base_url="https://api.darvareh.ir/v1",
    )

    yield

    app.state.ai_client.close()


app = FastAPI(
    title="Darvareh AI API Example",
    version="1.0.0",
    lifespan=lifespan,
)


@app.get("/health")
def health():
    return {"status": "ok"}


@app.post("/chat")
def chat(payload: ChatRequest, request: Request):
    try:
        response = request.app.state.ai_client.chat.completions.create(
            model=request.app.state.model_id,
            messages=[
                {
                    "role": "system",
                    "content": (
                        "You are a helpful Persian assistant. "
                        "Answer clearly and accurately in Persian."
                    ),
                },
                {
                    "role": "user",
                    "content": payload.message,
                },
            ],
            temperature=payload.temperature,
            max_tokens=payload.max_tokens,
        )

        answer = response.choices[0].message.content

        return {
            "answer": answer,
            "model": request.app.state.model_id,
        }

    except Exception:
        raise HTTPException(
            status_code=502,
            detail="دریافت پاسخ از سرویس هوش مصنوعی با مشکل مواجه شد.",
        )

آدرس پایه در این مثال برابر است با:

https://api.darvareh.ir/v1

کتابخانه سازگار با OpenAI مسیر chat/completions را به آدرس پایه اضافه می‌کند. در نتیجه درخواست نهایی به این Endpoint ارسال می‌شود:

https://api.darvareh.ir/v1/chat/completions

اجرای پروژه

uvicorn app:app --reload

بررسی سلامت برنامه:

curl http://127.0.0.1:8000/health

ارسال درخواست آزمایشی:

curl -X POST http://127.0.0.1:8000/chat \
  -H "Content-Type: application/json" \
  -d '{"message":"Git را در سه جمله ساده توضیح بده"}'

در PowerShell:

$body = @{
    message = "Git را در سه جمله ساده توضیح بده"
} | ConvertTo-Json

Invoke-RestMethod `
    -Method Post `
    -Uri "http://127.0.0.1:8000/chat" `
    -ContentType "application/json" `
    -Body $body

نمونه بالا برای توسعه محلی است. پیش از انتشار عمومی API باید احراز هویت، محدودیت نرخ درخواست، ثبت رویداد کنترل‌شده، تنظیم Timeout و مدیریت خطاهای دقیق‌تر را اضافه کنید.

ساخت مخزن Git

حالا داخل پوشه پروژه Git را فعال کنید:

git init

این دستور پوشه مخفی .git را می‌سازد. این پوشه شامل تاریخچه، تنظیمات و اطلاعات داخلی مخزن است و نباید به‌صورت دستی ویرایش شود.

وضعیت پروژه را مشاهده کنید:

git status

در این مرحله فایل‌ها به‌صورت untracked نمایش داده می‌شوند؛ یعنی Git هنوز آن‌ها را دنبال نمی‌کند.

بررسی .gitignore قبل از اولین Commit

مطمئن شوید فایل .env نادیده گرفته می‌شود:

git check-ignore -v .env

اگر دستور، نام فایل .gitignore و قانون مربوط به .env را نمایش دهد، تنظیم درست است.

همچنین می‌توانید وضعیت مخزن را دوباره بررسی کنید:

git status

فایل .env نباید در فهرست فایل‌های آماده ثبت ظاهر شود.

اضافه‌کردن فایل‌ها به Staging Area

تمام فایل‌های مجاز را Stage کنید:

git add .

سپس وضعیت را ببینید:

git status

برای اضافه‌کردن فقط چند فایل مشخص می‌توانید بنویسید:

git add app.py requirements.txt

استفاده از git add . سریع است، اما در پروژه‌های واقعی بهتر است قبل و بعد از اجرای آن git status را بررسی کنید تا فایل ناخواسته‌ای ثبت نشود.

ساخت اولین Commit

git commit -m "feat: add initial Darvareh AI API"

حالا تاریخچه خلاصه Commitها را ببینید:

git log --oneline

خروجی مشابه زیر خواهد بود:

a1b2c3d feat: add initial Darvareh AI API

مقدار ابتدای خط شناسه کوتاه Commit است.

تفاوت git add و git commit

این دو دستور وظایف متفاوتی دارند:

git add app.py

تغییر فعلی app.py را برای Commit بعدی انتخاب می‌کند.

git commit -m "fix: validate empty messages"

تمام تغییرات موجود در Staging Area را به‌صورت یک Snapshot در مخزن محلی ثبت می‌کند.

اجرای git add به‌تنهایی تاریخچه دائمی ایجاد نمی‌کند. اجرای git commit نیز تغییراتی را که Stage نشده‌اند ثبت نمی‌کند.

مشاهده تغییرات قبل از Commit

تغییرات Stage‌نشده:

git diff

تغییراتی که برای Commit بعدی Stage شده‌اند:

git diff --staged

مشاهده فهرست کوتاه وضعیت فایل‌ها:

git status --short

نمونه خروجی:

 M app.py
A  README.md
?? tests/

معانی رایج:

  • M: فایل تغییر کرده است.
  • A: فایل جدید به Staging Area اضافه شده است.
  • ??: فایل هنوز توسط Git دنبال نمی‌شود.
  • D: فایل حذف شده است.

چگونه پیام Commit خوب بنویسیم؟

پیام Commit باید توضیح دهد چه تغییری انجام شده است. پیام‌هایی مانند update، changes یا fix stuff در آینده کمک زیادی نمی‌کنند.

نمونه‌های بهتر:

feat: add chat endpoint
fix: handle empty model response
docs: add local setup instructions
test: add chat request validation tests
refactor: move AI client configuration
chore: update Python dependencies

الگوی Conventional Commits یک قرارداد رایج است، نه الزام داخلی Git. رایج‌ترین پیشوندهای آن عبارت‌اند از:

  • feat: قابلیت جدید
  • fix: رفع اشکال
  • docs: تغییر مستندات
  • test: افزودن یا اصلاح تست
  • refactor: بازآرایی بدون تغییر رفتار اصلی
  • chore: کارهای نگهداری
  • perf: بهبود عملکرد

بهتر است هر Commit فقط یک تغییر منطقی و مشخص را ثبت کند.

Branch در Git چیست؟

Branch یا شاخه مسیر مستقلی برای توسعه تغییرات است. به‌جای آنکه مستقیماً نسخه اصلی را ویرایش کنید، برای هر قابلیت یا رفع اشکال شاخه جداگانه‌ای می‌سازید.

ساخت شاخه جدید و ورود به آن:

git switch -c feature/streaming

مشاهده شاخه‌ها:

git branch

شاخه فعال با علامت ستاره مشخص می‌شود:

  main
* feature/streaming

پس از تغییر فایل‌ها:

git add app.py
git commit -m "feat: add streaming response support"

بازگشت به شاخه اصلی:

git switch main

ادغام شاخه قابلیت با شاخه اصلی:

git merge feature/streaming

اگر ادغام موفق بود و دیگر به شاخه نیاز ندارید:

git branch -d feature/streaming

برای نام شاخه‌ها از الگوی واضح استفاده کنید:

feature/chat-history
fix/empty-response
docs/api-setup
refactor/client-config

اتصال پروژه به GitHub

ابتدا در GitHub یک Repository خالی بسازید. بهتر است هنگام ساخت مخزن آنلاین، گزینه ایجاد خودکار README را فعال نکنید؛ زیرا پروژه محلی از قبل Commit دارد.

سپس آدرس Remote را اضافه کنید:

git remote add origin https://github.com/USERNAME/darvareh-ai-api.git

بررسی Remoteها:

git remote -v

اطمینان از نام شاخه اصلی:

git branch -M main

ارسال اولین نسخه:

git push -u origin main

گزینه -u ارتباط شاخه محلی main را با شاخه راه دور آن ثبت می‌کند. دفعات بعد معمولاً کافی است بنویسید:

git push

برای احراز هویت از روش‌های پشتیبانی‌شده GitHub استفاده کنید. رمز عبور، Token یا کلید API را داخل آدرس Remote، فایل README یا اسکریپت‌های پروژه قرار ندهید.

git clone چیست؟

اگر پروژه از قبل در GitHub وجود دارد، به‌جای git init آن را Clone کنید:

git clone https://github.com/USERNAME/darvareh-ai-api.git
cd darvareh-ai-api

دستور git clone موارد زیر را دریافت می‌کند:

  • فایل‌های پروژه
  • تاریخچه Commitها
  • Branchهای قابل دسترسی
  • تنظیمات Remote با نام origin

تفاوت git fetch و git pull

دریافت اطلاعات جدید مخزن راه دور بدون ادغام خودکار:

git fetch origin

این دستور وضعیت Remote را به‌روزرسانی می‌کند، اما فایل‌های شاخه فعلی شما را تغییر نمی‌دهد.

برای مشاهده تفاوت شاخه محلی با شاخه راه دور:

git log --oneline main..origin/main

دریافت و ادغام تغییرات:

git pull origin main

برای جلوگیری از ساخت Merge Commit ناخواسته می‌توانید در جریان‌های ساده از حالت Fast Forward Only استفاده کنید:

git pull --ff-only origin main

اگر Fast Forward ممکن نباشد، Git عملیات را متوقف می‌کند تا خودتان درباره نحوه ادغام تصمیم بگیرید.

Pull Request چیست؟

Pull Request یا PR درخواستی برای بررسی و ادغام تغییرات یک Branch با Branch دیگر است.

جریان معمول کار تیمی:

  1. دریافت آخرین نسخه main
  2. ساخت Branch جدید
  3. انجام تغییرات
  4. اجرای تست‌ها
  5. ساخت Commitهای مشخص
  6. ارسال Branch به GitHub
  7. ایجاد Pull Request
  8. بررسی کد
  9. اصلاح بازخوردها
  10. ادغام با main

نمونه:

git switch main
git pull --ff-only origin main
git switch -c feature/add-model-selection

پس از انجام تغییرات:

git add .
git commit -m "feat: add model selection to chat requests"
git push -u origin feature/add-model-selection

حالا در GitHub از Branch جدید به main یک Pull Request بسازید.

در راهنمای رسمی GitHub Flow، استفاده از Branch، Commit، Pull Request، بررسی و ادغام به‌عنوان مراحل اصلی این جریان کاری معرفی شده است.

Merge Conflict چیست؟

Merge Conflict زمانی رخ می‌دهد که Git نتواند تغییرات دو شاخه را به‌صورت خودکار ترکیب کند؛ برای مثال، وقتی دو نفر یک خط یکسان را به شکل متفاوت تغییر داده‌اند.

علامت‌های Conflict داخل فایل ممکن است چنین باشند:

<<<<<<< HEAD
مدل پیش‌فرض نسخه شاخه main
=======
مدل پیش‌فرض نسخه شاخه feature
>>>>>>> feature/model-selection

بخش بالایی تغییر شاخه فعلی و بخش پایینی تغییر شاخه مقابل است.

برای حل Conflict:

  1. فایل را باز کنید.
  2. نسخه درست را انتخاب یا دو نسخه را ترکیب کنید.
  3. علامت‌های <<<<<<<، ======= و >>>>>>> را حذف کنید.
  4. فایل را ذخیره و تست کنید.
  5. فایل حل‌شده را Stage کنید.
  6. ادغام را Commit کنید.
git add app.py
git commit -m "merge: resolve model configuration conflict"

اگر می‌خواهید عملیات Merge را لغو کنید:

git merge --abort

قبل از حل Conflict، کد را با دقت بررسی کنید. حذف‌کردن صرف علامت‌ها بدون فهم منطق دو تغییر ممکن است برنامه را خراب کند.

برگرداندن تغییرات در Git

روش بازگردانی به وضعیت تغییر بستگی دارد.

لغو تغییر یک فایل Stage‌نشده

git restore app.py

این دستور تغییرات ثبت‌نشده فایل را حذف می‌کند. اگر به آن تغییرات نیاز دارید، قبل از اجرا نسخه‌ای از آن‌ها نگه دارید یا از Stash استفاده کنید.

خارج‌کردن فایل از Staging Area

git restore --staged app.py

محتوای فایل باقی می‌ماند، اما از Commit بعدی خارج می‌شود.

اصلاح آخرین Commit محلی

اگر فایلی را فراموش کرده‌اید:

git add README.md
git commit --amend --no-edit

برای اصلاح پیام آخرین Commit:

git commit --amend -m "docs: complete API setup instructions"

روی Commitهایی که قبلاً Push شده‌اند و دیگران بر مبنای آن‌ها کار کرده‌اند، با احتیاط از amend استفاده کنید؛ زیرا شناسه Commit تغییر می‌کند.

خنثی‌کردن یک Commit منتشرشده

git revert COMMIT_HASH

git revert یک Commit جدید می‌سازد که اثر Commit قبلی را خنثی می‌کند. این روش برای تاریخچه اشتراکی معمولاً قابل‌ردیابی‌تر از بازنویسی تاریخچه است.

احتیاط درباره git reset --hard

دستور زیر تغییرات ثبت‌نشده را حذف می‌کند:

git reset --hard

تا زمانی که دقیقاً نمی‌دانید چه داده‌ای حذف می‌شود، آن را اجرا نکنید. قبل از عملیات‌های مخرب، git status و git diff را بررسی کنید و در صورت نیاز از تغییرات خود Commit یا Stash بگیرید.

ذخیره موقت تغییرات با git stash

گاهی وسط توسعه یک قابلیت هستید اما باید سریعاً به Branch دیگری بروید. اگر تغییرات هنوز برای Commit آماده نیستند، از Stash استفاده کنید:

git stash push -m "WIP: streaming response"

مشاهده Stashها:

git stash list

برگرداندن آخرین Stash و حذف آن از فهرست:

git stash pop

اعمال Stash بدون حذف از فهرست:

git stash apply

فایل‌های Untracked به‌صورت پیش‌فرض وارد Stash نمی‌شوند. برای اضافه‌کردن آن‌ها:

git stash push -u -m "WIP: new endpoint"

ساخت Tag و نسخه انتشار

Tag برای مشخص‌کردن نقاط مهم تاریخچه مانند نسخه‌های انتشار استفاده می‌شود.

ساخت Tag توضیح‌دار:

git tag -a v1.0.0 -m "First stable release"

مشاهده Tagها:

git tag

ارسال Tag به Remote:

git push origin v1.0.0

ارسال تمام Tagها:

git push origin --tags

برای شماره‌گذاری نسخه‌ها می‌توانید از ساختار رایج زیر استفاده کنید:

MAJOR.MINOR.PATCH

برای مثال:

  • 1.0.0: اولین نسخه پایدار
  • 1.1.0: قابلیت جدید سازگار
  • 1.1.1: رفع اشکال سازگار
  • 2.0.0: تغییر ناسازگار عمده

مدیریت امن کلید API در Git

کلید API درواره را نباید داخل فایل‌های Commit‌شده قرار دهید. روش مناسب در پروژه نمونه این است:

  • مقدار واقعی داخل .env
  • نام .env داخل .gitignore
  • فقط مقادیر نمونه داخل .env.example
  • استفاده از Secret Manager یا متغیر محیطی در سرور
  • خودداری از ثبت کلید در README، Issue، Log و Pull Request

اگر کلید API را تصادفاً Commit و Push کردید، حذف آن در Commit بعدی کافی نیست؛ زیرا ممکن است مقدار در تاریخچه باقی مانده باشد. ابتدا کلید را در پنل سرویس باطل یا تعویض کنید و سپس در صورت نیاز تاریخچه مخزن را پاک‌سازی کنید.

همچنین قبل از Commit می‌توانید جست‌وجوی ساده‌ای انجام دهید:

git diff --staged

و مطمئن شوید مقادیر محرمانه وارد تغییرات Stage‌شده نشده‌اند.

آیا فایل‌های مدل و Dataset را داخل Git قرار دهیم؟

Git برای کد و فایل‌های متنی مناسب است، اما برای فایل‌های بسیار بزرگ انتخاب مناسبی نیست.

معمولاً این موارد را مستقیماً Commit نکنید:

  • وزن مدل‌های زبانی یا تصویری
  • Datasetهای حجیم
  • ویدئوهای تولیدشده
  • خروجی‌های صوتی بزرگ
  • فایل‌های Build
  • پوشه محیط مجازی
  • Cache مدل‌ها
  • فایل‌های موقت Notebook
  • خروجی‌های لاگ حجیم

برای این فایل‌ها می‌توان از فضای ذخیره‌سازی Object Storage، سامانه مدیریت Dataset، Model Registry یا Git LFS استفاده کرد. GitHub نیز برای فایل‌های بزرگ محدودیت‌هایی دارد و استفاده از روش‌های مناسب مدیریت فایل حجیم را توصیه می‌کند؛ جزئیات در مستندات رسمی فایل‌های بزرگ GitHub آمده است.

نمونه .gitignore برای پروژه‌های یادگیری ماشین:

data/
datasets/
models/
checkpoints/
outputs/
runs/
wandb/
*.pt
*.pth
*.ckpt
*.onnx
*.h5
*.parquet

اگر پروژه شما نیاز دارد ساختار پوشه خالی حفظ شود، می‌توانید داخل آن فایل .gitkeep قرار دهید.

نوشتن README مناسب برای پروژه

فایل README باید به توسعه‌دهنده جدید کمک کند پروژه را سریع اجرا کند.

نمونه:

# Darvareh AI API Example

نمونه API هوش مصنوعی با FastAPI و سرویس درواره.

## پیش‌نیازها

- Python 3.11 یا جدیدتر
- کلید API درواره
- شناسه یکی از مدل‌های در دسترس

## نصب

```bash
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env

مقادیر DARVAREH_API_KEY و DARVAREH_MODEL_ID را در .env تنظیم کنید.

اجرا

uvicorn app:app --reload

بررسی سلامت

curl http://127.0.0.1:8000/health

README خوب معمولاً این بخش‌ها را دارد:

- معرفی پروژه
- قابلیت‌ها
- پیش‌نیازها
- روش نصب
- تنظیم متغیرهای محیطی
- روش اجرا
- نمونه درخواست و پاسخ
- اجرای تست‌ها
- ساختار پروژه
- روش مشارکت
- مجوز پروژه، در صورت وجود

## جریان پیشنهادی Git برای تیم‌ها

یک جریان ساده و کاربردی برای تیم‌های کوچک:

```text
main
  ├── feature/chat-history
  ├── feature/streaming
  ├── fix/empty-response
  └── docs/deployment-guide

قواعد پیشنهادی:

  • شاخه main همیشه قابل اجرا باشد.
  • هر قابلیت در Branch جداگانه توسعه داده شود.
  • قبل از Merge، تست‌ها اجرا شوند.
  • تغییرات از طریق Pull Request بررسی شوند.
  • هر PR فقط یک هدف اصلی داشته باشد.
  • Commitها کوچک و قابل فهم باشند.
  • فایل‌های محرمانه و خروجی‌های حجیم وارد مخزن نشوند.
  • Branch پس از Merge حذف شود.
  • انتشارهای پایدار Tag داشته باشند.

دستورات پرکاربرد Git

شروع و دریافت پروژه

git init
git clone REPOSITORY_URL

مشاهده وضعیت و تاریخچه

git status
git status --short
git log
git log --oneline
git log --oneline --graph --decorate --all

مدیریت تغییرات

git add FILE
git add .
git diff
git diff --staged
git commit -m "MESSAGE"

مدیریت Branch

git branch
git switch BRANCH_NAME
git switch -c NEW_BRANCH
git merge BRANCH_NAME
git branch -d BRANCH_NAME

کار با Remote

git remote -v
git remote add origin REPOSITORY_URL
git fetch origin
git pull --ff-only origin main
git push
git push -u origin BRANCH_NAME

بازگردانی و نگهداری

git restore FILE
git restore --staged FILE
git revert COMMIT_HASH
git stash push -m "MESSAGE"
git stash list
git stash pop

Tag

git tag
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0

خطاهای رایج Git و راه‌حل آن‌ها

خطای not a git repository

نمونه خطا:

fatal: not a git repository

در پوشه‌ای قرار دارید که مخزن Git نیست. ابتدا مسیر فعلی را بررسی کنید:

pwd

در ویندوز:

Get-Location

سپس وارد پوشه صحیح شوید یا مخزن جدید بسازید:

git init

پیام nothing to commit

nothing to commit, working tree clean

این خطا نیست. یعنی تغییر جدیدی برای Commit وجود ندارد. وضعیت را بررسی کنید:

git status

خطای remote origin already exists

اگر origin از قبل تعریف شده باشد:

error: remote origin already exists

آدرس فعلی را ببینید:

git remote -v

برای تغییر آدرس:

git remote set-url origin NEW_REPOSITORY_URL

ردشدن Push به دلیل non-fast-forward

این وضعیت معمولاً زمانی رخ می‌دهد که Remote دارای Commitهایی است که در مخزن محلی شما وجود ندارند.

ابتدا تغییرات را دریافت کنید:

git fetch origin
git pull --ff-only origin main

اگر Fast Forward ممکن نبود، تفاوت شاخه‌ها را بررسی و تصمیم مناسب برای Merge یا Rebase بگیرید. بدون بررسی از Force Push استفاده نکنید.

خطای احراز هویت

ممکن است پیام‌هایی مانند Authentication failed یا Permission denied مشاهده کنید.

موارد زیر را بررسی کنید:

  • آدرس Remote درست باشد.
  • به Repository دسترسی داشته باشید.
  • روش احراز هویت معتبر باشد.
  • Credential قدیمی در سیستم ذخیره نشده باشد.
  • حساب کاربری درست انتخاب شده باشد.

کلیدها و Tokenها را داخل فرمان‌هایی که در History ترمینال باقی می‌مانند قرار ندهید.

اشتباه‌کردن Branch

شاخه فعلی را ببینید:

git branch --show-current

اگر تغییرات Commit نشده‌اند، پیش از جابه‌جایی آن‌ها را Commit یا Stash کنید:

git stash push -u -m "WIP before switching branch"
git switch main

هشدار Line Ending

در پروژه‌های مشترک ویندوز و Linux ممکن است درباره LF و CRLF هشدار ببینید. برای مدیریت یکپارچه می‌توانید فایل .gitattributes ایجاد کنید:

* text=auto
*.sh text eol=lf
*.bat text eol=crlf
*.ps1 text eol=crlf

این تنظیم به Git کمک می‌کند پایان خط فایل‌های متنی را سازگارتر مدیریت کند.

اشتباهات متداول مبتدیان

Commit‌کردن تمام تغییرات بدون بررسی

قبل از Commit همیشه این دستورات را اجرا کنید:

git status
git diff
git diff --staged

ذخیره کلید API در کد

روش نامناسب:

api_key = "کلید واقعی"

روش مناسب:

api_key = os.getenv("DARVAREH_API_KEY")

استفاده از یک Branch برای تمام کارها

هر قابلیت یا رفع اشکال را در Branch جداگانه توسعه دهید تا بررسی و بازگردانی تغییرات آسان‌تر باشد.

Commitهای بسیار بزرگ

Commit بزرگ معمولاً چند تغییر نامرتبط را مخلوط می‌کند. تغییرات را به واحدهای منطقی کوچک تقسیم کنید.

Pull‌کردن بدون بررسی تغییرات محلی

قبل از دریافت تغییرات Remote:

git status

اگر فایل‌های اصلاح‌شده دارید، آن‌ها را Commit یا Stash کنید.

Force Push بدون آگاهی

Force Push می‌تواند تاریخچه Remote را بازنویسی کند. روی Branch مشترک از آن استفاده نکنید، مگر آنکه جریان کاری تیم صریحاً چنین عملی را مجاز بداند و اثر آن را کاملاً بدانید.

چک‌لیست روزانه کار با Git

در ابتدای کار:

git switch main
git pull --ff-only origin main
git switch -c feature/my-feature

در زمان توسعه:

git status
git diff
git add FILE
git diff --staged
git commit -m "feat: describe the change"

پیش از ارسال:

git status
git log --oneline -5
git push -u origin feature/my-feature

پیش از Pull Request:

  • برنامه اجرا می‌شود.
  • تست‌ها موفق‌اند.
  • فایل محرمانه‌ای Commit نشده است.
  • تغییرات ناخواسته وجود ندارد.
  • توضیح PR روشن است.
  • دامنه تغییر بیش از حد بزرگ نیست.
  • README در صورت نیاز به‌روزرسانی شده است.

پرسش‌های متداول

آیا Git همان GitHub است؟

خیر. Git نرم‌افزار کنترل نسخه است و GitHub یکی از سرویس‌های میزبانی مخزن Git محسوب می‌شود.

آیا برای استفاده از Git به اینترنت نیاز داریم؟

برای بیشتر عملیات محلی مانند Commit، Branch، Merge و مشاهده تاریخچه به اینترنت نیاز ندارید. عملیات Push، Pull و Fetch از مخزن آنلاین به اتصال شبکه نیاز دارند.

آیا می‌توانم بدون خط فرمان از Git استفاده کنم؟

بله. ویرایشگرهایی مانند VS Code و محیط‌هایی مانند PyCharm رابط گرافیکی Git دارند. بااین‌حال، یادگیری دستورات اصلی خط فرمان کمک می‌کند رفتار Git را بهتر بفهمید و مشکلات را راحت‌تر برطرف کنید.

تفاوت Commit و Push چیست؟

Commit تغییرات را در مخزن محلی ثبت می‌کند. Push، Commitهای محلی را به مخزن راه دور می‌فرستد.

تفاوت Merge و Pull Request چیست؟

Merge عملیات ترکیب دو Branch است. Pull Request یک فرایند همکاری و بررسی است که معمولاً در پایان آن Merge انجام می‌شود.

آیا .gitignore فایل قبلاً Commit‌شده را حذف می‌کند؟

خیر. .gitignore معمولاً روی فایل‌های Untracked اثر دارد. اگر فایلی از قبل Commit شده باشد، ابتدا باید آن را از Index خارج کنید:

git rm --cached FILE_NAME

سپس تغییر را Commit کنید. اگر فایل شامل اطلاعات محرمانه بوده، تعویض آن اطلاعات نیز ضروری است.

آیا Git نسخه پشتیبان کامل پروژه است؟

Git تاریخچه کد و فایل‌های ثبت‌شده را نگه می‌دارد، اما جایگزین کامل Backup نیست. فایل‌های خارج از Git، داده‌های تولیدی، پایگاه داده و Secretها باید راهکار پشتیبان‌گیری جداگانه داشته باشند.

برای پروژه هوش مصنوعی چه چیزهایی را Commit کنیم؟

معمولاً کد، تست‌ها، فایل‌های پیکربندی نمونه، پرامپت‌های نسخه‌بندی‌شده، مستندات و فایل قفل وابستگی‌ها را Commit کنید. Dataset حجیم، وزن مدل، Cache، خروجی‌های تولیدشده و کلید API را وارد مخزن نکنید.

آیا می‌توان پرامپت‌ها را با Git مدیریت کرد؟

بله. پرامپت‌ها را می‌توانید در فایل‌های متنی یا قالب‌های ساخت‌یافته نگه دارید و تغییرات آن‌ها را مانند کد Commit کنید. بهتر است همراه هر تغییر، دلیل و نتیجه ارزیابی آن را نیز ثبت کنید.

جمع‌بندی

Git یکی از بنیادی‌ترین ابزارهای برنامه‌نویسی مدرن است. با یادگیری چند مفهوم اصلی شامل Working Directory، Staging Area، Commit، Branch و Remote می‌توانید بیشتر نیازهای روزمره خود را مدیریت کنید.

برای شروع، همین جریان ساده کافی است:

git status
git add .
git commit -m "feat: describe the change"
git push

اما استفاده حرفه‌ای از Git فقط حفظ دستورات نیست. باید تغییرات را قبل از Commit بررسی کنید، Commitهای کوچک و معنادار بسازید، قابلیت‌ها را در Branch جدا توسعه دهید و اطلاعات محرمانه را از تاریخچه دور نگه دارید.

در پروژه عملی این مقاله یک API هوش مصنوعی با FastAPI ساختیم، آن را به API درواره متصل کردیم و سپس تمام مراحل ساخت مخزن، Commit، Branch، Push و Pull Request را مرور کردیم.

اگر می‌خواهید پروژه مشابهی بسازید، در درواره ثبت‌نام کنید، کلید API بگیرید و مدل مناسب پروژه خود را از فهرست مدل‌های درواره انتخاب کنید.

منابع تکمیلی

مقالات مرتبط

برای مطالعه شرایط استفاده و محدودیت‌های مسئولیت، صفحه «سلب مسئولیت» را مشاهده کنید.

Read more

اتوماسیون هوش مصنوعی چیست؟ کاربردها و آموزش ساخت AI Automation

اتوماسیون هوش مصنوعی چیست؟ کاربردها و آموزش ساخت AI Automation

اتوماسیون هوش مصنوعی با ترکیب گردش‌کارهای خودکار و مدل‌های هوش مصنوعی، پردازش متن، دسته‌بندی، استخراج اطلاعات و تصمیم‌های پیشنهادی را خودکار می‌کند. در این راهنما، معماری و ساخت نمونه عملی آن با API درواره را می‌آموزید.

Agentic Commerce چیست؟ آینده خرید با ایجنت هوش مصنوعی

Agentic Commerce چیست؟ آینده خرید با ایجنت هوش مصنوعی

Agentic Commerce شیوه‌ای جدید برای خرید اینترنتی است که در آن ایجنت هوش مصنوعی می‌تواند نیاز کاربر را بفهمد، محصولات را جست‌وجو و مقایسه کند و فرایند خرید را پیش ببرد. در این راهنما با معماری، UCP، ACP و پیاده‌سازی آن با API درواره آشنا می‌شوید.