خلاصه: اگر git diff رو بدون هیچ آرگومانی بنویسیم می‌تونیم تغییرات تویِ working directory (نسخه‌ی جدید) رو با staging area (نسخه‌ی قدیمی) مقایسه کنیم. و اگر از staged-- استفاده کنیم می‌تونیم تغییراتی که stage شدن (نسخه‌ی جدید) رو با آخرین کامیتِ فعلی (نسخه‌ی قدیمی) رو ببینیم.


خُب ما یه سری از تغییرات رو stage کردیم.

M   file1.js
A   file2.js

حالا قبل از کامیت کردنِ چیز‌هایی که در staging area داریم باید کدمون رو بازنگری کنیم. چون نمی‌خوایم که کدِ اشتباه یا بَد به ریپومون کامیت کنیم.

به عنوانِ best practice همیشه چیزی رو که در staging area دارین رو قبل از کامیت یه بازنگری کنین.

حالا دستورِ status فقط فایل‌هایی رو نشون می‌ده که تغییر داشتن. اما چطور می‌تونیم دقیقاً خط‌هایی که stage کردیم رو ببینیم؟ از دستورِ diff استفاده می‌کنیم.

از دستورِ زیر استفاده می‌کنیم تا چیزی که در staging area داریم و قراره تو کامیت بعدی باشن رو ببینیم.

git diff --staged

خروجیِ دستورِ بالا:

diff --git a/file1.js b/file1.js
index badfb70..47c3216 100644
--- a/file1.js
+++ b/file1.js
@@ -1,3 +1,5 @@
	hello
	world
	test
+sky
+ocean
diff --git a/file2.js b/file2.js
new file mode 100644
index 0000000..f5e95e7
--— /dev/null
+++ b/file2.js
@@ -@,@ +1 @@
+sky

صراحتاً مقایسه‌ی فایل‌ها با کمکِ ترمینال خیلی روشِ مناسبی نیست. برای انجامِ این کار معمولاً ما از ابزارهایِ بصری استفاده می‌کنیم. اما گمونم ضروریه که خروجیِ این دستور رو یاد بگیرین. چون زمان‌هایی هست که ممکنه به یک ابزارِ‌ بصری دسترسی نداشته باشین.

در خط اول diff با آرگومان‌هاش مشخص شده. پس داریم a/file1.js (نسخه‌ی قدیمی؛ که در آخرین کامیت داریمش) رو با b/file1.js (نسخه‌ی جدید؛ که در staging area داریمش) رو مقایسه می‌کنیم. یعنی دو نسخه از یک فایل رو داریم مقایسه می‌کنیم.

خط دوم، فقط یه سری metadata هستش. خیلی مهم نیستن.

خط سوم و چهارم، legend داریم. تغییراتِ موجود در نسخه‌ی قدیمی با علامتِ منفی نمایان می‌شن و تغییراتِ نسخه‌ی جدید با علامت مثبت.

خط پنجم؛ این هدر با اطلاعاتی در موردِ اینه که کدوم بخش از فایلمون تغییر داشته. با توجه به اینکه در این مثال، ‌فایل‌هامون خیلی کوچیکن و فقط یک خط، متن دارن اما در پروژه‌ی واقعی فایل‌تون ممکنه صدها خط از کد باشه. اگر فقط چند خط رو تغییر بدین، گیت کلِ فایل رو نشونتون نمی‌ده بلکه کدتون رو به بخش‌هایی تبدیل می‌کنه و چیزی که اینجا داریم فقط یه بخششه. هر بخش یک هدر با یه سری اطلاعات که محتوا رو بهتون می‌ده داره.

در خطِ پنجم دو تا بخش داریم. اولین بخش، با یک پیشوندِ علامت منفی نمایش داده شده. این اطلاعاتی رو در مورد نسخه‌ی قبلی (چیزی که در آخرین snapshot داریم) می‌ده. دومین بخش، که با پیشوندِ علامتِ مثبت هستش شاملِ اطلاعاتی در موردِ نسخه‌ی جدید که همون چیزی هست که در staging area داریم، میشه.

در نسخه‌ی قدیمی از خطِ یک، سه خط صادر یا extract شده (hello, world, test). در نسخه‌ی جدید که دوباره از خطِ اول شروع شده، پنج خط extract شده. (hello, world, test, sky, ocean)

خطِ نه و ده که با علامتِ مثبت شروع شدن خط‌هایی هستن که ما به نسخه‌ی جدید اضافه کردیم. پس این خط‌ها رو در staging area اضافه کردیم. سبز رنگن که بدین معناست که خط‌هایِ جدید هستن.

در خطِ 11، یه diff دیگه داریم. این بار دو تا نسخه‌ از file2 رو مقایسه می‌کنیم. به legendش نگاه کنین. در این مورد، نسخه‌ی قدیمی نداریم چون این یک فایلِ کاملاً جدید هستش. پس در آخرین کامیت هیچ فایلی با نامِ file2 نداشتیم برای همینم هست که در هِدر 0,0- داریم که بدین معناست که از خطِ‌ صفر به بعد خط extract شده چون هیچ نسخه‌ی قبلی‌ای در کار نیست. اوکی.

حالا اگر بخواین تغییراتِ در working directory رو که هنوز stage نشدن رو ببینین چی؟

برای این کار از git diff بدونِ هیچ آرگومانی استفاده می‌کنیم. این دستور چیزی رو که در مسیرِ‌کاری‌مون داریم رو با چیزی که در staging area داریم مقایسه می‌کنه.

با توجه به اینکه تمامیِ تغییرات در مسیرِ‌کاری‌ رو stage کردیم دستورِ زیر هیچ خروجی‌‌ای رو نخواهد داشت.

git diff

می‌تونیم دلیلِ بی‌خروجی بودنِ دستورِ بالا رو با status نسخه‌ی کوتاه هم تأیید کنیم.

M   file1.js
A   file2.js

تمام تغییرات در مسیرِ‌کاری‌مون در staging area هستن.

اگه برایِ file1.js تغییراتی رو بدیم. خروجیِ git status -s زیر خواهد بود.

MM  file1.js
A   file2.js

حالا دستورِ git diff خروجیِ زیر رو خواهد داشت.

diff --git a/file1.js b/flle1.js
index 47c3216..8636dbe 100644
--- a/flle1.js
+++ b/flle1.js/
@@ -1,4 +1,4 @@
—hello
+hello world
world
test
sky

با توجه به خروجیِ بالا دو نسخه از file1.js رو داریم مقایسه می‌کنیم. نسخه‌ی قبلی چیزی هست که ما در staging area داریم (a/file1.js) و نسخه‌ی جدید اونیه که در working directory داریمش.

در نسخه‌ی قدیمی که با علامتِ منفی مشخص شده خطِ hello داریم که پاک شده چون قرمزه و در نسخه‌ی جدید که چیزیه که در مسیرِ‌کاری‌مون داریم خطِ جدیدِ hello world رو داریم.

اگر ما git diff رو بدون هیچ آرگومانی بنویسیم می‌تونیم تغییرات stage نشده رو ببینیم و اگر از staged-- استفاده کنیم می‌تونیم تغییراتی که stage شدن و قراره به کامیتِ بعدی برن رو ببینیم.