1. 程式人生 > 實用技巧 >【工具】Git 基礎

【工具】Git 基礎

Git 基礎

Git 簡介

Git 是一個開源的分散式版本控制系統,用於高效地管理任何或小或大的專案。

在 Linux 發展的時候,程式碼的管理是手工合併的,效率很低,所以 Linus 用 C 語言開發了一套分散式的版本控制系統 Git,之後 Linux 開原始碼的管理就放在了 Git 上管理了。後來 GitHub 的上線也讓 Git 風靡至今。

安裝和配置 Git

  • 安裝 Git:sudo apt install git
  • 配置 Git:設定 name 和 email,因為 Git 在每次 commit 時都會記錄這些資訊。
    • git config --global user.name "name"
    • git config --global user.email "[email protected]"

如果用了--global選項,那麼配置檔案儲存在~/.gitconfig中,否則儲存在當前專案的.git/config檔案中,後者會覆蓋前者的配置。

工作區、暫存區和版本庫

  • 工作區:電腦中的一個目錄。
  • 版本庫:工作區中有一個隱藏目錄.git,這是 Git 的版本庫。
  • 暫存區:暫存區是.git/index檔案。

建立倉庫

git init

在一個目錄下,使用git init命令來初始化一個倉庫,此後該目錄才成為一個工作區。

在執行完成git init命令後,工作區會生成一個.git

目錄,該目錄是版本庫,包含了資源的所有元資料。

git clone

如果在遠端倉庫中已經有現有的專案,可以使用git clone從遠端倉庫中拷貝專案,該命令會自動建立專案目錄。例如:git clone git://github.com/schacon/grit.git

git clone可以使用不同的協議,包括ssh, git, https等,其中最常用的是https。各種寫法如下:

# SSH 協議
git clone [email protected]:zghong/test.git
# GIT 協議
git clone git://github.com/zghong/test.git
# HTTPS 協議
git clone https://github.com/zghong/test.git

# 指定分支
git clone -b develop https://github.com/zghong/test.git
# 淺拷貝
git clone --depth 1 https://github.com/zghong/test.git

一般倉庫不大時,我們可以直接使用git clone倉庫,但如果在倉庫歷史的某次 commit 不小心提交了 1G 的檔案,雖然後面把這個檔案刪除了,但是版本庫(.git資料夾)中仍然儲存著這個檔案,所以如果我們仍然使用git clone這個倉庫,會把所有版本記錄 clone 下來,這樣整個倉庫會非常大。如果僅僅是使用倉庫,而不是管理倉庫,只要把最近的一次 commit 給 clone 下來就好了,實現這個功能就需要用到git clone --depth=1命令。

基本操作

git status 和 git log

  • git status:檢視在你上次提交之後是否有修改。
  • git log:檢視提交日誌。
  • git reflog:檢視歷史操作和對應的commit id

git add

git add:可將增刪改的檔案新增到暫存區。

git add READEME hello.c
git add *.c
git add *

git commit

git commit將暫存區內容提交到版本庫中,並可以使用-m選項以在命令列中提供提交註釋。

每一次git commit就相當於建立一個還原點,並生成一個對應的commit idcommit id是一個 SHA1 計算出來的一個非常大的數字,用十六進位制表示。

git commit -m 不帶空格註釋
git commit -m "帶空格 的註釋"

git diff

git diff:顯示檔案修改的區別。

  • 對比尚未暫存的改動:git diff
  • 對比已暫存的改動:git diff --cached
  • 對比已暫存的與未暫存的所有改動:git diff HEAD
  • 對比工作區和暫存區的不同:git diff HEAD -- 檔名
  • 對比兩個版本的不同:git diff HEAD HEAD^ -- 檔名

git rm

當使用rm test.txt刪除了倉庫中的檔案時,接下來有兩種情況:

  • 確實要刪除:git rm test.txt或者git add test.txt,並提交。
  • 誤刪除:git checkout -- test.txt即可恢復檔案。

撤銷修改

  • 當修改沒有新增到暫存區時,丟棄工作區的改動:git checkout -- 檔名
  • 當修改已經新增到暫存區時,取消暫存:
    • 新檔案:git rm --cached 檔名
    • 修改檔案:git reset HEAD 檔名
  • 當修改已經新增到暫存區並且已經建立了一個版本時:git reset --soft|--mixed|--hard <commit_id>
    • git reset --soft HEAD^:撤銷最近一次 commit,不撤銷 git add。
    • git reset --mixed HEAD^:預設操作,撤銷最近一次 commit,撤銷 git add。
    • git reset --hard HEAD^:撤銷最近一次的 commit,撤銷 git add,並且放棄修改。

分支管理

分支可以類似於兩個平行的宇宙。主要用於去開闢一個新的分支去實現一個新的功能,這個分支並不會對其他分支產生任何影響。當功能開發完善之後,還可以將新分支的內容一次性合併到主分支 master 上。這樣既安全有不影響其他人的正常工作。

建立和合並分支

在建立倉庫時會預設建立一個主分支master,指標是HEAD。當建立一個分支dev時,將HEAD指標指向dev分支。可以指定當前工作分支在哪一個分支上,之後的修改提交就會記錄在該分支下。

  • 檢視分支:git branch
  • 建立分支:git branch 分支名
  • 建立並切換分支:git checkout -b 分支名
  • 切換分支:git checkout 分支名
  • 將某個分支合併到當前所在分支:git merge 分支名
  • 刪除分支:git branch -d 分支名

合併衝突

當兩個分支沒有同時有兩個相同的修改時,合併時預設採用Fast-forward,即快速合併。但是如果兩個分支修改的內容有衝突時會發生合併衝突,這時就需要手動解決衝突。

  • 禁止快速合併:git merge --no-ff -m '版本資訊' 分支名

標籤管理

如之前所說,每一次 commit 就是建立一個版本,但是由於 commit 號是使用 SHA-1 生成的,不容易記住且沒有意義,因此標籤應運而生。

tag 就是一個讓人容易記住的有意義的名字,它跟某個 commit 綁在一起,其實它就是指向某個 commit 的指標。

當釋出一個版本時,我們通常先在版本庫中打一個 tag,這樣就唯一確定了打標籤時刻的版本。將來無論什麼時候,取某個標籤的版本,就是把那個打標籤的時刻的歷史版本取出來。

建立標籤

  • git tag tag名 [commit id] -m "註釋":建立一個標籤,預設標籤是打在最新提交的 commit 上的。例如git tag v1.0 -m "Release Edition v1.0"
  • git tag:檢視所有標籤。
  • git show tag名:檢視標籤資訊。

操作標籤

因為建立的標籤都只儲存在本地,不會自動推送到遠端。如果需要同步遠端倉庫,需要使用單獨的命令對標籤進行同步。

  • 刪除本地標籤:git tag -d tag名
  • 刪除遠端標籤名:
    • git tag -d tag名:先刪除本地標籤。
    • git push origin :refs/tags/tag名:刪除遠端標籤名。
  • 推送標籤:git push orgin tag名
  • 一次性推送所有未推送到遠端的標籤名:git push origin --tags

GitHub 的使用

新增 ssh 公鑰

如果某臺電腦需要與 GitHub 倉庫進行互動就需要將這臺電腦的 ssh 公鑰新增到 GitHub 賬號上。

  • 在本機生成 ssh 祕鑰:ssh-keygen -t rsa -C "[email protected]"
  • 將使用者目錄下的.ssh資料夾下的id_rsa.pub公鑰新增在 GitHub 設定中。
  • 驗證是否新增成功:ssh -T [email protected]

克隆和上傳專案

克隆專案

從遠端倉庫克隆一個已存在的專案只需要一條命令即可。

上傳專案

已經在本地建立了一個 Git 倉庫後,想把本地專案上傳到 GitHub 上,並且讓這兩個倉庫進行遠端同步,這樣,GitHub 上的倉庫既可以作為備份,又可以讓其他人通過該倉庫來協作。

  • 在 Github 上建立一個空倉庫 hehe。
  • git remote add origin [email protected]:zghong/hehe.git,將遠端庫與本地建立關聯。
  • git push -u origin master,把本地庫的所有內容推送到遠端庫上。

由於遠端庫是空的,我們第一次推送 master 分支時,加上了-u引數,Git 不但會把本地的 master 分支內容推送的遠端新的 master 分支,還會把本地的 master 分支和遠端的 master 分支關聯起來,在以後的推送或者拉取時就可以簡化命令。

推送和拉取程式碼

  • 推送程式碼:git push origin 分支名
  • 拉取程式碼:git pull origin 分支名