GIT-HISTORY(1) دستورات عمومی کاربر GIT-HISTORY(1)

git-history - آزمایشی: بازنویسی تاریخچه

git history fixup <commit> [--dry-run] [--update-refs=(branches|head)] [--reedit-message] [--empty=(drop|keep|abort)]
git history reword <commit> [--dry-run] [--update-refs=(branches|head)]
git history split <commit> [--dry-run] [--update-refs=(branches|head)] [--] [<pathspec>...]

بازنویسی تاریخچه با بازآرایی یا تغییر کامیت‌های مشخص در تاریخچه.

این دستور آزمایشی است. رفتار آن ممکن است تغییر کند.

این دستور با git-rebase(1) مرتبط است از این جهت که هر دو دستور می‌توانند برای بازنویسی تاریخچه استفاده شوند؛ با این حال چند تفاوت عمده وجود دارد:

•بیشتر زیردستورهای git-history(1) می‌توانند در یک مخزن لخت (bare repository) کار کنند، زیرا نیازی به لمس نمایه (index) یا درخت کاری (worktree) ندارند. زیردستور fixup از این قاعده مستثنی است، زیرا تغییرات مرحله‌بندی‌شده (staged) را از نمایه می‌خواند.
•git-history(1) در حال حاضر هیچ‌کدام از githooks(5) را اجرا نمی‌کند. این امر ممکن است در آینده تغییر کند.
•git-history(1) به‌طور پیش‌فرض تمام شاخه‌هایی را که از نوادگان کامیت اصلی هستند به‌روزرسانی می‌کند تا به کامیت بازنویسی‌شده اشاره کنند.

به‌طور کلی، git-history(1) هدف دارد رویکردی مشخص‌تر برای اصلاح تاریخچه کامیت شما ارائه دهد که استفاده از آن در مقایسه با git-rebase(1) به‌طور کلی ساده‌تر است.

اگر می‌خواهید محدوده‌ای از کامیت‌ها را بر روی یک پایه متفاوت مجدداً اعمال کنید از git-rebase(1) استفاده کنید، یا اگر می‌خواهید محدوده‌ای از کامیت‌ها را هم‌زمان ویرایش کنید از rebaseهای تعاملی بهره ببرید.

این دستور (هنوز) با تاریخچه‌هایی که شامل ادغام هستند کار نمی‌کند. باید در عوض از git-rebase(1) با پرچم --rebase-merges استفاده کنید.

علاوه بر این، این دستور از عملیاتی که می‌توانند منجر به تعارض ادغام (merge conflict) شوند پشتیبانی نمی‌کند. این محدودیت از روی طراحی است، زیرا بازنویسی‌های تاریخچه به عنوان عملیات دارای وضعیت در نظر گرفته نشده‌اند. این محدودیت زمانی می‌تواند برداشته شود که گیت قابلیت تعارض‌های تراز اول (first-class conflicts) را به دست آورد (اگر به دست آورد).

هنگام استفاده از fixup با --empty=drop، حذف کامیت ریشه هنوز پشتیبانی نمی‌شود.

دستورات زیر برای بازنویسی تاریخچه به روش‌های مختلف در دسترس هستند:

fixup <commit>

تغییرات مرحله‌بندی‌شده فعلی را روی کامیت مشخص‌شده اعمال می‌کند. ماهیت این کار مشابه git commit --fixup=<commit> و در ادامه git rebase --autosquash <commit>~ است. تغییرات با انجام یک ادغام سه‌طرفه میان کامیت HEAD، کامیت مقصد و درخت تولیدشده از تغییرات مرحله‌بندی‌شده، روی کامیت مقصد اعمال می‌شوند.

پیام کامیت و نویسندگی کامیت مقصد به‌طور پیش‌فرض حفظ می‌شوند، مگر اینکه --reedit-message را مشخص کنید.

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

reword <commit>

پیام کامیت مشخص‌شده را بازنویسی می‌کند. تمام جزئیات دیگر این کامیت بدون تغییر باقی می‌مانند. این دستور یک ویرایشگر را به همراه پیام فعلی آن کامیت اجرا می‌کند.

split <commit> [--] [<pathspec>...]

کامیت <commit> را با انتخاب هانک‌های (hunks) ایجادشده توسط آن که به کامیت تفکیک‌شده جدید منتقل خواهند شد، به‌صورت تعاملی به دو کامیت تقسیم می‌کند. این هانک‌ها سپس در یک کامیت جدید نوشته می‌شوند که والد کامیت قبلی می‌شود. کامیت اصلی دست‌نخورده باقی می‌ماند، به جز اینکه والد آن کامیت جدید تفکیک‌شده خواهد بود.

پیام‌های کامیت مربوط به کامیت‌های تفکیک‌شده با راه‌اندازی ویرایشگر پیکربندی‌شده درخواست می‌شوند. نویسندگی کامیت همانند کامیت اصلی خواهد بود.

در صورت ارسال، <pathspec> می‌تواند برای محدود کردن اینکه کدام تغییرات باید از کامیت اصلی تفکیک شوند استفاده شود. فایل‌هایی که با هیچ‌یک از pathspecها مطابقت ندارند بخشی از کامیت اصلی باقی خواهند ماند. برای جزئیات بیشتر، مدخل pathspec در gitglossary(7) را ببینید.

انتخاب همه هانک‌ها یا هیچ‌کدام از آن‌ها نامعتبر است، زیرا منجر به خالی شدن یکی از کامیت‌ها خواهد شد.

--dry-run

هیچ ارجاعی را به‌روزرسانی نمی‌کند، بلکه در عوض به‌روزرسانی‌های ارجاع را در قالبی چاپ می‌کند که می‌تواند توسط git-update-ref(1) مصرف شود. اشیاء جدید مورد نیاز در مخزن نوشته خواهند شد، بنابراین اعمال این به‌روزرسانی‌های ارجاع چاپ‌شده به‌طور کلی ایمن است.

--reedit-message

یک ویرایشگر را برای تغییر پیام کامیت مقصد باز می‌کند.

--empty=(drop|keep|abort)

کنترل می‌کند هنگامی که یک کامیت در نتیجه fixup خالی می‌شود چه اتفاقی رخ دهد. این حالت می‌تواند در دو وضعیت پیش بیاید:
•خود مقصد fixup خالی می‌شود زیرا تغییرات مرحله‌بندی‌شده دقیقاً تمام تغییرات ایجادشده توسط آن کامیت را خنثی می‌کنند.
•یک کامیت نواده در حین بازپخش خالی می‌شود زیرا همان تغییری را ایجاد کرده بود که هم‌اکنون در یک نیا اصلاح شده است.

با drop (پیش‌فرض)، کامیت‌های خالی از تاریخچه بازنویسی‌شده حذف می‌شوند. نوادگان یک کامیت مقصد حذف‌شده مستقیماً روی والد مقصد بازپخش می‌شوند. توجه داشته باشید که حذف کامیت ریشه پشتیبانی نمی‌شود؛ بخش محدودیت‌ها (LIMITATIONS) را ببینید.

با keep، کامیت‌های خالی همان‌طور که هستند در تاریخچه بازنویسی‌شده حفظ می‌شوند.

با abort، اگر هر کامیتی خالی شود، دستور با خطا متوقف می‌شود.

--update-refs=(branches|head)

کنترل می‌کند که در صورت وجود، کدام ارجاع‌ها توسط دستور به‌روزرسانی شوند. با branches، تمام شاخه‌های محلی که به کامیت‌های نواده کامیت اصلی اشاره دارند بازنویسی خواهند شد. با head، تنها ارجاع فعلی HEAD بازنویسی می‌شود. پیش‌فرض branches است.

$ git log --oneline --stat
abc1234 (HEAD -> main) third
 third.txt | 1 +
def5678 second
 second.txt | 1 +
ghi9012 first
 first.txt | 1 +
$ echo "change" >>unrelated.txt
$ git add unrelated.txt
$ git history fixup ghi9012
$ git log --oneline --stat
jkl3456 (HEAD -> main) third
 third.txt | 1 +
mno7890 second
 second.txt | 1 +
pqr1234 first
 first.txt     | 1 +
 unrelated.txt | 1 +

افزودن مرحله‌بندی‌شده unrelated.txt در کامیت first ادغام شده است. تمام کامیت‌های نواده بر روی تاریخچه بازنویسی‌شده بازپخش شده‌اند.

$ git log --stat --oneline
3f81232 (HEAD -> main) original
 bar | 1 +
 foo | 1 +
 2 files changed, 2 insertions(+)
$ git history split HEAD
diff --git a/bar b/bar
new file mode 100644
index 0000000..5716ca5
--- /dev/null
+++ b/bar
@@ -0,0 +1 @@
+bar
(1/1) Stage addition [y,n,q,a,d,p,?]? y
diff --git a/foo b/foo
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/foo
@@ -0,0 +1 @@
+foo
(1/1) Stage addition [y,n,q,a,d,p,?]? n
$ git log --stat --oneline
7cebe64 (HEAD -> main) original
 foo | 1 +
 1 file changed, 1 insertion(+)
d1582f3 split-out commit
 bar | 1 +
 1 file changed, 1 insertion(+)

git(1), git-rebase(1), git-update-ref(1), githooks(5), gitglossary(7)

بخشی از مجموعه git(1)

2026-06-29 Git 2.55.0