دستورات پایه Git
حالا که Git نصب و پیکربندی شده، اولین repository را میسازیم و چرخه کاری روزمره را تمرین میکنیم: init، add، commit، status، log و diff.
حالا که Git نصب و پیکربندی شده، اولین repository را میسازیم و چرخه کاری روزمره را تمرین میکنیم: init، add، commit، status، log و diff.
git init – ساخت Repository
mkdir hello-git
cd hello-git
git init
# Initialized empty Git repository in /home/user/hello-git/.git/
# تأیید
ls -la
# . .. .git/
git status
# On branch main
# No commits yet
# nothing to commit (create/copy files and use "git add" to track)
چه اتفاقی افتاد؟
Git پوشهای به نام .git ساخت که شامل تمام metadata و تاریخچه پروژه است. این پوشه مخفی است (با . شروع میشود).
git init بزنید.
git status – بررسی وضعیت
git status پرکاربردترین دستور Git است. به شما میگوید الان در چه وضعیتی هستید:
# یک فایل بسازید
echo "Hello Git" > README.md
git status
# On branch main
#
# No commits yet
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
# README.md
#
# nothing added to commit but untracked files present
وضعیتهای ممکن یک فایل
| وضعیت | توضیح |
|---|---|
| Untracked | فایل جدید که Git خبر ندارد |
| Modified | فایل tracked شده اما تغییر کرده |
| Staged | تغییرات آماده commit |
| Committed | در تاریخچه ذخیره شده |
| Unmodified | tracked اما هیچ تغییری ندارد |
┌───────────┐ add file ┌───────────┐ edit file ┌───────────┐
│ Untracked │ ────────→ │ Staged │ ─────────→ │ Modified │
└───────────┘ └─────┬─────┘ └─────┬─────┘
│ commit │ add
▼ │
┌──────────┐ │
│Committed │ ←───────────────────┘
└──────────┘
git status -s (خلاصه)
git status -s # یا --short
# ?? new-file.txt ← Untracked
# A added.txt ← Staged، new
# M modified.txt ← Modified بعد از add (یعنی add شده اما باز هم تغییر کرده)
# M edited.txt ← Modified نه staged
# MM both.txt ← هم staged هم تغییر بعد از add
# D deleted.txt ← Deleted
git add – افزودن به Staging
قبل از commit، باید بگوییم کدام فایلها در commit بعدی باشند:
# یک فایل خاص
git add README.md
# چند فایل
git add file1.txt file2.txt
# یک پوشه کامل (هر چی داخلش هست)
git add docs/
# همه فایلهای جدید و modified در پوشه فعلی و زیرپوشهها
git add .
# همه فایلهای جدید و modified در کل پروژه
git add -A
git add --all
# فقط فایلهایی که قبلاً tracked هستند
git add -u
git add --update
# با glob pattern
git add "*.py"
git add "src/**/*.js"
# add همراه با مرور تغییرات (interactive)
git add -p file.txt
git add -p – مرور تغییرات
قابلیت بسیار قدرتمند که اجازه میدهد قسمتی از تغییرات یک فایل را add کنید:
git add -p script.py
# Git هر hunk (قسمت تغییر) را نشان میدهد و میپرسد:
# Stage this hunk [y,n,q,a,d,s,e,?]?
# y = yes
# n = no
# s = split (تقسیم به hunkهای کوچکتر)
# e = edit (ویرایش دستی)
git commit – ثبت در تاریخچه
# commit با پیام مستقیم
git commit -m "Initial commit"
# پیام چند خطی
git commit -m "Add user authentication" -m "Implements login, logout, and password reset using bcrypt for hashing."
# باز کردن editor برای پیام
git commit
# commit همه tracked فایلهای modified بدون نیاز به add (untracked را add نمیکند)
git commit -a -m "Update docs"
# تصحیح آخرین commit (اضافه کردن فایل فراموششده یا تغییر پیام)
git add forgotten-file.txt
git commit --amend --no-edit # بدون تغییر پیام
git commit --amend -m "New message" # با پیام جدید
git commit --amend commit آخر را بازنویسی میکند. اگر آن commit را push کردهاید، استفاده نکنید (یا با force-push دقت کنید).
پیامهای commit خوب
قاعدههای پذیرفتهشده:
- خط اول: کوتاه (≤۵۰ کاراکتر)، فعل امری
- خط دوم: خالی
- خطهای بعدی: توضیح بیشتر (۷۲ کاراکتر در هر خط)
- چرا تغییر کردیم، نه چه تغییری دادیم
Add user authentication system
Implement login, logout and password reset using bcrypt
for password hashing. JWT tokens are used for sessions
with 24-hour expiry.
Refs: #42
Conventional Commits
یک استاندارد محبوب برای پیامها:
<type>(<scope>): <subject>
[body]
[footer]
typeهای رایج:
feat: قابلیت جدیدfix: رفع باگdocs: تغییر مستنداتstyle: فرمت کد، بدون تغییر منطقrefactor: بازنویسی بدون تغییر رفتارtest: افزودن تستchore: کارهای maintenanceperf: بهبود performance
feat(auth): add JWT-based authentication
fix(api): correct null check in user endpoint
docs(readme): update installation steps
refactor(db): migrate from MySQL to PostgreSQL
chore(deps): bump Django to 5.0
perf(query): add index on orders.user_id
git log – مشاهده تاریخچه
git log
# commit a3f4b2c1... (HEAD -> main)
# Author: Mohammad Ali <you@example.com>
# Date: Fri May 1 10:30:45 2026 +0330
#
# Add user authentication
# آخرین N commit
git log -5
git log -n 10
# خلاصه یکخطی
git log --oneline
# a3f4b2c (HEAD -> main) Add user authentication
# b2c3d4e Initial commit
# با graph (نمایش branchها)
git log --oneline --graph --all --decorate
# فایلهای تغییریافته
git log --stat
# تغییرات کامل
git log -p
# جستجو در پیام
git log --grep="bug fix"
# فقط commitهای یک نویسنده
git log --author="Mohammad"
# بازه زمانی
git log --since="2 weeks ago"
git log --until="2026-01-01"
git log --since="2026-01-01" --until="2026-02-01"
# commitهایی که فایل خاص را تغییر دادند
git log --follow -- path/to/file.py
# فرمت سفارشی
git log --pretty=format:"%h - %an, %ar : %s"
# a3f4b2c - Mohammad Ali, 2 hours ago : Add user authentication
placeholderهای فرمت
| کد | معنی |
|---|---|
%H |
commit hash کامل |
%h |
commit hash کوتاه |
%an |
نام نویسنده |
%ae |
ایمیل نویسنده |
%ad |
تاریخ نویسنده |
%ar |
تاریخ نسبی (مثلاً 2 hours ago) |
%s |
موضوع (خط اول پیام) |
%b |
body پیام |
Alias مفید برای log
git config --global alias.lg "log --oneline --graph --all --decorate"
# حالا
git lg
git diff – مقایسه تغییرات
# تغییرات بین Working Directory و Staging
git diff
# تغییرات بین Staging و آخرین commit
git diff --staged
git diff --cached # معادل
# تغییرات بین Working Directory و آخرین commit
git diff HEAD
# مقایسه دو commit
git diff a3f4b2c b2c3d4e
# مقایسه دو branch
git diff main feature-x
# تغییرات یک فایل خاص
git diff README.md
# فقط نام فایلهای تغییریافته
git diff --name-only
# آمار تغییرات
git diff --stat
خواندن خروجی diff
diff --git a/script.py b/script.py
index 4a1b2c3..5d6e7f8 100644
--- a/script.py
+++ b/script.py
@@ -10,7 +10,7 @@ def calculate(x, y):
a = x + y
b = x - y
- return a * b
+ return a * b if a > 0 else 0
def helper():
- خطوط با
-: حذف شده - خطوط با
+: اضافه شده @@ -10,7 +10,7 @@: مکان تغییر (شروع از خط ۱۰)
.gitignore – چه فایلهایی نادیده گرفته شوند
اکثر پروژهها فایلهایی دارند که نباید در Git باشند:
- وابستگیهای نصبشده (node_modules، venv)
- فایلهای کامپایل (.pyc، .class، dist/)
- تنظیمات IDE (.vscode/، .idea/)
- secrets (.env)
- لاگها (*.log)
- فایلهای OS (.DS_Store، Thumbs.db)
# .gitignore برای پروژه Python/Django
*.pyc
__pycache__/
*.egg-info/
dist/
build/
# Virtual env
venv/
env/
.venv/
# Django
db.sqlite3
media/
staticfiles/
# IDE
.vscode/
.idea/
*.swp
# OS
.DS_Store
Thumbs.db
# Secrets
.env
.env.local
*.pem
# Logs
*.log
logs/
الگوهای .gitignore
# کامنت
*.log # هر فایل با پسوند log
build/ # پوشه build (هر کجا)
/build/ # پوشه build فقط در root
docs/*.txt # فایلهای txt در docs (نه زیرپوشهها)
docs/**/*.txt # فایلهای txt در docs و همه زیرپوشهها
!important.log # exception - این یکی track شود
الگوهای آماده
سایت gitignore.io برای هر زبان/فریمورک .gitignore آماده میدهد:
curl -L "https://www.toptal.com/developers/gitignore/api/python,django,vscode"
-o .gitignore
وقتی فایلی track شده اما الان میخواهید ignore شود
# حذف از Git بدون حذف از دیسک
git rm --cached file.txt
# برای پوشه
git rm --cached -r node_modules/
# سپس .gitignore را آپدیت کنید
echo "node_modules/" >> .gitignore
git add .gitignore
git commit -m "Add node_modules to gitignore"
git rm و git mv
# حذف فایل از Git و دیسک
git rm file.txt
git commit -m "Remove file.txt"
# حذف فقط از Git (نگهداشتن روی دیسک)
git rm --cached file.txt
# تغییر نام (rename)
git mv old-name.txt new-name.txt
# معادل:
mv old-name.txt new-name.txt
git rm old-name.txt
git add new-name.txt
git show – مشاهده یک commit
# نمایش آخرین commit
git show
# نمایش یک commit خاص
git show a3f4b2c
# نمایش یک فایل در یک commit خاص
git show a3f4b2c:src/script.py
# فقط نام فایلهای یک commit
git show --name-only a3f4b2c
مثال کامل: یک چرخه کاری
# ساخت پروژه
mkdir todo-app
cd todo-app
git init
# تنظیم نام پروژه
echo "# Todo App" > README.md
# اولین فایل
cat > main.py << 'EOF'
def main():
print("Hello, Todo App!")
if __name__ == "__main__":
main()
EOF
# بررسی وضعیت
git status
# Untracked: README.md, main.py
# گذاشتن .gitignore
cat > .gitignore << 'EOF'
__pycache__/
*.pyc
.venv/
EOF
# add همه
git add .
# commit اول
git commit -m "Initial commit: project structure"
# تغییر بعدی
echo "todos = []" >> main.py
# دیدن تغییرات
git diff
# add و commit
git add main.py
git commit -m "feat: add empty todos list"
# تاریخچه
git log --oneline
# 8b9c2d4 (HEAD -> main) feat: add empty todos list
# a3f4b2c Initial commit: project structure
بهترین شیوهها
- commitهای کوچک و منطقی – یک commit = یک تغییر منطقی
- پیام commit واضح و معنادار
- قبل از commit حتماً
git statusوgit diff --stagedبزنید - هرگز secrets را commit نکنید (.env در .gitignore)
- زود و مرتب commit کنید – نه یک commit بزرگ آخر روز
- از
git add .با احتیاط (شاید فایلهای ناخواسته اضافه شوند) - هر پروژه از روز اول .gitignore داشته باشد
- Conventional Commits برای پروژههای تیمی
جمعبندی
git init: ساخت repository جدیدgit status: بررسی وضعیت فعلیgit add: افزودن به staginggit commit: ثبت در تاریخچهgit log: مشاهده تاریخچهgit diff: مقایسه تغییرات.gitignore: نادیده گرفتن فایلهاgit rmوgit mv: حذف و تغییر نام- پیامهای commit خوب: کوتاه، معنادار، فعل امری
در فصل بعد، Branchها را یاد میگیریم – قابلیتی که Git را از سایر VCSها متمایز میکند.