Perbedaan arsitektur dengan svn
- SVN : working --> remote repo
- Git : working --> staging --> local repo --> remote repo
Istilah
- HEAD : posisi branch saat ini
- trunk : branch utama di svn
- master : branch utama di git
- commit :
- svn : memindahkan changes dari working ke remote
- git : memindahkan changes dari staging ke local repo
- checkout :
- svn : memindahkan changes dari remote ke working (git : git pull)
- git : pindah ke branch lain (svn : svn switch)
- add :
- svn : menambahkan file yang belum diversion
- git : menambahkan changes ke staging
- rm :
- svn & git : stop versioning file, hapus dari filesystem
- Instalasi
apt-get install git-svn
- Checkout svn repo
git svn clone -s http://blabla
- Konfigurasi dulu user dan email
git config --global user.name "Endy Muhardin"
git config --global user.email "[email protected]"
Biar ada warnanya
git config --global color.ui true
- Import
svn:ignore
ke.gitignore
git svn show-ignore > .gitignore
- Best practices, kerjanya di topic branch, jangan di master
git checkout -b branch_kerja
ini cara cepat, cara lambatnya :
git branch branch_kerja
git checkout branch_kerja
Lihat daftar branch, yang ada bintangnya berarti kita sedang berada di sana
git branch
- Lihat status working folder
git status -s
- Add modifikasi ke staging index
git add .
Perintah add akan mendaftarkan changeset ke staging. Bukan file !!!
Jadi kalau kita edit file halo.txt
, add, kemudian edit lagi,
maka yang akan berangkat pada saat commit hanya perubahan pertama.
- Commit ke local repo Yang ini hanya commit yang sudah ada di staging index
git commit -m "keterangan commit"
Kalo males add dulu baru commit, langsung aja commit dari working folder ke local repo
git commit -a -m "keterangan commit"
- Melihat keterangan commit terakhir (-1)
git log -1
Lengkap dengan diff nya
git log -p -1
- Pindah lagi ke master (branch utama)
git checkout master
- Update dulu repo lokal, kali aja ada yang sudah commit sementara kita sibuk
git svn rebase
git fetch origin + git merge origin/master
- Apply semua commit di branch_kerja ke master
git merge --no-ff --no-commit branch_kerja
no-ff : semua commit gabung jadi satu, dicommit lagi di branch tujuan
no-commit : jangan langsung commit, biarin aja di staging index, supaya kita bisa bikin commit msg sendiri biasanya berisi release note
squash : semua commit digabung jadi 1
kadang-kadang kena fast forward kalau di master tidak ada commit, sehingga historinya menjadi linier
Kalau master tidak ada commitnya, gunakan opsi --no-ff
untuk menandai commit
git merge --squash --no-ff branch_kerja
fast forward adalah memindahkan pointer HEAD branch target menjadi sama seperti branch asal. Merge fast forward tidak menimbulkan commit baru
- Cek dulu apakah ada konflik. Kalau ada, fix dulu, baru commit. Kalau tidak ada, ya langsung saja commit
git add .
git commit -m "implement task #12"
- Sudah ok semua, commit ke svn repo
git svn dcommit
1 commit di master = 1 commit di svn
- Cara undo
- Skenario 1 : masih di local dan belum naik ke staging (belum add), mau kembalikan ke posisi terakhir commit
git reset --hard HEAD
- Skenario 2 : sudah add tapi belum commit, add nya mau dicancel
git reset -- namafile
- Skenario 3 : sudah add tapi belum commit, setelah add ada modifikasi lagi, mau dikembalikan ke kondisi terakhir sync
git reset --hard
- Skenario 4 : sudah add tapi belum commit, setelah add ada modifikasi lagi, mau dikembalikan ke kondisi terakhir add
git checkout -- namafile
- Skenario 5 : sudah commit, tapi belum push / dcommit
git reset HEAD^ # kembalikan ke commit - 1
git reset HEAD~3 # hapus commit terakhir, commit sebelumnya, dan commit sebelumnya lagi
-- soft : cuma HEAD yang direset, working dan index tetap
-- mixed : index dan HEAD direset, working tidak
-- hard : working, index, dan HEAD direset semua
- Skenario 6 : sudah push
git revert [sha_commit_yang_mau_diundo] # akan menggenerate commit baru yang isinya reverse diff dari commit yang direvert
- Interrupted workflow Misalnya, lagi asik tambah fitur, ada request bugfix
- pindahkan work in progress ke branch baru
git stash fitur-baru
git commit -m "save dulu sebentar, nanti abis bugfix diterusin lagi"
- balik lagi ke master, kali ini sudah bersih dari tambahan fitur, seperti kondisi terakhir commit
git checkout master
- add bugfix, lalu commit
git commit -m "bugfix"
- balik ke branch fitur-baru, terserah mau rebase atau merge
git checkout fitur-baru
git rebase master / git merge master
... edit ... edit ...
git commit -m "fitur baru selesai"
- integrate ke master
git checkout master
git merge fitur-baru
Bekerja dengan remote Skema URL :
- Local : /path/ke/repo
- SSH : username@hostname:/path/ke/repo
- GIT : git://hostname/namarepo
- HTTP(s) : http(s)://hostname/namarepo
- Kalau di lokal belum ada reponya, clone saja
git clone namaremote urlremote
- Kalau di lokal ada, dan mau sync dengan repo orang lain, add remote saja
git remote add namaremote urlremote
- Ambil changeset dari remote
git fetch namaremote
untuk meremove juga branch yang sudah gak ada di remote, gunakan
opsi --prune
git fetch --prune namaremote
- Setelah difetch, merge ke local supaya bisa diedit
git merge
- Tracking branch, branch di local sebagai padanan remote Manual
git branch localbranch namaremote/remotebranch
git checkout localbranch
Otomatis checkout
git checkout -b localbranch namaremote/remotebranch
Kalo namanya sama (localbranch = remotebranch), bisa pakai --track
git checkout --track namaremote/remotebranch
- Push commits ke remote
git push namaremote localbranch:remotebranch
kalau nama branch di remote sama dengan local
git push namaremote namabranch
kalau dikosongkan, git akan push ke remote branch yang namanya sama dengan local misalnya master => namaremote/master
git push namaremote
- Menghapus branch di remote
git push namaremote :remotebranch
Fine tuning commit Misalnya ada beberapa perubahan di 1 file untuk menyelesaikan 3 issue. Kita ingin menyesuaikan commit dengan issue, sehingga untuk 1 file ini commitnya harus dipecah. Caranya, kelompokkan change dengan menggunakan staging area. Kita sortir per potongan file (hunk)
git add -i namafile
Nanti kita akan ditunjukkan diff dari file. Kemudian bisa :
- update : add ke staging
- patch : pilih satu-satu change yang mau distaging
- revert : gak jadi staging
- status : melihat rekapan semua file yang berubah di lokal dan di staging
Diff dan Patch Kalau kita punya diff, kita bisa mengubah bentuk suatu file dengan patch Misalnya awal + diff = akhir
patch awal.txt < diff.txt
Mengembalikan akhir ke awal
patch -R akhir.txt < diff.txt
Gitosis
Add User :
- add pubkey ke folder keydir
- add di konfig gitosis.conf
- commit
- push
Add Project :
- siapkan repo lokal
git add remote namaremote git@server:namarepo
git push namaremote master
Debugging
- Switch working folder ke revisi lama
git checkout namacommit
- Kembalikan lagi ke revisi terakhir
git reset --hard
- Lihat siapa yang berbuat (blame)
git blame -L 2405,2418 namafile
- Menelusuri bug dengan bisect
git bisect start
git bisect bad
git bisect rev-terakhir-yang-masih-bagus
- git akan switch ke pertengahan rev-bagus dan current
- cek file yang menimbulkan bug, atau test aplikasinya
- kalau bagus, ketik git bisect good
- kalau broken, ketik git bisect bad
- teruskan sampai ketemu pesan a25f13e5e924e55752fd39f7164627ce822ba699 is the first bad commit
- itulah commit yang menyebabkan error
- kembalikan ke posisi awal
git bisect reset
Releasing Local Tag
git tag -a 01.00.00.GA -F CHANGE.txt
Menambah tag di tag existing (promote RC to stable)
git tag -a 01.00.00 a25f13e
Informasi tag
git show 01.00.00.GA
Menghapus tag
git tag -d 01.00.00.GA
Push Tag ke Origin
git push origin --tags # semua tags
git push origin 01.00.00.GA # hanya 1 tag tertentu
Lihat perubahan sejak tagging terakhir :
git log --pretty=format:'%ad - %an - %h - %s' 02.01.00.M002..HEAD
Lihat daftar file yang berubah sejak tagging terakhir
git log --name-status 02.01.00.M002..HEAD
Output ke file supaya bisa diedit untuk release note
git --no-pager log --pretty=format:'%h - %s' 02.01.00.M002..HEAD > output.txt
Output ke file untuk menentukan daftar file untuk incremental deployment
git --no-pager log --name-status 02.01.00.M002..HEAD > daftar-file-
deploy.txt
Konversi repo
- Checkout dulu repo subversion
svn co file:///repo/yang/mau/dimigrasi
- Generate svnusers
#!/usr/bin/env bash
authors=$(svn log -q | grep -e '^r' | awk 'BEGIN { FS = "|" } ; { print $2 }' | sort | uniq)
for author in ${authors}; do
echo "${author} = NAME <USER@DOMAIN>";
done
- Checkout lagi menggunakan git-svn
mkdir migrasi-git
cd migrasi-git
git svn clone --stdlayout --no-metadata -A file-authors.txt file:///repo/yang/mau/dimigrasi/trunk dest_dir-tmp
- Migrasi branch svn menjadi branch git
$ git branch -r | grep -v tags | sed -rne 's, *([^@]+)$,\1,p' | while read branch; do echo "git branch $branch $branch"; done | sh
- Migrasi tag svn menjadi tag git
$ git branch -r | sed -rne 's, *tags/([^@]+)$,\1,p' | while read tag; do echo "git tag $tag 'tags/${tag}^'; git branch -r -d tags/$tag"; done | sh
- Konversi
svn-ignore
menjadigitignore
git svn show-ignore > .gitignore
git add .gitignore
git commit -m "konversi svn ignore menjadi gitignore"
- Clone supaya bersih
cd ..
git clone --bare migrasi-git migrasi-git-bersih
- Pasang di server
scp migrasi-git-bersih ke server
- Mengganti committer name setelah clone
git-filter-branch --env-filter "export GIT_AUTHOR_NAME='New name'; export GIT_AUTHOR_EMAIL='New email'" HEAD
Creating a svn.authorsfile when migrating from subversion to git
Cleanly Migrate Your Subversion Repository To a GIT Repository
How to migrate SVN repository with history to a new Git repository?
SVN to GIT migration
Migrating from svn to git