Git 101 #0 – Git Nedir? Clone’u Edit’leyip Commit’leri Push Ettiniz mi?

Çok uzun zamandır elimdeki ufak tefek kod parçalarını bir Git sunucusunda paylaşmayı planlıyordum. Shell Scripting yazılarımdaki örnekleri bir şekilde paylaşıma açabilmek için oturdum biraz Git çalıştım. Notlarımı da sizlerle paylaşmak istedim. Shell Scripting 101 reposuna da buradan ulaşabilirsiniz.

git commit çıktısı
git commit çıktısı

Git Nedir? Amacı Nedir?

Bir yazılım projeniz var. Kodları yazmaya başladınız. Bir arkadaşınız “A” modülünü yazmakla meşgul. Siz de “B” modülünü yazıyorsunuz. Sonra kodlarınızı birbirinize atıp, elinizdeki kodlarla birleştiriyorsunuz. Pekala…

Aynı modül üzerindeki çalışmanızın üçüncü haftasındasınız. Bir hatanızı fark ettiniz. Acaba hatayı tetikleyecek değişikliği ne zaman yapmıştınız?

Projedeki modül sayısı 10’a, geliştirici sayısı 20’ye çıktığında ne yapacaksınız? Bir kişinin ufak bir syntax hatası var, bunu fark ettiniz ve düzelttiniz. Diğer geliştiricilerin elindeki kopya ne olacak? Herkese tek tek bunu bildirip ellerindeki dosyaları güncellemelerini mi bekleyeceksiniz?

Yazılıma yeni bir fonksiyon eklendi, var olan başka bir fonksiyon güncelendi. İki sürüm arasındaki farkı nasıl kıyaslayacaksınız? Güncel sürümü herkese nasıl dağıtacaksınız?

Bir özgür yazılım üzerinde çalışıyorsunuz ve katkıda bulunmak istiyorsunuz. Kodunuzu binlerce geliştirici ile nasıl paylaşacaksınız?

Bu soruların tamamına ve hatta daha fazlasına yanıt olarak “sürüm yönetim sistemi (versiyon yönetim sistemi)” cevabını verebiliriz.

Linux kernel projesini başlatan “Linus Torvalds”, dilediği özelliklere sahip bir sürüm yönetim sistemi bulamadığından, “Git” yazılımını yazmıştır. Git, açık kaynak kodlu ve özgür bir yazılımdır. Git, dünyada en çok kullanılan sürüm yönetim sistemlerinden biridir.

Kısaca özetlemek gerekirse; Git sayesinde uzaktaki bir sunucudan proje içeriğini çekebilir, lokalinizde düzenlemeler yapabilir ve sonrasında yaptığınız tüm değişikliklerin kaydını tutacak şekilde düzenlemelerinizi uzak sunucuya tekrar gönderebilirsiniz.

Bu sayede tüm proje içeriği ve değişiklik kaydı (changelog), ortak bir alanda tutulmuş olacaktır. Ayrıca; bu değişikliklerin kim tarafından, ne amaçla, ne zaman yapıldığı ve nelerin değiştiği bilgilerini de rahatlıkla takip edebilirsiniz.

Git ile İlgili Temel Kavramlar

Git kullanırken karşımıza sıklıkla çıkacak bazı kavramlara açıklık getirmek isterim:

  • Repository (Kısaca repo): Proje dizini diyebiliriz. Proje dosyalarınızı, projenizin repository’sinde tutarsınız.
  • Clone: Uzaktaki bir repo’yu kendi lokalinize çekme işidir.
  • Commit: Lokaldeki değişikliklerin Git tarafından kayıt altına alınmasıdır.
  • Push: Lokaldeki değişikliklerin uzaktaki repository’e gönderilmesi işidir.
  • Pull: Lokale çekmiş olduğunuz repository için, uzakta yapılan değişikliklerin tekrar çekilip lokalin güncellenmesi işidir.

GitHub Nedir?

Git ve GitHub kesinlikle birbirinden farklı kavramlardır. GitHub; Git repolarınızı barındırabileceğiniz, repo’lar ya da repo’lar üzerindeki dosyalarda web arayüzü üzerinden değişiklikler yapabileceğiniz, projeniz ile ilgili tartışabileceğiniz bir nevi sosyal bir platformdur.

RHEL ve Türevlerinde Git Kurulumu

Dağıtımın repository’lerinde yer alan Git versiyonunu kurmak için:

[root@localhost ~]# yum install git
Yüklü eklentiler: fastestmirror
......
Kur  1 Paketler (+3 Bağımlı paketler)
Toplam indirme boyutu: 4.5 M
Kurulu boyutu: 22 M
Is this ok [y/d/N]: y
Downloading packages:
......
Kuruldu:
  git.x86_64 0:1.8.3.1-23.el7_8

Bağımlılık Kuruldu:
  perl-Error.noarch 1:0.17020-2.el7       perl-Git.noarch 0:1.8.3.1-23.el7_8       perl-TermReadKey.x86_64 0:2.30-20.el7

Tamamlandı!
[root@localhost ~]# git --version
git version 1.8.3.1

Git ile İlk Commit’imiz

Bu kısımdan sonrasında, bir GitHub hesabınız olduğunu düşünerek hareket edeceğim. Farklı bir platform kullanmak isterseniz (GitLab veya self-hosted Git), GitHub ile ilgili kısımları atlayabilirsiniz.

GitHub Üzerinde Repository Oluşturma

GitHub profilinize gittiğinizde sağ üst köşede yer alan “+” simgesine tıklayın, sonrasında “New Repository” linkine tıklayın:

GitHub üzerinde yeni repository oluşturma
GitHub üzerinde yeni repository oluşturma

Karşınıza gelen sayfada, ilgili alanları doldurun. Seçeneklerin açıklamaları form üzerinde zaten belirtilmiş. Ben bu sayfada en alt kısımda lisans belirttim ve “GNU General Public License v3.0” “copyleft” lisansını tercih ettim. Lisanslar ile ilgili detaylı bilgiyi, lisans metinlerini okuyarak edinebilirsiniz. Ek olarak bir de repository’min tanıtımını yapmak amacıyla “README.md” dosyası oluşturulmasını istedim. Buradaki “md” uzantısı, “markdown” anlamına gelmektedir. Markdown da tıpkı HTML gibi bir işaretleme dilidir.

GitHub repository ayarları
GitHub repository ayarları

Repository’den Lokale Clone Almak

Bulunduğumuz dizin içerisine uzaktaki projeyi çekip, bir de bu dizin içeriğinin Git tarafından yönetilebilir olmasını istiyoruz. Burada yardımımıza “git clone” koşuyor.

Öncelikle repo’muzun URL’ini alalım. Bunun için repository sayfanızdaki “Code” linkine tıklayabilirsiniz:

GitHub üzerinden repository linkini alma
GitHub üzerinden repository linkini alma

Sonrasında, projemizi saklayacağımız dizin içerisine giriyoruz ve “git clone” çalıştırıyoruz:

[root@localhost ~]# mkdir projeler
[root@localhost ~]# cd projeler/
[root@localhost projeler]# git clone https://github.com/alisezisli/ShellScripting101.git
Cloning into 'ShellScripting101'...
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 7 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (7/7), done.

Repository’nizin adında bir dizin, bulunduğunuz dizine oluşturulacaktır. Bu dizinin içeriğini inceleyelim:

[root@localhost projeler]# cd ShellScripting101/
[root@localhost ShellScripting101]# ls -la
toplam 40
drwxr-xr-x. 3 root root    50 Oca 25 13:48 .
drwxr-xr-x. 3 root root    31 Oca 25 13:48 ..
drwxr-xr-x. 8 root root   163 Oca 25 13:52 .git
-rw-r--r--. 1 root root 35149 Oca 25 13:48 LICENSE
-rw-r--r--. 1 root root   115 Oca 25 13:48 README.md

Görüldüğü üzere, “ShellScripting101” isimli bir dizin gelmiş. Bu dizinin içerisinde, repo’yu oluştururken seçtiğimiz “LICENSE” ve “README.md” dosyaları bulunuyor. Bunun haricinde bir de “.git” dizini mevcut. Git programının bu dizini yönetebilmesini sağlayan bütün olay, bu dizin içerisinde dönüyor.

İlk Düzenleme

“README.md” dosyasını bir text editor ile açıp düzenledim. Lokalimizdeki dosya, uzak repo’dakinden farklı oldu. Bakalım Git bu duruma nasıl bir tepki verecek. Repository’nin durumunu öğrenmek için “git status” çalıştırıyoruz:

[root@localhost ShellScripting101]# git status
# On branch main
# 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:   README.md
#
no changes added to commit (use "git add" and/or "git commit -a")

Yukarıdaki çıktıdan da anlaşılacağı üzere Git, bir dosyanın değiştiğini fakat bu değişikliklerin henüz bildirilmediğini (commit edilmediğini) söylüyor.

Proje dizinimize bir de yeni dosya ekleyelim. Sonrasında tekrar “git status”a bakalım:

[root@localhost ShellScripting101]# git status
# On branch main
# 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:   README.md
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       1-echo_ornekleri.sh
no changes added to commit (use "git add" and/or "git commit -a")

Çıktıda bazı değişiklikler görüyoruz. “README.md” dosyası güncellenmiş. Fakat “1-echo_ornekleri.sh” dosyası şu an Git tarafından takip edilmiyor (untracked).

Git’in önerisini dikkate alalım ve bu dosyalardaki değişiklikleri de takip etmeye başlayalım. Eğer yalnızca bir dosyayı takip etmek isterseniz “git add dosyaadi” komutunu kullanabilirsiniz. Fakat ben bu dizin içindeki tüm dosyaların takip edilmesini istiyorum. Böyle bir senaryoda, bulunduğumuz dizinin tüm içeriğini gösterebilmek için “git add .” yazabiliriz. Sonrasında “git status” çalıştırıp yeni durumu inceleyelim:

[root@localhost ShellScripting101]# git add .
[root@localhost ShellScripting101]# git status
# On branch main
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   1-echo_ornekleri.sh
#       modified:   README.md
#

Gördüğünüz gibi çıktı değişti. Takip edilen 2 dosyamız oldu. Bunlardan bir tanesi zaten vardı ve düzenlendi. Bir tanesi ise orijinal repository’de yok, yeni bir dosya.

Değişiklikleri Commit Etmek

Takip edilen bu dosyalardaki değişiklikleri Git tarafında kaydetmek için “git commit” kullanacağız. Her commit için, o commit’in amacını açıklayan bir mesaj yazılması beklenir. Aksi takdirde commit’lerin ne için yapıldığı konusunda karmaşa yaşanabilir.

Aşağıdaki komutta “-m” sonrasında bir kısa açıklama giriyorum. Sonrasında tekrar “-m” çağırıp bir açıklama daha yazıyorum. Bu iki kısımdan ilkini commit’in başlığı, ikincisini ise commit’in açıklaması olarak düşünebilirsiniz:

[root@localhost ShellScripting101]# git commit -m "Git yazısı için ilk commit." -m "README.md güncellendi. 1-echo_ornekleri.sh eklendi."
[main 833b4ae] Git yazısı için ilk commit.
 Committer: root <root@localhost.localdomain>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

    git config --global user.name "Your Name"
    git config --global user.email you@example.com

After doing this, you may fix the identity used for this commit with:

    git commit --amend --reset-author

 2 files changed, 54 insertions(+), 2 deletions(-)
 create mode 100755 1-echo_ornekleri.sh
 rewrite README.md (79%)

Ve… Biraz sıkıntı yaşadık anlaşılan. Commit’i yapan kişi “root”. Adım root olsaydı epey havalı olabilirdi fakat bu ben değilim.

Burada, aslında en başta düşünmemiz gereken bir noktayı atladığımızı görüyoruz. Tamam, repo’yu klonladık. Değişiklikler yaptık. Peki biz kimiz? Git’e kendimiz hakkında hiçbir bilgi vermedik. Neyse ki aldığımız çıktı, bizi yönlendiriyor. “git config” yardımıyla bir şeyleri düzenleyip tekrar deneyeceğiz:

[root@localhost ShellScripting101]# git config --global user.name "Ali Sezişli"
[root@localhost ShellScripting101]# git config --global user.email "example@example.com"
[root@localhost ShellScripting101]# git commit --amend --reset-author
[main e9457e9] Git yazısı için ilk commit.
 2 files changed, 54 insertions(+), 2 deletions(-)
 create mode 100755 1-echo_ornekleri.sh
 rewrite README.md (79%)

Konfigürasyonu tamamladıktan sonra yazar bilgilerini reset’liyoruz ve yolumuza devam edebiliyoruz.

Commit’lerin Push’lanması

Değişikliklerimizi commit ettik. Fakat uzaktaki repo’nun hâlâ bizden haberi yok. Lokaldeki değişikliklerimizi uzaktaki repo’ya göndermek için “git push” kullanacağız. Tabii ki canımızın istediği her repo’ya bir push yapamayız değil mi? Yetkimizin olması gerekir. Burada Git, bizden uzak sunucuya bağlanmak için kullanıcı adı ve parolamızı isteyecek.

Önemli bir nokta. GitHub hesabınızda benim gibi “İki Adımlı Doğrulama (Two Factor Authentication – 2FA)” açtıysanız, benim gibi siz de hata alacaksınız. Merak etmeyin, çözümü var 🙂

[root@localhost ShellScripting101]# git push
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Username for 'https://github.com': alisezisli
Password for 'https://alisezisli@github.com':
remote: Invalid username or password.
fatal: Authentication failed for 'https://github.com/alisezisli/ShellScripting101.git/'

2FA kullanmıyorsanız, işlem burada tamamlanmış olmalı. 2FA kullanıyorsanız da çözüm için birden fazla yol var. Ben “Personal Access Tokens” yoluyla ilerledim.

GitHub hesabınızın ayarlarından “Developer Settings“e gelin. Sonrasında “Personal Access Tokens” linkine tıklayın ve yeni bir access token oluşturun. Oluşturacağınız token’a gerekli yetkileri verin. Ben tümünü seçtim. Bu token inanılmaz derecede değerlidir ve hiçkimseyle paylaşılmamalıdır.

Token’ı aldıktan sonra yapmanız gereken; az önce karşımıza çıkan kullanıcı adı / parola ekranında, parola yerine token’ı yazmak olacak.

[root@localhost ShellScripting101]# git push
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Username for 'https://github.com': alisezisli
Password for 'https://alisezisli@github.com':
Counting objects: 6, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 1.91 KiB | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To https://github.com/alisezisli/ShellScripting101.git
   f9a6e5d..e9457e9  main -> main

Yukarıdaki çıktıda görüldüğü üzere, push işlemi başarıyla tamamlandı. Repo’nuzu ziyaret ettiğinizde, yaptığınız değişiklikleri görebileceksiniz:

git push sonrası GitHub reposu
git push sonrası GitHub reposu

Sonuç Olarak

Git oldukça güçlü bir araç. Burada anlatılan kısım, sizin kendi repo’nuza commit’ler yapabilmenize yardımcı olacaktır. Fakat daha ileri adımlar için Internet’te bol miktarda Git kaynağı mevcut. freeCodeCamp.org’un bu dersiyle başlamayı deneyebilirsiniz.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir