Git基本操作流程

技術背景

Gitee是一款國內的git託管服務,對於國內用戶較為友好,用戶可以訪問Gitee地址來創建自己的帳號和項目,並託管在Gitee平台上。既然是git的託管服務,那我們就可以先看看git的一些基本用法:

[dechin@dechin-manjaro ~]$ git --help
用法:git [--version] [--help] [-C <路徑>] [-c <名稱>=<取值>]
           [--exec-path[=<路徑>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<路徑>] [--work-tree=<路徑>] [--namespace=<名稱>]
           <命令> [<參數>]

這些是各種場合常見的 Git 命令:

開始一個工作區(參見:git help tutorial)
   clone             克隆倉庫到一個新目錄
   init              創建一個空的 Git 倉庫或重新初始化一個已存在的倉庫

在當前變更上工作(參見:git help everyday)
   add               添加文件內容至索引
   mv                移動或重命名一個文件、目錄或符號鏈接
   restore           恢復工作區文件
   rm                從工作區和索引中刪除文件
   sparse-checkout   初始化及修改稀疏檢出

檢查歷史和狀態(參見:git help revisions)
   bisect            通過二分查找定位引入 bug 的提交
   diff              顯示提交之間、提交和工作區之間等的差異
   grep              輸出和模式匹配的行
   log               顯示提交日誌
   show              顯示各種類型的對象
   status            顯示工作區狀態

擴展、標記和調校您的歷史記錄
   branch            列出、創建或刪除分支
   commit            記錄變更到倉庫
   merge             合併兩個或更多開發歷史
   rebase            在另一個分支上重新應用提交
   reset             重置當前 HEAD 到指定狀態
   switch            切換分支
   tag               創建、列出、刪除或校驗一個 GPG 簽名的標籤對象

協同(參見:git help workflows)
   fetch             從另外一個倉庫下載對象和引用
   pull              獲取並整合另外的倉庫或一個本地分支
   push              更新遠程引用和相關的對象

命令 'git help -a' 和 'git help -g' 顯示可用的子命令和一些概念幫助。
查看 'git help <命令>' 或 'git help <概念>' 以獲取給定子命令或概念的
幫助。
有關係統的概述,查看 'git help git'。

如果git安裝成功,就會有上述的執行反饋。我們可以在git命令行上進行操作,比如執行代碼的提交等任務。

拷貝倉庫

首先我們在Gitee上面創建好一個項目,或者我們可以查看其他已經創建好的項目的首頁,一般是如下的形式:

我們可以點擊這裡的Fork,將該倉庫fork到自己的帳號下。一般如果我們沒有原倉庫的developer權限的話,只能通過提交Pull Request來進行代碼提交。因此操作邏輯變成了:先把代碼倉Fork到自己的帳號下,在自己的帳號下進行修改,將Fork倉庫的代碼更新到源倉庫代碼中。Fork成功後可以在自己的帳號下看到這樣的一個項目:

拉取倉庫

在通過上一章節的方法拷貝了倉庫到自己的帳號下之後,我們可以將該倉庫下載到本地進行操作,使用git clone即可:

[dechin@dechin-manjaro 2021-quantum]$ git clone //gitee.com/dechin/your_library.git
正克隆到 'your_library'...
Username for '//gitee.com': dechin
Password for '//[email protected]': 
remote: Enumerating objects: 200, done.
remote: Counting objects: 100% (200/200), done.
remote: Compressing objects: 100% (113/113), done.
remote: Total 200 (delta 85), reused 200 (delta 85), pack-reused 0
接收對象中: 100% (200/200), 2.01 MiB | 433.00 KiB/s, 完成.
處理 delta 中: 100% (85/85), 完成.

下載倉庫完成後,可以看到本地新建了一個名為your_library的目錄,點擊進去就是我們下載下來的倉庫代碼。

這裡我們順帶介紹一下在本地用vim操作的一些簡單技巧,比如顯示行號及其效果圖片:

:set nu

取消行號顯示及其效果圖片:

:set nonu

提交更新

在上一章節中我們介紹了如何將代碼下載到本地,下載到本地之後我們可以使用各種的編輯器和IDE進行代碼增加修改與測試。譬如完成了某一項任務之後,修改了一個名為_circuit_level_count_test.py的文件,那我們就可以將這個代碼文件用git add提交到遠程倉庫:

[dechin@dechin-manjaro tests]$ git add _circuit_level_count_test.py 

為了使得代碼庫的歷史更加明了,我們最好規範一下提交信息,比如下述示例介紹了一個案例,修復了#i3CDFM這個Issue,那麼我們就可以將提交信息按照如下寫法進行編寫:

[dechin@dechin-manjaro tests]$ git commit -m 'Fix issue #i3CDFM'
作者身份未知

*** 請告訴我你是誰。

運行

  git config --global user.email "[email protected]"
  git config --global user.name "Your Name"

來設置您賬號的缺省身份標識。
如果僅在本倉庫設置身份標識,則省略 --global 參數。
fatal: 無法自動探測郵件地址(得到 'dechin@dechin-manjaro.(none)')

一開始任務進行的不太順利,按照提示中的說法,是因為我們沒有配置帳號和郵箱,這裡我們可以用提示的指令進行配置:

[dechin@dechin-manjaro tests]$ git config --global user.email "[email protected]"
[dechin@dechin-manjaro tests]$ git config --global user.name "dechin"

配置完基本信息之後,我們再次嘗試代碼提交信息的編寫:

[dechin@dechin-manjaro tests]$ git commit -m 'Fix issue #i3CDFM'[master 591f9cf] Fix issue #i3CDFM
 1 file changed, 2 insertions(+), 5 deletions(-)

在上述信息出現之後,就表示執行成功了,那麼我們就可以進行遠程代碼提交了:

[dechin@dechin-manjaro tests]$ git push
Username for '//gitee.com': dechin
Password for '//[email protected]': 
枚舉對象中: 7, 完成.
對象計數中: 100% (7/7), 完成.
使用 8 個線程進行壓縮
壓縮對象中: 100% (4/4), 完成.
寫入對象中: 100% (4/4), 411 位元組 | 411.00 KiB/s, 完成.
總共 4(差異 3),復用 0(差異 0),包復用 0
remote: Powered by GITEE.COM [GNK-5.0]
To //gitee.com/dechin/your_library.git
   6e345ad..591f9cf  master -> master

提交過程中有可能要求我們輸入Gitee平台的用戶名和密碼,我們按照提示進行輸入即可。需要注意的是,如果提交的不是默認分支,最好可以指定一個分支進行提交,比如git push origin master

多次提交

一般在一次特性提交的過程中,會涉及到不止一次的提交,我們也可以將這些提交同步刷新到同一個分支下,相關的操作都在上一章節中介紹過,這裡我們僅簡單展示一下這個流程:

[dechin@dechin-manjaro drivers]$ git add _save_molecule.py 
[dechin@dechin-manjaro drivers]$ git commit -m 'Fix issue'
[master bff0b02] Fix issue
 1 file changed, 3 insertions(+), 6 deletions(-)
[dechin@dechin-manjaro drivers]$ git push
Username for '//gitee.com': dechin
Password for '//[email protected]': 
枚舉對象中: 11, 完成.
對象計數中: 100% (11/11), 完成.
使用 8 個線程進行壓縮
壓縮對象中: 100% (5/5), 完成.
寫入對象中: 100% (6/6), 526 位元組 | 526.00 KiB/s, 完成.
總共 6(差異 4),復用 0(差異 0),包復用 0
remote: Powered by GITEE.COM [GNK-5.0]
To //gitee.com/dechin/your_library.git
   591f9cf..bff0b02  master -> master

提交成功2次之後,我們可以用如下指令查看歷史提交信息,這裡的-n 5表示我們只查詢最近的5條提交信息:

[dechin@dechin-manjaro your_library]$ git log --oneline --graph -n 5
* bff0b02 (HEAD -> master, origin/master, origin/HEAD) Fix issue
* 591f9cf Fix issue #i3CDFM
* 6e345ad update README.md.
* 591af5d update README.md.
* 664d276 modify the setup.py

這裡編號bff0b02和編號591f9cf的commit就是我們剛才所更新的兩條,我們還可以在這裡看到commit的信息。

變基

在上一章節中,我們可以看到過往的2條commit實際上是在執行同一個任務,比如修復某一個issue。但是這裡的commit信息卻有2條,因為我們是分了2次來提交的,這顯得提交的信息和內容非常的不簡潔,變基(rebase)就是優化這個commit信息顯示的方案,我們可以將過往的2條相同的提交記錄合併成1條:

[dechin@dechin-manjaro your_library]$ git rebase --interactive HEAD~2
成功變基並更新 refs/heads/master。

這裡省略了一些編輯的流程,實際上我們要進入到一個rebase的編輯界面,我們pick需要保留的commit。對於不需要保留的commit信息,我們可以直接將前面的pick改成fixup,然後刪除後面的commit信息。變基執行完畢之後,需要強行push:

[dechin@dechin-manjaro your_library]$ git push --force
Username for '//gitee.com': dechin
Password for '//[email protected]': 
枚舉對象中: 15, 完成.
對象計數中: 100% (15/15), 完成.
使用 8 個線程進行壓縮
壓縮對象中: 100% (7/7), 完成.
寫入對象中: 100% (8/8), 731 位元組 | 731.00 KiB/s, 完成.
總共 8(差異 6),復用 0(差異 0),包復用 0
remote: Powered by GITEE.COM [GNK-5.0]
To //gitee.com/dechin/your_library.git
 + bff0b02...7ffc12a master -> master (forced update)

遠程鏈接

我們可以使用git remote -v查看當前倉庫的遠程鏈接狀態,如果要從我們Fork的倉庫向原始倉庫提交PR的話,就需要創建兩者的鏈接。如果是鏈接未建立的情況,該命令的返回結果如下:

[dechin@dechin-manjaro your_library]$ git remote -v
origin  //gitee.com/dechin/your_library.git (fetch)
origin  //gitee.com/dechin/your_library.git (push)

這裡只顯示了Fork之後的倉庫的地址,說明我們還沒有跟原始倉庫建立起鏈接,這時候需要執行upstream指令:

[dechin@dechin-manjaro your_library]$ git remote add upstream //gitee.com/origin_library.git

此時再運行git remote -v,我們就可以看到新的遠程鏈接:

[dechin@dechin-manjaro your_library]$ git remote -v
origin  //gitee.com/dechin/your_library.git (fetch)
origin  //gitee.com/dechin/your_library.git (push)
upstream        //gitee.com/origin_library.git (fetch)
upstream        //gitee.com/origin_library.git (push)

提交PR

在上述操作流程都結束後,我們可以準備在Gitee界面上直接提交Pull Request了。首先找到我們Fork過來的倉庫:

點擊新建Pull Request,選擇源分支為我們Fork過來的分支,目標分支選擇原始倉庫中的目標分支,然後往下拉可以看到我們提交的更新內容,這裡我們所有的提交內容被壓成了一個commit:

最後提交PR,等待審批人審批即可。

補充示例

前面我們說到修改pickfixup,但是缺少了一個示例圖,這裡重新再提交一個新的commit,來展示這個過程。首先我們執行rebase的時候會彈出這樣的一個命令行界面:

這裡可以直接編輯,因此我們將第二行,也就是我們需要合併的提交,修改為fixup,並且去掉了後面的commit信息:

最後同樣的提交上去,我們可以在PR裏面看到commit仍然只有一條信息,但是代碼修改是有同步的。

這裡也需要額外說明一下,在同一條PR未關閉的情況下,所有在源分支上的提交都會被同步到這個PR裏面來。

修改編輯器

在上一章節中我們看到了一個很奇怪的編輯器,這是因為git默認的編輯器不是vim,但是我們可以手動將其配置為本地的vim編輯器。執行vim ~/.gitconfig編輯git的配置文件,我們發現在這個文件中已經有我們此前配置過的部分信息:

[user]
        email = [email protected]
        name = dechin

這裡我們增加一個editor的配置即可使用vim來編輯git執行中的指令:

[user]
        email = [email protected]
        name = dechin
[core]
        editor = /usr/bin/vim

如果堅持要使用原本的編輯器,那麼在編輯結束之後,需要執行ctrl+X退出,選擇Y選項保存修改,最後回車退出修改狀態,同樣也是可以的,只是使用vim對於大部分人來說會更加的順手。

總結概要

在本文中我們通過一個實例來介紹了Git的基本用法,包括提交代碼、遠程鏈接以及變基等,這使得我們可以更美觀更簡潔的去維護我們自己的開源代碼倉庫。

版權聲明

本文首發鏈接為://www.cnblogs.com/dechinphy/p/git.html
作者ID:DechinPhy
更多原著文章請參考://www.cnblogs.com/dechinphy/