日期:08/03/2017 - 08/07/2017
一、基本概念
版本控制系統(tǒng):記錄某項(xiàng)(常為多人)工作的進(jìn)度歷史遂填,enable項(xiàng)目版本查看和回溯选泻,并且能夠便捷合并多人的同時性工作的系統(tǒng)。分布式版本控制系統(tǒng)的代表是Git恢着。集中式版本控制系統(tǒng)的代表有SVN茶宵、CVS危纫。
集中式版本控制系統(tǒng):擁有中央服務(wù)器,過往版本乌庶、當(dāng)前版本都存放在中央服務(wù)器上种蝶,成為系統(tǒng)的瓶頸,并且不能脫機(jī)使用瞒大。
分布式版本控制系統(tǒng):沒有中央服務(wù)器或中央服務(wù)器僅起輔助作用螃征,個人端存放完整的版本庫。
2005年透敌,Linus為管理開源的Linux代碼庫而用兩周時間編寫了Git盯滚。
二、本機(jī)操作
由于Git原本運(yùn)行于Linux酗电,所安裝的windows版本中(似乎)集成了Linux的shell魄藕,可以運(yùn)用Linux的命令行指令進(jìn)行操作。Git提交的事實(shí)上是對文件的修改(而非文件本身的內(nèi)容)撵术。若在文件末尾不換行背率,則提交的修改中總是包括原文檔最后一行的刪除修改和其增加修改。
Git在邏輯上分為工作區(qū)(Working Directory)荷荤,暫存區(qū)(stage/index)和版本庫區(qū)退渗。本機(jī)文件狀態(tài)(實(shí)則其修改情況)為工作區(qū)移稳。工作區(qū)工作完成后蕴纳,需將工作區(qū)文件提交到暫存區(qū)。暫存區(qū)確認(rèn)無誤后个粱,將暫存區(qū)內(nèi)容提交到版本庫古毛,即實(shí)現(xiàn)版本更新。
>> git init
指令將當(dāng)前所在目錄建成一個git版本庫(repository)。
Git僅能記錄純文本文件版本稻薇。編寫時使用支持多國語言的UTF-8編碼可以規(guī)避大量編碼問題嫂冻。Windows自帶的記事本在記錄UTF-8編碼時的多余前綴導(dǎo)致其不能被正常識別蒙兰,不應(yīng)用來編輯Git管理的文本文件断凶。不應(yīng)使用包含中文的文件名/路徑。
>> git add <filename1> <filename2> ...
將(目錄下的)文件添加到暫存區(qū)谎痢。
>> git rm <filename>
提交一個修改到暫存區(qū)案狠,此修改是刪除特定文件服傍。
>> git commit -m "<note>"
提交整個版本庫。
>> git status
查看版本庫的狀態(tài)骂铁。changes not staged for commit: 被修改的文件尚未add; changes to be committed: 已經(jīng)add吹零,等待commit。
>> git diff
查看已提交的版本庫與現(xiàn)有版本庫(本機(jī)文件)之間的區(qū)別拉庵。
>> git log (--pretty=oneline)
查看版本庫的往昔所有commit記錄(顯示版本號和相應(yīng)的注釋)灿椅。
>> git reset --hard <version>
將版本庫(本機(jī)文件)回退為指定版本。版本指代格式:HEAD(當(dāng)前版本)钞支,HEAD^^(上上個版本)茫蛹,HEAD~100(往前一百個版本),版本號(可僅輸入前x位伸辟,一般七位足夠)麻惶。
>> git reflog
顯示你對每個版本庫執(zhí)行過的操作,包括添加版本庫信夫、重置版本庫窃蹋。可以通過此指令找到被回退的版本庫號静稻。
>> git checkout -- <filename>
用版本庫或暫存區(qū)的文件替換本機(jī)文件警没。這意味著,若文件尚未被add振湾,則會回退到當(dāng)前版本庫狀態(tài)杀迹;若文件已被add,其會回退到add時的狀態(tài)(當(dāng)add后執(zhí)行修改時押搪,這些修改會被抹除)树酪。
>> git reset HEAD <filename>
將暫存區(qū)的指定文件扔掉。即撤銷add指令大州。
三续语、遠(yuǎn)程倉庫
SSH:一種網(wǎng)絡(luò)協(xié)議,用于計算機(jī)之間的加密登錄厦画。1995年由芬蘭學(xué)者Tatu Ylonen設(shè)計疮茄,目前成為Linux計算機(jī)的標(biāo)配加密方式滥朱。Putty是Windows操作系統(tǒng)上的一種提供SSH加密協(xié)議的軟件。SSH采用的是公鑰加密方法力试,即用戶向遠(yuǎn)程主機(jī)發(fā)送登錄請求徙邻,遠(yuǎn)程主機(jī)回復(fù)一個公鑰,用戶用公鑰將賬號密碼加密后發(fā)送給遠(yuǎn)程主機(jī)畸裳。公鑰加密很容易受到中間人攻擊(Man-in-the-middle attack)缰犁,即有人在中間截獲用戶的請求,偽造公鑰與用戶通信從而獲取密碼怖糊。但SSH協(xié)議中在初次采用公鑰之前會向用戶確認(rèn)是否采用特定指紋的公鑰民鼓。要登錄的遠(yuǎn)程主機(jī)可以將公鑰指紋(長公鑰的一個縮短化處理)告知用戶,使用戶得以檢查蓬抄。通過用戶手動信任某些特定公鑰丰嘉,SSH協(xié)議保護(hù)了用戶不受中間人攻擊。
公鑰與私鑰:不對稱加密方式嚷缭。用公鑰加密的內(nèi)容只能用私鑰解密饮亏,用私鑰加密的內(nèi)容只能用公鑰解密[3]。若用他人公鑰加密后發(fā)送信息阅爽,則可確保收信人身份路幸;若用自己私鑰加密后發(fā)送信息,則可證明發(fā)信人身份付翁。
>> ssh-keygen -t rsa -C "youremail@example.com"
采用RSA算法創(chuàng)建本機(jī)的的SSH密鑰對(公鑰和私鑰)简肴。RSA算法下的密鑰長達(dá)1024位,存儲在.ssh/id_rsa和.ssh/id_rsa.pub百侧。Git軟件會自動識別文件夾中的公鑰(pub)并將其添加到信任列表中砰识。只有信任列表中的公鑰有權(quán)對遠(yuǎn)程版本庫進(jìn)行修改。
>> git remote add origin git@github.com:用戶名/版本庫名.git
將當(dāng)前庫與GitHub上的某個庫關(guān)聯(lián)起來佣渴。關(guān)聯(lián)后辫狼,遠(yuǎn)程庫的名字默認(rèn)叫做origin。
>> git push -u origin master
將當(dāng)前庫推送到其叫做origin的遠(yuǎn)程庫辛润。-u參數(shù)在第一次推送時使用膨处,可以將當(dāng)前庫的master與遠(yuǎn)程庫的master分支關(guān)聯(lián)(?砂竖?真椿?)。再次推送時可省略此參數(shù)乎澄。
初次連接GitHub時要求信任GitHub的公鑰指紋突硝。
向GitHub推送修改需要權(quán)限。將SSH公鑰添加到GitHub賬戶設(shè)置中的允許訪問列表中即可三圆。此時我遇到了第一個真正的bug狞换。雖然已經(jīng)添加了公鑰,但我還是無法將本機(jī)內(nèi)容推送上去舟肉。這可能是在關(guān)聯(lián)兩個庫的時候尚未添加公鑰導(dǎo)致的修噪。
>> git remote rm origin
刪除遠(yuǎn)程庫origin。之后重新添加再add路媚,顯示似乎有未盡工作分支黄琼,所以推送失敗。>> git pull
拉取遠(yuǎn)程庫狀態(tài)整慎。這顯然是我使用舊的遠(yuǎn)程庫與本機(jī)版本庫關(guān)聯(lián)的結(jié)果脏款,盡管舊庫已經(jīng)空了。Git的分支合并真差勁裤园,差評撤师!重新創(chuàng)建新庫后一切順利。
>> git clone git@github.com:<username>/<repositoryname>.git
將遠(yuǎn)程庫克隆到本機(jī)拧揽√甓埽可以視為即在本機(jī)創(chuàng)建一個空庫、將兩個庫關(guān)聯(lián)淤袜、并將遠(yuǎn)程庫的內(nèi)容拉取到本機(jī)文件痒谴。
四、多人協(xié)作
Git通過分支來實(shí)現(xiàn)多人協(xié)作铡羡。分支的實(shí)質(zhì)是樹形結(jié)構(gòu)+指針积蔚。HEAD是一個指向當(dāng)前分支的指針的指針,當(dāng)前分支的指針指向分支下最近的一次修改(或回退后的某個修改)烦周。master是默認(rèn)的分支名稱尽爆。
基于Git的強(qiáng)大分支功能,可以設(shè)計多種項(xiàng)目開發(fā)結(jié)構(gòu)读慎。安全的主分支(穩(wěn)定版本)教翩、便捷的個人開發(fā)分支、靈活的小分支贪壳、語法清晰的注解是好的項(xiàng)目開發(fā)系統(tǒng)的必要特征饱亿。
>> git remote
查看遠(yuǎn)程版本庫信息。
>> git branch
查看當(dāng)前分支列表闰靴。
>> git checkout -b <branchname>
//or
>> git branch <branchname>
>> git checkout <branchname>
創(chuàng)建并切換到特定分支彪笼。新創(chuàng)建的分支默認(rèn)與當(dāng)前分支指向同一修改節(jié)點(diǎn)。切換分支后蚂且,本機(jī)文件也被更改為當(dāng)前分支的狀態(tài)配猫。
>> git merge <branchname>
將指定分支合并到當(dāng)前分支。
>> git branch -d <branchname>
刪除指定分支杏死。不能刪除當(dāng)前所在的分支泵肄。刪除master時候會被警告(捆交??腐巢?)品追。
>> git log --graph --pretty=oneline --abbrev-commit
查看當(dāng)前分支狀態(tài)(帶樹形圖)。
>> git merge --no-ff -m "note" <branchname>
合并分支但保留被合并的分支結(jié)構(gòu)冯丙,方便回顧分支開發(fā)過程和繼續(xù)開發(fā)分支肉瓦。需要為此操作提交注解。
>> git tag <tagname> (<versionname>)
>> git tag -a <tagname> -m "<note>"
在當(dāng)前分支上打一個標(biāo)簽(實(shí)際是一個有名字的固定指針)胃惜。若不提供版本號泞莉,則打在當(dāng)前最新commit的版本上。
>> git tag
查看所有標(biāo)簽船殉。
>> git show <tagname>
查看標(biāo)簽所在版本的詳細(xì)信息鲫趁。
>> git tag -d <tagname>
刪除標(biāo)簽。
>> git push <remotebranchname> <tagname>
將本地標(biāo)簽推送到遠(yuǎn)程版本庫利虫。
>> git push <remotebranchname> --tags
將全部本地標(biāo)簽推送到遠(yuǎn)程版本庫饮寞。
>> git push origin :refs/tags/<tagname>
刪除遠(yuǎn)程標(biāo)簽。
>> git stash
將工作區(qū)和暫存區(qū)的內(nèi)容(修改)保存起來列吼,清空這兩個區(qū)域幽崩。配合分支切換,這一操作適用于臨時一次性執(zhí)行其他優(yōu)先任務(wù)寞钥,如其他分支上的bug修改慌申。
>> git stash list
查看本機(jī)上的stash列表。
>> git stash pop //only for the first stash
//or
>> git stash apply <stashindex>
>> git stash drop <stashindex>
恢復(fù)stash并刪除理郑。
如需更改遠(yuǎn)程庫蹄溉,需使用push指令,將本機(jī)分支推送到遠(yuǎn)程分支上您炉。
六柒爵、開源項(xiàng)目
fork:將他人的遠(yuǎn)程版本庫復(fù)制到自己的賬號下(值傳遞)。
pull:向他人推送(xiao)自己修改后的版本庫赚爵。若他人采納棉胀,即參與開源完成。
七冀膝、參考文獻(xiàn)
[1] Git教程
[2] SSH與遠(yuǎn)程登錄
[3] 公鑰和私鑰
[4] GitHub常見錯誤
[5] Markdown語法