一、版本控制系統(tǒng)對比
先說集中式版本控制系統(tǒng)苟径,版本庫是集中存放在中央服務器的,而大家工作的時候躬审,用的都是自己的電腦棘街,所以要先從中央服務器取得最新的版本,然后開始工作承边,工作完成遭殉,再把自己的修訂推送給中央服務器。這類系統(tǒng)博助,都有一個單一的集中管理的服務器险污,保存所有文件的修訂版本,而協(xié)同工作的人們都通過客戶端連到這臺服務器翔始,取出最新的文件或者提交更新罗心。
那分布式版本控制系統(tǒng)與集中式版本控制系統(tǒng)有何不同呢?首先城瞎,分布式版本控制系統(tǒng)根本沒有“中央服務器”渤闷,每個人的電腦上都是一個完整的版本庫,這樣脖镀,你工作的時候飒箭,就不需要聯網了,因為版本庫就在你自己的電腦上蜒灰。既然每個人電腦上都有一個完整的版本庫弦蹂,那多個人如何協(xié)作呢?比方說你在自己電腦上改了文件A强窖,你的同事也在他的電腦上改了文件A凸椿,這時,你們倆之間只需把各自的修改推送給對方翅溺,就可以互相看到對方的修改了脑漫。
和集中式版本控制系統(tǒng)相比,分布式版本控制系統(tǒng)的安全性要高很多咙崎,因為每個人電腦里都有完整的版本庫优幸,某一個人的電腦壞掉了不要緊,隨便從其他人那里復制一個就可以了褪猛。而集中式版本控制系統(tǒng)的中央服務器要是出了問題网杆,所有人都沒法干活了。
在實際使用分布式版本控制系統(tǒng)的時候,其實很少在兩人之間的電腦上推送版本庫的修改碳却,因為可能你們倆不在一個局域網內队秩,兩臺電腦互相訪問不了,也可能今天你的同事病了追城,他的電腦壓根沒有開機刹碾。因此,分布式版本控制系統(tǒng)通常也有一臺充當“中央服務器”的電腦座柱,但這個服務器的作用僅僅是用來方便“交換”大家的修改迷帜,沒有它大家也一樣干活,只是交換修改不方便而已色洞。
二戏锹、git基礎命令應用(配置)
-
Git 配置
配置個人名稱和郵箱,每次提交時將附帶這些信息:使用**git config ** 命令配置$ git config --global user.name = '******' $ git config --global user.email = '******'
然后會在當前用戶的家目錄創(chuàng)建一個.gitconfig文件火诸,如下:
$ ls -l ~/.gitconfig
-rw-r--r-- 1 user staff 28 12 14 11:25 .gitconfig
$ cat ~/.gitconfig
[user]
name = ******
email = ******
上面的配置文件就是Git全局配置的文件锦针,一般配置方法是git config --global <配置名稱> <配置的值>
如果你想使項目里的某個值與前面的全局設置有區(qū)別(例如把私人郵箱地址改為工作郵箱),你可以在項目中使用git config命令不帶 --global 選項來設置. 這會在你當前的項目目錄下創(chuàng)建 .git/config置蜀,從而使用針對當前項目的配置奈搜。
- 獲得一個git倉庫
-
Clone 一個倉庫
為了得一個項目的拷貝(copy),我們需要知道這個項目倉庫的地址(Git URL). Git能在許多協(xié)議下使用,所以Git URL可能以ssh://, http(s)://, git://. 有些倉庫可以通過不只一種協(xié)議來訪問盯荤。$ git clone https://git.oschina.net/minasia/GitTest.git
clone操作完成后馋吗,會發(fā)現當前目錄下多了一個GitTest
文件夾,這個文件夾里的內容就是我們剛剛clone下來的代碼秋秤。由于當前`gitproject僅是測試項目宏粤,里面僅有一個README.md文件。
$ cd GitTest/(master)
$ ls README.md
可以發(fā)現在命令提示符$前面多了個(master)灼卢。這是由于當前Shell使用的是zsh Shell绍哎,zsh會判斷當前的目錄是否有Git倉庫,如果是的話則自動把目前所在的git分支顯示在提示符中鞋真。Git 分支的概念我們會在稍后介紹崇堰。
- 初始化一個新倉庫
可以對一個已存在的文件夾用下面的命令讓它置于Git的版本控制管理之下。
創(chuàng)建一個文件夾涩咖,進入赶袄,并執(zhí)行初始化命令** git init**
$ mkdir GitInit
$ cd GitInit
$ git init
Initialized empty Git repository in /Users/****/****/GitInit/.git/
通過ls -la命令會發(fā)現project目錄下會有一個名叫.git 的目錄被創(chuàng)建,這意味著一個倉庫被初始化了抠藕。可以進入到.git目錄查看下有哪些內容蒋困。
三盾似、git基礎命令應用(工作流程)
git的基本流程如下:
- 創(chuàng)建或修改文件
- 使用git add命令添加新創(chuàng)建或修改的文件到本地的緩存區(qū)(Index)
- 使用git commit命令提交到本地代碼庫(可選,有的時候并沒有可以同步的遠端代碼庫)使用git push命令將本地代碼庫同步到遠端代碼庫
進入我們剛才從git上clone的GitTest目錄,分別創(chuàng)建文件file1零院,file2溉跃,file3:
~/Test/GitTest ?master? $ touch file1 file2 file3
~/Test/GitTest ?master*? $ echo "content1" >> file1
~/Test/GitTest ?master*?$ echo "content2" >> file2
~/Test/GitTest ?master*?$ echo "content3" >> file3
~/Test/GitTest ?master*?$ ###使用** git status ** 命令查看當前git倉庫的狀態(tài)
~/Test/GitTest ?master*?$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
file1
file2
file3
nothing added to commit but untracked files present (use "git add" to track)
~/Test/GitTest ?master*?$ ### 可以發(fā)現有三個文件處于untracked狀態(tài),下一步用** git add ** 命令將這些文件加入到緩存區(qū)中
~/Test/GitTest ?master*?$ git add file1 file2 file3
~/Test/GitTest ?master*?$ ### 再次執(zhí)行** git status ** 查看git狀態(tài)告抄,發(fā)現變化
~/Test/GitTest ?master*?$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: file1
new file: file2
new file: file3
~/Test/GitTest ?master*?$ ### 提示已經為commit做好準備撰茎,此時可以使用** git diff --cached** 命令查看緩存區(qū)中哪些文件被修改了,進去到git diff --cached 頁面后需要輸入q才可以退出
~/Test/GitTest ?master*?$ git diff --cached
~/Test/GitTest ?master*?$ ## 通過命令** git commit -m 'comment: 提交文件' 提交已處理的文件
~/Test/GitTest ?master*?$ git commit -m "update file"
[master (root-commit) 7bcd6cf] update file
3 files changed, 3 insertions(+)
create mode 100644 file1
create mode 100644 file2
create mode 100644 file3
~/Test/GitTest ?master?$ ## 需要使用-m添加本次修改的注釋打洼,完成后就會記錄一個新的項目版本龄糊。除了用git add 命令,我們還可以用下面的命令將所有沒有加到緩存區(qū)的修改也一起提交募疮,但-a命令不會添加新建的文件
~/Test/GitTest ?master?$ git commit -a -m 'add files'
On branch master
nothing to commit, working tree clean
~/Test/GitTest ?master?$ git status
On branch master
nothing to commit, working tree clean
~/Test/GitTest ?master?$ ## 至此炫惩,我們完成了第一次代碼提交,這次提交的代碼中我們創(chuàng)建了三個新文件阿浓。需要注意的是如果是修改文件他嚷,也需要使用git add命令添加到緩存區(qū)才可以提交。如果是刪除文件芭毙,則直接使用git rm命令刪除后會自動將已刪除文件的信息添加到緩存區(qū)筋蓖,git commit提交后就會將本地倉庫中的對應文件刪除
~/Test/GitTest ?master?$ ## 如果本地倉庫連接到了遠程Git服務器,可以使用下面的命令將本地倉庫同步到遠程服務器
~/Test/GitTest ?master?$ git push origin master
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (5/5), 346 bytes | 0 bytes/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To https://git.oschina.net/minasia/GitTest.git
f8f87cf..a4b1acb master -> master
三退敦、git基礎命令應用(分支與合并)
Git的分支可以讓你在主線(master分支)之外進行代碼提交粘咖,同時又不會影響代碼庫主線。分支的作用體現在多人協(xié)作開發(fā)中苛聘,比如一個團隊開發(fā)軟件涂炎,你負責獨立的一個功能需要一個月的時間來完成,你就可以創(chuàng)建一個分支设哗,只把該功能的代碼提交到這個分支唱捣,而其他同事仍然可以繼續(xù)使用主線開發(fā),你每天的提交不會對他們造成任何影響网梢。當你完成功能后震缭,測試通過再把你的功能分支合并到主線。
一個Git倉庫可以維護很多開發(fā)分支≌铰玻現在我們來創(chuàng)建一個新的叫 branchTest的分支:
$ git branch branchTest
運行git branch命令可以查看當前的分支列表拣宰,已經目前的開發(fā)環(huán)境處在哪個分支上:
$ git branch
branchTest
* master
master 是系統(tǒng)創(chuàng)建的, branchTest 是你剛剛穿件的烦感。切換分支到branchTest中
$ git branch branchTest
且換到新分支后巡社,編輯file1文件,然后添加并提交
$ vi file1
~/Test/GitTest ?branchTest*? $ git status
On branch branchTest
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: file1
no changes added to commit (use "git add" and/or "git commit -a")
~/Test/GitTest ?branchTest*? $ git add file1
~/Test/GitTest ?branchTest*? $ git commit -m 'update branchTest file1'
[branchTest c5bc27a] update branchTest file1
1 file changed, 4 insertions(+)
~/Test/GitTest ?branchTest? $ git status
On branch branchTest
nothing to commit, working tree clean
~/Test/GitTest ?branchTest?$ git checkout master
切換到master分支下手趣,查看剛才編輯的文件晌该,發(fā)現剛才的修改已經不見了,因為剛才的修改是在branchTest分支下操作的,現在切換回了master
分支朝群,目錄下的文件都是master分支上的文件了燕耿。
現在可以在master分支下再作一些不同的修改:
## 編輯file2
~/Test/GitTest ?master? $ echo 'edit file2' >> file2
~/Test/GitTest ?master*? $ cat file2
file2
edit file2
~/Test/GitTest ?master*? $ git add file2
~/Test/GitTest ?master*? $ git commit -m '提交file2'
[master 73568ca] 提交file2
1 file changed, 1 insertion(+)
這時,兩個分支就有了各自不同的修改姜胖,分支的內容都已經不同誉帅,如何將多個分支進行合并呢?
可以通過下面的git merge命令來合并branchTest到主線分支master:
## 在master分支上執(zhí)行
$ git merge -m 'merge master' branchTest
-m參數仍然是需要填寫合并的注釋信息右莱。
由于兩個branch修改了兩個不同的文件蚜锨,所以合并時不會有沖突,執(zhí)行上面的命令后合并就完成了隧出。
如果有沖突踏志,比如兩個分支都改了一個文件file3,則合并時會失敗胀瞪。如下:
~/Test/GitTest ?master?$ ## 編輯file3
~/Test/GitTest ?master?$ echo "abc" >> file3
~/Test/GitTest ?master*?$ cat file3
file3
abc
~/Test/GitTest ?master*?$ git add file3
~/Test/GitTest ?master*?$ git commit -m 'update file3'
[master 1e9e80a] update file3
1 file changed, 1 insertion(+)
~/Test/GitTest ?master?$ git status
On branch master
Your branch is ahead of 'origin/master' by 4 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
~/Test/GitTest ?master?$ git checkout branchTest
Switched to branch 'branchTest'
~/Test/GitTest ?branchTest?$ ls
README.md file1 file2 file3
~/Test/GitTest ?branchTest?$ cat file3
file3
~/Test/GitTest ?branchTest?$ echo 'aaaa' >> file3
~/Test/GitTest ?branchTest*?$ git add file3
~/Test/GitTest ?branchTest*?$ git commit -m 'update file3'
[branchTest e817b05] update file3
1 file changed, 1 insertion(+)
~/Test/GitTest ?branchTest?$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 4 commits.
(use "git push" to publish your local commits)
~/Test/GitTest ?master?$ ## 合并分支
~/Test/GitTest ?master?$ git merage -m '合并分支' branchTest
Auto-merging file3
CONFLICT (content): Merge conflict in file3
Automatic merge failed; fix conflicts and then commit the result.
~/Test/GitTest ?master*?$ ## 提示合并沖突针余,失敗
~/Test/GitTest ?master*?$ ## 合并失敗后,通過 git status 查看狀態(tài)凄诞,會發(fā)現file3 顯示為both modified , 查看file3的內容
~/Test/GitTest ?master*?$ cat file3
file3
<<<<<<< HEAD
abc
=======
aaaa
>>>>>>> branchTest
~/Test/GitTest ?master*?$ ## 可以看到沖突的內容都被添加到了file3中圆雁,我們使用vim編輯這個文件,去掉git自動產生標志沖突的<<<<<<等符號后帆谍,根據需要只保留我們需要的內容后保存伪朽,然后使用git add file3和git commit命令來提交合并后的file3內容,這個過程是手動解決沖突的流程汛蝙。
~/Test/GitTest ?master*?$ vim file3
~/Test/GitTest ?master*?$ git add file3
~/Test/GitTest ?master*?$ git commit
[master 1f4e771] 合并分支
~/Test/GitTest ?master?$ git commit -m 'merge file3'
On branch master
Your branch is ahead of 'origin/master' by 6 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
~/Test/GitTest ?master?$ ## 完成合并后烈涮,通過如下命令可以刪掉分支
~/Test/GitTest ?master?$ git branch -d branchTest
Deleted branch branchTest (was e817b05).
撒銷一個合并
如果你覺得你合并后的狀態(tài)是一團亂麻,想把當前的修改都放棄窖剑,你可以用下面的命令回到合并之前的狀態(tài):
$ git reset --hard HEAD^# 查看file3的內容坚洽,已經恢復到合并前的master上的文件內容$ cat file3
三、git基礎命令應用(日志)
~/Test/GitTest ?master? $ ## git log 命令顯示所有提交日志
~/Test/GitTest ?master? $ git log
~/Test/GitTest ?master? $ ## 如果日志記錄較長西土,可通過按鍵q退出
~/Test/GitTest ?master? $ ## git log 有很多參數讶舰,可以使用git help log 查看
~/Test/GitTest ?master? $ ## 日志統(tǒng)計 git log --stat
~/Test/GitTest ?master? $ ## 如果用--stat選項使用'git log',它會顯示在每個提交(commit)中哪些文件被修改了, 這些文件分別添加或刪除了多少行內容,這個命令相當于打印詳細的提交記錄:
~/Test/GitTest ?master? $ git log --stat
~/Test/GitTest ?master? $ ## 格式化日志需了, --pretty 參數可以使用n多表現形式跳昼,如oneline, short, medium, full, fuller, email 或raw。也可以通過--pretty=format參數定義格式肋乍。--graph 選項可以可視化你的提交圖(commit graph)鹅颊,會用ASCII字符來畫出一個很漂亮的提交歷史(commit history)線:
~/Test/GitTest ?master? $ git log --pretty=oneline
~/Test/GitTest ?master? $ git log --graph --pretty=oneline
~/Test/GitTest ?master? $ $ git log --pretty=format:'%h : %s' --topo-order --graph
~/Test/GitTest ?master? $ git log --pretty=format:'%h : %s' --topo-order --graph