Git
Chapters ▾ 2nd Edition

7.3 Git Alətləri - Stashing və Təmizləmə

Stashing və Təmizləmə

Tez-tez, layihənizin bir hissəsi üzərində işlədiyiniz zaman işlər qarışıq vəziyyətdədir və başqa bir şey üzərində işləmək üçün branch-ları biraz dəyişdirmək istəyirsiniz. Məsələ burasındadır ki, bu məqama daha sonra qayıtmaq üçün yarımçıq iş görmək istəmirsiniz. Bu məsələnin cavabı git stash əmridir.

Stashing iş qovluğunuzun çirkli vəziyyətini alır - yəni dəyişdirilmiş izlənilmiş sənədlərinizi və mərhələli dəyişikliklərinizi - və istənilən vaxt yenidən tətbiq edə biləcəyiniz tamamlanmamış dəyişikliklər yığınında saxlayır (fərqli bir branch-da da).

Note
git stash push-ə köçmək

2017-ci il Oktyabr ayının sonundan etibarən Git poçt siyahısında geniş şəkildə müzakirələr aparıldı, burada git stash save əmri mövcud alternativ git stash push yerinə ləğv edildi. Bunun əsas səbəbi, git stash push seçilmiş pathspecs-ni saxlama seçimini təqdim etməsidir, git stash save-i dəstəkləmir.

git stash save tezliklə getməyəcək, buna görə birdən yox olmasından narahat olmayın. Ancaq yeni funksionallıq üçün push alternativinə keçməyə başlamaq istəyə bilərsiniz.

İşinizi Stashing Etmək

Stashing-i nümayiş etdirmək üçün layihənizə girib bir neçə sənəd üzərində işləməyə başlayacaqsınız və ola bilsin dəyişikliklərdən birini səhnələşdirəsiniz. git status işlədirsinizsə, çirkli vəziyyətinizi görə bilərsiniz:

$ git status
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   index.html

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   lib/simplegit.rb

İndi branch-ları dəyişdirmək istəyirsiniz, amma hələ işlədiyin şeyi etmək istəmirsiniz, buna görə də dəyişiklikləri gizlədəcəksiniz. Yeni bir yığını yığınınıza göndərmək üçün git stash və ya git stash push əmrlərini işlədin:

$ git stash
Saved working directory and index state \
  "WIP on master: 049d078 Create index file"
HEAD is now at 049d078 Create index file
(To restore them type "git stash apply")

İndi iş qovluğunuzun təmiz olduğunu görə bilərsiniz:

$ git status
# On branch master
nothing to commit, working directory clean

Bu nöqtədə branch-ları dəyişə və başqa yerdə işləyə bilərsiniz; dəyişiklikləriniz stack-da saxlanılır. Hansı zibil saxladığınızı görmək üçün git stash list-dən istifadə edə bilərsiniz:

$ git stash list
stash@{0}: WIP on master: 049d078 Create index file
stash@{1}: WIP on master: c264051 Revert "Add file_size"
stash@{2}: WIP on master: 21d80a5 Add number to log

Bu vəziyyətdə, əvvəl iki stash qeyd olundu, beləliklə üç fərqli stash işinə giriş əldə edə bilərsiniz. Orijinal stash əmrinin kömək çıxışında göstərilən əmrdən istifadə edərək təzə saxladığınızı yenidən tətbiq edə bilərsiniz: git stash apply.

Daha köhnə işarələrdən birini tətbiq etmək istəyirsinizsə, onu belə adlandıraraq təyin edə bilərsiniz:git stash apply stash@{2}. Bir saxlama yeri təyin etməsəniz, Git ən son stash-ı götürür və tətbiq etməyə çalışır:

$ git stash apply
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   index.html
	modified:   lib/simplegit.rb

no changes added to commit (use "git add" and/or "git commit -a")

Git’in stash-ı saxladığınız zaman geri qaytardığınız faylları yenidən dəyişdirdiyini görə bilərsiniz. Bu vəziyyətdə, stash-ı tətbiq etməyə çalışarkən təmiz bir iş qovluğuna sahib oldunuz və onu saxladığınız eyni branch-a tətbiq etməyə çalışdınız. Təmiz bir iş qovluğuna sahib olmaq və eyni branch-da tətbiq etmək, bir stash-a müvəffəqiyyətlə tətbiq etmək üçün lazım deyil. Bir branch-da bir stash saxlaya bilərsiniz, daha sonra başqa bir branch-a keçə və dəyişiklikləri yenidən tətbiq etməyə çalışa bilərsiniz. Bir stash tətbiq edərkən iş qovluğunuzda dəyişdirilmiş və sənədləşdirilməmiş fayllara da sahib ola bilərsiniz - Git bir şeyi artıq təmiz bir şəkildə tətbiq etmirsə, konfliktləri birləşdirəcəkdir.

Fayllarınızdakı dəyişikliklər yenidən tətbiq edildi, lakin əvvəllər səhnələşdirdiyiniz fayl yenidən bərpa olunmadı. Bunu etmək üçün mərhələli dəyişiklikləri yenidən tətbiq etməyini demək üçün --index seçimi ilə git stash apply əmrini çalıştırmalısınız. Bunun əvəzinə işləsəniz, əvvəlki vəziyyətinizə qayıdardınız:

$ git stash apply --index
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   index.html

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   lib/simplegit.rb

Tətbiq etmə seçimi yalnız stash edilmiş işi tətbiq etməyə çalışır - onu stack-nızda saxlamağa davam edirsiniz. Silmək üçün stash-ın adı ilə git stash drop-u işlədə bilərsiniz:

$ git stash list
stash@{0}: WIP on master: 049d078 Create index file
stash@{1}: WIP on master: c264051 Revert "Add file_size"
stash@{2}: WIP on master: 21d80a5 Add number to log
$ git stash drop stash@{0}
Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)

Stash-ı tətbiq etmək üçün git stash pop-ı da işə sala və dərhal stack-a ata bilərsiniz.

Kreativ Stashing

Faydalı ola biləcək bir neçə stash variantı var. Kifayət qədər populyar olan ilk seçim, git stash əmrinə --keep-index seçimidir. Bu, Git-dən yalnız hazırlanmış bütün məzmunu yaratmaq üçün deyil, həm də indeksləşdirməsini tələb edir.

$ git status -s
M  index.html
 M lib/simplegit.rb

$ git stash --keep-index
Saved working directory and index state WIP on master: 1b65b17 added the index file
HEAD is now at 1b65b17 added the index file

$ git status -s
M  index.html

Stash ilə etmək istəyə biləcəyiniz başqa bir ümumi şey izlənilməmiş faylların yanında izlənilməmiş sənədləri də zibilə salmaqdır. Varsayılan olaraq, git stash yalnız dəyişdirilmiş və səhnələşdirilmiş tracked fayllarını saxlayır. Əgər --include-untracked və ya -u qeyd etsəniz, Git, yaradılan depoda izlənməmiş faylları əlavə edəcəkdir. Bununla birlikdə, izlənməmiş faylları stash-a daxil etmək hələ açıq şəkildə ignored fayllarını daxil etməyəcək; əlavə olaraq məhəl qoyulmayan sənədləri daxil etmək üçün --all (və ya sadəcə -a) istifadə edin.

$ git status -s
M  index.html
 M lib/simplegit.rb
?? new-file.txt

$ git stash -u
Saved working directory and index state WIP on master: 1b65b17 added the index file
HEAD is now at 1b65b17 added the index file

$ git status -s
$

Nəhayət, --patch flag-nı təyin etsəniz, Git dəyişdirilmiş hər şeyi stash etmiyəcək, əksinə dəyişiklərdən hansını saxlamağınızı və iş qovluğunuzda saxlamaq istədiyinizi interaktiv şəkildə təklif edəcəkdir.

$ git stash --patch
diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index 66d332e..8bb5674 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -16,6 +16,10 @@ class SimpleGit
         return `#{git_cmd} 2>&1`.chomp
       end
     end
+
+    def show(treeish = 'master')
+      command("git show #{treeish}")
+    end

 end
 test
Stash this hunk [y,n,q,a,d,/,e,?]? y

Saved working directory and index state WIP on master: 1b65b17 added the index file

Stash-dan bir Branch Yaratmaq

İşin bir hissəsini saxlasanız, bir müddət orada qoyun və işi saxladığınız branch-da davam edin, işi yenidən tətbiq etməkdə çətinlik çəkə bilərsiniz.

Tətbiq dəyişdirdiyiniz bir faylı dəyişdirməyə çalışırsa, birləşmə konflikti yaranacaq və onu həll etməyə çalışmalı olacaqsınız. Gizlənmiş dəyişiklikləri yenidən sınamaq üçün daha asan bir yol istəyirsinizsə, seçdiyiniz branch adı ilə sizin üçün yeni bir branch yaradan git stash branch <new branchname> düyməsini işə sala bilərsiniz. İşləyin, işinizi orada yenidən tətbiq edin və sonra müvəffəqiyyətlə tətbiq olunarsa saxlayın:

$ git stash branch testchanges
M	index.html
M	lib/simplegit.rb
Switched to a new branch 'testchanges'
On branch testchanges
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   index.html

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   lib/simplegit.rb

Dropped refs/stash@{0} (29d385a81d163dfd45a452a2ce816487a6b8b014)

Bu stashed işi asanlıqla bərpa etmək və yeni bir branch-da işləmək üçün gözəl bir qısayoldur.

İş Qovluğunuzun Təmizlənməsi

Nəhayət, işinizdəki bəzi işləri və ya faylları saxlamaq istəməyəcəksiniz, o zaman sadəcə bunlardan qurtulun; git clean əmri bunun üçündür.

İş qovluğunuzu təmizləməyin bəzi ümumi səbəbləri birləşmə və ya xarici alətlər nəticəsində əmələ gələn qırıntıları aradan qaldırmaq və ya təmiz bir quruluşu idarə etmək üçün tikinti əsərlərini silmək ola bilər.

Bu əmrlə olduqca diqqətli olmaq istərdiniz, çünki işləmə qovluğundan izlənilməyən faylları silmək üçün hazırlanmışdır. Fikrinizi dəyişirsinizsə, bu faylların məzmununun alınmasına çox vaxt rast gəlinmir. Daha etibarlı bir seçim, hər şeyi aradan qaldırmaq, ancaq bir yerə yığmaq üçün git stash --all işlətməkdir.

Cruft fayllarını silmək və ya iş qovluğunuzu təmizləmək istədiyinizi düşünsək, bunu git clean ilə edə bilərsiniz. İşləmə qovluğundakı bütün izlənilməmiş faylları silmək üçün, bütün faylları və nəticədə boş qalan subdirectory-ləri silən git clean -f -d düyməsini işə sala bilərsiniz. -f, force və ya “həqiqətən bunu et” deməkdir və Git konfiqurasiya dəyişəninin clean.requireForce açıq şəkildə false olaraq ayarlanmadığı təqdirdə tələb olunur.

Nə edəcəyini görmək istəyirsinizsə, əmri --dry-run (və ya -n) seçimi ilə işlədə bilərsiniz, yəni “quru işləyin və nəyi çıxardığınızı mənə deyin.”.

$ git clean -d -n
Would remove test.o
Would remove tmp/

Varsayılan olaraq, git clean əmri yalnız göz ardı edilməyən yoxlanılmamış faylları siləcəkdir. .gitignore-dakı bir nümunə ilə uyğun gələn hər hansı bir fayl silinməyəcək. Bu faylları da silmək istəyirsinizsə, məsələn, bir yığımdan yaradılan bütün .o fayllarını silmək istəyirsinizsə, beləliklə tamamilə təmiz bir yığın yarada bilərsiniz, təmiz əmrinə -x əlavə edə bilərsiniz.

$ git status -s
 M lib/simplegit.rb
?? build.TMP
?? tmp/

$ git clean -n -d
Would remove build.TMP
Would remove tmp/

$ git clean -n -d -x
Would remove build.TMP
Would remove test.o
Would remove tmp/

git clean əmrinin nə ediləcəyini bilmirsinizsə, -n-i -f-ə dəyişdirmədən və real olaraq yerinə yetirmədən əvvəl həmişə bir -n ilə işləyin. Prosesə diqqətli olmağınızın başqa bir yolu, -i or “interactive” flag-la işlətməkdir.

Bu, təmiz əmri interaktiv bir rejimdə işlədəcəkdir.

$ git clean -x -i
Would remove the following items:
  build.TMP  test.o
*** Commands ***
    1: clean                2: filter by pattern    3: select by numbers    4: ask each             5: quit
    6: help
What now>

Bu şəkildə hər bir faylı ayrı-ayrılıqda nəzərdən keçirə və ya interaktiv şəkildə silmək üçün nümunələri təyin edə bilərsiniz.

Note

Git-dən iş qovluğunuzu təmizləməsini istəməyinizdə daha güclü olmanız lazım ola biləcəyi qəribə bir vəziyyət var. Digər Git depolarını (bəlkə də submodul kimi) kopyaladığınız və ya klonladığınız bir iş qovluğundasınızsa, hətta git clean -fd bu qovluqları silməkdən imtina edəcəkdir. Belə hallarda vurğu üçün ikinci bir -f seçimi əlavə etməlisiniz.