Git - رفع اشتباهات


Advertisements

تمام VCS ها یک ویژگی برای اصلاح خطاها تا نقطهای خاص در نظر گرفتهاند git ویژگیای فراهم آورده است که با استفاده از آن میتوانیم برخی دستکاریهایمان را به حالت قبل برگردانیم.

توانایی بازگشت به حالت قبل در مواردی که کاربر بطور تصادفی برخی دستکاریها را روی انبار محلی انجام داده است، و میخواهد آنها را حذف کند، نقش کلیدی ایفا میکند.

بازگرداندن تغییراتی که commit نشدهاند

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

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git status -s
M string_operations.c

[jerry@CentOS src]$ git checkout string_operations.c

[jerry@CentOS src]$ git status –s

ما میتوانیم از دستور git checkout برای بازیابی فایلهای پاک شده از انبار محلی هم استفاده کنیم. Tom یک فایل را از انبار محلی خودش پاک کرده و حالا ما میخواهیم آن را برگردانیم. ما میتوانیم از git checkout استفاده کنیم

[tom@CentOS src]$ pwd
/home/tom/top_repo/project/src

[tom@CentOS src]$ ls -1
Makefile
string_operations.c

[tom@CentOS src]$ rm string_operations.c

[tom@CentOS src]$ ls -1
Makefile

[tom@CentOS src]$ git status -s
D string_operations.c

Fit کاراکتر D را قبل از فایلهایی که پاک شدهاند نشان میدهد.

[tom@CentOS src]$ git checkout string_operations.c

[tom@CentOS src]$ ls -1
Makefile
string_operations.c

[tom@CentOS src]$ git status -s

نکته: ما میتوانیم تمام این کارها را قبل از commit کردن تغییرات انجام دهیم.

پاک کردن تغییرات از Staging Area

دیدیم که با git add )عملیات افزودن( یک فایل از انبار محلی به staging area منتقل میشود. اگر کاربر، تصادفی فایلی را دستکاری و سپس به منتقل کرد، ولی ناگهانی متوجه شد که اشتباه کرده است و میخواهد تغییراتش را بازگرداند، در چنین حالتی میتوانیم از git checkout استفاده کنیم

در Git یک head pointer وجود دارد که همیشه روی آخرین commit )درواقع commit pointer هم هست( قرار دارد. اگر شما بخواهید که یک تغییر را از staging area بازگردانید، میتوانید از دستور git checkout استفاده کنید، اما باید یک پارامتر دیگر را هم به دستور اضافه کنید که آن head pointer است. این پارامتر اضافه باعث میشود که این دستور working tree را reset کند و تغییرات را از staging area پاک کند

حال بیایید فرض کنیم Tom یک فایل از انبار محلی را دستکاری کرده است. اگر ما وضعیت فایل را با git status واررسی کنیم، میبینیم که فایل دستکاری شده ولی هنوز به staging area افزوده)با دستور git add نشده است

tom@CentOS src]$ pwd
/home/tom/top_repo/project/src
# Unmodified file

[tom@CentOS src]$ git status -s

# Modify file and view it’s status.
[tom@CentOS src]$ git status -s
M string_operations.c

[tom@CentOS src]$ git add string_operations.c

Git status نشان میدهد که فایل اکنون در staging area قرار دارد، حالا باgit checkout فایل را برگردانده و وضعیت آن را با git status میبینیم

[tom@CentOS src]$ git checkout HEAD -- string_operations.c

[tom@CentOS src]$ git status -s

منتقل کردن head pointer با git reset

بعد از انجام چند تغییر ممکن است تصمیم بگیریم آنها را پاک 1 کنیم. دستور git reset برای reset یا پاک کردن برخی تغییرات بکار میرود. ما میتوانیم سه نوع متفاوت بازگردانی یا reset را انجام دهیم

دیاگرام زیر نمودار وضعیت head pointer را قبل و بعد از reset نمایش میدهد

git Tutorial git Tutorial

Soft

