شاید شما هم مث من خیلی به گیت هاب سر زده باشین اما هر سری با حجم انبوه اصطلاحاتی که تو این سایت هست، شوکه شده باشین و ندونین چی به چیه :دی

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

این چرخه تو هر آموزشی،"همواره" تکرار میشه.

بدون فوت وقت بریم سر وقت گیت.ببینیم چجوری راش بندازیم..چجوری پروژه های دیگه رو فورک کنیم و از این داستانها.

اولین کار اینه که برید تو سایت گیت هاب و یه اکانتِ تر و تمیز واسه خودتون درست کنید.

تذکّر1: ادامه ی این آموزش با این فرض جلو میره که خواننده، تفاوت بین "گیت" و "گیت هاب" رو متوجه شده باشه و این دو تا رو بتونه از هم تمیز بده.(مطمین هستم که سرچ کردنتون در اون حدِ معقولی هست که بتونید این تفاوت ها رو دربیارید.)

تذکّر2: از این به بعد هر جا لفظ گیت رو به کار بردم، منظورم سیستمِ ورژن کنترلی(revision control system) هست که توسط خط فرمان اجرا میشه و هر جا سخن از گیت هاب به میون اومد، منظورم سایتی هست با همین نام که سرویس های مبتنی بر بستر وب(hosting service) ارایه میده.

ست کردن یوزرنیم و ایمیل

قبل از شروع هر کاری باید یوزر-نیم و ایمیل تون رو واسه گیت تنظیم کنید.اگر در لینوکس هستید، این تنظیمات میره تو فایل config در مسیر git./~ میشینه.

برای ست کردن ایمیلِ کاربر جاری:

git config --global user.email "your_email@example.com"

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

git config --global user.email

ست کردن کاربر جاری:

git config --global user.name "Billy Everyteen"

و برای اطلاع از مقدار جاریش:

git config --global user.name

ست کردن ادیتور پیش فرض برای گیت

در آینده احتمالا به این موضوع برمیخورین که در حال کامیت کردن هستید و میخواین مسیج کامیت تونو با ادیتور موردعلاقه تون ویرایش کنید.توی آرچ به صورت پیش فرض vi باز میشه در این جور مواقع.چون جز بسته های کور هست.اگه میخواین ادیتورتون رو مثلا به vim تغییر بدید باید کارهای زیر رو انجام بدید.

فرض کنید میخواین پروژه تون رو که توی یکی از دایرکتوری های محلی سیستم تون هست با بقیه دنیا به اشتراک بذارید.خوب روال کار خیلی راحته.

اول از همه باید توی گیت هاب یه ریپوزیتوری یا مخزن برای پروژه لوکال تون درست کنید.این کار با زدن دکمه + که در تولبار سایت قرار داره و انتخاب گزینه New Repository به راحتی انجام میشه.تو مرحله بعد ازتون میخوان نامی برای این ریپوی جدید انتخاب کنید.(این اسم بعدا خودش تبدیل به یه آدرس یونیک برای هر پروژه تون در گیت هاب خواهد شد.) هر اسمی دوست داشتین میتونید براش بذارین.یادتون باشه تیک گزینه زیر رو بزنید:

Initialize this repository with a README

میتونید واسه پروژه تون لایسنس انتخاب کنید..من معمولا gpl رو انتخاب میکنم.روی دکمه create کلیک کنید تا ریپوتون ساخته بشه.

حالا کارمون با "گیت هاب" تموم شده.باید بریم سر وقت گیت و پروژه ای که روی هاردسیستم مون در انتظار ماست:)

.فرض کنید پروژه من تو مسیر زیر باشه:

/home/saeed/.conky

و اسمش هم ArchConky/ باشه.کافیه با یه cd کوچولو برم توش.

cd ArchConky

بعد دستور زیر رو بزنم:

git init 

یه دایرکتوری هیدن با نام git. برام میسازه.حالا دستور زیر رو بزنید:

git status

ملاحظه میکنید که لیستی از تمامی فایل ها و دایرکتوری ها رو با  رنگ قرمز برامون لیست میکنه. رنگ قرمز به این معنیه که هنوز تغییرات لوکال هستن و چیزی داخل ریپوی شما در گیت هاب قرار نگرفته.واسه اینکه بتونید این فایل ها رو بفرستید رو ریپوی گیت هاب تون باید چند تا کار به ترتیب انجام بدین.

دونه دونه، یا با استفاده از پترن ها، کل فایل ها رو به stage تون اد کنید.مثلا من فایل متنی زیر رو به استیج م اد میکنم:

git add Arch.txt

اگه یه بار دیگه از گیت تون استاتوس بگیرین، می بینین که این فایل با رنگ سبز، تو یه ردیف بالاتر قرارگرفته.به این معنی که آماده کامیت شدن هست.

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

مرحله بعد اینه که فایل اد شده مون رو کامیت کنیم.اینجوری:

git commit -m "first commit"

بعد باید بهش بگیم به کدوم ریپو در گیت هاب وصل شه:

git remote add origin https://github.com/yourAccount/yourRepo.gi

قبل از اینکه تغیرات خودمون رو بفرستیم تو گیتهاب، باید تغییرات و فایل هایِ گیتهاب رو بگیریم:

git pull origin master

اگه دستور بالا خطای fatal: refusing to merge unrelated histories رو داد دستور زیر رو بزنید:

git pull --allow-unrelated-histories 

حالا یه برنچِ پیش فرض بسازیم:

git branch --set-upstream-to=origin/master 

نکته 1:origin اسم پیش فرض ریپومون توی گیت هابه و master اسم پیش فرض برنچ مون.

نکته2: حتما حتما باید برنامه vi روی سیستم لینوکسی تون نصب باشه.اگه حذفش کردین دوباره نصبش کنید.

حالا میتونیم با خیال راحت، فایل هامونو تو گیت هاب Push کنیم:

git push -u origin master

نکته 1: سوییچِ u به گیت میگه پارامتر ها رو به خاطر بسپار.(اینکه هر سری به ریپوی origin  و به برنچ master وصل بشه)

نکته 2: سری های بعد، به راحتی میتونید "فقط" دستور push رو تایپ کنید.

نکته 3: هر سری که قراره تغییرات رو پوش کنید، گیت ازتون یوزر و پس میخواد.واسه اینکه هی نخواد Prompt بده، دستور زیر رو صادر کنید:

git config --global credential.helper wincred

*یه سری نکته اضافی*

تو این بخش سعی میکنم نکاتی که کار با گیت رو سریع تر میکنه خدمت تون عرض کنم.همین طور نکاتی که شاید لابلای کارهاتون بهش بربخورید.

برای اضافه کردن تمامی تغییرات:

git add .

اد کردن فایل های با پسوند خاص:

git add '*.txt'

کامیت کردن تغیرات:

git commit -m "MY MESSAGE HERE" #-m is the message flag

کارهای بالا رو همزمان انجام بدین:

git commit -a -m "MY MESSAGE HERE"

برای اینکه تغییراتتون رو از ریپوی محلی بریزین تو ریپوی گیت هاب:

git push origin master

*اگه به هر دلیلی به شما اجازه push کردن رو نمیده، میتونید از سوییچ force-- به همراه این دستور استفاده کنید:

git push origin master --force

پیداکردن آخرین تغییرات کامیت شده:

git diff HEAD

پیداکردن آخرین تغییر:

git diff

نکته 4:فایل های stage فایل هایی هستند که به گیت میگن:"هی گیت!ما آماده کامیت شدن هستیم."

یکی از دلایلی که فایل رو میبریم تو فاز استیج اینه که اونا از نظر گیت "قابل ردگیری باشن."

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

git diff --staged

برای اینکه فایل ها رو از تو فاز استیج بیاریم بیرون از دستور reset استفاده میکنیم.حالا فرض کنید من کل فایل هایی که تو فاز استیج هستن رو میخوام‌ آن-استیج کنم.اینجوری میشه:

git reset .

برای حذف کردن ریپو:

git remote -v
# View current remotes
origin  https://github.com/OWNER/REPOSITORY.git (fetch)
origin  https://github.com/OWNER/REPOSITORY.git (push)
destination  https://github.com/FORKER/REPOSITORY.git (fetch)
destination  https://github.com/FORKER/REPOSITORY.git (push)

git remote rm destination

برای بازگشت از حالت کامیت به حالت استیج:

git revert HEAD

برای آن-استیج کردن یک فایل بخصوص:

git reset HEAD foo.py 

برای تعریف برنچ جدید:

git branch clean_up

حالا اگه دستور branch رو بزنید میتونید تعداد برنچ هاتو رو ببینید:

git branch

سوییچ کردن بین برنچ ها:

git checkout clean_up

برای ادغام دو برنچ در همدیگه:

git merge clean_up

پاک کردن برنچ:

git branch -d clean_u

نمایش هیستوری تغیرات مربوط به یه فایل مخصوص:

gitk filename

نمایش blame مربوط به یه فایل خاص محدود به لاین های خاص:

git blame filename -L 1,10

برای پیدا کردن url ای که داریم باهاش کار میکنیم دو دستور وجود داره:

git config --get remote.origin.url

و

git remote show origin 

حذف دایرکتوری یا فایل از گیت هاب یا سیستم لوکال

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

git rm -r --cached myFolder

و برای اینکه هم از لوکال حذف بشه هم از گیت هاب:

git rm -r one-of-the-directories

و در نهایت برای اعمال تغییرات:

git commit -m "Remove duplicated directory"
git push

تغییر remote's URL

فرض کنید بخواید یو.آر.ال ریموت تون رو تغییر بدید.مثلا ممکنه پسورد گیت هابتون رو عوض کرده باشین.با استفاده از دستور زیر به سادگی این کار شدنیه:

git remote set-url origin https://github.com/newName.git

اگه بخواین از https برین رو ssh:

git remote set-url origin git@github.com:USERNAME/OTHERREPOSITORY.git

نمایش لیست remote urls;

git remote -v

تو خط های بالاتر گفتم واسه اینکه هر سری میخوایم push کنیم تو ریپو ترمینال ازمون پس نخواد باید دستور زیر رو بزنیم:

git config --global credential.helper cache

این کار باعث میشه واسه مدت 15 دقیقه،هر موقع خواستیم تغییری رو پوش کنیم دیگه یوزر پس نزنیم.البته میشه با دستور زیر این تایم رو کاستومایزشم کرد:

git config --global credential.helper 'cache --timeout=3600'

البته اینا واسه زماینه که شما دارین از پروتکل https استفاده میکنید و به ریپوتون وصل میشین.اگه از ssh استفاده کنید دیگه این دردسرها رو هم ندارین. دی:(واسه اطلاعات بیشتر:اینجا)

اتصال به گیت با پروتکل ssh:

روالش پنج مرحله ای هست.بدین صورت:

۱-Checking for existing SSH keys

دستور زیر رو بزنید:

ls -al ~/.ssh

و این خروجی رو باید ببینید:

  • id_dsa.pub
  • id_ecdsa.pub
  • id_ed25519.pub
  • id_rsa.pub

۲-Generating a new SSH key

قبل از هرچیز بسته زیر رو نصب کنید:

sudo pacman -S openssh

حالا دستور زیر رو بزنید:

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

نکته:همیشه یه فایل به نام gitignore. تو مسیر روت پروژه تون بذارید و پوشه ها و فایل هایی که دوست ندارین ردگیری بشن رو توش بذارید.نمونه فرمتش اینجا براتون گذاشتم.

تگ زنی و ریلیز دهی

tag:اشاره گری به کامیت های مشخص است.این پوینتر می تواند حاوری اطلاعاتی نظیر شناسه، سازنده ی تگ و .. باشد.

Releases:راهی برای ارایه پروژه از طریق گیت هاب به کاربران می باشد.

نکته مهم:تگ جز مفاهیم گیت است.در حالی که ریلیز، جز مفاهیم گیت هاب است.برای اینکه بتوانید از پروژه خود در گیت هاب نسخه های متخلف(releases) ارایه بدید.اول باید از طریق گیت، تگ بزنید واسه پروژه تون.

دو نوع تگ اصلی در گیت داریم:lightweight و annotated.

توصیه مهم:همواره سعی کنید تگ annotatd بسازید.(چون این نوع تگ، کل آبجکت رو در دیتابیس گیت نگه میداره.چکسام ها،ایمیل و تاریخ بهمراه پیغامی که روی تگ گذاشته میشه فقط در این نوع از تگ نگهداری میشه.و البته این تگ ها میتونن با GPG امضا بشن.)مگر اینکه نیاز به یه نسخه سبک ازتگ داشته باشید که امکانات تگ annotated رو نداشته باشه

ساخت تگ annotated :

git tag -a 0.1.0 -m "version: 0.1.0"

تذکر: سوییچ a، ورژن تگ و سوییچ mنشان دهنده پیغامی ست که بهمراه تگ نگاشته می شود.

ساخت تگlightweight :

git tag 0.1.0

تگ زدن روی کامیت خاص:

فرض کنید لیست بلندبالایی از کامیت ها دارین که میخواین روی کامیت های مشخصی تگ بزنید.برای اینکار ابتدا باید commit-id مورد نظرتونو با دستور زیر پیدا کنید:

git log

و بعدش از دستور زیر استفاده کنید:

git tag -a 0.1.1 9fceb02 -m "Message here"

تذکر: با سوییچ a ورژنی که قرار است روی این کامیت بخورد را مشخص میکنیم.عدد 9fceb02 چند رقم ابتدایی کامیت مدنظر می باشد و با سوییچ m  هم میتوان برای تگ، پیام خاصی نگاشت.

لیست تگ های ریپوی محلی:

git tag

لیست تگ های ریپوی گیت هاب:

 git ls-remote --tags 

حذف تگ از ریپوی گیت هاب:

git push --delete origin tagname

حذف تگ از ریپوی محلی:

git tag --delete tagname

سرچ کردن بین تگ های محلی:

git tag -l "0.1.0*"

برای نمایش محتویات تگی خاص:

git show 0.1.0

لیست تمامی کامیت ها:

git log --pretty=oneline

و یا:

git log --pretty=format:"%h - %an, %ar : %s"

و یا:

git log --pretty=format:"%h %s" --graph

جدول زیر لیست تمامی آپشن های دستور بالا را نشان میدهد:

Option Description of Output

%H

Commit hash

%h

Abbreviated commit hash

%T

Tree hash

%t

Abbreviated tree hash

%P

Parent hashes

%p

Abbreviated parent hashes

%an

Author name

%ae

Author email

%ad

Author date (format respects the --date=option)

%ar

Author date, relative

%cn

Committer name

%ce

Committer email

%cd

Committer date

%cr

Committer date, relative

%s

Subject

push کردن تگ های لوکال به remote:

git push origin --tags 

یا:

git push origin v1.5

یا:

git push --tags origin master

برای اصلاح تگ های موجود:

git tag <tag name> <tag name> -f -a 

این کار باعث میشه تگ تون به همراه محتوای قبلی ش تو ادییتور پیش فرض سیستم تون باز بشه.(واسه من ویم هست.) و مناسب نوشتن تگ با کامنت های طولانی و رعایت اصول نگارشی هست.

git tag <tag name> <tag name> -f -m "<new message>"

که این کار باعث میشه یک تگ جدید(با همون نام قبلی) ایجاد و تگ اصلی رو اوررایت کنه.

اصلاح کامنت تگی که در گیت هاب پوش شده

اول باید اون تگ بخصوص رو با دستور زیر(از گیت هاب) پاکش کنید:(نگران نباشید.چون توی لوکال تون نمونه همین تگ رو دارید.)

git push --delete origin tagname

بعد با دستور زیر اصلاحش کنید:

git tag <tag name> <tag name> -f -a 

و در نهایت با دستور زیر دوباره پوشش کنید:

git push origin v1.5

مرج کردن pull requestها

اول از همه تمامی رفرنس هایی که در ریموت فعلی تون وجود دارن رو لیست کنید:

git ls-remote origin  

رفرنس هایی که شامل pull هستن، در واقع همون pull request ها می باشند.

Step 1: From your project repository, check out a new branch and test the changes.

git checkout -b gavinlyonsrepo-command-line-option master
git pull git://github.com/gavinlyonsrepo/tvdoon.git command-line-option

Step 2: Merge the changes and update on GitHub.

git checkout master
git merge --no-ff gavinlyonsrepo-command-line-option
git push origin master

پاسخ به چند سوال

origin چیست؟

Aliasای ست در سیستم لوکالِ شما که به مخزن ریموت مشخصی اشاره می کند.بعنوان مثال:

git push origin branchname

شما در دستور بالا دارین میگین که برنجِ branchname رو در ریپوزیتوری ای که آلیاسش origin‌هست پوش کنه.در واقع همین ریپوزیتوری ممکنه برای افراد دیگه، نام دیگه ای داشته باشه.دستور بالا رو میشه به صورت زیر هم استفاده کرد:

git push git@github.com:git/git.git branchname

برای اینکه متوجه بشید در حال حاضر روی چه ریموتی دارین کار میکنید:

git remote  

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

git branch 

ترکیب دو مورد بالا:

git branch -r  

remote چیست؟

همون طور که میدونید، گیت یه سیستم مدیریت نسخه ی توزیع شده هست.به این معنی که اکثر کارها در اون به صورت local انجام میشه.برای ارتباط با دنیای بیرون(outWorld)، گیت قابلیتی به نام ریموت رو معرفی میکنه.در واقع ریموت ها، ریپوزیتوری های آنلاینی هستن که می تونید داخلشون push کنید یا ازشون pull بگیرین.دستور:

git remote add origin git@github.com/peter/first_app.git

میاد و یه ریموت جدید به نام origin میسازه که در آدرس:

git@github.com/peter/first_app.git

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

تعریف دوم:ریموت ها،بوک مارک هایی برای ریپوزیتوری های مختلف هستن که قصد دارین ازشون pull یا push بگیرید.

تعریف خود سایت گیت هاب:یه روش ساده واسه گفتن این جمله :"جایی که کدهای شما نگهداری میشن!" 

گیت ریموت ها رو به یک نام متناظر می کنه و ریموت پیش فرضِ ریپوزیتوری شما، نام origin رو داره.البته میشه با دستور:

git remote set-url origin new_address.git

آدرس ریموت ها رو عوض کرد.

مشارکت در دیگر پروژه ها، فورک کردن و ارسال pull request

  • Fork it: در مرحله اول باید از ریپویی که قصد مشارکت در آن را دارید فورک بگیرید.
  • Create your feature branch: در مرحله بعد برای اینکه کارتان متمایز از برنج اصلی(master)‌پیش برود باید به ازای هر feature ای که اضافه می کنید یک برنچ جدید ایجاد کنید.(best practice=به ازای هر ایشو=یک برنچ جدید).نام برنچ را متناسب با کاری که قرار است در آن ایشو انجام شود انتخاب کنید. مثلا به جای new-branch می توانید از fix-document-types استفاده کنید.پس از ساخت برنچ جدید باید روی آن برنچ کار کنید. این کار به کمک دستور checkout که بین برنچ ها سوییچ میکند انجام می پذیرد:
git checkout -b my-new-feature
  • Commit your changes: پس از آن بایستی تغییرات خود را کامیت کنید.(این تغییرات روی ریپوی محلی تان و روی برنچی که ساخته اید اعمال خواهند شد.)
git commit -am 'Add some feature'
  • Push to the branch:تغییرات را به ریپوی گیت هاب خود پوش کنید:
git push origin my-new-feature
  • Submit a pull request :D

ignore کردن فایل های Untracked شده

برای این مشکل دو راه وجود داره:

git status --porcelain | grep '^??' | cut -c4- >> .gitignore

و یا:

git ls-files --others --exclude-standard >> .gitignore

Untrack کردن فایل های Unstaged شده

git update-index --assume-unchanged filename

حذف Branch

برای حذف برنچ به صورت لوکال:

git branch -d the_local_branch

حذف برنچ از ریپوی موجود در گیت هاب:

git push origin :the_remote_branch

و یا:

git push -f origin last_known_good_commit:branch_name

اصلاح، مشاهده و پرش بین کامیت ها

لیست تمامی کامیت ها

git log --oneline  

سوییچ به کامیت خاص

git checkout <sha1>

حذف کامیت از برنچ (بازگشت به کامیتی خاص)

git reset --hard <sha> 

بازگشت از آخرین کامیت به حالت unstaged

git reset --soft <sha>

لیست تمامی فایل ها در کامیت بخصوص

git diff-tree --no-commit-id --name-only -r bd61ad98
git show --pretty="" --name-only bd61ad98   
git ls-tree --name-only -r <commit-ish>
git diff-tree --no-commit-id --name-only -r <commit-ish>

دانلود دایرکتوری خاص از گیت هاب

مواقعی پیش میاد که میخواین از گیت هاب، دایرکتوری خاصی رو دانلود کنید.فرض کنید به کتابخونه معروفی برخورید که میخواید فقط پوشه sample شو داشته باشید.تا بتونید بررسی ش کنید و بعدا اگه خواستید کلا اون پروژه رو کلون کنید.از طرفی ممکنه حجم کلی پروژه خیلی زیاد باشه.تو این جور مواقع باید چکار کرد؟(گیت هاب هم با گذاشتن یه دکمه سبز توی صفحه اول پروژه عملا داره میگه اجازه دانلود بهت نمیدم:/)

خوب باید گفت که واسه این مشکل هم راهکار وجود داره و راهکارش دور زدن این محدودیت به کمک ساب ورژن هست.(svn)

اول از همه نصبش کنید.

 sudo pacman -S subversion 

بعد اون دایرکتوری ای که میخواین رو اکسپورت بگیرید:

 svn export https://github.com/airbnb/lottie-android/tree/master/LottieSample 

البته اگه دستور بالا رو بزنید با یه هم چین اروری مواجه میشید:

svn: E170000: URL Does Not Exist

علتش هم اینه که ساب ورژن چیزی به نام master رو بعنوان برنچ نمی شناسه و به جاش از trunk استفاده میکنه.پس کافیه که عبارت tree/master رو با trunk عوض کنیم:

svn export https://github.com/airbnb/lottie-android/trunk/LottieSample

قبل از دانلود هم می تونید از دایرکتوری تون ls بگیرید:

svn ls https://github.com/gemhome/rmagick/trunk/examples   

کلون کردن برنچ خاص:

گاهی وقتا نیاز دارین یه پروژه ای رو کلون کنید و روش کار کنید اما حجمِ کلی پروژه انقد بالاست که عملیات کلون کردن ممکنه ساعت ها طول بکشه.یه راهش اینه که بیاید و ریلیزهایی که با تگ های خاصی منتشر شدن رو بگیرین.(کاربردش واسه من این بود که تونستم یه ریلیز خاص از نرم افزار monodovelo رو بگیرم و با makepkg کامپایل ش کنم.)

git clone --depth 1 --single-branch --branch monodevelop-7.0.1.24 git://github.com/mono/monodevelop.git

نکته:monodevelop-7.0.1.24 نامِ تگی هست که قراره بگیریدش.

منابع

  1. فرق بین تگ و ریلیز
  2. Git-Basics-Tagging
  3. creating-releases
  4. http://semver.org/
  5. نحوه صحیح ساخت تگ و شماره نسخه برای برنامه
  6. اصلاح تگ
  7. Git-Basics-Viewing-the-Commit-History

**برای استفاده از گیت به همراه سابلایم ادیتور از افزونه sublime-git استفاده کنید.و برای داشتن ترمینال در سابلایم از:glue

***یه سایت باحال واسه یادگیری گیت:https://try.github.io

password problem

  1. caching-your-github-password-in-git
  2. set-up-git

ssh

  1. hould-the-sudo-command-be-used-with-git
  2. Collaborative_Github_Workflow
  3. are-git-forks-actually-git-clones
  4. fork-a-repo