Chapters ▾ 2nd Edition

7.2 ابزارهای گیت (Git Tools) - مرحله‌بندی تعاملی (Interactive Staging)

مرحله‌بندی تعاملی (Interactive Staging)

در این بخش، با چند دستور تعاملی Git آشنا می‌شوید که به شما کمک می‌کنند کامیت‌های خود را طوری تنظیم کنید که تنها شامل ترکیب‌ها و بخش‌های مشخصی از فایل‌ها باشند. این ابزارها زمانی مفیدند که شما تغییرات زیادی در چندین فایل ایجاد کرده‌اید و بعد تصمیم می‌گیرید که این تغییرات به جای یک کامیت بزرگ و نامنظم، به چند کامیت متمرکز و جداگانه تقسیم شوند. به این ترتیب، می‌توانید مطمئن شوید که کامیت‌های شما مجموعه تغییرات منطقی و جداگانه‌ای هستند که به راحتی توسط توسعه‌دهندگان دیگر قابل بررسی می‌باشند.

اگر دستور git add را با گزینه -i یا --interactive اجرا کنید، Git وارد حالت تعاملی می‌شود و چیزی شبیه به این نمایش داده می‌شود:

$ git add -i
           staged     unstaged path
  1:    unchanged        +0/-1 TODO
  2:    unchanged        +1/-1 index.html
  3:    unchanged        +5/-1 lib/simplegit.rb

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now>

شما می‌بینید که این دستور نمایی کاملاً متفاوت از ناحیه مرحله‌بندی (staging area) نشان می‌دهد که احتمالا به آن عادت ندارید — اساساً همان اطلاعاتی که با git status می‌گیرید اما به صورت خلاصه‌تر و مفیدتر. تغییراتی که مرحله‌بندی شده‌اند در سمت چپ و تغییرات مرحله‌بندی نشده در سمت راست فهرست می‌شوند.

پس از آن بخش «دستورات» قرار دارد که به شما اجازه می‌دهد کارهای متعددی مانند مرحله‌بندی و بازگرداندن فایل‌ها، مرحله‌بندی بخش‌هایی از فایل‌ها، افزودن فایل‌های دنبال‌نشده، و نمایش تفاوت‌های مرحله‌بندی شده را انجام دهید.

مرحله‌بندی و بازگرداندن فایل‌ها (Staging and Unstaging Files)

اگر در پرامپت What now> حرف u یا عدد 2 (برای update) را تایپ کنید، از شما پرسیده می‌شود که کدام فایل‌ها را می‌خواهید مرحله‌بندی کنید:

What now> u
           staged     unstaged path
  1:    unchanged        +0/-1 TODO
  2:    unchanged        +1/-1 index.html
  3:    unchanged        +5/-1 lib/simplegit.rb
Update>>

برای مرحله‌بندی فایل‌های TODO و index.html می‌توانید شماره‌های مربوطه را وارد کنید:

Update>> 1,2
           staged     unstaged path
* 1:    unchanged        +0/-1 TODO
* 2:    unchanged        +1/-1 index.html
  3:    unchanged        +5/-1 lib/simplegit.rb
Update>>

علامت * کنار هر فایل به این معناست که آن فایل برای مرحله‌بندی انتخاب شده است. اگر پس از تایپ نکردن هیچ چیز در پرامپت Update>> کلید Enter را فشار دهید، Git هر چیزی که انتخاب شده باشد را مرحله‌بندی می‌کند:

Update>>
updated 2 paths

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now> s
           staged     unstaged path
  1:        +0/-1      nothing TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +5/-1 lib/simplegit.rb

اکنون می‌توانید ببینید که فایل‌های TODO و index.html مرحله‌بندی شده‌اند و فایل simplegit.rb هنوز مرحله‌بندی نشده است. اگر در این مرحله بخواهید فایل TODO را از مرحله‌بندی خارج کنید، باید گزینه r یا عدد 3 (برای revert) را استفاده کنید:

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now> r
           staged     unstaged path
  1:        +0/-1      nothing TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +5/-1 lib/simplegit.rb
Revert>> 1
           staged     unstaged path
* 1:        +0/-1      nothing TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +5/-1 lib/simplegit.rb
Revert>> [enter]
reverted one path

اگر دوباره وضعیت Git خود را بررسی کنید، می‌بینید که فایل TODO از مرحله‌بندی خارج شده است:

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now> s
           staged     unstaged path
  1:    unchanged        +0/-1 TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +5/-1 lib/simplegit.rb

برای مشاهده تفاوت آنچه که مرحله‌بندی کرده‌اید، می‌توانید از دستور d یا عدد 6 (برای diff) استفاده کنید. این دستور فهرستی از فایل‌های مرحله‌بندی شده را نشان می‌دهد و می‌توانید فایل‌هایی که می‌خواهید تفاوت‌های مرحله‌بندی آن‌ها را ببینید انتخاب کنید. این کار مشابه اجرای git diff --cached در خط فرمان است:

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now> d
           staged     unstaged path
  1:        +1/-1      nothing index.html
Review diff>> 1
diff --git a/index.html b/index.html
index 4d07108..4335f49 100644
--- a/index.html
+++ b/index.html
@@ -16,7 +16,7 @@ Date Finder

 <p id="out">...</p>

-<div id="footer">contact : support@github.com</div>
+<div id="footer">contact : email.support@github.com</div>

 <script type="text/javascript">

با این دستورات پایه، می‌توانید با حالت تعاملی git add ناحیه مرحله‌بندی خود را راحت‌تر مدیریت کنید.

مرحله‌بندی بخش‌هایی از فایل‌ها (Staging Patches)

همچنین امکان مرحله‌بندی بخش‌هایی از فایل‌ها و نه کل فایل وجود دارد. مثلاً اگر در فایل simplegit.rb دو تغییر ایجاد کرده‌اید و می‌خواهید یکی را مرحله‌بندی کنید و دیگری را نه، این کار در Git بسیار ساده است. در همان پرامپت تعاملی که در بخش قبلی توضیح داده شد، حرف p یا عدد 5 (برای patch) را تایپ کنید. Git از شما می‌پرسد کدام فایل‌ها را می‌خواهید به صورت جزئی مرحله‌بندی کنید؛ سپس برای هر بخش از فایل‌های انتخاب‌شده، بخش‌هایی از تفاوت فایل (hunks) را نمایش می‌دهد و از شما می‌پرسد که می‌خواهید آن‌ها را مرحله‌بندی کنید یا خیر، یکی‌یکی:

diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index dd5ecc4..57399e0 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -22,7 +22,7 @@ class SimpleGit
   end

   def log(treeish = 'master')
-    command("git log -n 25 #{treeish}")
+    command("git log -n 30 #{treeish}")
   end

   def blame(path)
Stage this hunk [y,n,a,d,/,j,J,g,e,?]?

در این مرحله گزینه‌های زیادی در اختیار دارید. با تایپ ? فهرستی از کارهایی که می‌توانید انجام دهید نمایش داده می‌شود:

Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ?
y - stage this hunk
n - do not stage this hunk
a - stage this and all the remaining hunks in the file
d - do not stage this hunk nor any of the remaining hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

به طور کلی، اگر بخواهید هر بخش را جداگانه آماده کنید، y یا n را تایپ خواهید کرد، اما آماده کردن همه بخش‌ها در برخی فایل‌ها یا رد تصمیم‌گیری برای یک بخش تا بعد نیز می‌تواند مفید باشد. اگر بخشی از یک فایل را آماده کنید و بخش دیگری را آماده نکنید، خروجی وضعیت شما به این شکل خواهد بود:

What now> 1
           staged     unstaged path
  1:    unchanged        +0/-1 TODO
  2:        +1/-1      nothing index.html
  3:        +1/-1        +4/-0 lib/simplegit.rb

وضعیت فایل simplegit.rb جالب است. نشان می‌دهد که چند خط آماده شده و چند خط آماده نشده باقی مانده‌اند. شما این فایل را به صورت جزئی آماده کرده‌اید. در این مرحله، می‌توانید از حالت افزودن تعاملی خارج شوید و با اجرای فرمان git commit فایل‌های جزئی آماده شده را ثبت کنید.

همچنین لازم نیست حتماً در حالت افزودن تعاملی باشید تا فایل‌ها را به صورت جزئی آماده کنید — می‌توانید همین اسکریپت را با استفاده از git add -p یا git add --patch در خط فرمان اجرا کنید.

علاوه بر این، می‌توانید از حالت پچ برای بازنشانی جزئی فایل‌ها با فرمان git reset --patch، بازیابی بخش‌هایی از فایل‌ها با فرمان git checkout --patch و ذخیره‌سازی جزئی فایل‌ها با فرمان git stash save --patch استفاده کنید. در ادامه، هنگام بررسی کاربردهای پیشرفته‌تر این فرمان‌ها، جزئیات بیشتری در این زمینه ارائه خواهیم داد.

scroll-to-top