Git在實際生產中的使用

2022-11-06 06:02:16

最常用程式碼合作流程

建議首先看一下這個,如醍醐灌頂:https://www.bilibili.com/video/BV19e4y1q7JJ/

三個東西:

  • Remote:遠端倉庫;
  • Local:本地Git倉庫(可以理解為一個Git記錄表,本身不包括專案程式碼);
  • Disk:真正存放在磁碟中的程式碼,用編輯器編輯的。

  1. git clone <倉庫地址> 克隆遠端倉庫主分支到本地;
  2. git checkout -b mydev 切換到功能開發分支;
    • 相當於複製了本地主分支的程式碼,命名為新的分支名字;
    • 不於直接在主分支上修改程式碼,保證不論怎麼開發新功能都不會影響主分支的正常執行;
  3. Coding;
  4. git diff 檢視對程式碼做出的改變;
  5. git add上傳更新後的程式碼至暫存區;
  6. git commit -m "commit hints" 可以將暫存區裡更新後的程式碼更新到原生的Git記錄表中;
  7. git push origin mydev 將本地mydev分支,提交到遠端倉庫mvdev分支;

如果提交的時候發現遠端主倉庫已經更新了,(無更新請跳過

  • git checkout master 切換回主分支;

  • git pull origin master 將遠端修改過的程式碼再更新到本地;pull同時修改程式碼和本地Git記錄表;

  • git checkout mvdev 再切換回開發分支;

  • git rebase master 嘗試把遠端的最新更新,融入到我最新寫的程式碼之前;

  • 效果相當於,從最新的主分支建立開發分支,寫新的功能程式碼;

  • rebase過程可能會出現衝突,手動選擇儲存哪段程式碼;

  • git push -f origin mydev 把rebase後並且更新過的程式碼再推播到遠端倉庫;

  • -f 強制推播,覆蓋上次的提交記錄,不然會出現不恰當的兩條commit;

  • 在遠端倉庫發起PR(Pull Request / 合併請求),有其他夥伴來審閱你提交的程式碼;

稽核未通過,應當如下操作;

  • 在本地mydev上根據建議修改程式碼;

  • git commit --amend :修改上次的commit;

  • git push origin -f mydev :覆蓋上次提交;

  • 不用重新新建PR,上面過程後,剛的PR對應的程式碼也會更改的;


  • PR稽核通過後,合併到遠端的主分支了;常用合併方式:
    • Squash and merge :新功能開發的dev可能也有多個commit,合併到主分支就只有一個總的commit了;
    • Rebase and merge: 就相當於上面提交的時候發現遠端主倉庫已經更新了,如果沒衝突就順利合併了,如果有衝突就要先解決衝突;

  • 程式碼合併到主分支後,可以順手把你的開發分支刪除;
  • git branch -d mydev 刪除本地分支;
  • git pull origin master 再把遠端的最新程式碼拉至本地

至此,新功能開發完成!

簡單情況下的程式碼提交

  1. git fetch origin master:獲取最新的master分支
  2. git checkout -b mydev:建立一個自己寫程式碼的分支並切換
  3. Coding:開發人員寫程式碼
  4. git add
  5. git commit -m "commit hints"
  6. git push origin mydev:提交到origin的mydev分支
  7. 發起PR(Pull Requests)
  8. 團隊其他人員評論,建議
  9. 在本地mydev上根據建議修改程式碼
  10. git commit --amend :修改上次的commit
  11. git push origin -f mydev :覆蓋上次提交
  12. 如果還不通過,迴圈這個過程。

Fetch and Pull

總而言之一句話,fetch只同步了原生的Git記錄表,而本地實際程式碼並未同步;

Origin 其實是你原生的記錄(並不是程式碼),但他的指向是remote,remote更新程式碼以後,也就是新增了個提交之後,origin此時還並沒有更新到記錄。

通過一個小例子來看:

先對遠端倉庫的分支(這裡以master為例)合併一條請求,然後按順序執行下面的命令:

  • git log origin/master :注意檢視輸出,特別關注第一條
  • git fetch origin :更新遠端跟蹤分支(所有分支)
  • git log origin/master :看輸出的,跟第一條比較

fetch只是追蹤了遠端分支的變化,但並沒有將變化合併到本地分支。

所以,如果需要更新原生程式碼:

git pull origin master    //相當於git fetch 和 git merge

僅獲取某分支的程式碼

  • 先clone master分支到本地,然後:
git checkout -b dev origin/dev
  • 直接獲取分支程式碼
git clone -b <branchname> https://git.url <localfolderpath>

Localfolderpath 一定要是一個資料夾的名字,可以不存在會自己建立。

遠端倉庫已經合併了別人的程式碼

如果此時你在發起一個合併請求,且你們修改的不是同一個檔案,會出現以下現象:

可以通過點選「更新分支」,通過兩個commit實現的,先是他人合併到master的提交,接著才是你的提交。

但是推薦下面這種方式,只有一個commit,在你發起一個PR之後發現程式碼落後的處理。

git rebase origin/master 	# 如果沒衝突是順利執行的
git commit --amend
git push origin -f hang

衝突產生原因與解決辦法

產生原因:遠端倉庫已經合併的程式碼裡,修改了與你發起PR的分支中相同的部分。

舉例說明:O是master分支,O_0是合併程式碼前的,A是一個分支,B是另一個分支;A,B都是從O的同一個commit節點中檢出的。現在A修改了一些程式碼並且已經合併到O中了,A合併以後O_0變成了O_1,但是B不知道,B也修改了相同的位置發起了從B到O_0的PR(合併請求),因此導致了衝突。

那麼正確的應該是什麼?就是B不應該修改,然後fetch下遠端O的程式碼,再checkout B ,修改程式碼,然後從B發起到O_1的合併請求。

如果你已經沒注意這樣做了,如何解決?當然也有辦法。

git fetch										# 更新所有分支的程式碼
git rebase origin/master		# 在B分支下執行,將B變基
  • rebase之後,衝突的部分會清楚的顯示出來具體在那個檔案裡,而且檔案裡衝突的部分也會很清晰的標註出來。如下圖:

  • <<<<<<< 和 ======= 之間是你當前分支所修改的內容

  • >>>>>>> 和 ======= 之間是別人的修改,也就是這裡不同的修改造成的衝突。

  • 解決衝突,需要把這些衝突表示的符號也刪掉。

然後完成rebase的過程:

git rebase --continue

也可以中止rebase:git rebase --abort,並且分支會回退到rebase開始之前的狀態。

rebase完成之後,你按照正常提交程式碼就可以了。

不恰當的多個Commit合併為一個

git log	# 確認當前所處commit位置
git reset --soft HEAD~1 # 1是你想回退到幾次提交前,或者
git reset --hard HEAD~1	
  • --soft:需要儲存提交的程式碼用這個,然後git stash, 再git stash pop 更改變化。
  • --hard 恢復到上次提交前,但提交的程式碼被清空。

再次提交程式碼的時候:

git commit --amend
git push origin -f mydev

Git復原,放棄本地修改

參考來源:https://blog.csdn.net/A_grumpy_Mario/article/details/103282110?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

  1. 未使用git add 提交到暫存區的程式碼:
git checkout -- filepathname #放棄單個檔案的程式碼修改
git checkout .							 #放棄所有檔案的修改
此命令用來放棄掉所有還沒有加入到快取區(就是 git add 命令)的修改:內容修改與整個檔案刪除。但是此命令不會 刪除掉剛新建的檔案。因為剛新建的檔案還沒已有加入到 git 的管理系統中。所以對於git是未知的。
  1. 已經git add 提交到暫存區的程式碼:
git reset HEAD filepathname	 #放棄指定檔案的快取
git reset HEAD							 #放棄所有檔案的快取

# 此命令用來清除 git  對於檔案修改的快取。相當於復原 git add 命令所在的工作在使用本命令後,原生的修改並不會消失,而是回到瞭如(1)所示的狀態。繼續用(1)中的操作,就可以放棄原生的修改
  1. 已經使用了git commit提交了的程式碼
git reset --hard HEAD^			 #退到最近一次commit的狀態
git reset --hard  commitid	 #恢復到上次提交,提交的程式碼被清空。
git reset --soft  commitid	 
#恢復到上次提交,提交的程式碼還在,然後git stash, 再git stash pop 更改變化。
git log 命令來檢視git的提交歷史

更新遠端分支列表

git remote update origin --prune 

程式碼參照特定行

點開程式碼倉庫某一檔案的具體程式碼,按規則在url後面新增:

指定第30行程式碼:#L30

指定30~50行的程式碼:#L30-L50

團隊共同作業常用術語

  • WIP —   Work in progress, do not merge yet. // 進行中,尚未合併。
  • LGTM —  Looks good to me. // 在我看來很好。(Review 完別人的 PR ,沒有問題)
  • PTAL —  Please take a look. // 幫我看下 (一般都是請別人 review 自己的 PR)
  • CC —  Carbon copy // 複本 (一般代表抄送別人的意思)
  • RFC  —  request for comments. // 我覺得這個想法很好, 我們來一起討論下
  • IIRC  —  if I recall correctly. // 如果我沒記錯
  • ACK  —  acknowledgement. // 我確認了或者我接受了,我承認了
  • NACK/NAK — negative acknowledgement. // 我不同意