參考鏈接: 廖雪峰的Git教程
認識Git、Github與Gitee
一、Git
Git是一個版本控制系統。版本控制系統是設計用於跟蹤文件隨時間變化狀態的一款軟件。更具體地說,Git是一個分布式的版本控制系統。這就意味着,在Git中參與項目的每個程序員不僅能擁有文件的當前狀態,還能擁有項目完整的歷史記錄。
1.1 在Windows上安裝Git
從Git官網直接下載安裝程序,然后按默認選項安裝即可。 安裝完成后,在開始菜單里找到“Git”->“Git Bash”,蹦出一個類似命令行窗口的東西,就說明Git安裝成功!
安裝完成后,還需要最后一步設置,在命令行輸入:
1. $ git config --global user.name "Your Name"
2. $ git config --global user.email "email@example.com"
因為Git是分布式版本控制系統,所以,每個機器都必須自報家門:你的名字和Email地址。你也許會擔心,如果有人 故意冒充別人怎么辦?這個不必擔心,首先我們相信大家都是善良無知的群眾,其次,真的有冒充的也是有辦法可查的。
注意 git config
命令的 --global
參數,用了這個參數,表示你這台機器上所有的Git倉庫都會使用這個配置,當然也可以對某個倉庫指定不同的用戶名和Email地址。一般情況下,你可以在主目錄下的.gitconfig
里看到上面輸入的兩行命令。
1.2 使用Git創建版本庫
版本庫又名倉庫,英文名repository,你可以簡單理解成一個目錄,這個目錄里面的所有文件都 可以被Git管理起來,每個文件的修改、刪除,Git都能跟蹤,以便任何時刻都可以追蹤歷史,或者在將來某個時刻可 以“還原”。 所以,創建一個版本庫非常簡單。
首先,選擇一個合適的地方,創建一個空目錄:
$ mkdir learngit
$ cd learngit
$ pwd
/d/learngit
pwd
命令用於顯示當前目錄。在我的Windows上,這個倉庫位於 /d/learngit
。使用Windows系統時,為了避免遇到各種莫名其妙的問題,請確保目錄名(包括父目錄)不包含中文。
第二步,通過 git init
命令把這個目錄變成Git可以管理的倉庫:
$ git init
Initialized empty Git repository in /d/learngit/.git/
瞬間Git就把倉庫建好了,而且告訴你是一個空的倉庫(empty Git repository),可以發現當前目錄 下多了一個 .git
的目錄,這個目錄是Git來跟蹤管理版本庫的,沒事千萬不要手動修改這個目錄里面的文件,不然 改亂了,就把Git倉庫給破壞了。如果沒有看到 .git
目錄,那是因為這個目錄默認是隱藏的,在查看方式里勾選隱藏的項目即可。也不一定必須在空目錄下創建Git倉庫,選擇一個已經有東西的目錄也是可以的。
1.3 向版本庫添加文件
首先這里再明確一下,所有的版本控制系統,其實只能跟蹤文本文件的改動,比如TXT文件,網頁,所有的程序代碼等 等,Git也不例外。要真正使用版本控制系統,就要以純文本方式編寫文件。
因為文本是有編碼的,比如中文有常用的GBK編碼,日文有Shift_JIS編碼,強烈建議使用 標准的UTF-8編碼,所有語言使用同一種編碼,既沒有沖突,又被所有平台所支持。
盡量不要使用Windows自帶的記事本編輯任何文本文件。原因是Microsoft開發記事本的團隊使用了一個非常弱智的 行為來保存UTF-8編碼的文件,他們自作聰明地在每個文件開頭添加了0xefbbbf(十六進制)的字符,你會遇到很多不可思議的問題,比如,網頁第一行可能會顯示一個“?”,明明正確的程序一編譯就報語法錯誤,等等,都是由記事本的弱智行為帶來的。建議下載Notepad++代替記事本,不但功能強大,而且免費!把Notepad++的默認編碼設 置為UTF-8 without BOM即可:
言歸正傳,現在我們編寫一個 readme.txt
文件,內容如下:
Git is a version control system.
Git is free software
一定要放到 learngit
目錄下(子目錄也行),因為這是一個Git倉庫,放到其他地方Git再厲害也找不到這個文件。 和把大象放到冰箱需要3步相比,把一個文件放到Git倉庫只需要兩步
第一步,用命令 git add
告訴Git,把文件添加到倉庫:
$ git add readme.txt
執行上面的命令,沒有任何顯示,這就對了,Unix的哲學是“沒有消息就是好消息”,說明添加成功。
第二步,用命令 git commit
告訴Git,把文件提交到倉庫:
$ git commit -m "wrote a readme file"
[master (root-commit) ea97297] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
簡單解釋一下git commit
命令, -m
后面輸入的是本次提交的說明,可以輸入任意內容,當然最好是有意義的,這樣你就能從歷史記錄里方便地找到改動記錄。
git commit
命令執行成功后會告訴你, 1 file changed
:1個文件被改動(我們新添加的readme.txt文件);2 insertions
:插入了兩行內容(readme.txt有兩行內容)。
為什么Git添加文件需要 add
,commit
一共兩步呢?因為 commit
可以一次提交很多文件,所以你可以多次 add
不同的文件,比如:
$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."
1.4 文件修改及版本回退
我們已經成功地添加並提交了一個readme.txt文件,現在,是時候繼續工作了,於是,我們繼續修改readme.txt 文件,改成如下內容:
Git is a distributed version control system.
Git is free software.
現在,運行 git status
命令看看結果:
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
git status
命令可以讓我們時刻掌握倉庫當前的狀態,上面的命令輸出告訴我們, readme.txt 被修改過了,但還 沒有准備提交的修改。
雖然Git告訴我們 readme.txt
被修改了,但如果能看看具體修改了什么內容,自然是很好的。比如你休假兩周從國外 回來,第一天上班時,已經記不清上次怎么修改的readme.txt
,所以,需要用 git diff
這個命令看看:
$ git diff
diff --git a/readme.txt b/readme.txt
index d8036c1..013b5bc 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,2 @@
-Git is a version control system.
+Git is a distributed version control system.
Git is free software.
\ No newline at end of file
git diff
顧名思義就是查看difference,顯示的格式正是Unix通用的diff格式,可以從上面的命令輸出看到, 我們在第一行添加了一個 distributed
單詞。
知道了對 readme.txt
作了什么修改后,再把它提交到倉庫就放心多了,提交修改和提交新文件是一樣的兩步,第一 步是 git add
:
$ git add readme.txt
同樣沒有任何輸出。在執行第二步 git commit
之前,我們再運行 git status
看看當前倉庫的狀態:
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: readme.txt
git status
告訴我們,將要被提交的修改包括 readme.txt
,下一步,就可以放心地提交了:
$ git commit -m "add distributed"
[master ac4c73d] add distributed
1 file changed, 1 insertion(+), 1 deletion(-)
提交后,我們再用 git status
命令看看倉庫的當前狀態:
$ git status
On branch master
nothing to commit, working tree clean
Git告訴我們當前沒有需要提交的修改,而且,工作目錄是干凈(working tree clean)的。
再練習一次,修改readme.txt
文件如下:
Git is a distributed version control system.
Git is free software distributed under the GPL.
然后嘗試提交:
$ git add readme.txt
$ git commit -m "append GPL"
[master 1094adb] append GPL
1 file changed, 1 insertion(+), 1 deletion(-)
像這樣,你不斷對文件進行修改,然后不斷提交修改到版本庫里,就好比玩RPG游戲時,每通過一關就會自動把游戲狀 態存盤,如果某一關沒過去,你還可以選擇讀取前一關的狀態。有些時候,在打Boss之前,你會手動存盤,以便萬一 打Boss失敗了,可以從最近的地方重新開始。
Git也是一樣,每當你覺得文件修改到一定程度的時候,就可以“保存一 個快照”,這個快照在Git中被稱為 commit
。一旦你把文件改亂了,或者誤刪了文件,還可以從最近的一 個 commit 恢復,然后繼續工作,而不是把幾個月的工作成果全部丟失。
想知道文件一共有幾個版本被提交到Git倉庫里?在Git中,我們用 git log 命令查看:
$ git log
commit 3db02ce718daef235dd6655c8b4d8e09cda002db (HEAD -> master)
Author: gylic <981897889@qq.com>
Date: Tue Feb 23 14:43:19 2021 +0800
append GPL
commit ac4c73d1e2434301d22b837807c8386afa141719
Author: gylic <981897889@qq.com>
Date: Tue Feb 23 14:39:29 2021 +0800
add distributed
commit ea97297057d9cdf96db031b0fa5457341d431baa
Author: gylic <981897889@qq.com>
Date: Tue Feb 23 14:25:13 2021 +0800
wrote a readme file
git log
命令顯示從最近到最遠的提交日志,我們可以看到3次提交,最近的一次是 append GPL
,上一次是 add distributed
,最早的一次是 wrote a readme file
。
如果嫌輸出信息太多,看得眼花繚亂的,可以試試加上 --pretty=oneline
參數:
$ git log --pretty=oneline
3db02ce718daef235dd6655c8b4d8e09cda002db (HEAD -> master) append GPL
ac4c73d1e2434301d22b837807c8386afa141719 add distributed
ea97297057d9cdf96db031b0fa5457341d431baa wrote a readme file
一大串類似3db02ce718d...
的是 commit id (版本號),和SVN不一樣,Git的 commit id 不是1,2,3……遞增的數字,而是一個SHA1計算出來的一個非常大的數字,用十六進制表示。
現在我們准備把 readme.txt 回退到上一個版本,也就是 add distributed 的那個版本,怎 么做呢?
首先,Git必須知道當前版本是哪個版本,在Git中,用 HEAD
表示當前版本,也就是最新的提交 3db02ce718d...
(注意提交ID和你的肯定不一樣),上一個版本就是 HEAD^
,上上一個版本就是 HEAD^^
,當然往上100個版本寫 100個 ^ 比較容易數不過來,所以寫成 HEAD~100
。
現在,我們要把當前版本append GPL
回退到上一個版本 add distributed
,就可以使用 git reset
命令:
$ git reset --hard HEAD^
HEAD is now at ac4c73d add distributed
看看 readme.txt
的內容是不是版本 add distributed
:
$ cat readme.txt
Git is a distributed version control system.
Git is free software.
果然被還原了。此時再看現在版本庫的狀態:
$ git log
commit ac4c73d1e2434301d22b837807c8386afa141719 (HEAD -> master)
Author: gylic <981897889@qq.com>
Date: Tue Feb 23 14:39:29 2021 +0800
add distributed
commit ea97297057d9cdf96db031b0fa5457341d431baa
Author: gylic <981897889@qq.com>
Date: Tue Feb 23 14:25:13 2021 +0800
wrote a readme file
最新的那個版本 append GPL
已經看不到了!好比你從21世紀坐時光穿梭機來到了19世紀,想再回去已經回不去了, 腫么辦?
辦法其實還是有的,只要上面的命令行窗口還沒有被關掉,你就可以順着往上找啊找啊,找到那個 append GPL
的 commit id
是3db02ce718d...
,於是就可以指定回到未來的某個版本:
$ git reset --hard 3db02ce718d
HEAD is now at 3db02ce append GPL
版本號沒必要寫全,前幾位就可以了,Git會自動去找。當然也不能只寫前一兩位,因為Git可能會找到多個版本號, 就無法確定是哪一個了。 再小心翼翼地看看 readme.txt
的內容:
$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
果然,又回來了。
假如你回退到了某個版本,關掉了電腦,第二天早上就后悔了,想恢復到新版本但找不到新版本的 commit id
怎么辦?
在Git中,總是有后悔葯可以吃的。當你用 $ git reset --hard HEAD^
回退到 add distributed
版本時,再想恢復 到 append GPL
,就必須找到append GPL
的commit id
。Git提供了一個命令git reflog
用來記錄你的每一次命令:
$ git reflog
3db02ce (HEAD -> master) HEAD@{0}: reset: moving to 3db02ce718d
ac4c73d HEAD@{1}: reset: moving to HEAD^
3db02ce (HEAD -> master) HEAD@{2}: commit: append GPL
ac4c73d HEAD@{3}: commit: add distributed
ea97297 HEAD@{4}: commit (initial): wrote a readme file
終於舒了口氣,從輸出可知, append GPL
的commit id是 1094adb
。
1.5 Git工作原理
git四大域:工作目錄,暫存區,倉庫,遠程倉庫。
git對文件的操作都是在四大域上進行的,文件可以在四大域內與四大域間進行各種操作。(有一個例外,進行“git stash”系列操作時,文件可能被保存到四大域外的堆棧中)
工作區(Working Directory)就是你在電腦里能看到的目錄,比如我的 learngit
文件夾就是一個工作區:
版本庫(Repository): 工作區有一個隱藏目錄 .git
,這個不算工作區,而是Git的版本庫。
Git的版本庫里存了很多東西,其中最重要的就是稱為stage(或者叫index)的暫存區,還有Git為我們自動創建的 第一個分支 master
,以及指向 master
的一個指針叫 HEAD
。
前面講了我們把文件往Git版本庫里添加的時候,是分兩步執行的:
第一步是用 git add
把文件添加進去,實際上就是把文件修改添加到暫存區;
第二步是用 git commit
提交更改,實際上就是把暫存區的所有內容提交到當前分支。
因為我們創建Git版本庫時,Git自動為我們創建了唯一一個 master
分支,所以,現在, git commit
就是 往 master
分支上提交更改。
可以簡單理解為,需要提交的文件修改通通放到暫存區,然后,一次性提交暫存區的所有修改。
俗話說,實踐出真知。現在,我們再練習一遍,先對 readme.txt
做個修改,比如加上一行內容:
然后,在工作區新增一個LICENSE
文本文件(內容隨便寫)
先用 git status
查看一下狀態:
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: readme.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
LICENSE.txt
no changes added to commit (use "git add" and/or "git commit -a")
Git非常清楚地告訴我們, readme.txt
被修改了,而 LICENSE.txt
還從來沒有被添加過,所以它的狀態 是 Untracked
。
現在,使用兩次命令 git add
,把 readme.txt
和LICENSE.txt
都添加后,用 git status 再查看一下:
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: LICENSE.txt
modified: readme.txt
現在,暫存區的狀態就變成這樣了:
所以, git add
命令實際上就是把要提交的所有修改放到暫存區(Stage),然后,執行 git commit
就可以一次性 把暫存區的所有修改提交到分支。
$ git commit -m "understand how stage works"
[master bbfb3e2] understand how stage works
2 files changed, 3 insertions(+), 1 deletion(-)
create mode 100644 LICENSE.txt
一旦提交后,如果你又沒有對工作區做任何修改,那么工作區就是“干凈”的:
$ git status
On branch master
nothing to commit, working tree clean
現在版本庫變成了這樣,暫存區就沒有任何內容了:
一些小結
-
Git比其他版本控制系統設計得優秀, 因為Git跟蹤並管理的是修改,而非文件。要注意每次修改,如果不用
git add
到暫存區,那就不會加入到 commit 中。 -
git checkout -- file
可以丟棄工作區的修改:命令git checkout -- readme.txt
意思就是,把readme.txt
文件在工作區的修改全部撤銷,這里有兩種情況: 一種是readme.txt
自修改后還沒有被放到暫存區,現在,撤銷修改就回到和版本庫一模一樣的狀態; 一種是readme.txt
已經添加到暫存區后,又作了修改,現在,撤銷修改就回到添加到暫存區后的狀態。 總之,就是讓這個文件回到最近一次git commit
或git add
時的狀態。 -
git reset
命令既可以回退版本,也可以把暫存區的修改回退到工作區。 -
git reset HEAD
可以把暫存區的修改撤銷掉(unstage),重新放回工作區
1.6 刪除文件
在Git中,刪除也是一個修改操作,我們實戰一下,先添加一個新文件 test.txt 到Git並且提交:
$ git add test.txt
$ git commit -m "add test.txt"
[master b982eea] add test.txt
1 file changed, 1 insertion(+)
create mode 100644 test.txt
一般情況下,你通常直接在文件管理器中把沒用的文件刪了,或者用 rm
命令刪了:
$ rm test.txt
這個時候,Git知道你刪除了文件,因此,工作區和版本庫就不一致了, git status 命令會立刻告訴你哪些文件被刪 除了:
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
現在有兩個選擇,一是確實要從版本庫中刪除該文件,那就用命令 git rm
刪掉,並且 git commit
:
$ git rm test.txt
rm 'test.txt'
$ git commit -m "remove test.txt"
[master d46f35e] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt
現在,文件就從版本庫中被刪除了。
小提示:先手動刪除文件,然后使用git rm
或git add
效果是一樣的。
另一種情況是刪錯了,因為版本庫里還有呢,所以可以很輕松地把誤刪的文件恢復到最新版本
$ git checkout -- test.txt
git checkout
其實是用版本庫里的版本替換工作區的版本,無論工作區是修改還是刪除,都可以“一鍵還原”。
注意:從來沒有被添加到版本庫就被刪除的文件,是無法恢復的!
1.7 遠程倉庫
有 個叫GitHub的神奇的網站,從名字就可以看出,這個網站就是提供Git倉庫托管服務的,所以,只要注冊一個 GitHub賬號,就可以免費獲得Git遠程倉庫。
由於你的本地Git倉庫和GitHub倉庫之間的傳輸是通過SSH加密 的,所以,需要一點設置:
第1步:創建SSH Key。
在用戶主目錄下,看看有沒有.ssh目錄,如果有,再看看這個目錄下有沒 有id_rsa
和 id_rsa.pub
這兩個文件,如果已經有了,可直接跳到下一步。如果沒有,打開Shell(Windows下打 開Git Bash),創建SSH Key:
$ ssh-keygen -t rsa -C "youremail@example.com"
你需要把郵件地址換成你自己的郵件地址,然后一路回車,使用默認值即可,由於這個Key也不是用於軍事目的,所以 也無需設置密碼。
如果一切順利的話,可以在用戶主目錄里找到 .ssh
目錄,里面有 id_rsa
和 id_rsa.pub
兩個文件,這兩個就是 SSH Key的秘鑰對, id_rsa
是私鑰,不能泄露出去, id_rsa.pub
是公鑰,可以放心地告訴任何人。
第2步:登陸GitHub,打開“Account settings”,“SSH Keys”頁面
然后,點“Add SSH Key”,填上任意Title,在Key文本框里粘貼 id_rsa.pub 文件的內容:
點“Add Key”,你就應該看到已經添加的Key。
為什么GitHub需要SSH Key呢?
因為GitHub需要識別出你推送的提交確實是你推送的,而不是別人冒充的,而Git 支持SSH協議,所以,GitHub只要知道了你的公鑰,就可以確認只有你自己才能推送。
當然,GitHub允許你添加多個Key。假定你有若干電腦,你一會兒在公司提交,一會兒在家里提交,只要把每台電腦 的Key都添加到GitHub,就可以在每台電腦上往GitHub推送了。
最后友情提示,在GitHub上免費托管的Git倉庫,任何人都可以看到喔(但只有你自己才能改)。所以,不要把敏感信息放進去。
如果你不想讓別人看到Git庫,有兩個辦法,一個是交點保護費,讓GitHub把公開的倉庫變成私有的,這樣別人就看 不見了(不可讀更不可寫)。另一個辦法是自己動手,搭一個Git服務器,因為是你自己的Git服務器,所以別人也是看不見的。
添加遠程庫
現在的情景是,你已經在本地創建了一個Git倉庫后,又想在GitHub創建一個Git倉庫,並且讓這兩個倉庫進行遠程 同步,這樣,GitHub上的倉庫既可以作為備份,又可以讓其他人通過該倉庫來協作,真是一舉多得。
首先,登陸GitHub,然后,在右上角找到“Create a new repo”按鈕,創建一個新的倉庫。
在Repository name填入 learngit ,其他保持默認設置,點擊“Create repository”按鈕,就成功地創建了一 個新的Git倉庫。
目前,在GitHub上的這個learngit
倉庫還是空的,GitHub告訴我們,可以從這個倉庫克隆出新的倉庫,也可以把 一個已有的本地倉庫與之關聯,然后,把本地倉庫的內容推送到GitHub倉庫。
現在,我們根據GitHub的提示,在本地的learngit
倉庫下運行命令:
git remote add origin git@github.com:gylic/learngit.git
請千萬注意,把上面的 gylic
替換成你自己的GitHub賬戶名,否則,你在本地關聯的就是我的遠程庫,關聯 沒有問題,但是你以后推送是推不上去的,因為你的SSH Key公鑰不在我的賬戶列表中。 添加后,遠程庫的名字就是 origin
,這是Git默認的叫法,也可以改成別的,但是 origin
這個名字一看就知道是 遠程庫。 下一步,就可以把本地庫的所有內容推送到遠程庫上:
$ git push -u origin master
Enumerating objects: 17, done.
Counting objects: 100% (17/17), done.
Delta compression using up to 12 threads
Compressing objects: 100% (12/12), done.
Writing objects: 100% (17/17), 1.36 KiB | 232.00 KiB/s, done.
Total 17 (delta 3), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (3/3), done.
To github.com:gylic/learngit.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
把本地庫的內容推送到遠程,用 git push
命令,實際上是把當前分支 master 推送到遠程。
由於遠程庫是空的,我們第一次推送 master
分支時,加上了-u
參數,Git不但會把本地的 master
分支內容推 送的遠程新的 master
分支,還會把本地的 master
分支和遠程的 master
分支關聯起來,在以后的推送或者拉取 時就可以簡化命令。
推送成功后,可以立刻在GitHub頁面中看到遠程庫的內容已經和本地一模一樣。
從現在起,只要本地作了提交,就可以通過命令:
$ git push origin master
注意
當你第一次使用Git的 clone
或者 push
命令連接GitHub時,會得到一個SSH警告:
The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.
RSA key fingerprint is xx.xx.xx.xx.xx.
Are you sure you want to continue connecting (yes/no)?
這是因為Git使用SSH連接,而SSH連接在第一次驗證GitHub服務器的Key時,需要你確認GitHub的Key的指紋信息 是否真的來自GitHub的服務器,輸入yes
回車即可
Git會輸出一個警告,告訴你已經把GitHub的Key添加到本機的一個信任列表里了:
Warning: Permanently added 'github.com' (RSA) to the list of known hosts.
如果你實在擔心有人冒充GitHub服務器,輸入 yes
前可以對照GitHub的RSA Key的指紋信息是否與SSH連接給出 的一致。
從遠程庫克隆
$ git clone git@github.com:用戶名/倉庫名.git
你也許還注意到,GitHub給出的地址不止一個,還可以用 https://github.com/用戶名/倉庫名.git
這樣的地 址。
實際上,Git支持多種協議,默認的 git://
使用ssh
,但也可以使用 https
等其他協議。
使用 https
除了速度慢以外,還有個最大的麻煩是每次推送都必須輸入口令,但是在某些只開放http端口的公司內 部就無法使用 ssh
協議而只能用 https
。
參與開源項目時一定要從自己的賬號下clone倉庫,這樣你才能推送修改。如果從原作者的倉庫地 址克隆,因為沒有權限,你將不能推送修改。
1.8 創建與合並分支
創建一個屬於你自己的分支,別人看不到。你在自己的分支上干活,想提交就提交,直到開發完畢后,再一次性合並到原來的分支上,這樣既安全又不影響別 人工作。
首先,我們創建 dev
分支,然后切換到dev
分支:
$ git switch -c dev
Switched to a new branch 'dev'
git switch
命令加上-c
參數表示創建並切換,相當於以下兩條命令:
$ git branch dev
$ git switch dev
Switched to branch 'dev'
然后,用 git branch
命令查看當前分支:
$ git branch
* dev
master
git branch
命令會列出所有分支,當前分支前面會標一個 *
號。
然后,我們就可以在dev
分支上正常提交,比如對 readme.txt
做個修改,加上一行:
Creating a new branch is quick.
然后提交:
$ git add readme.txt
$ git commit -m "branch test"
[dev b75715d] branch test
1 file changed, 2 insertions(+), 1 deletion(-)
現在, dev 分支的工作完成,我們就可以切換回 master 分支:
$ git switch master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
切換回 master
分支后,再查看 readme.txt
文件,剛才添加的內容不見了!因為那個提交是在 dev
分支上, 而master
分支此刻的提交點並沒有變:
現在,我們把 dev
分支的工作成果合並到master
分支上:
$ git merge dev
Updating 39d3777..b75715d
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertions(+)
git merge
命令用於合並指定分支到當前分支。合並后,再查看 readme.txt 的內容,就可以看到,和 dev 分支的 最新提交是完全一樣的。
注意到上面的 Fast-forward
信息,Git告訴我們,這次合並是“快進模式”,也就是直接把 master
指向 dev
的當 前提交,所以合並速度非常快。
合並完成后,就可以放心地刪除 dev
分支了:
$ git branch -d dev
Deleted branch dev (was b75715d).
刪除后,查看 branch
,就只剩下 master 分支了:
$ git branch
* master
因為創建、合並和刪除分支非常快,所以Git鼓勵你使用分支完成某個任務,合並后再刪掉分支,這和直接 在master
分支上工作效果是一樣的,但過程更安全。
查看分支: git branch
創建分支: git branch <name>
切換分支: git checkout <name>
或者 git switch <name>
創建+切換分支: git checkout -b <name>
或者 git switch -c <name>
合並某分支到當前分支: git merge <name>
刪除分支:git branch -d <name>
二、Github
Github是一個提供代碼托管服務的網站,你可以向該網站上傳一個Git數據庫副本。使用Github使你與他人合作一個項目變得更容易,而這歸功於Github提供的下述機制:一個用於以共享庫的集中位置,一個基於Web的界面以及分叉(forking)、拉請求(pull request)、提出問題(issue)、維基(WiKi)等功能,這些功能使你和你的團隊能更有效地對所做的修改進行說明、討論和評估。
2.1 查看倉庫(repository)
以學習菌賬戶下的RSP倉庫為例:
2.2 為一個倉庫做貢獻
如果想直接對一個項目做出貢獻,你必須是項目的擁有者或作為合作者加入項目。若不是,則需要在Github上你的用戶賬戶下復制這個項目。這一過程稱為分叉(fork)。一旦你對一個項目進行了分叉操作,你就能對你復制過來的分叉副本做任何修改,同時還可以通過使用拉請求將你的改動納入原來的項目。現在讓我們一起來看一下這個過程。
首先,點擊頁面右上角的fork。然后你會發現自己多了一個該倉庫的副本。
接着就可以對這個倉庫的副本進行操作了。
現在,我們先選擇一個文件夾,再點擊Add file。
然后上傳文件,點擊Commit changes,將文件同步至倉庫。
完成上面的操作后進行Compare。
顯示Able to merge,就可以創建拉請求給原作者了。
最后再點擊Create pull request,等待作者合並你的拉請求吧。
以上都是在復制過來的副本上進行操作。要注意的是如果原作者的倉庫已經更新,那么你必須先保持同步,保持一個好的習慣,定期進行compare。確保自己復制的倉庫和原倉庫一樣,再上傳文件並創建pull request,這樣可以避免沖突。
2.3 使用Github Desktop
當倉庫太大或者要上傳的文件太大時,顯然通過網頁提交pull request是不太可行的。方便的是,有一個叫做Github Desktop的軟件可以幫助你。GitHub Desktop 是一個可讓您使用 GUI 而非命令行或網絡瀏覽器與 GitHub 交互的應用程序。到官網下載,然后只需簡單地配置一下就可以使用。關於Github Desktop如何使用,詳細內容可以參考官方文檔。
下載完成后,使用Github賬號登陸,然后將遠程庫克隆到本地。當你更改本地倉庫或者其他人更改遠程倉庫時,將項目的本地副本與遠程倉庫同步。要查看本地副本與遠程版本是否同步,只需點擊Fetch origin。 GitHub Desktop 可以通過push origin和pull origin來保持項目本地副本與遠程版本同步。確認無誤后在左下角點commit to master提交到master分支。
這樣一來,就可以借助軟件來管理倉庫了。
小提示:有時會出現沖突,大多數情況下是因為沒有和遠程版本保持同步就commit。先保持同步再提交。
三、Gitee
使用GitHub時,國內的用戶經常遇到的問題是訪問速度太慢,有時候還會出現無法連接的情況。 如果希望體驗Git飛一般的速度,可以使用國內的Git托管服務——Gitee(gitee.com)。
和GitHub相比,Gitee也提供免費的Git倉庫。此外,還集成了代碼質量檢測、項目演示等功能。對於團隊協作開 發,Gitee還提供了項目管理、代碼托管、文檔管理的服務,5人以下小團隊免費。 Gitee的免費版本也提供私有庫功能,只是有5人的成員上限。
3.1 配合Git
使用Gitee和使用GitHub類似,我們在Gitee上注冊賬號並登錄后,需要先上傳自己的SSH公鑰。選擇右上角用戶頭 像 -> 菜單“修改資料”,然后選擇“SSH公鑰”,填寫一個便於識別的標題,然后把用戶主目錄下 的 .ssh/id_rsa.pub 文件的內容粘貼進去:
如果我們已經有了一個本地的git倉庫(例如,一個名為learngit的本地庫),如何把它關聯到Gitee的遠程庫上呢?
首先,我們在Gitee上創建一個新的項目,選擇右上角用戶頭像 -> 菜單“控制面板”,然后點擊“創建項目”。項目名稱最好與本地庫保持一致。
然后,我們在本地庫上使用命令 git remote add
把它和Gitee的遠程庫關聯:
git remote add origin git@gitee.com:liaoxuefeng/learngit.git
之后,就可以正常地用 git push
和 git pull
推送了!
如果在使用命令 git remote add
時報錯:
git remote add origin git@gitee.com:liaoxuefeng/learngit.git
fatal: remote origin already exists.
這說明本地庫已經關聯了一個名叫 origin
的遠程庫,此時,可以先用 git remote -v
查看遠程庫信息:
git remote -v
origin git@github.com:michaelliao/learngit.git (fetch)
origin git@github.com:michaelliao/learngit.git (push)
可以看到,本地庫已經關聯了 origin 的遠程庫,並且,該遠程庫指向GitHub。
我們可以刪除已有的GitHub遠程庫:
git remote rm origin
再關聯Gitee的遠程庫(注意路徑中需要填寫正確的用戶名):
git remote add origin git@gitee.com:liaoxuefeng/learngit.git
此時,我們再查看遠程庫信息:
git remote -v
origin git@gitee.com:liaoxuefeng/learngit.git (fetch)
origin git@gitee.com:liaoxuefeng/learngit.git (push
現在可以看到,origin已經被關聯到Gitee的遠程庫了。通過 git push 命令就可以把本地庫推送到Gitee上。
有的小伙伴又要問了,一個本地庫能不能既關聯GitHub,又關聯Gitee呢?
答案是肯定的,因為git本身是分布式版本控制系統,可以同步到另外一個遠程庫,當然也可以同步到另外兩個遠程 庫。
使用多個遠程庫時,我們要注意,git給遠程庫起的默認名稱是 origin ,如果有多個遠程庫,我們需要用不同的名 稱來標識不同的遠程庫。
仍然以 learngit
本地庫為例,我們先刪除已關聯的名為 origin 的遠程庫:
git remote rm origin
然后,先關聯GitHub的遠程庫:
git remote add github git@github.com:michaelliao/learngit.git
注意,遠程庫的名稱叫 github ,不叫 origin 了。 接着,再關聯Gitee的遠程庫:
git remote add gitee git@gitee.com:liaoxuefeng/learngit.git
同樣注意,遠程庫的名稱叫 gitee ,不叫 origin 。
現在,我們用 git remote -v 查看遠程庫信息,可以看到兩個遠程庫:
git remote -v
gitee git@gitee.com:liaoxuefeng/learngit.git (fetch)
gitee git@gitee.com:liaoxuefeng/learngit.git (push)
github git@github.com:michaelliao/learngit.git (fetch)
github git@github.com:michaelliao/learngit.git (push)
如果要推送到GitHub,使用命令
git push github master
如果要推送到Gitee,使用命令:
git push gitee master
3.2 使用Github Desktop
可以將碼雲(Gitee)視作國內版的Github,很多操作都是類似的。也可以通過 GitHub Desktop 連接遠程倉庫。可以好好讀一讀官方文檔。