Git基礎知識學習1
Git是分布式版本控制系統,CVS和SVN都是集中式的版本控制系統。集中式版本控制系統,版本庫是幾種存放在中央伺服器的,需要先從中央伺服器擷取最新的版本,最後再推送給中央伺服器。集中式版本控制系統必須聯網才能工作。分布式版本控制系統沒有“中央伺服器”,每個電腦上都是一個完整的版本庫,不需要聯網。
安裝Git
1、在Linux上安裝
首先,輸入git,看系統有沒有安裝Git。
Debian或Ubuntu Linux,可以通過sudo apt-get install git 就可以直接完成GIt的安裝。
老一點的Debian或Ubuntu Linux,指令為sudo apt-get install git-core。
如果是其他Linux版本,可以直接通過源碼安裝。先從GIt官網下載下傳源碼,然後解壓,依次輸入:./config, make, sudo make install
2、在Mac OS X上安裝Git
有兩種安裝GIt的方法:1、安裝homebrew,然後通過homebrew安裝Git,具體方法參考homebrew的文檔:http://brew.sh/。2、直接從AppStore安裝Xcode,Xcode內建了Git,不過預設沒有安裝,需要運作Xcode,選擇菜單“Xcode->Preferences”,在彈出視窗中找到“Downloads”,選擇“Command Line Tools”,點install就可以完成安裝。
3、在Windows上安裝Git
在Windows上使用Git,可以從Git官網直接下載下傳安裝程式,然後按預設選項安裝即可。安裝完成後,在開始菜單中找到"Git"->"Git Bash“,出現一個類似指令行的視窗,說明Git安裝成功。安裝完成後,需要進行設定,在指令行中輸入:$git config --global user.name "Your name" $git config --global user.email "[email protected]"
注意,git config 指令的 --global參數,用了這個參數,表示這台機器上所有的GIt倉庫都會使用這個配置,當然也可以對某個倉庫指定不用的使用者名和Emai位址。
建立版本庫
版本庫又名倉庫,英文名為repository,可以簡單了解為一個目錄,這個目錄裡面的所有檔案都可以被Git管理起來,每個檔案的修改、删除,Git都能跟蹤,以便任何時刻都可以跟蹤曆史,或者在将來某個時刻“還原”。
建立一個版本庫非常簡單,首先,選擇一個合适的地方,建立一個空目錄:
$ mkdir learngit
$ cd learngit
$ pwd
/User/michael/learngit
如果使用的是Windows系統,確定目錄名(包括父目錄)不包含中文。
通過git init指令把這個目錄程式設計Git可以管理的倉庫:
$ git init
Initialized empty Git repository in /User/michael/learngit/.git
如果是Windows系統,可以使用Git Bash直接建立版本庫。并且千萬不要使用Windows自帶的記事本編輯任何文本檔案。建議使用Notepad++替代記事本,把Notepad++的預設編輯設定為UTF-8 without BOM。
将檔案添加到版本庫示例:
編寫一個readme.txt檔案,内容如下:
Git is a version control system.
Git is free software.
一定要放到learngit目錄下(子目錄也行)。
用指令git add 告訴Git,把檔案添加到倉庫。
$ git add readme.txt
用指令git commit告訴Git,把檔案送出到倉庫。
$ git commit -m "wrote a readme file"
[master (root-commit) 1dd0b93] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
簡單解釋指令git commit,-m後面輸入的本次送出的說明,可以輸入任意内容,最好是有意義的,這樣就能從曆史記錄裡友善找到改動記錄。不輸入-m "xxx",可以這麼幹,但不建議,輸入說明對自己對别人閱讀都很重要。
版本回退
對readme.txt檔案進行修改,然後把修改送出到Git版本庫。
readme.txt一共有三個版本送出到Git倉庫裡了,版本1——wrote a readme file;版本2——add distributed;版本3——append GPL;
在Git中,可以使用git log指令檢視曆史記錄。
$ git log
commit d563b94243836b68976fe996b2e9be0cedfca813 (HEAD -> master)
Author: sherry1993 <[email protected]>
Date: Thu Dec 7 10:32:26 2017 +0800
append GPL
commit 4795dfef0597daadf6712e24a0ed55b06008c9fb
Author: sherry1993 <[email protected]>
Date: Thu Dec 7 10:31:32 2017 +0800
add distributed
commit 1dd0b93912387e2a295832e9a76f72712fa93410
Author: sherry1993 <[email protected]>
Date: Thu Dec 7 10:14:51 2017 +0800
wrote a readme file
如果覺得輸出資訊太多,可以加上--pretty=oneline參數
$ git log --pretty=oneline
d563b94243836b68976fe996b2e9be0cedfca813 (HEAD -> master) append GPL
4795dfef0597daadf6712e24a0ed55b06008c9fb add distributed
1dd0b93912387e2a295832e9a76f72712fa93410 wrote a readme file
前面類似d563b...ca813是commit id(版本号)。在GIt中,用HEAD表示目前版本,上一個版本是HEAD^,上上一個版本就是HEAD^^,往上100個版本,是HEAD-100.
要把目前版本"append GPL"回退到上一個版本“add distributed”,可以使用git reset指令。
$ git reset --hard HEAD^
HEAD is now at 4795dfe add distributed
檢視readme.txt的内容
$ cat readme.txt
Git is a version control system
Git is free software.
Git is a distributed version control system.
還可以使用git log檢視現在版本庫的狀态:
$ git log
commit 4795dfef0597daadf6712e24a0ed55b06008c9fb (HEAD -> master)
Author: sherry1993 <[email protected]>
Date: Thu Dec 7 10:31:32 2017 +0800
add distributed
commit 1dd0b93912387e2a295832e9a76f72712fa93410
Author: sherry1993 <[email protected]>
Date: Thu Dec 7 10:14:51 2017 +0800
wrote a readme file
回退到append GPL,找到append GPL的commit id
$ git reset --hard d563b94243836b68976fe996b2e9be0cedfca813
HEAD is now at d563b94 append GPL
Git提供了一個指令git reflog用來記錄每一次指令
$ git reflog
d563b94 (HEAD -> master) HEAD@{0}: reset: moving to d563b94243836b68976fe996b2e9be0cedfca813
4795dfe HEAD@{1}: reset: moving to HEAD^
d563b94 (HEAD -> master) HEAD@{2}: reset: moving to HEAD
d563b94 (HEAD -> master) HEAD@{3}: commit: append GPL
4795dfe HEAD@{4}: commit: add distributed
1dd0b93 HEAD@{5}: commit (initial): wrote a readme file
小結:
HEAD指向的版本就是目前版本,Git允許在版本的曆史之間穿梭,使用指令git reset --hard commit_id。
用git log可以檢視送出曆史,以便确定回退的版本。
用git reflog檢視指令曆史,以便确定回到未來的版本。
工作區和暫存區
工作區,就是在電腦中看到的目錄,learngit檔案夾就是一個工作區。
版本庫,工作區有一個隐藏目錄.git,這個不算工作區,而是Git的版本庫。Git的版本庫裡存放了很多東西,其中最重要的就是成為stage的暫存區,還有Git自動建立的第一個分支master,以及指向master的一個指針HEAD。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiIXZ05WZD9CX5RXa2Fmcn9CXwczLcVmds92czlGZvwVP9EUTDZ0aRJkSwk0LcxGbpZ2LcBDM08CXlpXazRnbvZ2LcRlMMVDT2EWNvwFdu9mZvw1dJpXT3lkaNdXSU1UNK52YshmMjZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DO3UzMyMTM0EzNwITM3EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
用git add把檔案添加進去,實際上就是把檔案修改添加到暫存區。
用git commit送出更改,實際上就是把暫存區的所有内容送出到目前分支。
建立Git版本庫時,Git自動建立了唯一一個master分支,git commit就是往master分支上送出更改。
第一次修改->git add->第二次修改->git add->git commit
每次修改,如果不add到暫存區,就不會加入到commit中。
撤銷修改
git checkout --readme.txt指令,把readme.txt檔案在工作區的修改全部撤銷,有兩種情況:
一是readme.txt自修改後還沒有被放到暫存區,撤銷修改就回到和版本庫一模一樣的狀态;
二是readme.txt已經添加到暫存區後,又作了修改,撤銷修改就回到添加到暫存區後的狀态。
總之,就是讓這個檔案回到最近一次git commit或git add時的狀态。
git checkout --file指令中的--很重要,沒有--,就是另一個指令。
git reset指令既可以回退版本,也可以把暫存區的修改回退到工作區。
小結
場景1:若改亂了工作區某個檔案的内容,想直接丢棄工作區的修改時,用指令git checkout --file、
場景2:若該亂了工作區某個檔案的内容,還添加到暫存區,想丢棄修改,分兩步,第一步用指令git reset HEAD file,就回到了場景1,第二步按場景1操作。
場景3:已經送出了不合适的修改到版本庫時,想要撤銷本次送出,首先将版本回退,然後按場景2操作。不過前提是沒有推送到遠端庫。
删除檔案
使用rm指令删除檔案
$ rm test.txt
如果确定要删除檔案,就用指令git rm删掉,并且git commit
$ git rm test.txt
rm 'test.txt'
$ git commit -m "remove test.txt"
[master c33a95b] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt
檔案就從版本庫中被删除了。
如果是誤删檔案,在版本庫中還有,可以把誤删檔案恢複到最新版本。
$ git checkout -- test.txt
git checkout 其實就是用版本庫裡的版本替換工作區的版本,無論工作區是修改還是删除,都可以“一鍵還原”。
小結
指令git rm用于删除一個檔案,如果一個檔案已經被送出到版本庫,不用擔心誤删,但仍需小心,隻能恢複檔案到最新版本,會丢失最後一次修改的内容。
添加遠端庫
在本地建立了一個Git倉庫後,在GitHub上建立一個Git倉庫,并且讓着兩個倉庫進行遠端同步,這樣GitHub上的倉庫既可以備份,又可以讓其他人通過該倉庫來協作。
首先,登入GitHub,“Create a new repo”,建立一個新的倉庫;
在本地倉庫下運作指令:
$ git remote add origin [email protected]:michaelliao/learngit.git
上面的michaelliao替換成自己的GItHub賬戶名,learngit為GitHub的倉庫。添加後,遠端庫的名字就是origin,這是Git預設的叫法,也可以改為别的。
下一步,把本地庫的所有内容推送到遠端庫上
$ git push -u origin master
Counting objects: 19, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (19/19), done.
Writing objects: 100% (19/19), 13.73 KiB, done.
Total 23 (delta 6), reused 0 (delta 0)
To [email protected]:michaelliao/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分支關聯起來,在以後的推送或者拉取時就可以簡化指令。
$ git push origin master
SSH警告
當第一次使用Git的clone或者push指令連接配接GitHub時,會得到一個警告
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 remote add origin [email protected]:path/repo-name.git
關聯後,使用指令git push -u origin master第一次推送master分支的所有内容
此後,每次本地送出後,隻要有必要,就可以使用指令git push origin master推送最新修改
常見連接配接遠端庫的錯誤,可檢視部落格fatal: Could not read from remote repository.的解決辦法
從遠端庫克隆
使用指令git clone将遠端庫克隆到本地庫
$ git clone [email protected]:Yixiaohan/show-me-the-code
Cloning into 'show-me-the-code'...
remote: Counting objects: 93, done.
remote: Total 93 (delta 0), reused 0 (delta 0), pack-reused 93
Receiving objects: 100% (93/93), 22.08 KiB | 95.00 KiB/s, done.
Resolving deltas: 100% (26/26), done.
GitHub給出的位址不止一個,還可以使用https://github.com/Yixiaohan/show-me-the-code.git這樣的位址。實際上,Git支援多種協定,預設的git://使用ssh,但也可以https等其他協定。使用https除了速度慢以外,還有個最大的麻煩就是每次推送都必須輸入密碼,但是某些隻開發http端口的公司内部就無法使用ssh協定而隻能用https。
小結
要克隆一個倉庫,首先必須知道倉庫的位址,然後使用git clone 指令克隆。
Git支援多種協定,包括https,但通過ssh支援的原生的git協定速度最快。