安裝Git(Debian或Ubuntu Linux)
Debian或Ubuntu Linux,通過一條
sudo apt-getinstall git
就可以直接完成Git的安裝,安裝完成后,還需要最后一步設置,在命令行輸入:
$git config --global user.name"YourName"$git config --global user.email"email@example.com"
創建版本庫
版本庫又名倉庫,英文名repository。
$mkdir learngit
$cd learngit
$pwd
/Users/michael/learngit
第二步,通過git init命令把這個目錄變成Git可以管理的倉庫
$gitinit
把一個文件放到Git倉庫只需要兩步。
第一步,用命令git add告訴Git,把文件添加到倉庫:
$git add readme.txt
第二步,用命令git commit告訴Git,把文件提交到倉庫:
$ gitcommit-m"wrote a readme file"
[master (root-commit) cb926e7] wrote a readme file
1file changed,2insertions(+)
createmode100644readme.txt
小結
初始化一個Git倉庫,使用git init命令。
添加文件到Git倉庫,分兩步:
·第一步,使用命令git add ,注意,可反復多次使用,添加多個文件;
·第二步,使用命令git commit,完成。
隨時掌握工作區狀態git status命令
git diff查看被修改的內容
版本回退
·HEAD指向的版本就是當前版本,因此,Git允許我們在版本的歷史之間穿梭,使用命令git
reset --hard commit_id。
·穿梭前,用git
log可以查看提交歷史,以便確定要回退到哪個版本。
·要重返未來,用git
reflog查看命令歷史,以便確定要回到未來的哪個版本
·git reflog用來記錄你的每一次命令
·$gitreflog
·ea34578HEAD@{0}:reset:movingtoHEAD^
·3628164HEAD@{1}:commit:appendGPL
·ea34578HEAD@{2}:commit:adddistributed
·cb926e7HEAD@{3}:commit(initial):wroteareadmefile
工作區和暫存區
Git的版本庫里存了很多東西,其中最重要的就是稱為stage(或者叫index)的暫存區,還有Git為我們自動創建的第一個分支master,以及指向master的一個指針叫HEAD。
管理修改
第一次修改->git add->第二次修改->git commit
Git管理的是修改,當你用git add命令后,在工作區的第一次修改被放入暫存區,準備提交,但是,在工作區的第二次修改并沒有放入暫存區,所以,git commit只負責把暫存區的修改提交了,也就是第一次的修改被提交了,第二次的修改不會被提交。
那怎么提交第二次修改呢?你可以繼續git add再git commit,也可以別著急提交第一次修改,先git add第二次修改,再git commit,就相當于把兩次修改合并后一塊提交了:
第一次修改->git add->第二次修改->git add->git commit
提交后,用git diff HEAD -- readme.txt命令可以查看工作區和版本庫里面最新版本的區別
Git是如何跟蹤修改的,每次修改,如果不add到暫存區,那就不會加入到commit中。
撤銷修改
命令git checkout -- readme.txt意思就是,把readme.txt文件在工作區的修改全部撤銷,這里有兩種情況:
一種是readme.txt自修改后還沒有被放到暫存區,現在,撤銷修改就回到和版本庫一模一樣的狀態;
一種是readme.txt已經添加到暫存區后,又作了修改,現在,撤銷修改就回到添加到暫存區后的狀態。
總之,就是讓這個文件回到最近一次git commit或git add時的狀態。
場景1:當你改亂了工作區某個文件的內容,想直接丟棄工作區的修改時,用命令git checkout -- file。(--很重要,沒有--,就變成了“切換到另一個分支”的命令)
場景2:當你不但改亂了工作區某個文件的內容,還添加到了暫存區時,想丟棄修改,分兩步,第一步用命令git reset HEAD file,就回到了場景1,第二步按場景1操作。
場景3:已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考版本回退一節,不過前提是沒有推送到遠程庫。
git checkout其實是用版本庫里的版本替換工作區的版本,無論工作區是修改還是刪除,都可以“一鍵還原”。
刪除文件
命令git rm用于刪除一個文件。如果一個文件已經被提交到版本庫,那么你永遠不用擔心誤刪,但是要小心,你只能恢復文件到最新版本,你會丟失最近一次提交后你修改的內容。
遠程倉庫
GitHub
第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的秘鑰對
第2步:登陸GitHub,打開“Account settings”,“SSH Keys”頁面:
然后,點“Add
SSH Key”,填上任意Title,在Key文本框里粘貼id_rsa.pub文件的內容:
添加遠程庫
要關聯一個遠程庫,使用命令git remote add origin
git@server-name:path/repo-name.git;
關聯后,使用命令git push -u origin master第一次推送master分支的所有內容;
此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;
分布式版本系統的最大好處之一是在本地工作完全不需要考慮遠程庫的存在,也就是有沒有聯網都可以正常工作,而SVN在沒有聯網的時候是拒絕干活的!當有網絡的時候,再把本地提交推送一下就完成了同步!
從遠程庫克隆
要克隆一個倉庫,首先必須知道倉庫的地址,然后使用git clone命令克隆。
Git支持多種協議,包括https,但通過ssh支持的原生git協議速度最快
$git clone git@github.com:michaelliao/gitskills.git
Cloninginto'gitskills'...
remote:Countingobjects:3, done.
remote:Total3(delta0), reused0(delta0)
Receivingobjects:100% (3/3), done.
$cd gitskills
$ls
README.md
創建與合并分支
Git鼓勵大量使用分支:
查看分支:git branch
創建分支:git branch
切換分支:git checkout
創建+切換分支:git checkout -b
合并某分支到當前分支:git merge
刪除分支:git branch -d
解決沖突
當Git無法自動合并分支時,就必須首先解決沖突。解決沖突后,再提交,合并完成。
用git log --graph命令可以看到分支合并圖。
分支管理策略
首先,master分支應該是非常穩定的,也就是僅用來發布新版本,平時不能在上面干活;
git flow工作流
feature(多個、玫紅)。主要是自己玩了,差不多的時候要合并回develop去。從不與master交互。
develop(1個、黃色)。主要是和feature以及release交互。
release(同一時間1個、綠色)。總是基于develop,最后又合并回develop。當然對應的tag跑到master這邊去了。生命周期很短,只是為了發布
hotfix(同一時間1個、紅色)。總是基于master,并最后合并到master和develop。生命周期較短,用了修復bug或小粒度修改發布。
master(1個藍色)。沒有什么東西,僅是一些關聯的tag,因從不在master上開發
小結
Git分支十分強大,在團隊開發中應該充分應用。
合并分支時,加上--no-ff參數就可以用普通模式合并,合并后的歷史有分支,能看出來曾經做過合并,而fast forward合并就看不出來曾經做過合并。
多人協作的工作模式
多人協作的工作模式通常是這樣:
1.首先,可以試圖用git push origin branch-name推送自己的修改;
2.如果推送失敗,則因為遠程分支比你的本地更新,需要先用git pull試圖合并;
3.如果合并有沖突,則解決沖突,并在本地提交;
4.沒有沖突或者解決掉沖突后,再用git push origin branch-name推送就能成功!
如果git pull提示“no tracking information”,則說明本地分支和遠程分支的鏈接關系沒有創建,用命令git branch --set-upstream branch-name
origin/branch-name。
這就是多人協作的工作模式,一旦熟悉了,就非常簡單。
小結
·查看遠程庫信息,使用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
tag 用于新建一個標簽,默認為HEAD,也可以指定一個commit id;
·git tag -a
-m "blablabla..."可以指定標簽信息;
·git tag -s
-m "blablabla..."可以用PGP簽名標簽;
·命令git
tag可以查看所有標簽。
操作標簽
·命令git
push origin 可以推送一個本地標簽;
·命令git
push origin --tags可以推送全部未推送過的本地標簽;
·命令git
tag -d 可以刪除一個本地標簽;
·命令git
push origin :refs/tags/可以刪除一個遠程標簽
自定義Git
比如,讓Git顯示顏色,會讓命令輸出看起來更醒目:
$git config --global color.uitrue
忽略特殊文件
·忽略某些文件時,需要編寫.gitignore;
·.gitignore文件本身要放到版本庫里,并且可以對.gitignore做版本管理!
需要找出來到底哪個規則寫錯了,可以用git check-ignore命令檢查:
配置別名
$git config --globalalias.st status
$git config --globalalias.co checkout
$git config --globalalias.ci commit
$git config --globalalias.br branch
在撤銷修改一節中,我們知道,命令git reset HEAD file可以把暫存區的修改撤銷掉(unstage),重新放回工作區。既然是一個unstage操作,就可以配置一個unstage別名:
$git config --globalalias.unstage'reset HEAD'
當你敲入命令:
$git unstage test.py
實際上Git執行的是:
$ git resetHEAD test.py
配置一個git last,讓其顯示最后一次提交信息:
$git config --globalalias.last'log -1'
這樣,用git last就能顯示最近一次的提交:
甚至還有人喪心病狂地把lg配置成了:
git config --globalalias.lg"log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
配置文件
配置Git的時候,加上--global是針對當前用戶起作用的,如果不加,那只針對當前的倉庫起作用。
配置文件放哪了?每個倉庫的Git配置文件都放在.git/config文件中: