Pages

12/23/2013

My Note About Git

Git Config

  • ดู configuration ปัจจุบันของ git ได้ด้วย : git config -l
  • เซ็ตค่าสำหรับเฉพาะ git repo นั้น : git config --local  .........
  • เซ็ตค่าสำหรับทุกๆ git repo : git config --global  ........

Git Remote

  • ดู remote repo ทั้งหมด : git remote -v
  • เพิ่ม remote : git remote add origin username@server_ip:path_name.git
  • ลบ remote : git remote remove origin
  • แก้ URL ของ git remote : git remote set-url origin username@server_ip:path_name.git
  • แก้ URL ของ git remote #2 : git remote set-url origin ssh://username@server_ip/path_name.git

Git Bare & Git Non-Bare

Git repository สามารถสร้างได้ 2 แบบคือ แบบ bare กับ แบบ non-bare
  1. bare repository คือ repository ที่ข้างใน folder นั้นมีแค่ folder ".git" อย่างเดียว
    1. สร้างโดย 
      1. mkdir repo_name; cd repo_name; git init --bare 
      2. หรือ git clone --bare repo_name repo_path
    2. สามารถ config ให้ repo ใดๆที่มีอยู่แล้ว เป็น bare หรือไม่ได้ 
      1. โดยเข้าไปแก้ไฟล์ repo_path/.git/config ให้มีบรรทัด bare=true 
      2. หรือ git config --bool core.bare true
    3. ข้อดี: 
      1. ไม่ต้องเก็บโค้ดอยู่ในตัว folder ที่เก็บ repository
      2. ไม่ต้องคอยสั่ง git reset --hard HEAD บน repo directory เหมือนกับแบบ non-bare
      3. เวลา client จะ push ก็จะขึ้นมาได้เลย เนื่องจากว่าบน server ไม่ได้ checkout โค้ดอะไรไว้เลย
      4. เหมาะกับการใช้บน server
    4. ข้อเสีย
      1. เนื่องจากไม่มีโค้ดของตัวเอง ทำให้ไม่เห็นโค้ดได้ง่ายๆ ต้อง clone/checkout ออกมาก่อน
      2. การใช้ git status และ คำสั่ง git ที่ใช้ในการจัดการไฟล์ จะใช้ไม่ได้ใน directory นี้
  2. non-bare repository คือ repository ปกติ ที่ข้างในจะมีทั้ง ".git" และ ไฟล์อื่นๆที่ commit ขึ้นมา
    1. สร้างโดยคำสั่งแบบเดียวกับ bare แต่ต้องไม่มี "--bare"
    2. ถ้าอยากจะปรับให้ repo ที่เป็น bare ให้เป็น non-bare ต้องปรับค่า bare=false
    3. ข้อดี: บน server จะสามารถเห็นไฟล์และแก้ไขไฟล์ได้  ก็เหมือน checkout ออกมาดูตลอดเวลา
    4. ข้อเสีย: 
      1. เวลาที่ client สั่ง git push ขึ้นมา จะไม่สามารถเอาขึ้นมาได้ โดยจะขึ้นว่า 
        remote: error: refusing to update checked out branch: refs/heads/master
        remote: error: By default, updating the current branch in a non-bare repository
        remote: error: is denied, because it will make the index and work tree inconsistent
        remote: error: with what you pushed, and will require 'git reset --hard' to match
        remote: error: the work tree to HEAD.
        remote: error: 
        remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
        remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
        remote: error: its current branch; however, this is not recommended unless you
        remote: error: arranged to update its work tree to match what you pushed in some
        remote: error: other way.
        remote: error: 
        remote: error: To squelch this message and still keep the default behaviour, set
        remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'
        

        โดยจะต้องไปตั้งค่า receive.denyCurrentBranch ก่อน ถึงจะ push ขึ้นมาได้
      2. เวลาจะ update โค้ดบนฝั่ง server ( directory นี้ ) จะใช้ git pull ไม่ได้ เพราะมันบนเครื่องตัวเอง  ให้ใช้ git reset --hard HEAD แทน

Git Post-Receive Hook

ในการ deploy บน git server เองนั้น  สามารถใช้ hook ได้ ซึ่งหมายถึงว่า เราสามารถตั้งให้ เมื่อใดก็ตามที่ developer สั่ง git push ขึ้นมาบน server ใน branch "master"  เหตุการณ์นี้ก็จะสั่ง hook ที่ชื่อ post-receive เพื่อทำการรัน shell script ที่อยู่ข้างในได้

วิธีทำ
  1. เข้าไปใน ".git" directory ของ directory ที่เป็น repository หลัก ( repository ที่ตั้งไว้ตอน ssh หรือ git clone)
  2. สร้างไฟล์ชื่อ post-receive ภายใน path "hook/"
  3. ข้างในเขียนเป็น shell script โดยมีตัวแปรให้ตั้งสองตัวคือ
    1. GIT_DIR  : ตัวแปรที่ต้องตั้งเพื่อบอกว่า ".git" ที่จะใช้ อยู่ path อะไร
    2. GIT_WORKING_TREE : ตัวแปรที่บอกว่า path ที่จะดึงโค้ดออกมา อยู่ที่ path ไหน
  4. ตัวอย่าง: เมื่อมี push ขึ้นมา ให้เอาโค้ดล่าสุด(HEAD)จาก master ไปลงใน /var/www/myproject
    #!/bin/bash
    export GIT_DIR=~/myproject/.git
    export GIT_WORKING_TREE=/var/www/myproject
    git checkout -f master
    git reset --hard HEAD
    
  5. chmod u+x post_receive

No comments:

Post a Comment