Git 個人學習筆記及心得
一、認識 GitHub
Git 是個版本控制系統,說明白點就是進行程式碼的各種管理,比如你寫錯程式碼回滾啊、追尋 bug 是哪個傢伙造成的啊(邪惡臉)、合併別人程式碼等等,達到協同進行軟體的開發工作。再多說幾句,版本管理控制系統分為「集中式版本控制系統」和「分散式版本控制系統」,其中很多人可能用過 SVN,就是屬於集中式版本控制系統,但是 Git 屬於分散式版本控制系統。關於兩者區別自行搜尋資料瞭解下。當然學習起來,Git 相對算更難上手些。
如果說單純學習 Git 其實和 GitHub 也無關,但我覺得結合 GitHub 來學習是很好的。或許還有人還是不知道 GitHub 是什麼,沒關係,簡單講就是一個開源社群網站(也被大家叫為「同性戀社群」,因為活躍著基本都是程式設計師呀,而這個群體基本又都是 ♂ 哈哈),裡面囊及了全球很多程式大牛,包括 linux 之父
這裡對於如何為別人的開源的專案貢獻程式碼,再說幾句,其大概流程如下:
- 先點選 A 的專案倉庫站點的“fork”的按鈕,這樣的你的 GitHub 賬戶下也會有一個相同的倉庫;
- 然後把你這個 fork 過來的倉庫程式碼 clone 檢出,然後就可以進行你對該專案程式碼的修改了,覺得修改 ok,最後 push (即加入)到你該遠端倉庫,最後通過內建的“pull request”機制向專案負責人申請程式碼合併;
- A 覺得你修改的程式碼寫的很好,就可以進行同意了,同意之後,就能把你修改的程式碼合併到該專案,這樣你也算是為該專案貢獻了力量。
不過,相信還是存在部分人可能還停留在只聽過 GitHub,還沒登入過該網站,更別說網站全為英文,容易失去信心,好吧,建議還是要硬著頭皮先了解下這個網站吧,首先推薦下 stormzhang 寫的一份
二、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 push
。git 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 clone
、git remote
、git fetch
、git pull
、git 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.
- Git 提示你的當前 branch 已經領先於( “ahead of” )’origin/master’ 兩個提交了
- origin/master 的中的 origin 是遠端倉庫的名稱,是你在用 clone 指令初始化本地倉庫時 Git 自動幫你起的預設名稱;master 是 origin 上的分支名稱。
對於現在來說,可以暫時把 origin/master 簡單理解為「中央倉庫」,也就是說,這句話是告訴你,你的本地倉庫已經領先中央倉庫兩個提交了。
然後可以使用
git push
提交發布至中央伺服器(這裡即指 GitHub)。
由於這是聯網操作,所以在這個過程 GitHub 會再次向你索要賬戶和密碼。填入正確的賬戶和密碼,push 操作就完成了。這時你再去你的 GitHub 倉庫頁面可以看到提交記錄。說明你已經成功把本地倉庫的提交推送到了伺服器了。PS:如果覺得一遍遍地輸入密碼很煩,可以按照這個頁面 提供的方案來把密碼儲存起來。另外還有一個更簡單但安全性低一些的方案。執行這行程式碼:
git config credential.helper store
在這之後你只需要再輸入一次密碼, Git 就會把你的密碼儲存下來,這之後就再也不用輸入了。說它「安全性低」,是因為這條指令會讓 Git 把你的密碼以明文形式儲存在你的電腦上。具體這兩種儲存密碼的方案選擇哪個,看你自己了。
總結:
從 GitHub 把中央倉庫 clone 到本地(使用命令:
git clone
)
把寫完的程式碼提交(先用git add 檔名
把檔案新增到暫存區,再用git commit
提交)在這個過程中,可以使用
git status
來隨時檢視工作目錄的狀態
每個檔案有 “changed / unstaged”(已修改), “staged”(已修改並暫存), “commited”(已提交) 三種狀態,以及一種特殊狀態 “untracked”(未跟蹤)提交一次或多次之後,把本地提交
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_rsa
和 id_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] 進行測試。
最後就是 push
、pull
的操作了。新增 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 中重新命名遠端分支,其實就是先刪除遠端分支,然後重新命名本地分支,再重新提交一個遠端分支。
刪除分支的命令是:
在 Git1.7 之後可以使用這個命令git push origin --delete <遠端分支名稱>
,否則用這個也可以:git push origin :<遠端分支名稱>
表示推送一個空分支到遠端分支,其實就相當於刪除遠端分支。重新命名本地分支:
git branch -m <舊名稱> <新名稱>
重新提交:
git push origin <新名稱>:<新名稱>
五、Git 圖形化工具教程
SourceTree:
資料: