Tuesday, January 26, 2010

Git กับ Remote Branch

สรุปไว้กันลืม

สมมติว่าเรา clone git มาจาก Remote
โดย default เราจะได้ local branch ที่ชื่อ "master" ที่ track กับ remote branch ที่ชื่อ "master"

$ git branch
* master

แต่ถ้าเราสั่งให้ show branch ทั้งหมด

$ git branch -a
* master
origin/HEAD
origin/activity-calendar
origin/master
origin/pilot
origin/pilot_20100128
origin/user-admin

จะเห็นว่า git ทำการ fetch branch ทั้งหมดมาให้เรา เพียงแต่มัน map ขึ้นมาเป็น local branch ให้เราเฉพาะแค่ master

ถ้าเราสั่ง git fetch สิ่งที่เกิดก็คือ git จะทำการดึงข้อมูลการเปลี่ยนแปลงทุกอย่างของ server มาที่เครื่องเรา แต่จะยังไม่ update Working copy ให้เรา

ส่วน git pull ก็เทียบได้กับการสั่ง git fetch แล้วตามด้วย git merge โดยจะ merge จะเฉพาะ current HEAD ของเรา (ถ้า HEAD คือ master ก็จะ merge เฉพาะ master)

ที่นี้ถ้าเราต้องการ track remote branch บนเครื่องเรา สิ่งที่ต้องทำก็คือ

$ git checkout -b pilot origin/pilot
Branch pilot set up to track remote branch refs/remotes/origin/pilot.
Switched to a new branch "pilot"


ปัญหาที่เกิดบ่อยๆก็คือ เราสั่ง track remote branch โดยตั้งชื่อ local branch ไม่ตรงกับ remote branch เช่น

$ git checkout -b myb1 origin/b1
Branch myb1 set up to track remote branch refs/remotes/origin/b1.
Switched to a new branch "myb1"

เวลาเราแก้ไข file ใน branch myb1 เสร็จแล้วอยาก push ไปที่ server

$ vi MYFILE

$ git add MYFILE
$ git commit -m 'Add MYFILE'

$ git push
Everything up-to-date

จะเห็นว่ามันไม่ยอม push commit ใหม่ของเราไปที่ remote repository
ที่เป็นเช่นนี้เพราะถ้าเราสั่ง git push โดยไม่มี parameter สิ่งที่ git ทำก็คือ มันจะ push เฉพาะชื่อ branch ที่ตรงกันของทั้งสองฝั่ง

การแก้ไขก็คือ เปลี่ยนตัวแปร configuration push.defaut ให้เป็น tracking เพื่อที่จะให้มัน push เฉพาะ branch ที่มี tracking กับ remote branch โดยไม่สนใจเรื่องชื่อตรงกัน

$ git push
Everything up-to-date
pphetra@[~/t2]
$ git config push.default tracking
pphetra@[~/t2]
$ git push
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 248 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To git@github.com:pphetra/test.git
7d96d34..0dd66fa myb1 -> b1


ที่นี้ถ้าเราต้องการสร้าง branch ใหม่บน remote หล่ะ
เริ่มจากการสร้าง branch บน server

$ git push origin origin:refs/heads/b4
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:pphetra/test.git
* [new branch] origin/HEAD -> b4
$ gitx

$ git branch -a
* b1
b2
master
myb1
remotes/origin/HEAD -> origin/master
remotes/origin/b1
remotes/origin/b2
remotes/origin/b4
remotes/origin/master

จากนั้นก็สั่ง checkout ตามปกติได้เลย

$ git checkout -b b4 origin/b4
Branch b4 set up to track remote branch b4 from origin.
Switched to a new branch 'b4'

Related link from Roti

2 comments:

chanwit said...

- โอ้ อันนี้ล้ำลึกครับ ยังไม่เคยเห็น
git push origin origin:refs/heads/b4

- gitx คืออะไรครับ?

- ผม share เรื่องลบ remote branch
git push origin :b4

polawat phetra said...

gitx นี่เกินมาครับ (copy เพลิน)
gitx เป็น gui ของ git บน mac ครับ

syntax ลบ remote branch (รวมทั้งเพิ่ม branch ด้วย) นี่มันไม่สื่ออย่างแรงเลยนะครับ