Git و GitHub چیست؟
کنترل نسخه یعنی بتوانید بدانید چه چیزی، چه زمانی و توسط چه کسی تغییر کرده است و در صورت نیاز به وضعیت قبلی برگردید.

روش سادهای مثل ساخت پوشههای project-final، project-final-2 و project-final-really-final شاید برای چند فایل جواب بدهد، اما با بزرگشدن پروژه نه تاریخچه شفافی میدهد، نه مقایسه دقیقی و نه همکاری چند نفر را مدیریت میکند.
Version Control چیست؟
سیستم کنترل نسخه (Version Control System یا VCS) تغییرات فایلها را ثبت میکند تا بتوانید مسیر تکامل پروژه را ببینید. هر بار که یک وضعیت معنیدار از پروژه را ثبت میکنید، در Git یک Commit میسازید. مزیت اصلی این نیست که «نسخه پشتیبان» دارید؛ مزیت مهمتر این است که تاریخچه ساختیافته، قابل مقایسه و قابل شاخهبندی دارید.
Git چیست؟
Git یک سیستم کنترل نسخه توزیعشده است. «توزیعشده» یعنی Clone معمول یک Repository فقط آخرین فایلها را نمیگیرد؛ تاریخچه Repository را نیز در اختیار شما قرار میدهد و بسیاری از عملیات Git کاملاً Local انجام میشوند. به همین دلیل برای ساخت Commit، دیدن History، ایجاد Branch یا مقایسه تغییرات الزاماً به اینترنت نیاز ندارید.
GitHub چیست؟
GitHub یک سرویس میزبانی و همکاری پیرامون Git است. Repository را میتوانید روی GitHub قرار دهید، به دیگران دسترسی بدهید، Issue بسازید، Pull Request باز کنید، Code Review انجام دهید و Workflowهای خودکار ایجاد کنید. GitHub جای Git را نمیگیرد؛ یک لایه همکاری و سرویس آنلاین روی Repositoryهای Git اضافه میکند.
تفاوت Git و GitHub
این جدول مرز این دو را روشن میکند. اگر فقط یک نکته از این بخش به خاطر بسپارید، همین است: Git ابزار کنترل نسخه است و GitHub یکی از پلتفرمهایی است که Repositoryهای Git را میزبانی میکند.

| موضوع | Git | GitHub |
|---|---|---|
| ماهیت | نرمافزار کنترل نسخه | پلتفرم میزبانی و همکاری |
| نیاز به اینترنت | برای بیشتر کارهای Local خیر | برای سرویس آنلاین بله |
| کار اصلی | Commit، Branch، Merge و History | Remote، PR، Review، Issue و Automation |
| وابستگی | مستقل از GitHub | برای Repositoryهای Git از Git استفاده میکند |
مدل ذهنی Git
مهمترین بخش آموزش Git همینجاست. اگر Working Tree، Staging Area و Repository را بفهمید، دستورهایی مثل add، commit، restore و حتی بخش زیادی از reset دیگر مجموعهای از کلمات حفظی نیستند. مستند رسمی Git نیز سه وضعیت اصلی فایل را modified، staged و committed معرفی میکند. برای مرجع اصلی میتوانید توضیح رسمی Git درباره مدل سهحالته را ببینید.
سه ناحیه Git
Working Tree همان فایلهایی است که روی آنها کار میکنید. وقتی فایلی را ویرایش میکنید، تغییر در Working Tree وجود دارد. Staging Area یا Index ناحیهای است که مشخص میکند چه نسخهای از چه تغییراتی وارد Commit بعدی شود. Repository یا Git Directory جایی است که تاریخچه، Objectها و Metadata پروژه ذخیره میشود.
- فایل را در Working Tree تغییر میدهید.
- تغییرات موردنظر را بررسی و با
git addStage میکنید. - نسخه Stageشده را با
git commitبهعنوان Snapshot در History ثبت میکنید.
Stage کردن به معنی Commit نیست. Staging Area به شما اجازه میدهد از میان چند تغییر، فقط بخشی را برای Commit بعدی انتخاب کنید. همین قابلیت یکی از دلایل ارزشمند بودن Commitهای کوچک و هدفمند است.
Commit چیست؟
Commit را بهتر است یک Snapshot معنیدار از پروژه بدانید، نه صرفاً «ذخیره فایل». هر Commit شناسهای دارد و اطلاعاتی مانند نویسنده، زمان، پیام Commit و ارتباط با Commit قبلی را ثبت میکند. این ارتباطها در کنار Branchها یک Graph از تاریخچه پروژه میسازند.
HEAD چیست؟
HEAD مرجعی است که معمولاً به Branch فعلی شما اشاره میکند و مشخص میکند در کدام نقطه History قرار دارید. وقتی بین Branchها جابهجا میشوید، HEAD نیز همراه شما به Context جدید میرود. Detached HEAD یعنی HEAD مستقیماً به یک Commit اشاره کرده و روی Branch معمولی قرار ندارید.
نصب و راهاندازی
برای شروع فقط به Git و یک Terminal نیاز دارید. روی Windows نصب Git معمولاً Git Bash را هم در اختیار شما میگذارد؛ اما بعد از نصب میتوانید همان Git را از PowerShell، Windows Terminal یا محیطهای توسعه اجرا کنید. اگر با خط فرمان Windows کار میکنید، آموزش PowerShell مکمل خوبی است.
پیشنیازها
برای این مقاله لازم نیست از قبل برنامهنویس حرفهای باشید. آشنایی پایه با فایل و پوشه، توانایی بازکردن Terminal و ویرایش یک فایل متنی کافی است. Git به زبان برنامهنویسی خاصی وابسته نیست؛ همان Workflow را میتوانید برای Source Code، Documentation، Script، Configuration یا حتی مجموعهای از فایلهای متنی استفاده کنید.
برای تمرین بهتر، یک حساب GitHub نیز بسازید، اما بخشهای Local Git بدون حساب GitHub قابل اجرا هستند. پیشنهاد میشود تمرینها را در پوشه آزمایشی انجام دهید و روی Repository کاری یا فایل مهم شرکت اولین تجربه Reset، Rebase یا Conflict Resolution را انجام ندهید.
نصب در Windows
Git را از منبع رسمی پروژه نصب کنید و پس از نصب یک Terminal جدید باز کنید:
git --versionاگر شماره نسخه نمایش داده شد، Git در دسترس است. انتخاب Git Bash، PowerShell یا CMD ماهیت Repository را تغییر نمیدهد.
نصب در Linux و macOS
در Linux معمولاً Git از Package Manager توزیع نصب میشود و در macOS نیز میتوانید از ابزارهای سیستم یا Package Manager استفاده کنید. اگر قصد دارید Git را در Server، Shell یا DevOps بهکار ببرید، آموزش Linux مسیر مکمل مناسبی است.
تنظیم نام و ایمیل
Git اطلاعات Author را در Commitها ثبت میکند:
git config --global user.name "Your Name"
git config --global user.email "you@example.com"اگر یک Repository باید هویت متفاوتی داشته باشد، همان تنظیم را داخل Repository و بدون --global اعمال کنید.
بررسی Configuration
git config --listاگر میخواهید Branch اولیه Repositoryهای جدید main باشد:
git config --global init.defaultBranch mainدر Repository موجود، نام Branch را کورکورانه تغییر ندهید؛ ابتدا Workflow پروژه و Remote را بررسی کنید.
اولین Repository
در اولین تمرین، یک پوشه ساده را به Repository تبدیل میکنیم. این بخش را واقعاً اجرا کنید؛ Git با مشاهده Stateها سریعتر از حفظ توضیحات یاد گرفته میشود.
ساخت Repository
mkdir djh-git-demo
cd djh-git-demo
git initgit init پوشه .git را میسازد و از این لحظه Git میتواند تاریخچه پروژه را مدیریت کند. فایلهای پروژه هنوز خودکار Commit نشدهاند.
بررسی Status
echo "# DJH Git Demo" > README.md
git statusGit فایل را Untracked نشان میدهد؛ یعنی فایل در Working Tree وجود دارد ولی هنوز وارد History نشده است.
اولین Stage
git add README.md
git statusاکنون نسخه فعلی فایل برای Commit آماده است. اگر فایل دوباره تغییر کند، نسخه Stageشده و نسخه Working Tree میتوانند متفاوت باشند.
اولین Commit
git commit -m "Add initial README"حالا یک Snapshot ثبت شده است. از اینجا به بعد هر تغییر معنیدار میتواند چرخه Review → Stage → Commit را طی کند.
چرخه تغییر تا Commit
استفاده حرفهای از Git بیشتر از تعداد Commandها به کیفیت همین چرخه روزمره وابسته است. قبل از Stage بدانید چه چیزی تغییر کرده، قبل از Commit نسخه Stageشده را ببینید و Commit را فقط وقتی بسازید که یک واحد منطقی از کار آماده است.
خواندن Status
git status
git status --shortقبل از عملیات حساس Status را ببینید تا Branch فعلی، فایلهای Untracked و Modified و تغییرات Staged را بشناسید.
دیدن Diff
git diff
git diff --stagedدستور اول تغییرات Stageنشده و دستور دوم چیزی را نشان میدهد که وارد Commit بعدی میشود. این بررسی جلوی Commit شدن Debug Code یا فایل ناخواسته را میگیرد.
Stage انتخابی
git add README.md
git add src/app.py
git add -pgit add -p برای انتخاب تعاملی بخشی از تغییرات مفید است و به ساخت Commitهای تمیز کمک میکند.
Commit خوب
git commit -m "Validate empty task titles"پیام Commit باید نتیجه یا هدف تغییر را روشن کند. پیامهایی مثل update یا changes بعداً ارزش کمی دارند.
تاریخچه و مقایسه
History خوب Git را به ابزار تحقیق تبدیل میکند. میتوانید بفهمید یک رفتار از چه زمانی وارد پروژه شده، کدام فایلها در Commit خاص تغییر کردهاند و دو نقطه History چه تفاوتی دارند.
خواندن History
git log
git log --oneline
git log --oneline --graph --decorate --allنمای Graph هنگام کار با Branch و Merge بسیار مفید است، چون رابطه Commitها را نشان میدهد.
مقایسه Commitها
git show COMMIT_HASH
git diff COMMIT_A COMMIT_Bاز Hash برای اشاره دقیق به Commit استفاده کنید. تا زمانی که Prefix انتخابی یکتا باشد، Git معمولاً Hash کوتاه را نیز میپذیرد.
Commit Hash چیست؟
هر Commit یک Object ID دارد. به جای عبارتهای مبهمی مثل «نسخه سوم هفته پیش»، از Hash، Tag و Branch برای اشاره دقیق به History استفاده کنید.
Branch و Merge
Branch اجازه میدهد خط جدیدی از توسعه را بدون مخلوطکردن فوری با Branch اصلی جلو ببرید. این قابلیت پایه Feature Development، Bug Fix، Pull Request و آزمایش امن است.
Branch چیست؟
Branch را «کپی کامل پروژه» در نظر نگیرید. در مدل Git، Branch یک Reference سبکوزن به Commit است و با Commitهای جدید جلو میرود.
ساخت Feature Branch
git switch -c feature/task-filter
git branchبعد از پایان کار میتوانید با git switch main به Branch اصلی برگردید.
Merge چگونه کار میکند؟
git switch main
git merge feature/task-filterاگر Branch مقصد از زمان انشعاب تغییر نکرده باشد، Git ممکن است Fast-forward کند. اگر هر دو طرف Commit مستقل داشته باشند، Merge پیچیدهتر میشود و احتمال Conflict نیز وجود دارد.
حذف Branch تمامشده
git branch -d feature/task-filterگزینه -d در برابر حذف Branchی که کامل Merge نشده محافظهکارانهتر است. حذف اجباری را بدون فهم وضعیت Branch استفاده نکنید.
Conflict و بازیابی
Conflict به معنی خرابشدن Repository نیست. Git فقط میگوید دو تغییر را نمیتواند با اطمینان خودکار ترکیب کند و تصمیم انسانی لازم است. درباره Undo نیز اول State را تشخیص دهید و بعد Command انتخاب کنید.
حل Merge Conflict
git statusفایل Conflictدار را باز کنید، نسخه نهایی صحیح را دستی بسازید، Markerها را حذف کنید و نتیجه را تست کنید. سپس:
git add path/to/conflicted-file
git commitهدف انتخاب کورکورانه «سمت من» یا «سمت آنها» نیست؛ باید منطق نهایی درست را بسازید.
لغو تغییر Local
git restore path/to/fileاین دستور تغییر Working Tree آن فایل را دور میریزد؛ قبل از اجرا Diff را بررسی کنید. برای خارجکردن فایل از Stage در حالی که تغییر فایل باقی بماند:
git restore --staged path/to/fileبرگرداندن Commit
git revert COMMIT_HASHRevert Commit قبلی را حذف نمیکند؛ یک Commit جدید میسازد که اثر آن را معکوس میکند. برای History منتشرشده این رفتار معمولاً امنتر از Rewrite است.
Reset یا Revert؟

| ابزار | کاربرد اصلی | نکته ایمنی |
|---|---|---|
| restore | تغییر فایل یا Stage | ممکن است تغییر Working Tree را دور بریزد |
| reset | جابجایی Reference و تغییر Index/Working Tree بسته به Mode | روی History منتشرشده با احتیاط زیاد |
| revert | معکوسکردن Commit با Commit جدید | برای History اشتراکی معمولاً امنتر |
| reflog | یافتن موقعیتهای قبلی Referenceها | Recovery محلی است، نه Backup دائمی |
تشخیص قبل از Undo
قبل از هر Undo سه سؤال بپرسید. اول: تغییر فقط در Working Tree است یا Stage شده؟ دوم: Commit ساخته شده است یا نه؟ سوم: Commit به Remote Push شده و احتمالاً دیگران آن را دیدهاند؟ همین سه سؤال انتخاب ابزار را بسیار امنتر میکند.
- اگر تغییر فقط در فایل Local است و دیگر نمیخواهیدش،
restoreمیتواند مناسب باشد. - اگر فقط اشتباهی Stage کردهاید، Unstage کنید و محتوای فایل را نگه دارید.
- اگر Commit Local اشتباه ساختهاید، Reset یا Amend بسته به هدف میتواند گزینه باشد.
- اگر Commit منتشر شده و تیم روی History فعلی کار میکند، معمولاً Revert را قبل از Rewrite بررسی کنید.
این Decision Framework مهمتر از حفظ Optionهای متعدد Reset است. Command قویتر لزوماً راهحل بهتر نیست؛ راهحل بهتر کمریسکترین تغییری است که نتیجه موردنظر را ایجاد میکند.
Reflog؛ آخرین نجات
git reflogاگر با Reset، Rebase یا جابهجایی Branch تصور میکنید Commitی را گم کردهاید، Reflog میتواند Hash موقعیت قبلی را نشان دهد. آن را Backup دائمی فرض نکنید.
فایلهای Repository
Repository سالم باید مشخص کند چه فایلهایی نباید Track شوند و رفتار فایلهای متنی در سیستمهای مختلف چگونه مدیریت شود. این موضوع برای تیمهایی که بین Windows، Linux و CI جابهجا میشوند مهم است.
.gitignore
.env
*.log
__pycache__/
node_modules/
dist/.gitignore برای Cache، Build Output، Dependencyهای قابل بازسازی و Secretهای Local مفید است، اما اگر Secret قبلاً Commit شده باشد، اضافهکردن آن به ignore تاریخچه قبلی را پاک نمیکند.
فایل قبلاً Track شده
git rm --cached path/to/fileبعد وضعیت را با git status بررسی و تغییر را Commit کنید. اگر فایل حاوی Secret بوده، Untrack کردن برای حل Incident کافی نیست.
LF و CRLF
Windows معمولاً با CRLF و Linux/macOS اغلب با LF سروکار دارند. تفاوت Line Ending میتواند Diffهای بزرگ و بیمعنی بسازد و برای Shell Script حتی خطای اجرایی ایجاد کند. مقاله آموزش Bash Script در ویندوز این موضوع را از سمت اجرای Bash توضیح میدهد.
.gitattributes
*.sh text eol=lfاین Rule سیاست Line Ending فایلهای .sh را روشن میکند. سیاست واقعی را متناسب با Stack و سیستم مقصد انتخاب کنید.
Remote و GitHub
Remote نامی برای Repository دیگری است که میخواهید با آن تبادل داشته باشید. GitHub یکی از رایجترین مقصدهاست، اما مفهوم Remote به GitHub محدود نیست.
Remote چیست؟
git remote -v
git remote add origin https://github.com/USERNAME/REPOSITORY.gitorigin فقط نام قراردادی رایج است؛ کلمه رزروشده جادویی نیست.
Origin چیست؟
هنگام Clone معمولاً Git Remote اصلی را origin مینامد. عبارتی مثل origin/main Remote-tracking Reference است و همان Branch محلی main نیست.
Clone و Fetch
git clone https://github.com/OWNER/REPOSITORY.git
git fetch originClone Repository را برای شروع دریافت میکند. Fetch اطلاعات جدید Remote را میگیرد بدون اینکه خودکار Branch کاری فعلی را Integrate کند.
Pull دقیقاً چه میکند؟
git pullPull فقط «دانلود» نیست؛ معمولاً Fetch را انجام میدهد و سپس تغییرات را با Branch فعلی Integrate میکند. وقتی میخواهید قبل از ادغام وضعیت Remote را ببینید، Fetch شفافتر است.
Remote-tracking Branch
عبارتهایی مثل origin/main وضعیت شناختهشده Git از Branch راه دور را نشان میدهند. بعد از Fetch این Reference بهروز میشود، اما Branch محلی main شما خودکار روی آن جابهجا نمیشود. همین تفاوت توضیح میدهد چرا Fetch فرصت بررسی میدهد و Pull یک قدم جلوتر میرود.
برای مقایسه وضعیت Local با Remote میتوانید پس از Fetch از Log یا Diff استفاده کنید. برای مثال، این Command Commitهایی را نشان میدهد که Remote دارد ولی Branch محلی شما ندارد:
git log --oneline main..origin/mainو جهت برعکس مشخص میکند چه Commitهایی Local هستند ولی هنوز روی Remote دیده نمیشوند:
git log --oneline origin/main..mainخطاهای رایج Remote
بخش مهمی از خطاهای GitHub در واقع از Git Local یا تنظیم Remote میآیند. قبل از تغییر Credential یا استفاده از Force Push، پیام خطا را دقیق بخوانید و با git status، git branch -vv و git remote -v وضعیت را مشخص کنید. حل مسئله باید از تشخیص شروع شود، نه از اجرای مجموعهای از Commandهای تصادفی.
اگر خطای repository not found میبینید، URL Remote، نام Owner/Repository و دسترسی حساب را بررسی کنید. Repository خصوصی ممکن است وجود داشته باشد ولی Credential فعلی اجازه دسترسی نداشته باشد. URL فعلی را با این دستور ببینید:
git remote get-url originاگر خطای permission denied (publickey) در SSH دارید، ابتدا مطمئن شوید Remote واقعاً SSH است، Public Key درست در حساب GitHub ثبت شده و SSH Agent به Key موردنظر دسترسی دارد. ساخت Key جدید بدون بررسی Key فعلی میتواند فقط تعداد Credentialها را بیشتر کند و Root Cause را پنهان نگه دارد.
اگر Push با non-fast-forward رد میشود، معمولاً Remote History تغییراتی دارد که Branch Local شما هنوز Integrate نکرده است. ابتدا Fetch کنید و Graph را ببینید:
git fetch origin
git log --oneline --graph --decorate --allبعد مطابق Policy پروژه Merge یا Rebase را انتخاب کنید. Force Push فقط زمانی مطرح میشود که History Rewrite واقعاً هدف شما باشد و اثر آن روی دیگران را فهمیده باشید.
اگر Git مرتب Credential میخواهد، نوع Remote و Credential Helper را بررسی کنید. این مسئله با «ذخیره Password حساب GitHub در فایل» حل نمیشود. برای HTTPS از Credential Manager یا روش Authentication مناسب استفاده کنید و برای SSH مطمئن شوید Agent و Passphrase workflow درست تنظیم شدهاند.
Push و Upstream
git push -u origin feature/task-filterپس از تنظیم Tracking، دفعات بعد معمولاً git push کافی است. اگر Push با non-fast-forward رد شد، بهجای Force Push فوری، دلیل Divergence را بررسی کنید.
| عملیات | چه میکند؟ | زمان مناسب |
|---|---|---|
| clone | Repository موجود را Local میکند | شروع کار روی پروژه موجود |
| fetch | اطلاعات جدید Remote را میگیرد | بررسی قبل از Integration |
| pull | Fetch + Integration | وقتی آماده ادغام تغییرات هستید |
| push | Commitهای Local را به Remote میفرستد | انتشار Branch |
اتصال امن GitHub
در GitHub امروزی نباید Tutorial قدیمی Username + Account Password را برای Git Push دنبال کنید. GitHub احراز هویت Password-based را برای Git Operations حذف کرده است. برای Command Line دو مسیر اصلی HTTPS و SSH وجود دارد و جزئیات فعلی را میتوانید در مستند رسمی Authentication در GitHub بررسی کنید.
HTTPS
HTTPS برای شروع ساده است و معمولاً از شبکههایی با Firewall یا Proxy راحتتر عبور میکند. میتوانید از Git Credential Manager یا GitHub CLI برای مدیریت Credential استفاده کنید. اگر Personal Access Token لازم باشد، Scope و Expiration آن را محدود به نیاز واقعی نگه دارید.
SSH
در SSH یک Key Pair میسازید؛ Private Key روی سیستم شما میماند و Public Key در GitHub ثبت میشود. Remote نمونه:
git@github.com:USERNAME/REPOSITORY.gitبرای Key شخصی بهتر است Passphrase داشته باشید و Private Key را هیچوقت در Repository، Email یا پیامرسان منتشر نکنید.
PAT چه زمانی؟
Personal Access Token یا PAT در سناریوهای HTTPS یا API میتواند لازم باشد، اما قرار نیست Token دائمی با Permission گسترده بسازید و در فایل پروژه قرار دهید. Secretهایی مانند PAT نباید وارد Commit شوند.
HTTPS یا SSH؟
HTTPS برای شروع، Proxy و Credential Manager ساده است؛ SSH برای Developerهایی که Key-based workflow را ترجیح میدهند بسیار مناسب است.
| روش | مزیت اصلی | مناسب برای |
|---|---|---|
| HTTPS | Setup ساده و سازگاری شبکهای خوب | Beginner، Proxy/Firewall، GCM |
| SSH | احراز هویت Key-based | Developerهای دائمی و محیطهای شخصی |
همکاری با GitHub Flow
وقتی Repository روی GitHub قرار گرفت، هدف فقط Push کردن روی main نیست. GitHub Flow یک Workflow سبک Branch-based است: تغییر را روی Branch جدا انجام میدهید، آن را Push میکنید، Pull Request میسازید، Review و Checkها انجام میشوند و در نهایت Merge میکنید. مرجع رسمی این Workflow در راهنمای GitHub Flow قرار دارد.
GitHub Flow چیست؟
GitHub Flow برای بسیاری از پروژهها از Workflowهای پیچیدهتر سادهتر است. Branch اصلی باید تا حد امکان قابل اعتماد بماند و هر Feature یا Fix روی Branch جدا جلو برود.
Issue و Branch
Issue میتواند Problem، Feature Request یا Task را ثبت کند. برای کار روی آن Branch معنیدار بسازید:
git switch -c fix/empty-task-titleBranch Naming قانون جهانی واحد ندارد؛ مهم این است که تیم Convention واضح و قابل پیشبینی داشته باشد.
قبل از Pull Request
قبل از بازکردن PR بهتر است Branch را یک بار مثل Reviewer بررسی کنید: git status باید وضعیت قابل انتظار داشته باشد، Commitها باید مرتبط باشند، Debug File یا Secret وارد Diff نشده باشد و Testهای پروژه اجرا شده باشند. اگر Branch مدت زیادی از Main عقب مانده است، با توجه به Policy تیم آن را بهروز کنید تا Conflict اصلی قبل از Review روشن شود.
این عادت باعث میشود PR محل کشف اشتباهات ابتدایی نباشد؛ PR باید بیشتر روی Design، Correctness و کیفیت تغییر تمرکز کند.
Pull Request
پس از چند Commit مرتبط، Branch را Push و Pull Request باز میکنید. PR فقط «درخواست Merge» نیست؛ Context تغییر، Discussion، Review، Check و History تصمیم را یکجا نگه میدارد. توضیح PR باید بگوید چه چیزی تغییر کرده، چرا لازم بوده و چگونه تست شده است.
Review و Merge
Reviewer باید Diff را بررسی کند، درباره Design یا Bug احتمالی نظر بدهد و در صورت نیاز تغییر بخواهد. پس از تأیید و موفقیت Checkهای لازم، PR Merge میشود. نوع Merge Policy میتواند Merge Commit، Squash یا Rebase باشد و باید با سیاست Repository سازگار باشد.
Fork چه زمانی؟
Fork یک Copy مستقل از Repository در فضای حساب یا Organization دیگر میسازد و برای همکاری روی پروژهای که دسترسی مستقیم Push ندارید رایج است. Clone و Fork یک چیز نیستند: Clone عملیات Local است؛ Fork یک Repository جدید در Platform میسازد.
استاندارد یک Repository خوب
Repository خوب فقط Repositoryای نیست که Build شود. فرد دیگری باید بتواند بفهمد پروژه چیست، چگونه اجرا میشود، چگونه مشارکت کند و هر تغییر چه هدفی داشته است.

Checklist قبل از Push
قبل از Push کردن Branch، یک بررسی کوتاه میتواند جلوی بسیاری از اشتباهات را بگیرد. این Checklist مخصوصاً زمانی مفید است که Repository عمومی، پروژه تیمی یا Branch دارای Pull Request فعال باشد:
- با
git statusمطمئن شوید فایل ناخواسته یا Untracked حساس باقی نمانده است. - با
git diffوgit diff --stagedتغییرات را مرور کنید. - پیام Commitها را بررسی کنید و مطمئن شوید Commitهای Debug یا موقت وارد History نشدهاند.
- Test، Lint یا Build لازم پروژه را اجرا کنید.
- فایلهای Config، Token، Private Key و Credential را دوباره بررسی کنید.
- اگر Branch تیمی است، تغییرات Remote را Fetch کنید و Divergence را قبل از Push بفهمید.
این چند دقیقه بررسی در پروژه واقعی از هزینه بسیار بیشتری برای Revert، History Cleanup، Secret Rotation یا اصلاح Pull Request جلوگیری میکند. Git ابزار ثبت دقیق تغییر است؛ کیفیت ورودی شما تعیین میکند History تا چه اندازه قابل اعتماد بماند.
README
README حداقل باید هدف پروژه، روش Setup، نحوه اجرا و محدودیتهای مهم را توضیح دهد. برای Library، API Usage یا Example کوتاه نیز مفید است.
Commitهای کوچک
Commitهای بزرگ و چندمنظوره Review را سخت میکنند. تغییرات Formatting، Refactor و Feature جدید را تا جای ممکن جدا نگه دارید. این تفکیک Revert و Debug آینده را نیز قابل اعتمادتر میکند.
Branch Naming
Convention میتواند ساده باشد: feature/...، fix/... و docs/.... مهمتر از Prefix خاص، ثبات و قابل فهم بودن نام است.
Pull Request واضح
PR خوب Scope محدود دارد. در Description میتوانید Problem، Solution، روش تست و Trade-off مهم را توضیح دهید. اگر PR صدها تغییر نامرتبط دارد، مشکل معمولاً در تقسیم Task و Commitها شکل گرفته است.
برای Repositoryهای عمومی یا تیمی، این موارد نیز بسته به پروژه مفیدند:
- LICENSE: روشنکردن مجوز استفاده و توزیع.
- CONTRIBUTING: توضیح Workflow مشارکت و Test.
- Issue/PR Template: جمعآوری Context یکسان.
- Branch Rules: جلوگیری از Push یا Merge خارج از سیاست تیم.
Git پیشرفته کاربردی
بعد از تسلط بر Commit، Branch، Merge و Remote، چند ابزار پیشرفته در کار روزمره مفید میشوند. هدف این بخش حفظ همه Optionها نیست؛ باید بدانید هر ابزار چه مسئلهای را حل میکند و کجا میتواند History را پیچیده کند.
Stash
git stash push -m "WIP task filter"
git stash list
git stash popStash برای کنارگذاشتن موقت تغییرات ناتمام مفید است و جای Commit واقعی یا Backup را نمیگیرد.
Amend
git commit --amendAmend Commit جدیدی با Identity جدید میسازد. اگر Commit قبلی Push شده باشد، این تغییر میتواند History Rewrite ایجاد کند؛ روی Branch اشتراکی با احتیاط استفاده کنید.
Rebase
git switch feature/task-filter
git rebase mainRebase میتواند Commitهای Branch را روی Base جدید بازپخش کند و History خطیتری بسازد. Commitهایی را که دیگران بر مبنای آنها کار کردهاند بدون هماهنگی Rewrite نکنید.
Cherry-pick
git cherry-pick COMMIT_HASHCherry-pick یک Commit مشخص را روی History فعلی اعمال میکند. استفاده زیاد از آن میتواند History و Mergeهای بعدی را پیچیده کند.
Tag و Release
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0Tag برای علامتگذاری نقطهای مشخص مانند نسخه منتشرشده مناسب است و برخلاف Branch معمولاً قرار نیست با Commitهای جدید جلو برود.
امنیت Git و GitHub
یکی از خطرناکترین اشتباههای Git این است که اطلاعات محرمانه وارد Commit شوند. چون Git History برای حفظ سابقه طراحی شده، پاککردن Secret پس از Push بسیار پیچیدهتر از جلوگیری از Commit آن است.
Secret را Commit نکنید
فایلهایی مثل .env، Private Key، Token، Password، Credential Cloud و Backupهای Config نباید وارد Repository عمومی شوند.
.env
.env.*
*.pem
secrets/
credentials.jsonاین Patternها نمونهاند؛ بدون بررسی ساختار پروژه Pattern بسیار کلی نسازید که فایل لازم را ناخواسته Ignore کند.
اگر Secret Push شد
فرض کنید Secret افشا شده است و فقط حذف فایل را کافی ندانید:
- Credential را در Provider مربوطه Revoke یا Rotate کنید.
- Repository و دامنه Exposure را ارزیابی کنید.
- در صورت نیاز History Cleanup کنترلشده انجام دهید.
- به همکاران درباره Rewrite History اطلاع دهید.
- Rule پیشگیرانه اضافه کنید تا Incident تکرار نشود.
Force Push
git push --force میتواند History Remote را بازنویسی کند. روی Branch شخصی کنترلشده ممکن است کاربرد داشته باشد، اما برای حل عمومی «Push rejected» مناسب نیست.
Protected Branch
برای Repository تیمی میتوانید Branch اصلی را با Ruleset یا Branch Protection محدود کنید تا Merge فقط از مسیر PR، Review یا Checkهای لازم انجام شود.
Repository عمومی یا خصوصی
Private بودن Repository به معنی مجاز بودن ذخیره Secret نیست. دسترسی ممکن است در آینده تغییر کند، Account یا Token ممکن است در معرض خطر قرار گیرد و History همچنان Secret را نگه دارد. Private Repository سطح دسترسی را محدود میکند، اما Secret Management را جایگزین نمیکند.
حداقل دسترسی
برای Token، Deploy Key، GitHub App و دسترسی همکاران اصل Least Privilege را رعایت کنید: فقط Permission لازم، فقط Repository لازم و فقط مدت لازم. Credential دائمی و گسترده برای یک Script کوچک ریسک بیدلیل ایجاد میکند. در Automation نیز تا حد امکان از Credentialهای کوتاهعمر یا Tokenهای مخصوص همان Workflow استفاده کنید.
Push Protection
GitHub قابلیتهایی برای تشخیص برخی Secretها هنگام Push دارد و در سناریوهای پشتیبانیشده میتواند Push را پیش از ورود Secret به Repository متوقف کند. این کنترل کمککننده است و جای مدیریت صحیح Secret را نمیگیرد.
پروژه عملی Git و GitHub
برای اتصال همه مفاهیم، یک پروژه کوچک با نام djh-task-tracker میسازیم. هدف پروژه پیچیدگی برنامهنویسی نیست؛ هدف این است که Lifecycle واقعی Git و GitHub را از ایجاد Repository تا Pull Request، Conflict، Merge و Tag تمرین کنید.