هر branch یک head ponter دارد که روی آخرین commit قرار دارد. اگر از دستور git reset با -soft استفاده کنیم و در ادامهاش commit ID مورد نظر را بیاوریم head pointer, بدون اینکه چیزی را از بین ببرد reset میشود

commit ID, head pointer ها برای هر branch در آدرسی نظیر آدرس زیر که برای master branch است، ذخیره میشوند .git/refs/heads/master ما میتوانیم با استفاده از دستور git log-1 آن را بازبینی کنیم

[jerry@CentOS project]$ cat .git/refs/heads/master
577647211ed44fe2ae479427a0668a4f12ed71a1

حالا با دستور git log -2 آخرین commit ID را میبینیم که با commit ID بالا یکسان خواهد بود

[jerry@CentOS project]$ git log -2

دستورات بالا نتایج زیر را در برخواهند داشت

commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@howcodex.com>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary


commit 29af9d45947dc044e33d69b9141d8d2dad37cc62
Author: Jerry Mouse <jerry@howcodex.com>
Date: Wed Sep 11 10:16:25 2013 +0530

Added compiled binary

حالا بیایید HEAD POINTER را reset کنیم

[jerry@CentOS project]$ git reset --soft HEAD~

حالا ما فقط head pointer را به اندازه یک commit, reset کردیم. بیایید محتوای git/refs/heads/master file

[jerry@CentOS project]$ cat .git/refs/heads/master
29af9d45947dc044e33d69b9141d8d2dad37cc62

commit ID تغییر کرده است، حالا بازبینی میکنیم

jerry@CentOS project]$ git log -2

دستورات بالا نتایج زیر را در برخواهند داشت:

commit 29af9d45947dc044e33d69b9141d8d2dad37cc62
Author: Jerry Mouse <jerry@howcodex.com>
Date: Wed Sep 11 10:16:25 2013 +0530

Added compiled binary


commit 94f7b26005f856f1a1b733ad438e97a0cd509c1a
Author: Jerry Mouse <jerry@howcodex.com>
Date: Wed Sep 11 10:08:01 2013 +0530

Added Makefile and renamed strings.c to string_operations.c

mixed

دستور git reset --mixed تغییراتی را از staging area باز میگرداند که هنوز commit نشده باشند. فقط تغییرات را از staging area برمیگرداند. تغییرات واقعی که در فایل داده شدهاند دست نخورده میمانند. دستور پیشفرض git reset معادل git reset --mixed است

hard

اگر از --hard استفاده کنیم staging area پاک میشود head pointer به آخرین commit یا یک commit خاص reset شده و تمام فایلهای محلیای که تغییر کردهاند پاک خواهند شد

بیاید commit ID را چک کنیم

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git log -1

دستورات بالا نتایج زیر را در برخواهند داشت:

commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@howcodex.com>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary

Jerry فایل را با اضافه کردن یک خط توضیح در ابتدای فایل دستکاری میکند

[jerry@CentOS src]$ head -2 string_operations.c
/* This line be removed by git reset operation */
#include <stdio.h>

او با git status بازبینی میکند:

[jerry@CentOS src]$ git status -s
M string_operations.c

Jerry فایل را به staging area میافزاید و بازبینی میکند:

[jerry@CentOS src]$ git add string_operations.c
[jerry@CentOS src]$ git status

دستورات بالا نتایج زیر را در برخواهند داشت:

# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
#
modified: string_operations.c
#

git status نشان میدهد که فایل اکنون در staging area است. حالا دستور git reset --hard را وارد میکنیم

[jerry@CentOS src]$ git reset --hard 577647211ed44fe2ae479427a0668a4f12ed71a1

HEAD is now at 5776472 Removed executable binary

دستور با موفقیت اجرا و در نتیجه آن فایل از staging area حذف شد و همچنین تغییراتی که در انبار محلی ایجاد شده بودند پاک شدند

[jerry@CentOS src]$ git status -s

git status نشان میدهد که فایل از staging area برداشته شده است

[jerry@CentOS src]$ head -2 string_operations.c
#include <stdio.h>

دستور head نیز نشان میدهد که تغییرات محلی نیز حذف شدهاند

Advertisements