رفتن به محتوا
LoopX

نصب و تنظیم اولیه

توی این درس یاد می‌گیری Git را قبل از اولین commit درست تنظیم کنی: نام و ایمیل که روی هر commit ثبت می‌شود (git config --global user.name و user.email)، ایمیل noreply گیت‌هاب برای حفظ حریم خصوصی، شاخه‌ی پیش‌فرض (init.defaultBranch main)، ویرایشگر پیش‌فرض (core.editor) و alias ها. می‌فهمی تنظیمات در سه سطح (system، global، local) نگهداری می‌شوند و کدام برنده است، و با git config --list همه را می‌بینی. تمرین: تنظیمات سراسری Git را کامل کن.

مسئله: Git نمی‌داند تو کیستی

Section titled “مسئله: Git نمی‌داند تو کیستی”

Git تازه‌نصب اولین commit را رد می‌کند. بیا ببینیم دقیقاً چه می‌گوید (روی یک ماشین تمیز، بدون هیچ تنظیمی):

Terminal window
mkdir -p ~/gitlab/first && cd ~/gitlab/first
git init
echo "سلام" > a.txt
git add a.txt
git commit -m "اولین commit"
خروجی
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: git branch -m <name>
Initialized empty Git repository in /home/ali/gitlab/first/.git/
Author identity unknown
*** Please tell me who you are.
Run
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
to set your account's default identity.
Omit --global to set the identity only in this repository.
fatal: unable to auto-detect email address (got 'ali@pc.(none)')

دو چیز دیدی. اول، git init یک پیام hint (راهنمایی) درباره‌ی نام شاخه داد (مثال ۳). دوم و مهم‌تر، git commit رد شد: Author identity unknown. هر commit باید نویسنده داشته باشد (نام و ایمیل) و Git نمی‌خواهد حدس بزند. خودِ پیام هم راه‌حل را می‌گوید: دو دستور git config --global.

هر commit یک نامه‌ی رسمی است که باید امضا داشته باشد. نام و ایمیلی که تنظیم می‌کنی همان امضاست؛ Git آن را خودکار پای هر commit می‌گذارد. (و درست مثل امضا، تا وقتی اشتباهش را درست نکنی در همان commit می‌ماند؛ بعداً عوض‌کردنش یعنی بازنویسی تاریخچه.)

Git تنظیمات را از سه فایل می‌خواند. هر چه پایین‌تر است عمومی‌تر است؛ هر چه بالاتر، اختصاصی‌تر و برنده. مثلاً ایمیل کاری مخزن شرکت را در سطح local می‌گذاری و ایمیل شخصی را global.

مثال ۱: نام و ایمیل، --global

Section titled “مثال ۱: نام و ایمیل، --global”
Terminal window
git config --global user.name "Ali"
git config --global user.email "ali@example.com"
echo "--- مقدارها را بخوان:"
git config user.name
git config user.email
echo "--- و فایلی که Git ساخت (~/.gitconfig):"
cat ~/.gitconfig
خروجی
--- مقدارها را بخوان:
Ali
ali@example.com
--- و فایلی که Git ساخت (~/.gitconfig):
[user]
name = Ali
email = ali@example.com

دقت کن چه شد: git config --global کلید "مقدار" یک خط در فایل ~/.gitconfig نوشت. (این فایل قالب INI ساده دارد: بخش [user] و زیرش کلید = مقدار.) نام را داخل گیومه بنویس چون فاصله دارد (اشتباهات رایج). حالا commit قبلی کار می‌کند:

Terminal window
cd ~/gitlab/first
git commit -m "اولین commit"
echo "--- نویسنده‌ی ثبت‌شده:"
git log --format='%an <%ae> | %s'
خروجی
[master (root-commit) b7f0b04] اولین commit
1 file changed, 1 insertion(+)
create mode 100644 a.txt
--- نویسنده‌ی ثبت‌شده:
Ali <ali@example.com> | اولین commit

ایمیل و نام الان داخل commit ثبت شد. (در این آزمایش‌ها از ali@example.com استفاده می‌کنم؛ example.com یک دامنه‌ی رزرو‌شده برای مثال است.)

مثال ۲: ایمیل noreply گیت‌هاب

Section titled “مثال ۲: ایمیل noreply گیت‌هاب”

اگر کد را روی GitHub عمومی می‌گذاری، ایمیل داخل هر commit برای همه قابل‌دیدن است (در git log و روی سایت). برای حفظ حریم خصوصی، GitHub یک ایمیل مخصوص می‌دهد که commit ها را به حسابت وصل می‌کند ولی ایمیل واقعی را فاش نمی‌کند: ایمیل noreply. شکلش شناسه+نام‌کاربری@users.noreply.github.com است؛ مقدار دقیق خودت را در GitHub، بخش Settings ← Emails می‌بینی (و می‌توانی گزینه‌ی «Keep my email addresses private» را روشن کنی). تنظیمش همان دستور قبل است، فقط مقدار فرق دارد. با یک مقدار نمونه نشان می‌دهم (شناسه و نام کاربری فرضی‌اند):

Terminal window
git config --global user.email "12345678+example-user@users.noreply.github.com"
git config user.email
git config --global user.email "ali@example.com"
خروجی
12345678+example-user@users.noreply.github.com

(آخرین خط ایمیل را به مقدار قبلی برمی‌گرداند. روی GitHub واقعی، مقدار noreply حساب خودت را بگذار. این مقدار را من اجرا نکرده‌ام که روی GitHub به حساب شما وصل شود؛ فقط خود دستور git config را آزمایش کرده‌ام.)

مثال ۳: شاخه‌ی پیش‌فرض، init.defaultBranch

Section titled “مثال ۳: شاخه‌ی پیش‌فرض، init.defaultBranch”

وقتی git init زدی، پیام hint از اسم شاخه‌ی اول حرف می‌زد: Git سال‌ها اسم پیش‌فرض را master می‌گذاشت و حالا توصیه می‌شود main. GitHub هم مخزن‌های تازه را با main می‌سازد. اگر تنظیمش نکنی، مخزن محلی‌ات master و مخزن GitHub main می‌شود و گیج می‌شوی. تنظیم یک‌بار برای همیشه:

Terminal window
mkdir -p ~/gitlab/branchname && cd ~/gitlab/branchname
echo "--- قبل از تنظیم: نام شاخه‌ی اول؟"
git init -q && git branch --show-current
cd .. && rm -rf branchname
git config --global init.defaultBranch main
mkdir -p branchname && cd branchname
echo "--- بعد از تنظیم:"
git init
git branch --show-current
خروجی
--- قبل از تنظیم: نام شاخه‌ی اول؟
master
--- بعد از تنظیم:
Initialized empty Git repository in /home/ali/gitlab/branchname/.git/
main

حالا هیچ hint ای نمی‌آید و شاخه‌ی اول main است. برای مخزنی که از قبل با master ساخته‌ای، اسمش را با git branch -m main عوض کن (درس branch).

مثال ۴: سه سطح، و برنده کیست؟

Section titled “مثال ۴: سه سطح، و برنده کیست؟”

همه‌ی تنظیمات را با مبدأشان ببین (--show-origin فایل را نشان می‌دهد و --show-scope سطح را):

Terminal window
cd ~/gitlab/first
echo "--- همه‌ی تنظیمات با فایل مبدأ:"
git config --list --show-origin | head -6
echo "--- و فقط سطح هر مقدار:"
git config --list --show-scope | head -8
خروجی
--- همه‌ی تنظیمات با فایل مبدأ:
file:/home/ali/.gitconfig user.name=Ali
file:/home/ali/.gitconfig user.email=ali@example.com
file:/home/ali/.gitconfig init.defaultbranch=main
file:.git/config core.repositoryformatversion=0
file:.git/config core.filemode=true
file:.git/config core.bare=false
--- و فقط سطح هر مقدار:
global user.name=Ali
global user.email=ali@example.com
global init.defaultbranch=main
local core.repositoryformatversion=0
local core.filemode=true
local core.bare=false
local core.logallrefupdates=true

حالا یک مخزن «کاری» را فرض کن که باید با ایمیل شرکت commit بزنی. در سطح local (بدون --global) ایمیل دیگری می‌گذارم و می‌بینم کدام برنده است:

Terminal window
cd ~/gitlab/first
git config user.email "ali@company.example"
echo "--- مقدار مؤثر و مبدأش:"
git config --show-origin user.email
echo "--- همه‌ی مقدارهای user.email (از همه‌ی سطح‌ها):"
git config --show-origin --get-all user.email
echo "--- مخزن دیگر، همان کاربر:"
cd ~/gitlab/branchname
git config --show-origin user.email
خروجی
--- مقدار مؤثر و مبدأش:
file:.git/config ali@company.example
--- همه‌ی مقدارهای user.email (از همه‌ی سطح‌ها):
file:/home/ali/.gitconfig ali@example.com
file:.git/config ali@company.example
--- مخزن دیگر، همان کاربر:
file:/home/ali/.gitconfig ali@example.com

مقدار local برنده شد؛ ولی فقط داخل همین مخزن. مخزن دیگر هنوز ایمیل global را می‌بیند. (قاعده: هر چه اختصاصی‌تر، برنده‌تر؛ local ← global ← system.)

مثال ۵: ویرایشگر پیش‌فرض

Section titled “مثال ۵: ویرایشگر پیش‌فرض”

وقتی git commit را بدون -m می‌زنی، Git یک ویرایشگر باز می‌کند تا پیام را بنویسی. اگر چیزی تنظیم نکنی ممکن است vi باز شود که برای تازه‌کار گیج‌کننده است (درس ویرایشگرها). با core.editor عوضش می‌کنی. این‌جا nano را می‌گذارم و با ترمینال مجازی صفحه‌ی واقعی را می‌بینی:

Terminal window
run_in_tmux() { tmux -u kill-server 2>/dev/null; tmux -u new-session -d -s t -x 80 -y "${TH:-20}" "$@"; sleep 1; }
screen() { tmux capture-pane -t t -p | sed -e :a -e '/^[[:space:]]*$/{$d;N;ba' -e '}'; }
git config --global core.editor nano
cd ~/gitlab/first && echo "خط دوم" >> a.txt && git add a.txt
TH=20; run_in_tmux "bash --norc"
tmux send-keys -t t "cd ~/gitlab/first && git commit" Enter; sleep 2
screen
خروجی
GNU nano 7.2 /home/ali/gitlab/first/.git/COMMIT_EDITMSG
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Changes to be committed:
# modified: a.txt
#
[ Read 8 lines ]
^G Help ^O Write Out ^W Where Is ^K Cut ^T Execute ^C Location
^X Exit ^R Read File ^\ Replace ^U Paste ^J Justify ^/ Go To Line

ویرایشگر یک فایل موقت با چند خط توضیح (با # شروع می‌شوند و نادیده گرفته می‌شوند) نشان می‌دهد: بالا پیام را بنویس، ذخیره کن و ببند. خطی که نوشتم را می‌فرستم و بعد ذخیره و خروج:

Terminal window
screen() { tmux capture-pane -t t -p | sed -e :a -e '/^[[:space:]]*$/{$d;N;ba' -e '}'; }
tmux send-keys -t t -l "خط دوم را اضافه کردم"; sleep 1
tmux send-keys -t t C-o; sleep 1; tmux send-keys -t t Enter; sleep 1; tmux send-keys -t t C-x; sleep 2
screen | tail -4
tmux -u kill-server
cd ~/gitlab/first && git log --oneline | head -2
خروجی
bash-5.2$ cd ~/gitlab/first && git commit
[master 27092d1] خط دوم را اضافه کردم
1 file changed, 1 insertion(+)
bash-5.2$
27092d1 خط دوم را اضافه کردم
b7f0b04 اولین commit

اگر ویرایشگر دیگری دوست داری: git config --global core.editor "vim" یا برای VS Code (code --wait؛ --wait لازم است تا Git صبر کند فایل بسته شود).

مثال ۶: میان‌بر دستورها، alias

Section titled “مثال ۶: میان‌بر دستورها، alias”

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

Terminal window
git config --global alias.st "status -sb"
git config --global alias.lg "log --oneline --graph --decorate"
cd ~/gitlab/first
echo "--- git st ← git status -sb:"
git st
echo "--- git lg ← git log --oneline --graph --decorate:"
git lg
خروجی
--- git st ← git status -sb:
## master
--- git lg ← git log --oneline --graph --decorate:
* 27092d1 (HEAD -> master) خط دوم را اضافه کردم
* b7f0b04 اولین commit

status -sb نسخه‌ی کوتاه و فشرده‌ی git status است (در درس بعد). aliasها هم در ~/.gitconfig زیر بخش [alias] نوشته می‌شوند.

مثال ۷: هویت جدا برای کار و شخصی، includeIf

Section titled “مثال ۷: هویت جدا برای کار و شخصی، includeIf”

اگر هم برای شرکت و هم شخصی کد می‌زنی، نمی‌خواهی هر بار یادت بماند ایمیل را عوض کنی. Git می‌تواند بر اساس پوشه تنظیم بخواند: همه‌ی مخزن‌های داخل ~/work/ ایمیل کاری، بقیه ایمیل شخصی:

Terminal window
cd ~
printf '[user]\n\temail = ali@company.example\n' > ~/.gitconfig-work
git config --global includeIf."gitdir:~/work/".path "~/.gitconfig-work"
mkdir -p ~/work/proj ~/personal/proj
(cd ~/work/proj && git init -q)
(cd ~/personal/proj && git init -q)
echo "--- داخل ~/work/proj:"
cd ~/work/proj && git config --show-origin user.email
echo "--- داخل ~/personal/proj:"
cd ~/personal/proj && git config --show-origin user.email
echo "--- فایل ~/.gitconfig حالا:"
cat ~/.gitconfig
خروجی
--- داخل ~/work/proj:
file:/home/ali/.gitconfig-work ali@company.example
--- داخل ~/personal/proj:
file:/home/ali/.gitconfig ali@example.com
--- فایل ~/.gitconfig حالا:
[user]
name = Ali
email = ali@example.com
[init]
defaultBranch = main
[core]
editor = nano
[alias]
st = status -sb
lg = log --oneline --graph --decorate
[includeIf "gitdir:~/work/"]
path = ~/.gitconfig-work

یک بار تنظیم کردی و از آن به بعد خودکار است: در ~/work/ فایل .gitconfig-work وارد می‌شود و ایمیل کاری برنده می‌شود. (gitdir:~/work/ یعنی هر مخزنی که پوشه‌ی .gitاش زیر این مسیر است.)

مثال ۸: پایان خط‌ها، CRLF و LF

Section titled “مثال ۸: پایان خط‌ها، CRLF و LF”

ویندوز انتهای هر خط را با دو نویسه (\r\n، CRLF) و لینوکس و مک با یکی (\n، LF) می‌نویسند. اگر تیم ترکیبی باشد، فایل‌ها با خط‌های متفاوت وارد مخزن می‌شوند و diff پر از تغییر الکی می‌شود. تنظیم core.autocrlf آن را مدیریت می‌کند. ببین یک فایل ویندوزی بدون تنظیم و با تنظیم چه می‌شود (git ls-files --eol پایان خط را در ایندکس i/ و پوشه‌ی کاری w/ نشان می‌دهد):

Terminal window
mkdir -p ~/gitlab/eol && cd ~/gitlab/eol && git init -q
printf 'line1\r\nline2\r\n' > win.txt
git add win.txt
echo "--- بدون تنظیم (CRLF همان‌طور وارد مخزن شد):"
git ls-files --eol win.txt
git config core.autocrlf input
printf 'line1\r\nline2\r\n' > win2.txt
git add win2.txt 2>&1
echo "--- با core.autocrlf=input (در مخزن LF، در پوشه‌ی کاری همان CRLF):"
git ls-files --eol win2.txt
خروجی
--- بدون تنظیم (CRLF همان‌طور وارد مخزن شد):
i/crlf w/crlf attr/ win.txt
warning: in the working copy of 'win2.txt', CRLF will be replaced by LF the next time Git touches it
--- با core.autocrlf=input (در مخزن LF، در پوشه‌ی کاری همان CRLF):
i/lf w/crlf attr/ win2.txt

مقدارهای رایج:

مقدار رفتار برای
true هنگام commit به LF و هنگام checkout به CRLF ویندوز (تنظیم پیش‌فرض نصب‌کننده‌ی Git for Windows)
input هنگام commit به LF؛ هنگام checkout دست نمی‌زند لینوکس، مک، و WSL
false هیچ تبدیلی وقتی همه‌ی تیم LF دارد و فایل .gitattributes مشخص است

(روی ویندوز واقعی این تنظیم را اجرا نکرده‌ام؛ جدول از مستندات رسمی Git است و رفتار input را روی Ubuntu بالا دیدی.)

پشت پرده: git config فقط یک فایل متنی را ویرایش می‌کند

Section titled “پشت پرده: git config فقط یک فایل متنی را ویرایش می‌کند”

هیچ جادویی نیست: git config یک خط به فایل INI اضافه می‌کند. می‌شود فایل را مستقیم ویرایش کرد (git config --global --edit فایل را در ویرایشگر باز می‌کند). ببین هر سه فایل کجا هستند:

Terminal window
echo "--- global:"; git config --global --list --show-origin | head -3
echo "--- local (داخل یک مخزن):"; cd ~/gitlab/first && git config --local --list --show-origin | head -3
echo "--- system (ممکن است وجود نداشته باشد):"; ls -l /etc/gitconfig 2>&1 | head -1
echo "--- فایل جایگزین global (XDG):"; ls ~/.config/git 2>&1 | head -1
خروجی
--- global:
file:/home/ali/.gitconfig user.name=Ali
file:/home/ali/.gitconfig user.email=ali@example.com
file:/home/ali/.gitconfig init.defaultbranch=main
--- local (داخل یک مخزن):
file:.git/config core.repositoryformatversion=0
file:.git/config core.filemode=true
file:.git/config core.bare=false
--- system (ممکن است وجود نداشته باشد):
ls: cannot access '/etc/gitconfig': No such file or directory
--- فایل جایگزین global (XDG):
ls: cannot access '/home/ali/.config/git': No such file or directory
  • --global فایل ~/.gitconfig است (و اگر وجود داشته باشد ~/.config/git/config هم خوانده می‌شود).
  • --local فایل .git/config همان مخزن است (و پیش‌فرض وقتی داخل یک مخزن --global نمی‌زنی).
  • --system فایل /etc/gitconfig است (نیاز به sudo برای نوشتن).
  • متغیرهای محیطی هم می‌توانند برای یک بار برنده شوند: GIT_AUTHOR_NAME، GIT_AUTHOR_EMAIL و …
Terminal window
cd ~/gitlab/first
echo "تست" >> a.txt && git add a.txt
GIT_AUTHOR_NAME="مهمان" GIT_AUTHOR_EMAIL="guest@example.com" git commit -qm "با نویسنده‌ی موقت"
git log -1 --format='نویسنده: %an <%ae> | ثبت‌کننده: %cn <%ce>'
خروجی
نویسنده: مهمان <guest@example.com> | ثبت‌کننده: Ali <ali@company.example>

نویسنده‌ی این commit فقط برای همین یک بار عوض شد (متغیر محیطی از همه‌ی فایل‌ها قوی‌تر است)، ولی ثبت‌کننده (committer) همان تنظیم‌های معمولی است: Git این دو را جدا نگه می‌دارد (فرق‌شان در درس rebase دیده می‌شود).

دستور کار
git config --global user.name "نام" نام نویسنده (برای همه‌ی مخزن‌ها)
git config --global user.email "ایمیل" ایمیل نویسنده
git config --global init.defaultBranch main شاخه‌ی اول مخزن‌های تازه
git config --global core.editor nano ویرایشگر پیام commit
git config --global alias.st "status -sb" میان‌بر
git config --list همه‌ی تنظیمات (همه‌ی سطح‌ها)
git config --list --show-origin همراه با فایل مبدأ
git config کلید خواندن یک مقدار
git config --global --unset کلید حذف یک تنظیم
git config --global --edit ویرایش مستقیم فایل
کلید پرکاربرد مقدار توصیه‌شده کار
user.name / user.email نام و ایمیل خودت هویت نویسنده
init.defaultBranch main نام شاخه‌ی اول
core.editor nano یا vim یا code --wait ویرایشگر
core.autocrlf ویندوز true؛ لینوکس/مک/WSL input پایان خط‌ها
pull.rebase false یا true رفتار git pull (درس remotes)
color.ui auto (پیش‌فرض) رنگی‌بودن خروجی

۱) فراموش کردن نام و ایمیل

Section titled “۱) فراموش کردن نام و ایمیل”

مسئله‌ی ابتدای درس: Author identity unknown. راه‌حل: دو دستور git config --global.

برای اینکه تنظیم‌های اصلی‌ات به‌هم نریزد، این آزمایش را روی یک فایل جداگانه (--file) انجام می‌دهم؛ رفتار روی ~/.gitconfig دقیقاً همین است:

Terminal window
rm -f /tmp/demo.gitconfig
git config --file /tmp/demo.gitconfig user.name Ali Rezaei
echo "--- نامی که واقعاً ثبت شد:"
git config --file /tmp/demo.gitconfig user.name
cat /tmp/demo.gitconfig
خروجی
--- نامی که واقعاً ثبت شد:
Ali
[user]
name = Ali

هیچ خطایی نیامد، ولی فقط Ali ثبت شد؛ Rezaei به‌عنوان آرگومان سوم (الگوی مقدارِ قدیمی که باید جایگزین شود) حساب شد و بی‌صدا نادیده ماند. این از آن اشتباه‌های خطرناک است که خطا نمی‌دهد. (بدتر: اگر قبلاً نامی ثبت بود که با آن الگو نمی‌خواند، Git مقدار دوم را اضافه می‌کند و بعد cannot overwrite multiple values می‌گیری.) راه‌حل: نام و هر مقدار دارای فاصله را در گیومه بنویس، و بعد از تنظیم با git config user.name بخوان.

۳) غلط تایپی در اسم کلید

Section titled “۳) غلط تایپی در اسم کلید”
Terminal window
rm -f /tmp/demo.gitconfig
git config --file /tmp/demo.gitconfig user.mail "x@y.z"
echo "--- فایل (user.mail ثبت شد؛ در حالی که کلید درست user.email است):"
cat /tmp/demo.gitconfig
echo "--- و کلید درست خالی است:"
git config --file /tmp/demo.gitconfig user.email || echo "(خالی)"
rm -f /tmp/demo.gitconfig
خروجی
--- فایل (user.mail ثبت شد؛ در حالی که کلید درست user.email است):
[user]
mail = x@y.z
--- و کلید درست خالی است:
(خالی)

user.mail هم بدون خطا ثبت شد: Git هر کلیدی را می‌پذیرد، پس غلط تایپی (به‌جای user.email) بی‌اثر می‌ماند و بعداً همان خطای Author identity unknown برمی‌گردد. راه‌حل: بعد از هر تنظیم، مقدار را با git config کلید یا git config --list بخوان.

بدون --global داخل یک مخزن، تنظیم فقط برای همان مخزن است و در مخزن بعدی دوباره Author identity unknown می‌گیری. راه‌حل: برای نام و ایمیل شخصی همیشه --global؛ برای استثنای یک مخزن، local.

۵) ایمیلی که به حساب GitHub وصل نیست

Section titled “۵) ایمیلی که به حساب GitHub وصل نیست”

اگر ایمیل commit با هیچ‌کدام از ایمیل‌های حساب GitHub‌ات نخواند، commit ها روی سایت به حساب تو وصل نمی‌شوند (آواتار و نامت دیده نمی‌شود) و آمار مشارکتت ثبت نمی‌شود. راه‌حل: ایمیل noreply یا یکی از ایمیل‌های تأییدشده‌ی حساب را بگذار.

✎ تمرینآسان

همه‌ی تنظیمات فعلی Git را با نام فایل مبدأشان ببین و نام و ایمیلت را جداگانه بخوان.

دیدن جواب
Terminal window
git config --list --show-origin
echo "--- نام و ایمیل:"
git config user.name
git config user.email
خروجی
file:/home/ali/.gitconfig user.name=Ali
file:/home/ali/.gitconfig user.email=ali@example.com
file:/home/ali/.gitconfig init.defaultbranch=main
file:/home/ali/.gitconfig core.editor=nano
file:/home/ali/.gitconfig alias.st=status -sb
file:/home/ali/.gitconfig alias.lg=log --oneline --graph --decorate
file:/home/ali/.gitconfig includeif.gitdir:~/work/.path=~/.gitconfig-work
--- نام و ایمیل:
Ali
ali@example.com
✎ تمرینمتوسط

تمرین اصلی: تنظیمات سراسری Git را کامل کن: نام، ایمیل، init.defaultBranch main، ویرایشگر nano و یک alias به نام co برای checkout (یا هر دستور دلخواه). بعد با یک دستور فقط تنظیمات global را بخوان و ثابت کن یک مخزن تازه با main ساخته می‌شود و commit بدون خطا ثبت می‌شود.

دیدن جواب
Terminal window
rm -rf ~/.gitconfig
git config --global user.name "Ali"
git config --global user.email "ali@example.com"
git config --global init.defaultBranch main
git config --global core.editor nano
git config --global alias.co checkout
echo "--- فقط تنظیمات global:"
git config --global --list
echo "--- یک مخزن تازه:"
mkdir -p ~/gitlab/final && cd ~/gitlab/final
git init -q && git branch --show-current
echo x > x.txt && git add x.txt && git commit -qm "تست تنظیمات"
git log --format='%an <%ae> | %s'
خروجی
--- فقط تنظیمات global:
user.name=Ali
user.email=ali@example.com
init.defaultbranch=main
core.editor=nano
alias.co=checkout
--- یک مخزن تازه:
main
Ali <ali@example.com> | تست تنظیمات
✎ تمرینسخت

بدون دست‌زدن به تنظیم‌های هر مخزن، کاری کن که همه‌ی مخزن‌های داخل ~/oss/ با ایمیل me@oss.example و بقیه با ایمیل global commit بخورند. ثابت کن با یک commit واقعی در هر دو جا (git log).

دیدن جواب
Terminal window
printf '[user]\n\temail = me@oss.example\n' > ~/.gitconfig-oss
git config --global includeIf."gitdir:~/oss/".path "~/.gitconfig-oss"
mkdir -p ~/oss/lib ~/other/app
for d in ~/oss/lib ~/other/app; do
(cd $d && git init -q && echo x > x && git add x && git commit -qm "تست" && echo "$d: $(git log -1 --format='%ae')")
done
خروجی
/home/ali/oss/lib: me@oss.example
/home/ali/other/app: ali@example.com
⚡ بررسی سریع

اگر یک بار user.email را هم در ~/.gitconfig (global) و هم در .git/config (local) تنظیم کنی، داخل آن مخزن کدام استفاده می‌شود؟

؟ آزمونک
  1. پیام «Author identity unknown» یعنی چه و راهش چیست؟

  2. چرا ممکن است ایمیل noreply گیت‌هاب را در user.email بگذاری؟

  3. دستور git config --global user.name Ali Rezaei (بدون گیومه) چه می‌کند؟

  4. تنظیمات Git در چند سطح و به چه ترتیب اولویت‌اند؟

  5. با includeIf چه کاری ممکن است؟

  • قبل از اولین commit: git config --global user.name "نام" و user.email "ایمیل" (نام را در گیومه). بدون آن‌ها: Author identity unknown.
  • برای پروژه‌های عمومی از ایمیل noreply گیت‌هاب استفاده کن تا ایمیل واقعی‌ات فاش نشود.
  • git config --global init.defaultBranch main و core.editor nano را یک بار تنظیم کن؛ alias ها زندگی را آسان می‌کنند.
  • سه سطح: local (.git/config) ← global (~/.gitconfig) ← system (/etc/gitconfig)؛ اختصاصی‌تر برنده است. --show-origin مبدأ را نشان می‌دهد.
  • هویت جدا برای کار و شخصی: includeIf "gitdir:~/work/".
  • git config هر کلیدی را می‌پذیرد، پس بعد از تنظیم بخوان و بررسی کن (غلط تایپی و گیومه خطا نمی‌دهند).
  • core.autocrlf: ویندوز true، لینوکس/مک/WSL input.
برگه‌ی تقلب این درس
دستورکاری که می‌کند
git config --global user.name "نام"نام نویسنده
git config --global user.email "ایمیل"ایمیل نویسنده
git config --global init.defaultBranch mainشاخه‌ی اول مخزن‌های تازه
git config --global core.editor nanoویرایشگر پیام commit
git config --global alias.st "status -sb"میان‌بر
git config --list --show-originهمه‌ی تنظیمات با فایل مبدأ
git config کلیدخواندن یک مقدار
git config --global --unset کلیدحذف یک تنظیم
git config --global --editویرایش مستقیم ~/.gitconfig
git config --global includeIf."gitdir:~/work/".path "~/.gitconfig-work"تنظیم جدا برای یک پوشه