هدفهای تمرین
پروژه را فقط تا رسیدن به خروجی نهایی اجرا نکنید؛ در هر مرحله باید بتوانید توضیح دهید Git چه Stateای را تغییر داده است. بعد از هر Command مهم، حداقل یک بار از git status، git diff یا git log برای Verification استفاده کنید.
- تشخیص Untracked، Modified و Staged.
- ساخت Commitهای جدا و معنیدار.
- ساخت Feature Branch و Push آن.
- بازکردن Pull Request و دیدن Diff واقعی.
- ایجاد و حل Conflict کنترلشده.
- برگرداندن Repository به وضعیت تمیز و ساخت Tag.
طراحی پروژه
djh-task-tracker/
├── README.md
├── tasks.txt
├── config.example
└── .gitignoretasks.txt Taskها را نگه میدارد، config.example نمونه Config بدون Secret است و README روش استفاده را توضیح میدهد.
ساخت Repository
mkdir djh-task-tracker
cd djh-task-tracker
git init
echo "# DJH Task Tracker" > README.md
echo "1. Learn Git basics" > tasks.txt
echo ".env" > .gitignore
git add README.md tasks.txt .gitignore
git commit -m "Initialize task tracker"بعد git status و git log --oneline را بررسی کنید. این اولین Checkpoint پروژه است.
یک Repository خالی با همین نام در GitHub بسازید و Remote را تنظیم کنید. URL زیر را با Repository واقعی خودتان جایگزین کنید:
git remote add origin https://github.com/USERNAME/djh-task-tracker.git
git push -u origin mainاگر Branch اولیه شما نام دیگری دارد، نام واقعی Branch را با git branch بررسی کنید.
ایجاد Feature Branch
فرض کنید Issue پروژه این است: «Taskهای انجامشده باید Status داشته باشند».
git switch -c feature/task-statusفایل tasks.txt را به این شکل تغییر دهید:
[ ] Learn Git basics
[ ] Create GitHub pull requestسپس Diff، Stage و Commit را انجام دهید:
git diff
git add tasks.txt
git diff --staged
git commit -m "Add task status markers"
git push -u origin feature/task-statusPull Request
در GitHub از Branch جدید به main Pull Request بسازید. در Description توضیح دهید که تغییر چه Problemی را حل میکند و چگونه تست شده است. حتی در پروژه شخصی این تمرین PR را به ابزار Review تبدیل میکند.
قبل از Merge یک Commit کوچک دیگر بسازید؛ مثلاً README را بهروزرسانی کنید:
git add README.md
git commit -m "Document task status format"
git pushPull Request باید Commit جدید را نیز ببیند.
Conflict کنترلشده
برای یادگیری Conflict آن را در Repository آزمایشی عمداً ایجاد کنید. ابتدا روی main همان خط اول tasks.txt را تغییر دهید و Commit کنید؛ سپس روی Feature Branch همان خط را به شکل دیگری تغییر دهید.
git switch main
git pull
# edit tasks.txt
git add tasks.txt
git commit -m "Update first task wording"
git switch feature/task-status
# edit the same line differently
git add tasks.txt
git commit -m "Refine task status text"
git merge mainاگر Conflict ایجاد شد، فایل را باز کنید، نسخه صحیح نهایی را بسازید، Markerها را پاک کنید و سپس:
git add tasks.txt
git commit
git pushحالا PR باید Conflict حلشده و History جدید را نشان دهد.
Merge و Release
پس از Review، PR را Merge کنید و Local Main را بهروز کنید:
git switch main
git pull
git branch -d feature/task-status
git tag -a v1.0.0 -m "First task tracker release"
git push origin v1.0.0در این نقطه Workflow کامل Repository → Commit → Remote → Feature Branch → Push → Pull Request → Conflict → Review → Merge → Tag را تمرین کردهاید.
تمرینهای توسعه پروژه
بعد از پایان مسیر اصلی، این تمرینها را بدون دستور آماده انجام دهید. هدف این است که خودتان State را تشخیص دهید و Command مناسب را انتخاب کنید:
- یک فایل
notes.txtبسازید، آن را Stage کنید و بعد بدون حذف محتوا از Stage خارج کنید. - دو تغییر متفاوت در یک فایل ایجاد کنید و فقط یکی را با Patch Mode وارد Commit کنید.
- Branch جدیدی بسازید، دو Commit ایجاد کنید و Graph را با
git log --graphبررسی کنید. - یک Commit Local بسازید و قبل از Push پیام آن را با Amend اصلاح کنید.
- بعد از Fetch، تفاوت
mainوorigin/mainرا قبل از Pull بررسی کنید. - یک فایل آزمایشی را اشتباهی Commit کنید، سپس سناریوی حذف Tracking را بدون پاککردن فایل Local تمرین کنید.
اگر میتوانید برای هر تمرین توضیح دهید Working Tree، Index، HEAD و Remote-tracking Reference چه تغییری کردهاند، از مرحله حفظ دستورها عبور کردهاید و مدل Git را فهمیدهاید.
Clone و تست نهایی
git clone https://github.com/USERNAME/djh-task-tracker.git
cd djh-task-tracker
git log --oneline --graph --decorate --allREADME، فایلها و History را بررسی کنید. اگر Clone جدید بدون فایلهای Local و Secretهای سیستم شما قابل استفاده است، Repository قدم مهمی به سمت قابل حمل بودن برداشته است.
منتخب داریوش از یوتیوب
در این قسمت دو ویدئوی منتخب درباره «آموزش Git و GitHub از صفر تا صد + پروژه عملی» از یوتیوب و کانالهای آموزشی مرتبط انتخاب شدهاند. این ویدئوها با موتور و هوش مصنوعی اختصاصی سایت داریوش حقیقی دانلود، زیرنویس فارسی آنها تولید و ترجمه شده است و برای نمایش بهتر، دو ویدئوی منتخب با هم ادغام شدهاند و بهصورت یک فایل نهایی ارائه میشوند.
منبع اول، Git & GitHub Crash Course for Beginners [2026] از کانال freeCodeCamp.org با مدت 01:21:20 است؛ freeCodeCamp یک سازمان آموزشی غیرانتفاعی در حوزه برنامهنویسی و توسعه نرمافزار است. این آموزش Workflow خط فرمان Git را از مفاهیم پایه و Repository تا Branch، Merge Conflict، Fetch/Pull، Rebase و Pull Request دنبال میکند. منبع دوم، GitHub Tutorial for Beginners (2025) از کانال CodeWithChris با مدت 19:54 است؛ این کانال روی آموزش توسعه نرمافزار و برنامهنویسی تمرکز دارد و در این ویدئو Repository، Commit، Publish، History و Undo را از زاویه GitHub Desktop و محیط گرافیکی نشان میدهد.
در نسخه نهایی ویدئو این دو منبع بهصورت یک فایل ادغامشده دیده میشوند؛ بنابراین یک مسیر مکمل دارید که هم Workflow اصلی CLI را نشان میدهد و هم همان مفاهیم را در رابط گرافیکی قابل مشاهده میکند. توضیحات مقاله درباره Security، Safe Undo، Authentication و تصمیمگیری بین Commandها را مکمل ویدئو در نظر بگیرید، نه تکرار آن.
سوالات متداول
این پرسشها روی ابهامهایی تمرکز دارند که معمولاً بعد از یادگیری دستورات پایه Git و GitHub باقی میمانند.
آیا Git و GitHub یکی هستند؟
خیر. Git سیستم کنترل نسخه است و میتواند کاملاً مستقل کار کند؛ GitHub پلتفرمی برای میزبانی Repositoryهای Git و همکاری روی آنهاست.
آیا میتوان بدون GitHub از Git استفاده کرد؟
بله. Commit، Branch، Merge، History و بسیاری از عملیات Git کاملاً Local هستند. GitHub فقط یکی از مقصدهای Remote و Collaboration است.
GitHub Desktop بهتر است یا Command Line؟
برای فهم عمیقتر Git، Command Line شفافتر است؛ GitHub Desktop برای Workflow بصری و شروع سادهتر مفید است. میتوانید هر دو را روی یک Repository استفاده کنید.
تفاوت Git Fetch و Git Pull چیست؟
Fetch اطلاعات جدید Remote را میگیرد بدون اینکه خودکار Branch کاری شما را Integrate کند. Pull معمولاً Fetch را انجام میدهد و سپس تغییرات را با Branch فعلی ترکیب میکند.
Git Reset و Git Revert چه تفاوتی دارند؟
Reset میتواند Reference و بسته به Mode، Index یا Working Tree را جابهجا کند. Revert یک Commit جدید برای معکوسکردن اثر Commit قبلی میسازد و برای History اشتراکی معمولاً انتخاب امنتری است.
Merge بهتر است یا Rebase؟
هیچکدام همیشه بهتر نیست. Merge History شاخهها را حفظ میکند؛ Rebase میتواند History خطیتر بسازد ولی Commitها را بازنویسی میکند و روی History منتشرشده باید با احتیاط استفاده شود.
برای GitHub، HTTPS بهتر است یا SSH؟
HTTPS Setup ساده و سازگاری شبکهای خوبی دارد؛ SSH برای Workflow مبتنی بر Key مناسب است. انتخاب به محیط، سیاست سازمان و روش مدیریت Credential شما بستگی دارد.
چرا GitHub هنگام Push پسورد حساب را قبول نمیکند؟
GitHub Password Authentication را برای Git Operations حذف کرده است. برای HTTPS از Credential Manager، GitHub CLI یا Token مناسب استفاده کنید، یا Remote را روی SSH تنظیم کنید.
.gitignore فایل قبلاً Commitشده را حذف میکند؟
خیر. اضافهکردن Pattern به .gitignore Tracking قبلی را متوقف نمیکند؛ باید فایل را در صورت مناسب بودن از Index خارج کنید و تغییر را Commit کنید.
اگر Password یا API Key را Commit کردم چه کار کنم؟
ابتدا Credential را Revoke یا Rotate کنید و فرض را بر افشاشدن آن بگذارید. سپس History و دامنه Incident را بررسی و در صورت نیاز Cleanup کنترلشده انجام دهید.
Force Push چه زمانی خطرناک است؟
وقتی Branch مشترک است یا دیگران بر اساس History فعلی کار کردهاند، Force Push میتواند Commitهای Remote را کنار بزند و کار همکاران را مختل کند. آن را راهحل پیشفرض خطای Push ندانید.
Fork و Clone چه تفاوتی دارند؟
Fork یک Repository جدید در پلتفرمی مانند GitHub و تحت فضای حساب دیگری ایجاد میکند. Clone یک Repository را روی سیستم Local شما دریافت میکند؛ بنابراین معمولاً Fork را هم بعداً Clone میکنید.
نتیجهگیری
یادگیری Git زمانی پایدار میشود که به جای حفظ فهرست دستورها، مدل تغییرات را بفهمید: فایل در Working Tree تغییر میکند، نسخه انتخابشده وارد Staging Area میشود و Commit آن Snapshot را در History ثبت میکند. Branchها مسیرهای توسعه را جدا میکنند و Remoteهایی مانند GitHub امکان Synchronization و Collaboration را اضافه میکنند.

برای شروع حرفهای لازم نیست تمام Git را بدانید. اگر status، diff، add، commit، Branch/Merge، Fetch/Pull/Push و Pull Request را با Workflow امن یاد بگیرید، بخش بزرگی از نیاز روزمره را پوشش دادهاید. مرحله بعد، Recovery و Security است: بدانید چه زمانی Restore، Revert یا Reset مناسب است، Secret را وارد History نکنید و Force Push را بدون فهم اثر آن استفاده نکنید.
پروژه عملی این مقاله الگوی کوچکی از Workflow واقعی است. همین الگو را روی پروژههای Python، PHP، JavaScript، Bash یا هر Stack دیگری اجرا کنید و بعد بر اساس مسیر خود سراغ Rebase پیشرفته، Open Source، GitHub Actions و CI/CD بروید.



