Part 1 Git基本介紹
版本控制基本功能
所有的版本控制系統(tǒng),只能跟蹤文本文件的改動,比如TXT文件,網(wǎng)頁禁偎,所有的程序代碼等等,Git也不例外阀坏。版本控制系統(tǒng)可以告訴你每次的改動如暖,比如在第5行加了一個單詞“Linux”,在第8行刪了一個單詞“Windows”忌堂。而圖片盒至、視頻這些二進(jìn)制文件,雖然也能由版本控制系統(tǒng)管理士修,但沒法跟蹤文件的變化枷遂,只能把二進(jìn)制文件每次改動串起來,也就是只知道圖片從100KB改成了120KB棋嘲,但到底改了什么內(nèi)容酒唉,版本控制系統(tǒng)不知道,也沒法知道沸移。
Git優(yōu)勢
- 適合分布式開發(fā)痪伦,每一個個體都可以作為服務(wù)器。每一次Clone就是從服務(wù)器上pull到了所有的內(nèi)容雹锣,包括版本信息网沾。
- 公共服務(wù)器壓力和數(shù)據(jù)量都不會太大。
- 速度快蕊爵、靈活辉哥,分支之間可以任意切換。
- 任意兩個開發(fā)者之間可以很容易的解決沖突在辆,并且單機(jī)上就可以進(jìn)行分支合并证薇。
- 離線工作,不影響本地代碼編寫匆篓,等有網(wǎng)絡(luò)連接以后可以再上傳代碼浑度,并且在本地可以根據(jù)不同的需要,本地新建自己的分支鸦概。
- 在本機(jī)可以對同一個文件將它進(jìn)行簽出及修改箩张,并在最終簽入時甩骏,選擇保留哪一段代碼,如果在同一文件同一行有沖突時先慷,可以對沖突進(jìn)行選擇保留哪一個版本饮笛。
- 免費(fèi)。
Part 2 Git基本操作
本地操作
創(chuàng)建版本庫
-
Step 1: 創(chuàng)建項目目錄论熙,進(jìn)入目錄福青。
$ mkdir myproject $ cd myproject
-
Step 2: 初始化本地倉庫。
myproject $ git init myproject $ git add . myproject $ git commit -m "add myproject"
提交添加和修改操作
Step 1: 添加項目文件脓诡。創(chuàng)建文件
example.txt
无午,輸入文本This is an example.
。-
Step 2: 提交修改祝谚。
myproject $ git add example.txt myproject $ git commit -m "add example.txt"
查看倉庫狀態(tài)
-
可以隨時查看倉庫的狀態(tài)
myproject $ git status
-
若倉庫狀態(tài)告知有修改宪迟,可以使用下屬命令查看具體修改內(nèi)容
myproject $ git diff example.txt
版本退回
-
Step 1: 查看版本記錄。使用
--pretty=oneline
參數(shù)使顯示更簡潔交惯。myproject $ git log --pretty=oneline
-
Step 2:
HEAD
表示當(dāng)前版本次泽,HEAD^
表示上一版本,HEAD^^
表示上上一版本席爽,往上100個版本HEAD~100
意荤。# 退回上一版本 myproject $ git reset --hard HEAD^ # 退回上上一個版本 myproject $ git reset --hard HEAD^^
或者通過
git log
查看提交歷史,找到每個版本的commit id
,如xxxxx...
,xxxxx
是commit_id
的前5位拳昌,則可以退回到xxxxx...
對應(yīng)的版本myproject $ git reset --hard xxxxx
若想再次返回到最新版袭异,但卻找不到最新版的
commit id
钠龙,則使用以下命令查看命令歷史myproject $ git reflog
找到最新版本的
commit id
,再次使用git reset --hard commit_id
即可返回最新版本
對比工作區(qū)文件與版本庫最新版本
-
查看工作區(qū)和版本庫里面最新版本的區(qū)別
myproject $ git diff HEAD -- example.txt
撤銷操作
-
Scenario 1: 當(dāng)改亂了工作區(qū)某個文件的內(nèi)容炬藤,想直接丟棄工作區(qū)的修改時
myproject $ git checkout -- example.txt
-
Scenario 2: 當(dāng)不但改亂了工作區(qū)某個文件的內(nèi)容,還添加到了暫存區(qū)時碴里,想丟棄修改沈矿,分兩步
- 使用以下命令回到Scenario 1
myproject $ git reset HEAD example.txt
- 按照Scenario 1中的命令撤銷操作
Scenario 3: 在沒有推送到遠(yuǎn)程庫而已經(jīng)提交了不合適的修改到本地版本庫時,想要撤銷本次提交, 參考版本退回*操作咬腋。
刪除文件
-
Step 1: 刪除文件
myproject $ rm example.txt
-
Step 2.1: 確認(rèn)刪除
myproject $ git rm example.txt myproject $ git commit -m "remove example.txt"
-
Step 2.2: 撤銷刪除羹膳,把誤刪的文件恢復(fù)到最新版本。
myproject $ git checkout -- example.txt
git checkout
其實是用版本庫里的版本替換工作區(qū)的版本根竿,無論工作區(qū)是修改還是刪除
分支管理
-
查看當(dāng)前分支
$ git branch
-
創(chuàng)建分支
$ git branch <branch_name>
-
切換分支
$ git checkout <branch_name>
-
創(chuàng)建分支并切換
$ git checkout -b <branch_name>
-
刪除分支
# 無修改或完成所有提交下 $ git branch -d <branch_name> # 有修改或有未完成的提交陵像,需要強(qiáng)行刪除 $ git branch -D <branch_name>
-
合并分支,合并指定分支到當(dāng)前分支
$ git merge <branch_name>
-
查看分支合并情況
$ git log --graph --pretty=oneline --abbrev-commit
-
普通模式合并。合并分支時寇壳,加上
--no-ff
參數(shù)就可以用普通模式合并醒颖,合并后的歷史有分支,能看出來曾經(jīng)做過合并壳炎,而fast forward合并就看不出來曾經(jīng)做過合并泞歉。$ git merge --no-ff -m "some infos" <branch_name>
-
儲存當(dāng)前工作區(qū)。當(dāng)前工作尚未提交,但又接到比較緊急的任務(wù)腰耙,需要儲存當(dāng)前工作區(qū)榛丢,在完成緊急任務(wù)后讀取之前儲存的工作區(qū),繼續(xù)工作挺庞。
- 儲存工作區(qū)
$ git stash
- 查看所儲存的工作區(qū)
$ git stash list
-
恢復(fù)工作區(qū)
- 恢復(fù)后晰赞,stash內(nèi)容不刪除,需要手動刪除
# 恢復(fù) $ git stash apply # 刪除 $ git stash drop
- 恢復(fù)切自動刪除stash中的內(nèi)容
$git stash pop
- 若儲存了多個工作區(qū)选侨,需要先使用
git stash list
查看stash內(nèi)容宾肺,再使用下列命令恢復(fù)
git stash apply stash@{0}
解決沖突
在當(dāng)前分支修改了一文件,在某一分支對同一文件的同一地方做了修改侵俗,當(dāng)把該分支合并到當(dāng)前分支時锨用,由于是對同一個文件的同一個地方做了修改,會發(fā)生沖突隘谣。
解決方案:修改當(dāng)前分支的文件增拥,使其結(jié)果與合并后的相同,再提交寻歧。
標(biāo)簽管理
-
新建標(biāo)簽
# 默認(rèn)為HEAD $ git tag <tagname> # 可以指定 commit id $ git tag <tagname> commit_id
-
指定標(biāo)簽信息
$ git tag -a <tagname> -m "some infos"
-
查看所有標(biāo)簽
$ git tag
-
刪除標(biāo)簽
# 刪除本地標(biāo)簽 $ git tag -d <tagname> # 刪除遠(yuǎn)程倉庫標(biāo)簽 $ git tag -d <tagname> $ git push origin :refs/tags/<tagname>
-
推送某個標(biāo)簽到遠(yuǎn)程
# 推送標(biāo)簽到遠(yuǎn)程 $ git push origin <tagname> # 推送全部未推送過的本地標(biāo)簽 $ git push origin --tags
忽略特殊文件
當(dāng)出于保密等需求需要保留一些文件不推送它們時掌栅,需要使用忽略特殊文件。
- Step 1: 在項目根目錄下新建文件
.gitignore
码泛。 - Step 2: 將需要忽略的文件名或后綴添加在
.gitignore
猾封。
官方標(biāo)配.gitignore
文件: https://github.com/github/gitignore
-
需要強(qiáng)制加入被忽略的文件
$ git add -f <file>
本地-遠(yuǎn)程交互操作
與遠(yuǎn)程庫建立聯(lián)系
-
Step 1: 生成密鑰,可以全部設(shè)置為默認(rèn)值噪珊。
$ cd ~ $ ssh-keygen -t rsa -C "email@domain.com"
-
Step 2: 復(fù)制明碼到遠(yuǎn)程倉庫
~ $ cat .ssh/id_rsa.pub
將
id_rsa.pub
中的內(nèi)容復(fù)制晌缘,登陸遠(yuǎn)程倉庫如github.com,建立新的密鑰痢站,建立完成后可以直接通過命令行推送本地倉庫到遠(yuǎn)程倉庫磷箕。
添加遠(yuǎn)程倉庫
Step 1: 在遠(yuǎn)程倉庫新建Repository名為
myproject
。-
Step 2: 把一個已有的本地倉庫
myproject
與遠(yuǎn)程倉庫的myproject
關(guān)聯(lián)阵难。$ git remote add origin git@github.com:Account/myproject.git
其中,
Account
為Github
賬戶名岳枷,origin
為遠(yuǎn)程庫的默認(rèn)名字 -
Step 3: 把本地倉庫的所有內(nèi)容推送到遠(yuǎn)程庫上
$ git push -u origin master
使用
git push
命令把當(dāng)前分支master推送到遠(yuǎn)程origin中。參數(shù)-u
,Git不但會把本地的master分支內(nèi)容推送的遠(yuǎn)程新的master分支呜叫,還會把本地的master分支和遠(yuǎn)程的master分支關(guān)聯(lián)起來空繁。 Step 4: 完成本地提交后,使用以下命令將本地master分支的最新修改推送至Github
從遠(yuǎn)程庫Clone到本地庫
Step 1: 準(zhǔn)備好遠(yuǎn)程庫的倉庫朱庆,如,
account/myproject
盛泡。-
Step 2: 將遠(yuǎn)程庫
account/myproject
克隆到本地$ git clone git@github.com: account/myproject
從本地倉庫推送(push)到遠(yuǎn)程倉庫
-
已經(jīng)關(guān)聯(lián)遠(yuǎn)程庫
origin
,需要將本地倉庫的分支同步到遠(yuǎn)程倉庫的分支$ git push origin <branch_name>
從遠(yuǎn)程倉庫拉回(pull)到本地倉庫
-
已經(jīng)關(guān)聯(lián)遠(yuǎn)程庫
origin
椎工,需要將遠(yuǎn)程倉庫的分支同步到本地倉庫的分支$ git pull origin master
遠(yuǎn)程倉庫操作
-
查看遠(yuǎn)程倉庫名字
$ git remote
-
查看遠(yuǎn)程倉庫詳細(xì)信息
$ git remote -v
-
刪除已關(guān)聯(lián)的遠(yuǎn)程倉庫
# origin為遠(yuǎn)程倉庫名字 $ git remote rm origin
-
關(guān)聯(lián)多個遠(yuǎn)程倉庫饭于。假設(shè)當(dāng)前沒有任何關(guān)聯(lián)的遠(yuǎn)程倉庫蜀踏。
# 先關(guān)聯(lián)Github的遠(yuǎn)程倉庫 $ git remote add github git@github.com: Acount/repository_name.git # 再關(guān)聯(lián)Gitee的遠(yuǎn)程倉庫 $ git remote add gitee git@gitee: Acount/repository_name.git # 推送到Github $ git push github master # 推送到Gitee $ git push gitee master
Part 3 使用Git開發(fā)常見工作流
開源多人協(xié)作
- Step 1: 選擇遠(yuǎn)程倉庫,如github.com,gitee.com等掰吕,注冊公用賬戶果覆,新建項目Repository,將本地倉庫與遠(yuǎn)程倉庫建立聯(lián)系殖熟,將本地代碼推送到遠(yuǎn)程局待。詳細(xì)操作步驟參閱Part 2中的本地-遠(yuǎn)程交互操作遠(yuǎn)程庫建立聯(lián)系和添加遠(yuǎn)程倉庫小節(jié)。
- Step 2: 每個開發(fā)者在相同的遠(yuǎn)程倉庫注冊個人賬戶菱属,將遠(yuǎn)程倉庫Clone到本地庫钳榨。詳細(xì)步驟參閱Part 2中的本地-遠(yuǎn)程交互操作從遠(yuǎn)程庫Clone到本地庫小節(jié)。
- Step 3: 遠(yuǎn)程倉庫的master分支一般為發(fā)行版纽门,或穩(wěn)定版薛耻;新建分支dev為開發(fā)版,各個開發(fā)者在開發(fā)過程中推送本地的dev到遠(yuǎn)程赏陵,項目管理人定期或不定期從dev中更新master饼齿。
- Step 4: 開發(fā)者試圖用
git push origin <branch-name>
推送自己的修改。 - Step 5: 如果推送失敗蝙搔,則因為遠(yuǎn)程分支比你的本地更新缕溉,需要先用
git pull
試圖合并;如果合并有沖突吃型,則解決沖突证鸥,并在本地提交。 - Step 6: 沒有沖突或者解決掉沖突后勤晚,再用
git push origin <branch-name>
推送就能成功枉层。 - Step 7: 如果
git pull
提示no tracking information
,則說明本地分支和遠(yuǎn)程分支的鏈接關(guān)系沒有創(chuàng)建运翼,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>
返干。
閉源多人協(xié)作
與前文開源多人協(xié)作的不同之處是兴枯,閉源多人協(xié)作需要搭建私有Git服務(wù)器血淌。搭建Git服務(wù)器需要準(zhǔn)備一臺運(yùn)行Linux的機(jī)器,推薦使用Ubuntu财剖。
-
Step 1: 安裝git
$ sudo apt-get install git
-
Step 2: 創(chuàng)建一個git用戶悠夯,用來運(yùn)行g(shù)it服務(wù)
$ sudo adduser git
Step 3: 創(chuàng)建證書登錄。收集所有需要登錄的用戶的公鑰躺坟,就是他們自己的id_rsa.pub文件沦补,把所有公鑰導(dǎo)入到/home/git/.ssh/authorized_keys文件里,一行一個咪橙。此步驟原理類似前文本地-遠(yuǎn)程交互操作中的與遠(yuǎn)程庫建立聯(lián)系夕膀。
-
Step 4: 初始化倉庫虚倒。選定一個目錄作為Git倉庫,如
/srv/sample.git
$ cd /srv srv $ sudo git init --bare sample.git # 限制用戶直接登錄服務(wù)器修改倉庫 srv $ sudo chown -R git:git sample.git
-
Step 5: 出于安全考慮产舞,禁用shell登陸魂奥。編輯/etc/passwd文件完成。找到類似下面的一行:
git:x:1001:1001:,,,:/home/git:/bin/bash
修改為
git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
則git用戶可以正常通過ssh使用git易猫,但無法登錄shell耻煤。
之后步驟同前開源多人協(xié)作中的Step 2~Step 7。
個人開發(fā)
個人開發(fā)單純基于本地倉庫准颓,不涉及到與遠(yuǎn)程倉庫的交互哈蝇。
- Step 1: 選擇項目目錄
myproject
,初始化倉庫攘已,詳情參閱前文本地操作中的創(chuàng)建版本庫炮赦。 - Step 2: 其他操作諸如添加、刪除样勃、修改新文件眼五、添加新特性、修改bug等參考前文本地操作彤灶。
Part 4 參考資料
站在巨人的肩膀上學(xué)習(xí)看幼。