git版本管理策略及相關技巧(A)


公司幾乎所有的項目都是使用 git 倉庫來管理代碼,以前對 git 只有些膚淺的了解,每次提交代碼或者上線的時候總是會提心吊膽,生怕出現一些未知的問題。經過三個月的踩坑和填坑, git 操作頗顯成熟。僅以此文回憶學習 git 的歷史。

本文地址:http://www.cnblogs.com/hustskyking/p/git-improve.html,轉載請注明源地址。

一、基本操作

1. 克隆代碼

1.1 添加倉庫

最直接的方式:

cd dir  # 這里不用新建一個項目名的文件夾,dir為git文件夾的父文件夾
git clone https://github.com/barretlee/Micro-Share

你也可以進入一個目錄,然后初始化(init):

cd path/to/Project
git init
# 添加遠程目錄
git remote add origin https://github.com/barretlee/Micro-Share

這些都是最基本的了,上面的 remote add 是添加一個遠程目錄,你也可以添加多個遠程目錄,什么情況下會添加多個呢?比如:我想把別人的代碼處理之后放到自己的 git 倉庫上去,

git remote add origin https://github.com/barretlee/Micro-Share
git remote add mine http://your/path/to/git
# 拉取遠程代碼到 init 之后的 master 主干上
git fetch origin master
# 修改代碼之后,提交到自己的倉庫
git commit -am "fist"
git push -u mine master

1.2 添加文件

在提交文件之前首先要添加文件到分支中,很多人只知道:

git add .

如果有文件刪除,會發現這些刪除的文件並沒有被附加進去,腫么辦?

#方式一
git add --all .
#方式二
git add -A .
  • --all 參數,顧名思義,添加所有文件(change|delete|add)
  • -A 參數,添加修改過和刪除過的文件(change|delete)
  • 不加 參數,添加修改過和添加的文件(change|add)

1.3 提交文件

git commit -m "comment"

如果沒有刪除過文件,可以合並添加和提交文件為一步:

git commit -am "add and commit"

1.4 遠程提交

提交到遠程倉庫上:

# 將 master 提交到 origin 上
git push origin master

這一步操作可能會出現很多的問題,比如:

a) origin為一個多人開發的庫,別人在你提交之前已經向 origin 上提交過一次(或者多次),那么此時你的版本是落后於遠程服務器版本的,你需要先拉去線上最新的代碼:

# 拉去遠程分支到 master
git pull origin master

b) 執行 a) 之后,有可能也會有提醒:存在沖突,需要合並分支,這個在后面會提到

c) 如果你很自信,覺得線上的版本是存在問題,你這個版本木有問題,你可以強制提交你的代碼

git push -u origin master -f

這里需要特別注意,加了 -f 線上之前的修改就會被刪掉,請謹慎使用!

二、進階操作指南

上面是最基本的幾條命令,初用 git 的童鞋一般也只會接觸這些東西,在一些復雜的多人開發項目中,修改代碼、合並代碼十分頻繁,上面的命令顯然是不夠用了。在介紹進階命令之前,先了解下 git 的三種狀態。

+-----------+      +-----------+       +-----------+
|           |      |           |       |           |
|  working  | -->  |   index   |  -->  |  commit   |
|           |      |           |       |           |
+-----------+      +-----------+       +-----------+
      ↓                  ↓                   ↓
   當前操作            git add            git commit

                              <Created By Barret Lee>

你當前的操作狀態下,所有文件的狀態都在 work 狀態,當你執行 git add 之后,文件狀態變為 index,也就是在 git 中已經有過一次登記了,而 git commit 之后就被編入了分支,成為 commited 狀態了。需要注意的是,這三種狀態一直存在,只是會有不同的文件來對應這些狀態。

1. 場景切換

Barret 有一天敲代碼,代碼敲了一半,Boss 跟他說,線上出了個 bug,趕緊的,去修復!

咋辦?上面那堆代碼,敲了半個上午啊,重新新建一個文件夾,然后把線上代碼再克隆一次修改?這種處理的成本顯然太高了!其實 git 為我們提供了很好用的命令 git stash。只要在當前目錄下操作:

git stash

這句命令執行完畢之后,git 管理區中的 stash 會多出一條記錄,這條記錄保存了上一次提交到目前,你所有的修改:

last commit ... working file now

接着你就可以修改你的 bug 了,修改完了之后,再使用

git stash pop

將之前保存的修改(場景)還原回來。其內部的原理也是很簡單的:

+---------------+      +-----------+      +-----------+       +-----------+
|               |      |           |      |           |       |           |
|  last commit  | -->  |  working  | -->  |   index   |  -->  |  commit   |
|               |      |           |      |           |       |           |
+---------------+  ↑   +-----------+      +-----------+   |   +-----------+|         ↓                  ↓         |          ↓
   上次提交         |      當前操作            git add      |    git commit
                   |                                     s|
                   |                                     t|
                   |       +---------+                   a|
                   |       | Stash 0 |                   s|
                   |       +---------+                   h|
                   +------ | Stash 1 | <------------------+
                           +---------+
                           |  ....   |
                           +---------+
                           | Stash n |
                           +---------+<Created By Barret Lee>
                             stash堆棧

有些童鞋可能看不太懂上面的圖,git 有一個場景(stash)堆棧,這個堆棧的作用是用於保存修改的,下面舉個例子:

# 進入文件夾
$ cd test
# 初始化 git
$ it init
# 新建四個文件
$ touch f1 f2 f3 f4

上面初始化一個 git ,然后新建了四個文件

# 修改 f1
$ echo "1" > f1
# 將修改 push 到 stash 棧堆中
$ git stash

上面修改了文件 f1,並保存到場景棧堆中

# 查看 stash 棧堆
$ git stash list
  stash@{0}: WIP on master: 7f58be2 3

查看棧堆,可以看到 stash@{0}

# 修改 f2
$ echo "1" > f2
# 添加修改
$ git add .
# 將修改 push 到 stash 棧堆中
$ git stash

修改文件 f2,添加之后保存到棧堆之中

# 查看 stash 棧堆
$ git stash list
    stash@{0}: WIP on master: 7f58be2 3
    stash@{1}: WIP on master: 7f58be2 3

棧堆中多了一個 stash@{1},這個時候我們去修復 bug,改變其他位置的代碼,完了之后:

# pop 棧堆,還原修改
$ git stash pop

上面我們將棧堆 pop 出來,遵循后進先出的規則

# 查看文件狀態
git status
$ Changes not staged for commit:
    changed: f2
  please commit it

以上代碼都是我手動敲出來的,不是復制控制台的代碼,大概就是這個么意思吧。關於 stash 的最后一個想說明的命令是:

git stash clear

清空場景(stash)堆棧。

2. 代碼 diff

2.1 HEAD

在介紹這塊之前,也需要先了解幾個基本的常識:

HEAD     它表示上一次的 commit 版本

HEAD~n 它表示第上 n 詞的 commit 版本,這里的 n 是大於等於 1 的整數

如果我們要比較上一次和這一次代碼之間的差異,可以:

git diff HEAD~1 HEAD

比較前第三次與現在代碼的差異,可以:

git diff HEAD~3 HEAD

獲取前第n次的還有另外一種方式,如前第二次:

HEAD^^

前第五次:

HEAD^^^^^

這樣寫起來比較累,還是前面的方式比較順手。

2.2 SHA

關於 SHA 標識的介紹,我這里就懶得打字了,可以看我之前分享的一點東西,使用

git log

可以看到每次 commit 的 SHA 標識。要比較兩次提交之間的差異,可以直接

git diff SHA1 SHA2

其中 SHA1 和 SHA2 是兩次提交(commit)時的標識。

2.3 與場景的比較

這個用的比較少,對比目前代碼跟最近一次 push 的場景代碼差異:

git diff --cached

從字面上也好理解,就是跟緩存的文件做對比嘛~

3. 版本回退

如果上面的 SHA,working,index,commit 幾種狀態和標識沒有弄明白,相信這里也是十分難理解的。

版本回退使用的命令是:

git reset

3.1 三種操作

這個命令后面是要加參數的,分別為:

a) filename

git reset HEAD filename  # 從暫存區移除文件

如果之前有 add filename,上面的命令操作之后,filename 將處於未被 add 的狀態。也就是從 index 轉變成 working 狀態。

b) HEAD

git reset --hard HEAD~n

直接回退到前第 n 個版本。

c) SHA

git reset --hard SHA

回到 SHA 對應的 commit 的版本。

3.2 三種方式

上面我們使用的是 --hard 來 reset 代碼,這樣風險是特別大的,這里有三個可選參數:

  • --hard 回退版本,代碼也回退,忽略所有修改
  • --soft 回退版本,代碼不變,回退所有的 add 操作
  • --mixed 回退版本,代碼不變,保留 add 操作

4. 分支處理

4.1 查看分支

git branch

這是最簡單的查看,查看本地創建了哪些分支。

git branch -va

查看本地+遠程分支,及其詳細信息(上次提交commit信息)

4.2 添加分支

git branch branch_name

如果你當前所在的分支是 master,此處創建的分支會直接繼承 master 的所有修改歷史。

git branch -b branchnew branchold

-b 是 base 的意思,如果你有兩個分支 A 和 B ,目前在 A 分支上,你先新建一個分支繼承 B,此刻你有兩個選擇:

# 選擇一
# 先切換到 B 分支上
git checkout B
git branch C

# 選擇二
git branch -b C B

4.3 切換分支

a) 切換到本地分支

git checkout branch_name

b) 切換到遠程分支

git checkout remotes/origin/branch_name
git checkout branch_name

詳情請看之前分享的這篇文章,git切換到遠程分支

4.4 刪除分支

顯切換到別的分支上,然后

git branch -d branch_name

如果是遠程分支:

git push origin :branch_name

在需要刪除的分支前面加一個冒號OK了,push 上去之后,服務器上的分支自然就被刪除了。


 

 

由於想寫的內容實在太長,故打算下次再補充第二部分。

下期預告:

本節補充:
  5. tag處理
  6. 倉庫管理
第三章 版本管理策略
第四章 看懂 diff
第五章 配置別名

下次再做小結。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM