1. 程式人生 > >Git 個人學習筆記及心得

Git 個人學習筆記及心得

一、認識 GitHub

Git 是個版本控制系統,說明白點就是進行程式碼的各種管理,比如你寫錯程式碼回滾啊、追尋 bug 是哪個傢伙造成的啊(邪惡臉)、合併別人程式碼等等,達到協同進行軟體的開發工作。再多說幾句,版本管理控制系統分為「集中式版本控制系統」和「分散式版本控制系統」,其中很多人可能用過 SVN,就是屬於集中式版本控制系統,但是 Git 屬於分散式版本控制系統。關於兩者區別自行搜尋資料瞭解下。當然學習起來,Git 相對算更難上手些。

如果說單純學習 Git 其實和 GitHub 也無關,但我覺得結合 GitHub 來學習是很好的。或許還有人還是不知道 GitHub 是什麼,沒關係,簡單講就是一個開源社群網站(也被大家叫為「同性戀社群」,因為活躍著基本都是程式設計師呀,而這個群體基本又都是 ♂ 哈哈),裡面囊及了全球很多程式大牛,包括 linux 之父

Linus 也在的,並且其 linux 系統的程式碼也是放(即開源)在這個網站,任何人都可以檢視整個原始碼。對於這樣一個社群網站,如果只是人人可以把程式碼開源於上面以讓其他人也可以閱讀其程式碼進行學習這樣一個單一功能,這也太簡單了吧。其實它涉及了很多了基於 Git 有關的功能,如 A 可以開源某個專案程式碼,別人也能克隆(即下載)下來進行閱讀、修改,修改了好的功能,可以提交 A,A 覺得程式碼寫的不錯,同意請求,再進行程式碼合併,這樣通過 n 多人一起的努力,這個專案會越來越好。這些都涉及很多 Git 有關操作,離不開的。雖然有 GUI 客戶端軟體操作,但是一開始學會學習使用命令列 Git 操作,這樣能更好達到對 Git 的深層次學習,也有助於你更好的掌握。

這裡對於如何為別人的開源的專案貢獻程式碼,再說幾句,其大概流程如下:

  1. 先點選 A 的專案倉庫站點的“fork”的按鈕,這樣的你的 GitHub 賬戶下也會有一個相同的倉庫;
  2. 然後把你這個 fork 過來的倉庫程式碼 clone 檢出,然後就可以進行你對該專案程式碼的修改了,覺得修改 ok,最後 push (即加入)到你該遠端倉庫,最後通過內建的“pull request”機制向專案負責人申請程式碼合併;
  3. A 覺得你修改的程式碼寫的很好,就可以進行同意了,同意之後,就能把你修改的程式碼合併到該專案,這樣你也算是為該專案貢獻了力量。

不過,相信還是存在部分人可能還停留在只聽過 GitHub,還沒登入過該網站,更別說網站全為英文,容易失去信心,好吧,建議還是要硬著頭皮先了解下這個網站吧,首先推薦下 stormzhang 寫的一份

GitHub 教程,介紹的很清楚。下面幾個資料也供學習:

二、Git 命令學習

2. 1 參考資料

說明:以下都是基於我看過的資料後的個人理解和總結,有些地方沒表達清楚或者錯誤之處,還望見諒、指出。

先放出我看參考的並且認真看完的資料:

下面是我還沒看待有收藏下來待看的資料(相信這些也都是講 Git 操作而已吧,沒關係,留在這,日後遇到問題了,還是可以翻翻看的):

2.2 Git 命令

限於筆者我實在文筆太爛,我就以個人最直白通俗的話來講一講吧。

首先 Git 屬於「分散式版本控制系統」,先要好好理解這個分散式與集中式的不同。我簡單說下,集中式的如 SVN,是有一臺中央伺服器(其實就是某臺電腦安裝了 svn 軟體),所有開發人員從自己電腦(比如 eclipse 下安裝 svn 外掛)檢出專案程式碼,任何一人修改了程式碼就可以提交至中央伺服器,然後其他人檢出(即更新、合併了程式碼),這樣反覆重複的過程,其中包括衝突的解決等,這所有的程式碼操作記錄都記錄在中央伺服器 svn 中的。從中可以看出這臺中央伺服器的作用吧,說一個很明顯的問題:萬一那臺中央伺服器宕機了,你就不能提交,也不能更新程式碼了。

分散式的如 GIt,是每個人本地維護一個版本控制管理資訊,怎麼做到的呢?Git 啊,所以你本地需要安裝 Git ,這個軟體安裝完畢,新建目錄並在該目錄下執行git init就會有一個.git隱藏資料夾及內容,這個資料夾下內容維護著該目錄下的專案程式碼情況。但是怎麼就分散式呢?——大概的,是這樣,GitHub (其實就可以理解為某臺電腦/伺服器)上有別人提交上去的專案程式碼,然後你 clone (克隆/下載)來,你本地這份專案程式碼就包含.git資料夾,裡面就有這個專案程式碼的版本資訊,同樣的,其他任何人也可以同樣 clone 下來,也是有這樣一份這個專案的程式碼提交等資訊,然後你們(只要你們本地電腦都安裝了 Git)都可以基於專案程式碼進行程式碼的修改了,本地就會記錄你在的修改、提交、回滾等等操作資訊,就算 GitHub 網站掛了也沒事,你們本地都保持著這個專案程式碼的所有版本控制資訊。 大概意思大家體會下,然後其實這裡有關 Git 還有分支的概念,這個我覺得大家多去網上了解清楚。我還是說下大概意思吧,某個安卓專案為例,比如該專案有個主分支 master 是專門用來對外發布上線的程式碼,但是開發過程中某個節點遇到某個 bug 需要修復,則可以在此開發節點新建一個比如 hotfix 分支來進行程式碼的修復,修復好了再合併到主分支 master 上,然後可以刪除掉 hotfix 分支。所以看得出這都會涉及很多關於 Git 命令的操作,這也是學習的重點。要學的深刻,要懂得原理和本質,但是本文只是學習記錄筆記,筆者也實力有限,我只能把某些知道的點以及遇到的坑說說,更多是操作層面的闡釋。但相信還是會幫助一些人的。

2.2.1 本地庫常用 Git 命令

  • git init: 初始化一個目錄,其實初始化完畢然後本地多出了一個 .git的隱藏目錄,這個目錄管理著一個程式碼庫的版本資訊。

  • git add: 把一個檔案從untracked(未被追蹤)狀態轉為到 staged狀態,直白的講,就是把檔案提交到暫緩區,這個時候還沒真正意義上的程式碼提交。格式為:git add .提交所有改動,git add hello.txt提交指定檔案的改動。

  • git commit: 這步才是真正的程式碼提交到倉庫,格式為:git commit或者加引數git commit -m “這次的提交說明資訊”,前者會進入一個頁面,輸入 i 可以進入編輯介面,再寫上這次的提交的註釋說明資訊(一般用來記錄本次提交的主要意圖),然後按 ESC鍵退出編輯返回到命令模式,然後連續輸入兩個大寫的 “Z”(用 Shift 鍵或 Capslock 鍵都可以),就儲存並退出了;後者的話直接可以寫上提交的註釋說明資訊。

    如果在提交的時候出現提示設定郵箱和使用者名稱,是為了保證提交的準確性,在提交的時候 user.name 和 user.email 會進入日誌,這些資訊,是追蹤程式碼變更的關鍵,比如是誰修改的。以後會隨更新內容一起被永久納入歷史記錄。

    PS:在設定使用者名稱的時候,可以使用任意的字元。Git 實際上是使用 email 進行關聯每次提交的,只不過使用 username 作為標示符來進行顯示。當你的 email 地址和 github上的 email 地址一致時,則會使用 Github 上面的 name 來進行顯示。

    如果工作中只涉及一個 git 伺服器,用一個全域性配置就可以了。

    全域性配置:

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

    非全域性配置,某個專案下的配置:(去掉--global)

    git config user.name "strivebo"
    git config user.email "[email protected]"

    可以使用命令來檢視修改後的配置:

    git config --global user.name 或 git config user.name
    git config --global user.email 或 git config user.email

    取消全域性配置:

    git config --global --unset user.name
    git config --global --unset user.email
    
    git config --global user.name    #(檢視)全域性配置賬戶是否已經移除
    git config --global user.email   #(檢視)全域性配置郵箱是否已經移除
  • git reset –hard : 版本回退操作,比如我想把當前的版本回退到上一個版本,要使用什麼命令呢?可以使用如下2種命令,第一種是:git reset --hard HEAD^。那麼如果要回退到上上個版本只需把 HEAD^ 改成 HEAD^^ 以此類推。那如果要回退到前100個版本的話,使用上面的方法肯定不方便,我們可以使用下面的簡便命令操作:git reset --hard HEAD~100 即可。

    假設: 我進行了兩次修改,第一次 readme.txt 檔案添加了2222,第二次添加了3333,我已經使用回退操作回到了第一次的修改,即現在文字內容為2222,但我其實又想回到第二次的修改,該怎麼辦呢(如何恢復3333內容呢)?這裡可以:

    可以通過如下命令即可獲取到版本號:git reflog,可以看到增加內容3333的版本號是多少比如為 6fcfc89,我們現在可以命令:git reset --hard 6fcfc89 來恢復了。

  • git status: 檢視倉庫檔案狀態。可以加引數 -s,即git status -s,加個 -s 用簡潔模式檢視當前修改和倉庫裡面差別多少,可以看到有多少檔案被新增了,多少被修改了,多少被刪除了。

  • git log: 檢視提交歷史記錄,即版本歷史資訊,比如誰提交的,什麼時間啊。

  • git diff: (不加選項引數)可以顯示工作目錄和暫存區之間的不同。換句話說,這條指令可以讓你看到「如果你現在把所有檔案都 add,你會向暫存區中增加哪些內容」。比如git diff develop,檢視當前版本和 develop 分支的差異。

  • git diff –cached: 檢視已經暫存起來的檔案和上次提交的版本之間的差異。git diff –cached filename 檢視已經暫存起來的某個檔案和上次提交的版本之間的差異。

  • git diff –staged: 使用 git diff --staged 可以顯示暫存區和上一條提交之間的不同。換句話說,這條指令可以讓你看到「如果你立即輸入 git commit,你將會提交什麼」。

  • git branch: 檢視有哪些分支,並且能看到當前處於哪個分支上。PS:初始化倉庫後預設有 master 這個主分支,一般情況下不會輕易在該主分支操作。新建分支可以使用git branch <newBranch>格式,如 git branch dev新建分支 dev,其內容和和主分支一模一樣。

    git branch -a:檢視本地和遠端所有分支

    git branch -r:檢視遠端所有分支

    git branch -v:檢視遠端分支詳細資訊

  • git checkout a: 切換到 a 分支。

  • git checkout -b a: 有人就說了,我要先新建再切換,未免有點麻煩,有沒有一步到位的,有的:git checkout -b a 表示新建分支 a 並同時切換到分支 a。

  • git merge: 合併分支程式碼,比如合併 dev 分程式碼,需要先切換到 master 分支,再git merge dev即可合併 dev 分支程式碼。

  • git merge – about: 會嘗試恢復到你執行合併前的狀態。 但當執行命令前,在工作目錄中有未儲藏、未提交的修改時它不能完美處理,除此之外它都工作地很好。由於現在 Git 倉庫處於衝突待解決的中間狀態,所以如果你最終決定放棄這次 merge,也需要執行一次 merge –abort 來手動取消它。輸入這行程式碼,你的 Git 倉庫就會回到 merge 前的狀態。

  • git branch -d: 刪除分支。 假如這個分支新建錯了,或者a分支的程式碼已經順利合併到 master 分支來了,那麼 a 分支沒用了,需要刪除,這個時候執行 git branch -d a 就可以把a分支刪除了。

  • git branch -D: 強制刪除。有些時候可能會刪除失敗,比如如果 a 分支的程式碼還沒有合併到 master,你執行 git branch -d a 是刪除不了的,它會智慧的提示你 a 分支還有未合併的程式碼,但是如果你非要刪除,那就執行 git branch -D a 就可以**強制刪除**a分支。

  • git tag: 新建標籤。我們在客戶端開發的時候經常有版本的概念,比如 v1.0、v1.1 之類的,不同的版本肯定對應不同的程式碼,所以我一般要給我們的程式碼加上標籤(即把某次提交標記為某個 tags,如 v1.0),這樣假設 v1.1 版本出了一個新 bug,但是又不曉得v1.0 是不是有這個 bug,有了標籤就可以順利切換到 v1.0 的程式碼,重新打個包測試了。所以如果想要新建一個標籤很簡單,比如 git tag v1.0 就代表我在當前程式碼狀態下新建了一個 v1.0 的標籤,輸入 git tag 可以檢視歷史 tag 記錄。 想要切換到某個 tag,執行:git checkout v1.0,就可以切換到 v1.0 的程式碼狀態。

2.2.2 操作遠端倉庫相關 Git 命令

  • git clone: 遠端 clone 即複製/克隆一個完整的 repository (倉庫,即專案程式碼)到本地,克隆倉庫時所使用的遠端主機自動被 Git 命名為origin,如果想用其他的主機名,需要用git clone命令的-o選項指定。格式為:git clone -o jQuery https://github.com/jquery/jquery.git,然後git remote命令檢視,可以看到名字為遠端主機名 jQuery。

    這裡要特別說下,這裡克隆可以有兩種方式,一種 https 方式,一種 ssh 。

    1、如果是 https 方式,複製倉庫 https 地址進行 clone 操作,如:git clone https://github.com/strivebo/git-practice.git

    這樣克隆下來的專案倉庫,注意觀察.git資料夾下的config中的檔案 url:

    [remote "origin"]
      url = https://github.com/strivebo/git-practice.git
      fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
      remote = origin
      merge = refs/heads/master

    2、如果是 ssh 方式,複製倉庫的 ssh 地址進行 clone 操作,如:git clone [email protected]:strivebo/git-practice.git

    這樣克隆下來的專案倉庫,注意觀察.git資料夾下的config中的檔案 url:

    [remote "origin"]
      url = git@github.com:strivebo/git-practice.git
      fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
      remote = origin
      merge = refs/heads/master

    注: https 方式下 url 為 「https 地址」,shh 方式下 url 為「ssh 地址」(我就這麼任性瞎說了,反正意思明白就行),所以假設你採用的 https 方式 clone 下來的專案可以通過修改這個 url 為「ssh 地址」變為了 「ssh 方式 clone 下來的」。)

    兩者的區別有,若採用的 https 方式,則每次提交程式碼至 github 時,都要求輸入 github 賬號和密碼才能提交,若 ssh 方式,則不需要每次的輸入。但是當然在這之前,你得要新增 ssh 。

    這裡引用我看到的網上資料關於 https 和 SSH 的區別說下:

    1、前者可以隨意克隆 github上的專案,而不管是誰的;而後者則是你必須是你要克隆的專案的擁有者或管理員,且需要先新增 SSH key ,否則無法克隆。

    2、https url 在 push 的時候是需要驗證使用者名稱和密碼的;而 SSH 在 push 的時候,是不需要輸入使用者名稱的,如果配置 SSH key 的時候設定了密碼,則需要輸入密碼的,否則直接是不需要輸入密碼的。

    關於如何新增 ssh 我也在這裡說下步驟:

    ​ 1、Linux 與 Mac 都是預設安裝了 SSH ,而 Windows 系統安裝了 Git Bash(即安裝了 Git 就有這個) 應該也是帶了 SSH 的,在終端輸入ssh命令可以檢視是否安裝了 ssh;

    ​ 2、緊接著輸入 ssh-keygen -t rsa 或者ssh-keygen -t rsa -C "註釋"格式 ,就是指定 rsa 演算法生成金鑰,接著連續三個回車鍵(不需要輸入密碼)然後就會生成兩個檔案 id_rsa 和 id_rsa.pub ,而 id_rsa 是金鑰,id_rsa.pub 就是公鑰。這兩檔案預設分別在如下目錄裡生成: Linux/Mac 系統 在 ~/.ssh 下,win系統在 /c/Documents and Settings/username/.ssh 下, 都是隱藏目錄,大家應該能找到的;

    PS: 其實在連續安回車鍵中會提示輸入一個密碼以及確認密碼,這個密碼會在你提交專案時使用,如果為的話(即直接按回車鍵,也即未設定密碼)提交專案程式碼時則不用輸入密碼;

    ​ 3、接下來要做的是把 id_rsa.pub 的內容新增到 GitHub 上(PS:如何新增自行網上搜下,就不多說了),這樣你本地的 id_rsa 金鑰跟 GitHub 上的 id_rsa.pub 公鑰進行配對,授權成功,這樣就可以不用像 https 方式每次輸入賬號和密碼進行驗證身份才能提交了。(你就理解為,SSH 就好比進行了身份驗證的這種理解。)

    ​ 4、SSH key 新增成功之後,輸入 ssh -T [email protected] 進行測試,如果出現以下提示,再輸入 yes 出現如下圖則證明新增成功了。(圖我就不截了,我覺得問題應該不大)

    對於命令 ssh-keygen新增不同引數的含義的說明可以看這篇文章: ssh-keygen引數說明

    看完該文之後,我也能解釋下了。首先ssh-keygen用於為 生成、管理和轉換認證金鑰,包括 RSA 和 DSA 兩種金鑰。 金鑰型別可以用 -t 選項指定。如果沒有指定則預設生成用於 SSH-2 的 RSA 金鑰。-c 要求修改私鑰和公鑰檔案中的註釋。本選項只支援 RSA1 金鑰。程式將提示輸入私鑰檔名、密語(如果存在)、新註釋。

  • git remote: 列出所有的遠端倉庫。從別處 clone 來的,預設都會有一個別名”origin”的倉庫。帶上 -v 可以看到具體 URL。

  • git remote add: 新增遠端倉庫地址。其實這些操作都是在本地,並沒有實際牽涉到遠端。另外 github 裡面fork 過來的,預設叫”upstream”。該命令完整格式為:git remote add <主機名> <網址>,如git remote add orgin [email protected]:strivebo/git-practice.git

  • git remote rw: 刪除遠端倉庫地址。格式為:git remote rm <主機名>

  • git remote rename: 用於遠端主機的改名。完整格式為:git remote rename <原主機名> <新主機名>

  • git fetch: 一旦遠端主機的版本庫有了更新(Git 術語叫做 commit),需要將這些更新取回本地,這時就要用到git fetch命令。格式為:git fetch <遠端主機名>,預設情況下,git fetch取回所有分支(branch)的更新。

    1、如果只想取回特定分支的更新,可以指定分支名,格式為:git fetch <遠端主機名> <分支名>, 另外,所取回的更新,在本地主機上要用”遠端主機名/分支名”的形式讀取,比如origin主機的master,就要用origin/master讀取。

    2、取回遠端主機的更新以後,可以在它的基礎上,使用git checkout命令建立一個新的分支,git checkout -b newBrach origin/master,該命令表示,在origin/master的基礎上,建立一個新分支。此外,也可以使用git merge命令或者git rebase命令,在本地分支上合併遠端分支。

  • git pull: git pull命令的作用是,取回遠端主機某個分支的更新,再與本地的指定分支合併。相當於 fetch後,再進行 merge。其完整格式為:git pull <遠端主機名> <遠端分支名>:<本地分支名>,如取回origin主機的next分支,與本地的master分支合併,可以這樣寫:git pull origin next:master

    如果遠端分支是與當前分支合併,則冒號後面的部分可以省略,即git pull origin next,該命令表示,取回origin/next分支,再與當前分支合併。實質上,這等同於先做git fetch,再做git merge

    在某些場合,Git會自動在本地分支與遠端分支之間,建立一種追蹤關係(tracking)。比如,git clone的時候,所有本地分支預設與遠端主機的同名分支,建立追蹤關係,也就是說,本地的master分支自動”追蹤”origin/master分支。 Git 也允許手動建立追蹤關係。

    git branch --set-upstream master origin/next該命令指定master分支追蹤origin/next分支

    1、如果當前分支與遠端分支存在追蹤關係,git pull就可以省略遠端分支名。git pull origin該命令表示,本地的當前分支自動與對應的origin主機”追蹤分支”(remote-tracking branch)進行合併

    2、如果當前分支只有一個追蹤分支,連遠端主機名都可以省略,git pull該命令表示,當前分支自動與唯一一個追蹤分支進行合併

    3、合併需要採用rebase模式,可以使用--rebase選項。git pull --rebase <遠端主機名> <遠端分支名>:<本地分支名>

    4、如果遠端主機刪除了某個分支,預設情況下,git pull 不會在拉取遠端分支的時候,刪除對應的本地分支。這是為了防止,由於其他人操作了遠端主機,導致git pull不知不覺刪除了本地分支。但是,你可以改變這個行為,加上引數 -p 就會在本地刪除遠端已經刪除的分支。git pull -p 該命令等同於:

    git fetch --prune origin 
    git fetch -p
  • git push: git push命令用於將本地分支的更新,推送到遠端主機。它的格式與git pull命令相仿。其完整格式為:git push <遠端主機名> <本地分支名>:<遠端分支名>

    1、如果省略遠端分支名,則表示將本地分支推送與之存在”追蹤關係”的遠端分支(通常兩者同名),如果該遠端分支不存在,則會被新建。git push origin master該命令表示,將本地的master分支推送到origin主機的master分支。如果後者不存在,則會被新建。

    2、如果省略本地分支名,則表示刪除指定的遠端分支,因為這等同於推送一個空的本地分支到遠端分支。git push origin :master等同於git push origin --delete master該命令表示刪除origin主機的master分支。

    3、如果當前分支與遠端分支之間存在追蹤關係,則本地分支和遠端分支都可以省略。git push origin該命令表示,將當前分支推送到origin主機的對應分支。

    4、如果當前分支只有一個追蹤分支,那麼主機名都可以省略。git push

    5、如果當前分支與多個主機存在追蹤關係,則可以使用-u選項指定一個預設主機,這樣後面就可以不加任何引數使用git pushgit push -u origin master該命令將本地的master分支推送到origin主機,同時指定origin為預設主機,後面就可以不加任何引數使用git push了。

    備註:不帶任何引數的git push,預設只推送當前分支,這叫做 simple 方式。此外,還有一種matching 方式,會推送所有有對應的遠端分支的本地分支。Git 2.0版本之前,預設採用 matching 方法,現在改為預設採用 simple 方式。如果要修改這個設定,可以採用git config命令。

    $ git config --global push.default matching
    
    # 或者
    
    $ git config --global push.default simple

    還有一種情況,就是不管是否存在對應的遠端分支,將本地的所有分支都推送到遠端主機,這時需要使用--all選項。

    $ git push --all origin

    上面命令表示,將所有本地分支都推送到origin主機。

    如果遠端主機的版本比本地版本更新,推送時Git會報錯,要求先在本地做git pull合併差異,然後再推送到遠端主機。這時,如果你一定要推送,可以使用--force選項。

    git push --force origin

    上面命令使用--force選項,結果導致遠端主機上更新的版本被覆蓋。除非你很確定要這樣做,否則應該儘量避免使用--force選項。

    最後,git push不會推送標籤(tag),除非使用--tags選項。git push origin --tags

關於git clonegit remotegit fetchgit pullgit push的使用是操作遠端倉庫最常用的命令,強烈建議去看阮一峰這篇日誌文章:Git遠端操作詳解

三、實戰學習

3.1 程式碼提交到 GitHub 上

1、採用 https 方式克隆 github 上倉庫(專案):git clone https://github.com/strivebo/git-practice.git

2、採用 ssh 方式克隆:git clone [email protected]:strivebo/git-practice.git

3、如果想要在克隆至本地時指定別的目錄名稱,可以在後面加個引數,如:git clone https://github.com/strivebo/git-practice.git git-practice-another,手動指定本地倉庫的根目錄名稱為 git-practice-another。

從github上clone一個專案到本地的時候,有use HTTPS和use SSH兩種方式,這兩種主要是在push項到github上時有所不同。完成一個push操作,需要對其內容進行安全管理,這裡提供了ssh和https兩種方式。而在clone專案到本地時,做出選擇後,就已經決定了push的方式。

ssh使用了RSA,即非對稱加密的方式,存在一個公鑰和私鑰。可以生成一個本地的一組祕鑰,然後將公鑰複製到github的settings/profile下。

使用 https 方式,每次需要驗證使用者身份資訊。

1、採用的是https克隆

解釋下 your branch is ahead of 'origin/master' by 2 commits.

  1. Git 提示你的當前 branch 已經領先於( “ahead of” )’origin/master’ 兩個提交了
  2. origin/master 的中的 origin 是遠端倉庫的名稱,是你在用 clone 指令初始化本地倉庫時 Git 自動幫你起的預設名稱;master 是 origin 上的分支名稱。

對於現在來說,可以暫時把 origin/master 簡單理解為「中央倉庫」,也就是說,這句話是告訴你,你的本地倉庫已經領先中央倉庫兩個提交了。

然後可以使用

  • git push

    提交發布至中央伺服器(這裡即指 GitHub)。
    由於這是聯網操作,所以在這個過程 GitHub 會再次向你索要賬戶和密碼。填入正確的賬戶和密碼,push 操作就完成了。這時你再去你的 GitHub 倉庫頁面可以看到提交記錄。說明你已經成功把本地倉庫的提交推送到了伺服器了。

    PS:如果覺得一遍遍地輸入密碼很煩,可以按照這個頁面 提供的方案來把密碼儲存起來。另外還有一個更簡單但安全性低一些的方案。執行這行程式碼:git config credential.helper store在這之後你只需要再輸入一次密碼, Git 就會把你的密碼儲存下來,這之後就再也不用輸入了。說它「安全性低」,是因為這條指令會讓 Git 把你的密碼以明文形式儲存在你的電腦上。具體這兩種儲存密碼的方案選擇哪個,看你自己了。

總結:

  1. 從 GitHub 把中央倉庫 clone 到本地(使用命令: git clone
    把寫完的程式碼提交(先用 git add 檔名 把檔案新增到暫存區,再用 git commit 提交)

  2. 在這個過程中,可以使用 git status 來隨時檢視工作目錄的狀態
    每個檔案有 “changed / unstaged”(已修改), “staged”(已修改並暫存), “commited”(已提交) 三種狀態,以及一種特殊狀態 “untracked”(未跟蹤)

  3. 提交一次或多次之後,把本地提交 push 到中央倉庫(git push)…

2、採用的是ssh方式克隆

先要進行 ssh 新增。

SHH

你擁有了一個 GitHub 賬號之後,就可以自由的 clone 或者下載其他專案,也可以建立自己的專案,但是你沒法提交程式碼。仔細想想也知道,肯定不可能隨意就能提交程式碼的,如果隨意可以提交程式碼,那麼GitHub 上的專案豈不亂了套了,所以提交程式碼之前一定是需要某種授權的,而 GitHub 上一般都是基於 SSH 授權的。那麼什麼是 SSH 呢? 簡單點說,SSH是一種網路協議,用於計算機之間的加密登入。目前是每一臺 Linux 電腦的標準配置。而大多數 Git 伺服器都會選擇使用 SSH 公鑰來進行授權,所以想要在 GitHub 提交程式碼的第一步就是要先新增 SSH key 配置。

ssh 設定步驟:
1. Git Bash下輸入ssh出現如下則表示本機已經安裝 ssh,否則自行安裝下載。
2. 緊接著輸入 ssh-keygen -t rsa ,什麼意思呢?就是指定 rsa 演算法生成金鑰,接著連續三個回
車鍵(不需要輸入密碼) ,然後就會生成兩個檔案 id_rsaid_rsa.pub ,而 id_rsa 是金鑰id_rsa.pub 就是公鑰
這兩檔案預設分別在如下目錄裡生成:
Linux/Mac 系統 在 ~/.ssh 下,win系統在 /c/Documents and Settings/username/.ssh 下, 都是隱藏檔案。
3. 接下來要做的是把 id_rsa.pub 的內容新增到 GitHub 上,這樣你本地的 id_rsa 金鑰跟 GitHub 上的 id_rsa.pub 公鑰進行配對,授權成功才可以提交程式碼。
4. SSH key 新增成功之後,輸入 ssh -T [email protected] 進行測試。

最後就是 pushpull的操作了。新增 SSH key 成功之後,我們就有許可權向 GitHub 上我們自己的專案提交程式碼了!執行:git push origin master 進行程式碼提交。

問題: 假設我們本地有個 test2 的專案,我們需要的是在 GitHub 上建一個 test 的專案,然後把本地 test2 上的所有程式碼 commit 記錄提交到 GitHub 上的 test 專案。

第一步就是在 GitHub 上建一個 test 專案,這個想必大家都會了,就不用多講了。

第二步把本地 test2 專案與 GitHub 上的 test 專案進行關聯,切換到 test2 目錄,執行如下命
令:git remote add origin [email protected]:strivebo/test.git

什麼意思呢?就是新增一個遠端倉庫,他的地址是 [email protected]:strivebo/test.git ,而 origin 是給這個專案的遠端倉庫起的名字,是的,名字你可以隨便取,只不過大家公認的只有一個遠端倉庫時名字就是 origin ,為什麼要給遠端倉庫取名字?因為我們可能一個專案有多個遠端倉庫?比如 GitHub 一個,比如公司一個,這樣的話提交到不同的遠端倉庫就需要指定不同的倉庫名字了。

檢視我們當前專案有哪些遠端倉庫可以執行如下命令: git remote -v ,接下來,我們本地的倉庫就可以向遠端倉庫進行程式碼提交了:git push origin master,就是預設向 GitHub 上的 test 目錄提交了程式碼,而這個程式碼是在 master 分支。當然你可以提交到指定的分支。

兩種方式的區別: git 使用 https 協議,每次 pull, push 都要輸入密碼,相當的煩。使用 git 協議,然後使用 ssh 金鑰。這樣可以省去每次都輸密碼。

四、問題和筆記

4.1 問題列表

問題 1:

對於前面這個「假設我們本地有個 test2 的專案,我們需要的是在 GitHub 上建一個 test 的專案,然後把本地 test2 上的所有程式碼 commit 記錄提交到 GitHub 上的 test 專案。」情況,我在練習的時候出現了問題,錯誤是:fatal the current branch master has no upstream branch.

先參考這幾篇文章看看:

我的總結: 如果沒有配置 ssh(採用 ssh 方式),那採用以下方式:

git remote add origin https://github.com/strivebo/test.git(https方式地址克隆)

然後:(下面是引用的網上一個人的解決方式)

此時如果 origin 的 master 分支上有一些本地沒有的提交,push 會失敗.

所以解決的辦法是, 首先設定本地master的上游分支:git branch --set-upstream-to=origin/master

然後pull:git pull --rebase

最後再push:git push



問題2:官網下載的 Git 與 TortoiseGit 客戶端有什麼關係嗎?

  • Git自帶GUI介面。使用 git gui 命令可以開啟它。在這個介面中可以完成commit、merge、push、pull等等常用操作。

    …….

  • TortoiseGit沒有整合Git。在TortoiseGit官方網站可以下載到它。有32bit和64bit版本,同時也有中文語言包(但我不建議你安裝)。安裝完畢之後,如果你沒有安裝過 Git,那麼還需要去下載msysGit來安裝。因為TortoiseGit其實只是一個殼,它需要呼叫 Git 命令列才能發揮作用。(現在你知道我為什麼推薦你用命令行了麼?)如果你不安裝msysGit,那麼在執行TortoiseGit的時候會彈出這個提示:

    為什麼TortoiseGit不像TortoiseSVN一樣,把SVN命令列工具整合在安裝包中呢?我猜想是以下幾點原因:

    ​ - Git官方從未出過Windows版本二進位制包;

    ​ - msysGit和TortoiseGit是兩個不同的團隊開發的;

    ​ - msysGit和TortoiseGit的更新週期差異較大;

    ​ - TortoiseGit團隊希望安裝包更小;

    ​ - TortoiseGit團隊給使用者更靈活的選擇Git版本的權利。



問題3:Git 如何 clone 非 master 分支的程式碼?

問題描述:

在從github上clone專案下來的時候,如 https 方式克隆某個具有多個分支的專案:
git clone https://github.com/TeamNewPipe/NewPipe.git 注:該分支預設分支為 dev 分支,其他分支有 master 、multyservice 分支。

出現的問題是:克隆完畢,使用git branch檢視本地分支,只能看到 dev 分支。(git branch -a可以檢視到本地和遠端所有分支情況。)是隻能克隆到 github 專案的預設分支,其他分支沒有克隆下來嗎?

更具體的描述問題:

當我們想 clone 別人的在分支中修改的 code 時,我們在 github 中看到往往是 master,並且我們 clone 下來的也是也是 master,如下圖,是一個工程的不同分支,當我點選不同的分支,其 clone 的 https 卻是一樣的,那麼該如何clone我想要的分支呢?

參考的解決方式:

新的解決辦法:先git branch -a列出本地和遠端所有分支,比如某個遠端分支為 origin/daily/1.4.1,然後再直接使用git checkout origin/daily/1.4.1

舊的解決方法:1、先在本地建立與遠端分支同名分支名稱;2、切換到該本地分支;3、建立上游分支,即git branch --set-upstream-to=origin/daily/1.4.1 daily/1.4.1,這樣完成與上游分支的關聯,然後 pull 就好了。

Git 預設只顯示預設分支的資料,還需要手動切換到我們需要的分支並顯示出來。

git branch
git checkout -b 本地分支名字 origin/遠端分支名字

這樣大功告成。

使用 git checkout -b aaa origin/aaa。該語句作用是在本地建立新的分支,分支的名稱是 aaa,aaa 也是我想要 clone 的分支的名字,這裡為了便於理解將本地的分支名字和 clone 的分支名字設為一樣,其實 -b 後面的 aaa 可以隨意設定。

親測,② 的方式是 ok 的!



問題4:git pull 和 git fetch 有什麼區別?

首先,你的每一個操作都是要指明【來源】和【目標】的,而對於 pull 來說,【目標】就是當前分支;

其次,你得清楚 git 是有 tracking 的概念的,所謂 tracking 就是把【來源】和【目標】繫結在一起,節省一些操作是需要輸入的引數。

那麼,假設你的 master 和 develop 都是 tracking 了的,於是:

當你在 master 下,git pull等於 fetch origin,然後 merge origin/master;

當你在 develop 下,git pull等於 fetch origin,然後 merge origin/develop

4.2 筆記

筆記1:在本地倉庫初始化後,不進行 commit 提交,則新建不了分支;進行了commit提交,則真正建立了master 分支。

這裡引用阮一峰老師的 Git 文章寫的:

在某些場合,Git 會自動在本地分支與遠端分支之間,建立一種追蹤關係(tracking)。比如,在 git clone 的時候,所有本地分支預設與遠端主機的同名分支,建立追蹤關係,也就是說,本地的master分支自動”追蹤” origin/master 分支。Git 也允許手動建立追蹤關係:git branch --set-upstream master origin/next 該命令指定 master 分支追蹤 origin/next 分支。



筆記2:重新命名分支及遠端分支名稱:

在 git 中重新命名遠端分支,其實就是先刪除遠端分支,然後重新命名本地分支,再重新提交一個遠端分支。

  1. 刪除分支的命令是:
    在 Git1.7 之後可以使用這個命令git push origin --delete <遠端分支名稱>,否則用這個也可以:git push origin :<遠端分支名稱> 表示推送一個空分支到遠端分支,其實就相當於刪除遠端分支。

  2. 重新命名本地分支:git branch -m <舊名稱> <新名稱>

  3. 重新提交:git push origin <新名稱>:<新名稱>

五、Git 圖形化工具教程

SourceTree:

資料: