前幾年自己用過一段時間的git(原來是使用bzr,後來換成git),都是當作個人代碼備份工具,沒有涉及多人提交代碼到中央版本庫。

兩個月前,我們把原來的svn版本管理換成了git,這兩天提交版本時遇到許多問題,上網找些資料看,才發現用法不對,集體使用時,不能簡單地再延續原來個人使用時的習慣。

 

背景囉嗦完了,現在進入正題:如何提交避免版本衝突。

 

  • 首先在本地按方法1 clone 回來之後,只有一個默認分支master,不要直接在上面工作。

建立一個自己的分支,如取名working: git branch working

切換到這個新分支: git checkout working

現在可以自由修改代碼並保存了。

  • 確保你修改的代碼都是自己負責項目下,或者説你的兩次提交之間,沒有其他人來改相同項目下的代碼,

如果不能避免,你就要在下面的merge步驟手工處理衝突了。

  • 提交代碼時按下面的步驟:

可以將下面的腳本保存在你的每個項目之下,每次只修改提交一個項目。

 

 

Bash代碼  

git繞過eslient_提交代碼

  1. git checkout working    --force  #確保使用的是工作分支  
  2. git add .  
  3. git commit -m"$1" -a     #提交代碼到本地,工作分支增加一個版本,這裏的$1是運行腳本的第一個參數  
  4.   
  5. git checkout master        
  6. git pull origin master   #切換回默認分支,並將默認分支和中央最新版本合併  
  7. git merge working        #在本地合併你的這次修改到默認分支  
  8. git push origin master   #提交到中央版本庫,接下來還是要切換回工作分支的  
  9. git checkout working   --force  

 

如果不小心動了生產環境(就是隻從中央版本庫pull到本地)的文件,只好將本地版本退回一個,再從中央代碼庫pull代碼合併。

 

Bash代碼  

git繞過eslient_提交代碼

git reset --hard HEAD



創建分支

git branch

  沒有參數,顯示本地版本庫中所有的本地分支名稱。

  當前檢出分支的前面會有星號。

git branch newname

  在當前檢出分支上新建分支,名叫newname。

git checkout newname

  檢出分支,即切換到名叫newname的分支。

git checkout –b newname master

  這個命令將上面兩個命令合併:在master分支上創建分支newname分支並檢出到該分支。

 

合併分支間的修改 Merge

  合併操作將兩條或多條分支合併到一起,實際上有好幾種分支合併方法,下面介紹主要的三種:

1.直接合並(straight merge)

  把兩條分支上的歷史軌跡合併,交匯到一起。

  比如要把dev分支上的所有東東合併到master分支:

git checkout master

git merge dev

fast-forward的,即Git將master分支的指針直接移到dev的最前方。

快進式(Fast-forward)

 

2.壓合合並(squashed commits):

  將一條分支上的若干個提交條目壓合成一個提交條目,提交到另一條分支的末梢。

  把dev分支上的所有提交壓合成主分支上的一個提交,即壓合提交:

git checkout master

git merge --squash dev

  此時,dev上的所有提交已經合併到當前工作區並暫存,但還沒有作為一個提交,可以像其他提交一樣,把這個改動提交到版本庫中:

git commit –m “something from dev”

  

3.揀選合併(cherry-picking):

  揀選另一條分支上的某個提交條目的改動帶到當前分支上。

  每一次提交都會產生一個全局唯一的提交名稱,利用這個名稱就可以進行揀選提交。

  比如在dev上的某個提交叫:321d76f

  把它合併到master中:

git checkout master

git cherry-pick 321d76f

  要揀選多個提交,可以給git cherry-pick命令傳遞-n選項,比如:

git cherry-pick –n 321d76f

  這樣在揀選了這個改動之後,進行暫存而不立即提交,接着可以進行下一個揀選操作,一旦揀選完需要的各個提交,就可以一併提交。

 

衝突處理

  當兩條分支對同一個文件的同一個文本塊進行了不同的修改,並試圖合併時,Git不能自動合併的,稱之為衝突(conflict)。解決衝突需要人工處理。

  比如當前在master分支,想把dev分支merge過來,結果產生了一個衝突,打開文件內容可以看到這麼一個衝突:

git繞過eslient_版本庫_03

<<<<<<< HEAD

test in master

=======

test in dev

>>>>>>> dev

git繞過eslient_版本庫_03

 

<<<<<<<標記衝突開始,後面跟的是當前分支中的內容。

HEAD指向當前分支末梢的提交。

  =======之後,>>>>>>>之前是要merge過來的另一條分支上的代碼。

>>>>>>>之後的dev是該分支的名字。

  對於簡單的合併,手工編輯,然後去掉這些標記,最後像往常的提交一樣先add再commit即可。

 

刪除分支

  有些分支沒有必要長期保存,比如分支中的代碼已經打了標籤並已發佈,或者實驗分支已經成功完成工作或中途廢棄等等。 

注意:打了標籤的分支,Git在刪除該分支時,從版本樹起始到此標籤間的全部歷史軌跡均會保留,此時刪除分支操作只是刪除分支本身的名稱,因此可以説該分支沒有必要長期保存。

  而在其他版本控制工具中,刪除分支通常意味着刪除分支上的所有歷史軌跡,所以不能因為打了標籤就認為其沒有必要保存。

 

  刪除一個分支dev2:

git branch –d dev2

  注意不能刪除當前所在分支,需要轉到別的分支上。

  如果要刪除的分支已經成功合併到當前分支,刪除分支的操作會直接成功。

  如果要刪除的分支沒有合併到當前所在分支,則會出現提示,如果確定無須合併而要直接刪除,則執行命令:

git branch –D dev2

  進行強刪。

 

分支重命名

  重命名分支:

git branch –m oldname newname

-m不會覆蓋已有分支名稱,即如果名為newname的分支已經存在,則會提示已經存在了。

-M就可以覆蓋已有分支名稱了,即會強制覆蓋名為newname的分支,這種操作要謹慎。