Category Archives: git

Git Global Config dosyasını ayarlamak


$~ git config --global user.name "Faik"

gibi ayarlar --global parametresinden dolayı,
.git/config içine yazılmaz. [Projeye özgü ayarlar.]
$HOME/.gitconfig içine yazılır. [Genel Ayarlar]

Bu ayarlara;

lifeinbeta@lifeinbeta:~$ git config --global --edit

ile bakılabilir. Bu komut çalıştırıldığında görülebilen örnek bir Global Config dosyası içeriği;

[user]
        name = Taha Yavuz Bodur
        email = x@y.com
[github]
        user = tyb
        token = abcd1234...

Bu işlem global parametresi olmadan yapılsaydı;

lifeinbeta@lifeinbeta:~/GIT/dummy1$ git config deneme.param1 "deger1"
lifeinbeta@lifeinbeta:~/GIT/dummy1/.git$ cat config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "origin"]
	url = git@github.com:tyb/dummy1.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
	remote = origin
	merge = refs/heads/master
[deneme]
	param1 = deger1

projeye özgü config dosyasınına yazılırdı. Yukarıda, dummy1 projesine özgü config dosyasına (.git/configdeneme bölümü(section) altında param1 parametresi deger1 değeri ile yazılmıştır.

Yeni eklenen bölümü silmek için;

lifeinbeta@lifeinbeta:~/GIT/dummy1/.git$ git config --remove-section deneme

yazılır.
git-config komutları bölüm.parametre_adı şeklindedir.
git-config(1) Manual Page‘den daha detaylı kullanımına bakılabilir.

Güzel bir söz

Moments, when lost, can’t be found again. They’re just gone.

The Summer I Turned Pretty / Jenny Han

[Dakikalar, kaybedildiğinde, tekrar bulunamazlar. Geçip gitmiştirler.]

Advertisements

1 Comment

Filed under git

GitHub ile SSH kullanarak Haberleşmek ve ilk Push işlemini Gerçekleştirmek


Git‘i kurmak için:
  1. UNIX Tabanlı OS’ler için: http://help.github.com/linux-set-up-git/
  2. Tüm OS’ler için: How to Install Git
Git‘in kurulu olduğunu varsayalım:
$ git --version
git version 1.7.0.4

GitHub‘ta(uzakta) hesap açılmış olsun.

Set up Git(Linux) de anlatılanların Set up SSH Keys kısmından sonrası:

Yerelde,

lifeinbeta@lifeinbeta:~$ cd ./.ssh
lifeinbeta@lifeinbeta:~/.ssh$ ls -a
.  ..  known_hosts
lifeinbeta@lifeinbeta:~/.ssh$ touch config
lifeinbeta@lifeinbeta:~/.ssh$ ls -A
config  known_hosts
lifeinbeta@lifeinbeta:~/.ssh$ vim config

Vim içerisinde config dosyasına şunlar yazılır:

Host tybgit
HostName github.com
IdentityFile ~/.ssh/id_rsa_tybgit
User git

Host *
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p

SSH bağlantısında kullanılacak Private/Public Key çiftini oluşturmak için:

lifeinbeta@lifeinbeta:~/.ssh$ ssh-keygen -t rsa -C "xyz@xyzmail.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/lifeinbeta/.ssh/id_rsa): id_rsa_tybgit
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_rsa_tybgit.
Your public key has been saved in id_rsa_tybgit.pub.
The key fingerprint is:
44:dc:bc:0e:24:10:26:08:2d:87:65:de:28:bf:c5:64 xyz@xyzmail.com
The key's randomart image is:
+--[ RSA 2048]----+
|o=+ +o ..o       |
|+oo=  ..o o      |
|.oo E  o.  .     |
| o +   .. .      |
|  . o   So       |
|   o      .      |
|  .              |
|                 |
|                 |
+-----------------+

Bu işlem sonucunda Public/Private Key çiftleri:

lifeinbeta@lifeinbeta:~/.ssh$ la
config  id_rsa_tybgit  id_rsa_tybgit.pub  known_hosts

sırasıyla; id_rsa_tybgit.pub ve id_rsa_tybgit text dosyalarının içindedir.

Public Key, Github‘da Account Settings’deki kısma eklenir.

Bağlantı ayarları aşağıdaki gibi test edilebilir:

lifeinbeta@lifeinbeta:~/.ssh$ cd ~
lifeinbeta@lifeinbeta:~$ ssh tybgit
The authenticity of host 'github.com (207.97.227.239)' can't be established.
RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)? y
Please type 'yes' or 'no': yes
Warning: Permanently added 'github.com,207.97.227.239' (RSA) to the list of known hosts.
PTY allocation request failed on channel 0
Hi tyb! You've successfully authenticated, but GitHub does not provide shell access.
    Connection to github.com closed.

Bu işlem sonunda permission denied(publickey) vb. hatalar alınabilir ki bunu yazdığımın ertesi günü tekrar denediğimde aldım. Google’dan aratıp çeşitli yazılarda belirtilen adımlar takip edilerek sorun giderilebiliyor, ama işin içinden çıkılmaz bir hal de alabiliyor. Bu yazılardan okuduklarımdan anladığım kadarıyla, bu hatanın çözümü için:

  1. .ssh klasörü altındaki dosyaların izinlerinin 600 olması gerekir(SSH bunun aksindeki izinlerde istenen işlemi gerçekleştirmez). Bunun için $~ chmod 600 ~/.ssh/* yapılır.
  2.  ssh-add id_rsa_olusturulan_private_key ile [SONRA-YAZILACAK:???] yapılır.
  3. Ayrıca, config dosyasına
    PreferredAuthentications publickey
    Port 22
    TCPKeepAlive yes
    IdentitiesOnly yes

    ekledim. Ama, bu ayarlar zaten varsayılan ayarlarmış, belirtmeye gerek yok. 🙂

Bu işlemlerden sonra GitHub‘a ssh ile bağlanılıp repo oluşturulabilir. Yukarıdaki mesajda “GitHub does not provide shell access“(GitHub kabuk erişimi sağlamaz.) kısmında belirtildiği gibi, GitHub’da repo‘yu site üzerinde oluşturmak gerekir. Üstünü çizdiğim cümlede yanılmamın nedeni bu kısmı setting up a remote repository and doing initial push yazıyı referans alarak yazmamdı. Orada yazılanlar doğru olmasına rağmen,

ssh git@example.com

daki, HostName‘in example.com olduğuna dikkat etmedim. Yazı, kabuk erişimi sağlayan GitHub harici bir siteye(Git burada kurulmuş ve gerekli ayarları yapılmış) bağlanıp burada remote repo oluşturmak üzerineydi. Oysa, mevcut bağlantı ayarlarına göre amacım GitHub‘a bağlanıp burada Repo oluşturmaktı. Bu yüzden şu scriptin;

ssh git@example.com
mkdir my_project.git
cd my_project.git
git init --bare
git-update-server-info # If planning to serve via HTTP
exit

yaptığı işi, GitHub profilime girip oradan Create Repo seçeneğini seçerek yaptım.

NOT: Bu yazıda git komutlarını birleştiren iki tane kabuk script’i var. Bunlara benzer Git Commit Counter ve Git Logger yapılacak…

Bu repo‘ya ilk push işlemini yapalım. Bunun için:

lifeinbeta@lifeinbeta:~$ cd GIT
lifeinbeta@lifeinbeta:~/GIT$ mkdir dummy1
lifeinbeta@lifeinbeta:~/GIT$ cd dummy1
lifeinbeta@lifeinbeta:~/GIT/dummy1$ git init
Initialized empty Git repository in /home/lifeinbeta/GIT/dummy1/.git/
lifeinbeta@lifeinbeta:~/GIT/dummy1$ la
.git
lifeinbeta@lifeinbeta:~/GIT/dummy1$ touch dummy.file

lifeinbeta@lifeinbeta:~/GIT/dummy1$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	dummy.file
nothing added to commit but untracked files present (use "git add" to track)

lifeinbeta@lifeinbeta:~/GIT/dummy1$ git add dummy.file

lifeinbeta@lifeinbeta:~/GIT/dummy1$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#	new file:   dummy.file
#

lifeinbeta@lifeinbeta:~/GIT/dummy1$ git commit -m "ilk commit: dummy.file oluşturuldu,şu anda boş."
[master (root-commit) 29a685c] ilk commit: dummy.file oluşturuldu,şu anda boş.
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 dummy.file

lifeinbeta@lifeinbeta:~/GIT/dummy1$ git remote add origin git@github.com:tyb/dummy1.git
lifeinbeta@lifeinbeta:~/GIT/dummy1$ cat .git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "origin"]
	url = git@github.com:tyb/dummy1.git
	fetch = +refs/heads/*:refs/remotes/origin/*
lifeinbeta@lifeinbeta:~/GIT/dummy1$ git config --global user.name "Taha Yavuz Bodur"
lifeinbeta@lifeinbeta:~/GIT/dummy1$ git config --global user.email "xyz@xyzmail.com"
lifeinbeta@lifeinbeta:~/GIT/dummy1$ cat .git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "origin"]
	url = git@github.com:tyb/dummy1.git
	fetch = +refs/heads/*:refs/remotes/origin/*
lifeinbeta@lifeinbeta:~/GIT/dummy1$ git push -u origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 251 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:tyb/dummy1.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

yapılır.

NOT: Yukarıdaki, görüldüğü git config --global ... ile belirtilen değerler .git/config e yazılmaz(global parametresinden de anlaşılacağı gibi). Global Git Config dosyasına girdiğim ayarlar şunlardı:

$ git config --global user.name "Taha Yavuz Bodur"
$ git config --global user.email "your_email@youremail.com"
$ git config --global github.user tyb
$ git config --global github.token GitHub_da_hesap_acarken_verilen_token

Detaylı bilgi için: Git Global Config Dosyası

GitHub‘daki remote repo‘nun son hali:

GitHub Remote Repo'ya ilk Push işleminin sonucu

GitHub Remote Repo'ya ilk Push işleminin sonucu

 Güzel bir söz:

Hours fly, flowers die, new days, new ways, pass by, love stays!

[Vakit uçar, çiçekler ölürsolar, yeni günler, yeni yollar, geçip gider, aşk yerinde kalır! ]

Leave a comment

Filed under git

Yürü “Git”! :) – Bölüm 1: “Git” Nedir?


Kedi görünümli sevimli ahtopot 'Git'
“Git” Nedir?

Git(Türkçe: cit), bir versiyon kontrol sistemidir. Versiyon kontrolü(değişiklik kontrolü),  dosyalardaki değişiklikleri kayıt altında tutarak değişiklik tarihçesi oluşturmaktır. Bu şekilde kullanıcılar, tarihçe boyunca ilerleyip istedikleri duruma(state) geri dönebilirler. Bu amaca, değişikliğe başlamadan önce “Save as” diyerek değişiklik yaptığımız dosyaların kopyasını oluşturarak da ulaşabilirdik ama, değişiklik yaptığımız dosya sayısı arttıkça bunları aklımızda takip etmek yerine versiyon kontrol sisteminin takip etmesini sağlamak uygundur. Ayrıca, “Git”, sadece değişikliklerin yedeğini tutar dosyaların değil.  [Bunun nasıl yapıldığını ilerleyen bölümlerde “Git’in İç Yapısı, Çalışma Mekanizması” başlığı altında anlatacağım.]

Eş anlamlı kavramlar

Tarihçe = Tüm Versiyonlar

Versiyon = Commit = Değişiklik Kaydı = Değişiklik (Ekleme, Silme yapmak anlamındaki değil; belirli ekleme silmeleri niteleyen bir nokta) = Durum = State = Checkpoint = Geri Dönüş Noktası

Git’i diğer versiyon sistemlerinden ayıran özellikler nelerdir?
  1. Git dağıtık bir versiyon kontrol sistemidir: Bir yazılımın kullandığı dosyalardaki değişikliklerin tüm tarihçesi(tüm versiyonları) dosyalar(son versiyon) ile birlikte bir sunucu üzerinde bulunur. Yazılım üzerinde geliştirme yapmak isteyen biri, yazılımı oluşturan dosyaları, tüm versiyonları ile birlikte yerel bilgisayarına alır(pull) ve Git  ile bu dosyalarda yapacağı değişiklikleri kayıt altında tutmaya başlar. Geliştirme işlemi bittikten sonra değiştirdiği dosyalardan istediklerini, değişiklik kaydıyla birlikte istediği bir versiyonu sunucuya bırakır(push). Subversion(SVN) gibi klasik versiyon kontrol sistemleri, merkezi( centralized) dir. Yani, dosyalar ve bu dosyaların tek bir tane olan değişiklik tarihçesi vardır. Bu tarz sistemlerde kullanıcılar değişiklik tarihçesinin yerel bir kopyasına sahip değillerdir, sahip oldukları şey sadece üzerinde değişiklik yaptıkları dosyalardır,  değişiklik tarihçesine yani eski versiyonlara sahip değillerdir.  Neden dağıtık bir versiyon kontrol sistemine ihtiyaç duyulsun ki? Projede birlikte çalışan kişi sayısının (Collaboration) çok fazla olduğunu düşünelim. Bu kişiler merkezi bir versiyon kontrol sistemini kullanıyor olsun. Herkes, üzerinde değişiklik yapmak istediği dosyaları merkezi sunucudan alsın. Değişikliklerini yaparken, önceki versiyondan dosyalar almaya ihtiyaç duyduklarında sunucuyla tekrar iletişime geçmek zorunda kalacaklardır. Önceki versiyonun alınmak istenmesenin çeşitli sebepleri olabilir; eski bir özelliği geliştirmek, yeni özelliği eski özellikle karşılaştırmak, eski versiyondaki bir tasarım kalıbını yenisiyle karşılaştırmak gibi. Sunucuyla sürekli iletişime geçmek yerine bütün versiyonları bir anda yerel bilgisayarına alabilseydi, zaman kayıpları yaşanmayacaktı. Bu cevabı açıklarken Git Magic – Introduction#Distributed Control daki yazıda verilen bilgisayar oyunu kayıtları benzetmesinden yararlandım. Her ne kadar bu sebep bana yeterince somut görünmese de bu özelliğin birçok kişinin aynı anda üzerinde çalıştığı açık kaynak projelerde ortaya çıkan ihtiyaçtardan dolayı olduğu aklımda. Bu yazı serisinin ilerleyen bölümlerinde bu özelliğin kullanıldığı bir iş akışını(workflow) göstereceğim.
  2. “Index a.k.a. Staging Area”, Incremental Committing:  Diğer versiyon kontrol sistemlerinde, bir Commit birden fazla küçük Commit lerden oluşabilir. Oysa bir Commit in belirttiği değişiklikler, atomik olmalıdır. Burada atomik derken kastettiğim şey, sadece tek bir amacı olan değişiklikler kayıtlarıdır. Bunun amacı, daha net geri dönüş noktaları oluşturabilmektir. Bu sayede; tarihçeye bakarak bir versiyona geri döndüğümüzde karşılaşacağımız durum(state), tam istediğimiz durum olacaktır. Genelde dosyalar üzerinde yapılan değişikliklerinin ne kadarının bir Commit için yeterli olacağı düşünülmez, daha doğrusu versiyon kontrol sistemlerinin buna elverişli bir aracı yoktur. İşte Git, Staging Area ile incremental olarak atomik Commit’ler yapabilmeye elverişli bir ortam sağlar. Diğer versiyon kontrol sistemlerinde bu ara yapı yoktur. Git’ te ise üzerinde değişiklik yapılan dosyalar ile bu dosyaların değişiklik kaydının tutulduğu veritabanı arasında bir ara yapı, sahne(Staging Area) vardır. [Bu yazı serisinin ilerleyen bölümlerinde
    git  status, git add, git mv, git rm, git diff

    gibi Git komutları ile sahne üzerine işlemler yapan iş akışları göstereceğim.][Bu veritabanının yapısı ilerleyen bölümlerde “Git’in İç Yapısı, Çalışma Mekanizması” başlığı altında anlatılacak].

  3. “Remote Repo” ve “Code Hosting”: GitHub ve Gitorious gibi web uygulamaları hem yerelde geliştirilen projelerin konulabileceği bir ortam sağlar, hem de başka geliştiricilerin üzerinde çalıştığı çeşitli projelere ulaşıp o projelere katılabilmeyi sağlar. [Collaboration and Open Source]
  4. Unix üzerinde Vi(m) ile birlikte kullanımı: Vi(m)(Vee-eye-improved) ile birlikte tam olarak profesyonel bir şekilde yazılım geliştirme imkanı sağlar. [Kişisel Görüşüm 🙂 ]
Git Terminolojisi (Remote -> Local -> Remote işlem sırasına göre)

Repository(Repo)    :  Değişiklik tarihçesi(Versiyon, Checkpoint, Durum)nin tutulduğu veritabanıdır.

Remote Repository :  GitHub gibi sitelerde, versiyonları(tüm değişiklik tarihçesini) ve Dosyaları(Son Versiyonu) tutan veritabanlarıdır. Buradan birisinin ya da kendimizin bir repo sunu yerel bilgisayarımıza almak istediğimizde aşağıdaki gibi

git clone

komutunu kullanarak tüm değişiklik tarihçesini ve son versiyon anlamına gelen asıl dosyaları alırız:

$ git clone git://github.com/schacon/simplegit.git
Initialized empty Git repository in /private/tmp/simplegit/.git/
remote: Counting objects: 100, done.
remote: Compressing objects: 100% (86/86), done.
remote: Total 100 (delta 35), reused 0 (delta 0)
Receiving objects: 100% (100/100), 9.51 KiB, done.
Resolving deltas: 100% (35/35), done.
$ cd simplegit/
$ ls
README   Rakefile lib
Local Repository : Yukarıdaki işlemden sonra simplegit klasörü içinde bu projedeki değişikliklerin kaydının tutulacağı bir Git veritabanı oluşturulmuş olur.(initialize). Bu veritabanına Local Repo denir.
Working Copy : Uzaktaki(remote git hosting place) bir repodan alınan versiyonun belittiği dosyalar, ya da bir proje klasörünün altında yerelde oluşturulan dosyalar üzerinde ekleme silme değişikliklerinin yapılacağı kaynaklardır. Bunlara Working Copy denir. Git init edildiği andan itibaren tüm versiyon kontrol sistemi süreci working copy deki değişikleri local repo ya kontrollü bir şekilde commit ekmekten ibarettir.
You stage the files, adding snapshots of them to your staging area.
Stage, Snapshot, Staging Area: Yukarıdaki alıntıdan gidecek olursam, working copy de olan, üzerinde değişiklik yapılan dosyalar sahne(stage)lenir. Git terminolojisinde bu teknikten ziyade mantıksal bir kavramdır. Burada yapılan şey, mantıksal anlamda, bir değişikliği sahneleyerek değişikliğin hatıra fotoğrafı(snapshot)nı almaktır.  Bu fotoğraf hala çıkmamıştır, sahne alanı(staging area) dadır karanlık odada bekletilecek diye düşünebiliriz. Daha sonra karanlık odadan çıkıp fotoğrafın basılması demek; değişikliği Local repo ya commit etmektir. Bu durum, Git’in diğer versiyon kontrol sistemlerinden farklarını anlatırken bahsettiğim incremental committing özelliğinden dolayıdır.
Index: Yukarıdaki staging area nın teknik karşılığıdır. Yani, teknik anlamda, Working Copy deki örnek bir dosyadaki değişiklikler yapıldı diyelim, bu dosya  git add ile index e eklenir. Dosyanın o andaki hali yani yapılan değişiklik geçici, ara, bir yerde saklanmış olur. Bundan sonra working copy de aynı dosyada değişiklik yapılmaya devam edilebilir. Diyelim ki, dosyanın sonuna üç satır daha eklendi; bu durumda commit yapılırsa bu eklenen üç satır o commit e dahil edilmez. Bu durum ilk bakışta  karışıklara yol açabilecek gibi görünse de Index yapısının incremental commit amacından kaynaklanır. index e eklenen herhangi bir değişiklikten yani snapshot tan sonra, yine tek bir dosya için konuşursak eğer, working copy deki o dosya ile stage teki snapshot u arasındaki fark
git diff

ile görülebilir. Her zaman tek dosya ile uğraşmayız. Birden fazla dosyadaki değişikler sahnede durduğunda, çeşitli Git komutları ile, bir sonraki Commit e hangi değişiklerin dahil olacağı seçilebilir.

Push: Yereldeki geliştirmede commitler ile Local Repoya değişiklik kayıtları işlenip geliştirmenin o aşaması tamamlandığında oluşan versiyon, belirtilen remote repoya push edilir. Local Repodaki versiyon ile Remote Repodaki versiyon arasında çakışmalar Merge işleminden sonra Git in gösterdiği conflict mesajlarından tespit edilir.

Pull: Remote Repodaki bir versiyonu Local Repo‘ya alıp o versiyonu oluşturan dosyalar working copy olarak kabul edilir ve versiyon kontrolü altında geliştirmeye devam edilir. Bu işleme Pull işlemi denir.

[Push, Pull, Branching, Merging gibi Remote Repo ile işlem içeren konular; üzerinde birden fazla kişinin üzerinde yapılan projelerde Giti etkin kullanırken gereklidir. Bireysel geliştirmeden ortak geliştirmeye doğru ilerlendikçe senaryolar karmaşıklaşır. Bu yüzden bu konularda, bu yazı serisi içerisinde, çeşitli yazılar yazmayı düşünüyorum]

Bu yazı serisinde sonraki yazıları bu konularda yazmayı düşünüyorum:

[GitHub‘da hesap oluşturmak ve açılan hesap altında yerelde geliştirilen uygulamanın aktarılacağı Remote Repo açmak ve buraya ilk Push‘u yapmak.]

[Git Global Config dosyasını ayarlamak]

[Git’in değişiklik kontrolü altında geliştirilen örnek bir uygulamanın yerelde başlayıp yerelde biten geliştirme adımları]

[Yerel geliştirmede sık kullanılan Git komutlarının referansı]

[Git’in İç Yapısı, Çalışma Mekanizması]

[Remote Repo İşlemleri: push ve pull, clone]

[Branch işlemleri]

[Release, Tag işlemleri]

Git konusunda okumakta olduğum çeşitli makaleler: http://tyb.tumblr.com/tagged/git

NOT: My Git Workflow da yukarıda anlattığım kavramların, git’i kullanırken oluşan, birbirleri arasındaki ilişkiler resimli olarak gösterilmiştir.

Bu yazı serisinin motivasyonu:

Eğer bir konuyu altı yaşındaki bir çocuğa açıklayamıyorsan, o konuyu kendin de anlamıyorsun demektir.

Einstein

Einstein’ın sözlerinden örnek vermeyi severim, çünkü kimse ona karşı çıkmaz istemez.

Söyleyen kişiyi unuttum 🙂

1 Comment

Filed under git