Git 筆記
Git是分布式版本控制系統
集中式VS分布式:
集中式版本控制系統,版本庫集中存放在中央伺服器,必須要聯網才能工作,沒有曆史版本庫。
分布式版本控制系統,版本控制系統沒有“中央伺服器”,每個人電腦上都是一個完整的版本庫。
分布式系統優勢:安全性更高,不需要聯網,如果中央伺服器故障,任何其他一個開發人員的本地都有最新的帶有曆史記錄的版本庫。
主要差別在于曆史版本庫的存放,集中式系統曆史版本隻存在于中央伺服器,而分布式控制系統中每個本地庫都有曆史記錄存放。
Git指令
Git配置
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
注意
git config
指令的
--global
參數,用了這個參數,表示你這台機器上所有的Git倉庫都會使用這個配置,當然也可以對某個倉庫指定不同的使用者名和Email位址。
建立版本庫
在目前目錄建立git倉庫
git init
把檔案添加到倉庫
git add <file>
git commit
git add
可以反複多次使用,添加多個檔案,
git commit
可以一次送出很多檔案,在
git commit
指令後添加(-m '····')友善從曆史記錄裡找到修改記錄。
掌握工作區的狀态
git status
檢視檔案修改内容
git diff
版本回退
git reset -- hard HEAD^
HEAD指向的版本是目前版本,回到上一版本使用以上指令,如果回退上兩個版本使用
HEAD^^
,如果回退版本數較大(如往上50個版本),使用
HEAD~50
。
回退指定版本
git reset --hard commit_id
commit_id
是指定版本号,是由SHA1計算出來的數字
檢視送出曆史
commit_id
git log
檢視指令曆史
git reflog
工作區、暫存區和版本庫
git與其他版本控制系統的不同之處就是有暫存區的概念,工作區就是電腦中能看到的目錄,工作區有一個隐藏目錄[.git],這是git的版本庫。版本庫裡有許多東西,最重要的是稱為stage的暫存區。

将檔案往版本庫裡添加時是分兩步執行的:
第一步是用git add把檔案添加進去,實際上就是把檔案修改添加到暫存區。
第二步是用git commit送出修改,實際上就是把暫存區的所有内容送出到目前分支。
Git是如何跟蹤修改的,每次修改,如果不用git add到暫存區,那就不會加入到commit中。
撤銷修改
丢棄工作區的修改
git checkout -- <file>
該指令是将檔案在工作去的修改全部撤銷,這裡有兩種情況:
一種是file自修改後還沒有被放到暫存區,現在,撤銷修改就回到和版本庫一模一樣的狀态;
一種是file已經添加到暫存區後,又作了修改,現在,撤銷修改就回到添加到暫存區後的狀态。
總之,就是讓這個檔案回到最近一次git commit或git add時的狀态。
丢棄暫存區的修改
改亂了工作區某個檔案的内容同時還添加到了暫存區,想丢棄修改時,先使用指令git reset HEAD ,之後按撤銷工作區修改進行操作。
進行了commit指令送出的修改
已經送出了不合适的修改到版本庫時,想要撤銷修改,使用版本回退指令,前提是沒有推送到遠端庫.
删除檔案
git rm <file>
當你要删除檔案text.txt的時候,可以采用指令:rm test.txt
這個時候有兩種情況:
第一種情況:的确要把test.txt删掉,那麼可以執行
$ git rm test.txt
$ git commit -m "remove test.txt"
此時檔案被删除,且删除記錄上傳本地庫。
第二種情況:誤删檔案,想恢複,這時候還沒有commit -m "remove test.txt",執行git checkout test.txt将檔案恢複。
如果執行完git commit -m "remove test.txt"後就不能用checkout恢複了,得用git reset --hard HEAD^,再從版本庫寫回到工作區。
git rm用于删除一個檔案。如果一個檔案已經被送出到版本庫,那麼你永遠不用擔心誤删,但是要小心,你隻能恢複檔案到最新版本,你會丢失最近一次送出後你修改的内容。
遠端倉庫
建立SSH Key
ssh-keygen -t rsa -C "[email protected]"
關聯遠端倉庫
git remote add origin https://github.com/username/repositoryname.git
推送到遠端倉庫
git push -u origin master
-u 表示第一次推送master分支的所有内容,此後,每次本地送出後,隻要有必要,就可以使用指令
$ git push origin master
推送最新修改。
從遠端克隆
git clone https://github.com/usern/repositoryname.git
注意:當你不能使用 [email protected] 指令來進行推送和克隆,是因為沒有安裝密鑰。
添加私秘鑰到$ ssh-add ~/.ssh/id_rsa
如果添加失敗可以先執行指令$ eval \ssh-agent\是~鍵上的那個符号,然後再次添加私秘鑰。
用$ ssh -T [email protected]判斷是否綁定成功。如果傳回successfully表示成功。
分支管理
檢視分支
git branch
建立分支
git branch <name>
切換分支
git checkout <name>
建立+切換分支
git checkout -b <name>
合并某分支到目前name分支
git merge <name>
删除分支
git branch -d <name>
強行删除分支
git branch -D <name>
如果要丢棄一個沒有被合并過的分支,可以通過以上指令來實作。
檢視分支合并圖
git log --graph
當Git無法自動合并分支時,就必須首先解決沖突。解決沖突後,再送出,合并完成。
用
git log --graph
指令可以看到分支合并圖。
普通模式合并分支
git merge --no-ff -m "description" <branchname>
通常進行分支合并時,git會使用Fast forward模式,删除分支後,分支資訊會丢失,可以使用
--on-ff
參數,禁用Fast forward,需要時加上一個
-m
參數把commit描述寫進去。這樣進行合并後的曆史有分支,能看出來曾經做過合并。
儲存工作現場
git stash
檢視工作現場
git stash list
恢複工作現場
git stash pop
在建立分支中修改bug時的推薦操作
首先理清兩個概念:
未被追蹤的檔案:指的是建立的檔案或檔案夾且還沒加入到暫存區(建立的還沒有被git add)
未加入到暫存區的檔案:指的是已經被追蹤過,但是沒有加入到暫存區(已經執行過git add/commit的但是這次修改後還沒有git add)
舉例:
readme.md 已經被git add/git commit過,但是呢,我這次隻是修改了,而且沒有修改完,不能commit;
test 建立的檔案夾,沒有被git add/git commit;
有個bug需要處理,這時候我需要切換分支,去處理bug
正确的步驟:
git add test(讓git去追蹤這個新檔案)
git stash保留現場
如果不執行這兩個指令,那麼在修改BUG完成之後git status,就會發現readme.md沒有添加到暫存區,同時又多了個test檔案,
但是自己的readme.md沒有完成,萬萬不可以送出,這樣導緻bug的修改代碼也送出不了。
是以需要git stash,這樣在送出修改bug代碼的時候 ,就不會看見readme.md 和 test。可以安心送出修改bug的代碼。
檢視遠端庫資訊
git remote -v;
本地建立的分支如果不推送到遠端,對其他人就是不可見的;
從本地推送分支
git push origin branch-name
如果推送失敗,先用git pull抓取遠端的新送出;
在本地建立和遠端分支對應的分支
git checkout -b branch-name origin/branch-name
本地和遠端分支的名稱最好一緻;
建立本地分支和遠端分支的關聯
git branch --set-upstream branch-name origin/branch-name
從遠端抓取分支
git pull
如果有沖突,要先處理沖突。
标簽
git标簽是版本庫的快照,實際就是某個commit的指針,如果要找到某次版本的commit号,數字複雜不好找,使用tag取一個易于記住和了解的名字就友善許多,它跟某個commit綁在一起。(類似于域名和IP位址的關系?)
建立标簽
git tag<tagname>
預設為HEAD,也可以指定一個commit id。
檢視标簽資訊
git show <tagname>
建立帶有說明的标簽
git tag -a <tagname> -m <description> <branchname> or commit_id
用-a指定标簽名,-m指定說明文字
檢視所有标簽
git tag
推送某個标簽到遠端
git push origin <tagname>
一次性推送全部尚未推送到遠端的本地标簽
git push origin --tags
删除一個本地标簽
git tag -d <tagname>
删除一個遠端标簽
git push origin :refs/tags/<tagname>