cvs和svn都是集中式版本控制系統,而git是分布式版本控制系統。
1、集中式版本控制系統必須聯網才能工作,如果在局域網內還好,帶寬夠大,速度夠快,可如果在互聯網上,遇到網速慢的話,呵呵。分布式版本控制系統可以不連網工作, 因為版本庫就在你自己的電腦上。
2、集中式版本控制系統如果中央服務器掛了,就完蛋了。分布式版本控制系統可以沒有中央服務器,每個人的電腦上都是一個完整的版本庫,可靠性高。分布式版本控制系統也可以有一臺充當“中央服務器”的電腦,但這個服務器的作用僅僅是用來方便“交換”大家的修改,沒有它大家也一樣干活,只是交換修改不方便而已。
git
git的安裝
官網: https://git-scm.com/
[root@vm1 ~]# yum install git -y
[root@vm1 ~]# git --version
git version 1.8.3.1
[root@vm1 ~]# git --help 查看參數幫助
git的操作可以說只需要git一條命令加參數即可
git應用
git身份設置
因為git是分布式版本控制系統,不同的人提交代碼需要區分,所以每個人都要設置一個身份標識。如果不設置的話誰會知道你這個開發者是張三,李四,還是王五呢?
[root@vm1 ~]# git config --global user.name "daniel"
[root@vm1 ~]# git config --global user.email "daniel@itcast.cn"
[root@vm1 ~]# git config --global color.ui true[root@vm1 ~]# git config --list
user.name=daniel
user.email=daniel@itcast.cn
color.ui=true
創建本地倉庫
工作目錄(working directory): 也可叫工作區,是存放項目代碼文件的一個目錄。
倉庫(repository) : 也可叫版本庫,在git init命令初始化工作目錄后會產生一個隱藏的子目錄.git, 可以將其理解為git的倉庫或版本庫。
倉庫分為本地倉庫與遠程倉庫。
創建本地倉庫的步驟:
1. 創建工作目錄[root@vm1 ~]# mkdir GitTest
2. 在對應的工作目錄中創建本地倉庫[root@vm1 ~]# cd GitTest/[root@vm1 GitTest]# git initInitialized empty Git repository in /root/GitTest/.git/會產生一個.git子目錄,所有除代碼數據外的相關數據都在此目錄,不要修改它(它就是倉庫或叫版本庫)[root@vm1 GitTest]# ls .git/branches config description HEAD hooks info objects refs
mkdir創建一個工作目錄, 然后cd進去, 使用git init就創建好了本地倉庫。開發者就可以在工作目錄里開發項目代碼文件了。
暫存區
暫存區(stage或index): 也有叫緩存區,暫存區就看作是一個緩區區域,臨時保存你的改動。
如果在工作目錄創建了一個新文件,需要將新文件添加到暫存區。
添加文件到暫存區:
1, 準備一個文件[root@vm1 GitTest]# cat 1.py print("hello world")
2, 使用git add命令提交到暫存區(git rm --cached 1.py從暫存區移除但保留在工作目錄中)[root@vm1 GitTest]# git add 1.py
3, 提交第一個文件后,版本庫.git子目錄里就多了一個index[root@vm1 GitTest]# ls .git/branches config description HEAD hooks index info objects refs
4, 使用strings命令查看可以看到git add的文件列表[root@vm2 GitTest]# strings .git/index DIRC1.py 這里可以看到1.py文件添加到了index文件里了
git版本控制
提交文件(第1個版本)
代碼文件需要commit提交后才能納入版本控制。
1, 可以使用git status查看工作目錄里有哪些文件需要提交[root@vm1 GitTest]# git status# On branch master## Initial commit## Changes to be committed:# (use "git rm --cached <file>..." to unstage)## new file: 1.py#
2, 使用git commit提交; -m 后接提交的說明信息[root@vm1 GitTest]# git commit -m "提交1.py"[master (root-commit) 4e67190] 提交1.py1 file changed, 1 insertion(+)create mode 100644 1.py
3, 再次git status查看狀態,沒有需要提交的文件了[root@vm1 GitTest]# git status# On branch masternothing to commit, working directory clean
修改再提交(第2個版本)
1, 修改1.py文件,我這里加了一句print("hello python")[root@vm1 GitTest]# cat 1.pyprint("hello world")print("hello python")
2, 使用git status查看,信息告訴我們1.py被修改了[root@vm1 GitTest]# git status# On branch master# 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: 1.py#no changes added to commit (use "git add" and/or "git commit -a")
3, 使用git diff查看修改了什么[root@vm1 GitTest]# git diff 1.pydiff --git a/1.py b/1.pyindex 8cde782..5da7641 100644--- a/1.py+++ b/1.py@@ -1 +1,2 @@print("hello world")+print("hello python")
4, 提交修改(add+commit)[root@vm1 GitTest]# git add 1.py[root@vm1 GitTest]# git commit -m "添加了一行代碼打印hello python"[master 0e9371b] 添加了一行代碼打印hello python1 file changed, 1 insertion(+)
再修改再提交(第3個版本)
再增加一句代碼print("hello linux")
[root@vm1 GitTest]# cat 1.py
print("hello world")
print("hello python")
print("hello linux")[root@vm1 GitTest]# git add 1.py[root@vm1 GitTest]# git commit -m "添加了一行代碼打印hello linux"
[master b679b01] 添加了一行代碼打印hello linux1 file changed, 1 insertion(+)
- 工作目錄中寫好的代碼文件需要先git add 文件名添加到暫存區,再git commit 文件名提交。以后每次修改都要重復前兩步。
- git status查看工作目錄中的狀態
- git diff 文件名查看文件修改了什么
查看提交歷史
1, 使用git log查看提交的歷史版本信息[root@vm1 GitTest]# git logcommit b679b01f2ee42c1c4a7e14ed5d37e02da131a98eAuthor: daniel <daniel@itcast.cn>Date: Wed Jan 16 14:00:44 2019 +0800添加了一行代碼打印hello linuxcommit 0e9371bfdbc27049c31017773248ae8333b5bf3fAuthor: daniel <daniel@itcast.cn>Date: Tue Jan 15 23:43:58 2019 +0800添加了一行代碼打印hello pythoncommit 4e67190ec3c57f1708702c9eca5aebe88017bdd2Author: daniel <daniel@itcast.cn>Date: Tue Jan 15 23:23:26 2019 +0800提交1.py2, 使用git log --pretty=oneline查看提交的歷史版本信息, 查看的顯示信息更簡潔。前面字符串你可以看作就是一個版本號(commit id)。[root@vm1 GitTest]# git log --pretty=onelineb679b01f2ee42c1c4a7e14ed5d37e02da131a98e 添加了一行代碼打印hello linux0e9371bfdbc27049c31017773248ae8333b5bf3f 添加了一行代碼打印hello python4e67190ec3c57f1708702c9eca5aebe88017bdd2 提交1.py
版本回退與還原
1, 使用git reset --hard HEAD^回退到上一個版本(也就是第2個版本)[root@vm1 GitTest]# git reset --hard HEAD^HEAD is now at 0e9371b 添加了一行代碼打印hello python[root@vm1 GitTest]# cat 1.py print("hello world")print("hello python")2, 使用git reset --hard 第3個版本號還原到第3個版本。但如果我忘了第3個版本號是什么了,使用git reflog查看所有的操作歷史。[root@vm1 GitTest]# git reflog0e9371b HEAD@{0}: reset: moving to HEAD^b679b01 HEAD@{1}: commit: 添加了一行代碼打印hello linux0e9371b HEAD@{2}: commit: 添加了一行代碼打印hello python4e67190 HEAD@{3}: commit (initial): 提交1.py3, 還原到第3個版本[root@vm1 GitTest]# git reset --hard b679b01HEAD is now at b679b01 添加了一行代碼打印hello linux[root@vm1 GitTest]# cat 1.py print("hello world")print("hello python")print("hello linux")4, 回退到上上一個版本, 也就是回退兩個版本,使用git reset --hard HEAD^^回退三個版本,使用git reset --hard HEAD^^^, 以此類推。如果回退100個版本,那用100個^符號不方便,可以換成git reset --hard HEAD~100[root@vm1 GitTest]# git reset --hard HEAD^^HEAD is now at 4e67190 提交1.py[root@vm1 GitTest]# cat 1.py print("hello world")
- 提交后的代碼文件,使用git log查看當前版本及以前的歷史版本。
- 使用git reset --hard HEAD^或者git reset --hard HEAD~100實現版本回退。
- 使用git reflog查看提交的所有操作及版本號。
- 使用git reset --hard 版本號,你可以自由的在不同版本之間來回切換。
git工作流再次理解與應用拓展: - 工作目錄里任何修改或增加的文件,都要git add到暫存區,讓暫存區和工作目錄的狀態一致,這樣才能提交一個版本。
- git commit提交的是在暫存區里的所有文件狀態。也就是說是整個工作目錄里的狀態保存為一個版本,而不是某一個文件。
- git版本控制不僅僅是用于項目開發,你也可以用于一個軟件包倉庫的版本控制。
撤銷修改
準備一行或一段寫錯的代碼
[root@vm1 GitTest]# cat 1.py
print("hello world")
print("hello python")
print("hello linux")
print("hey,xxx is a gay") 這是寫錯的代碼,需要反悔
想要撤銷修改有以下方法:
- 直接把寫錯的代碼刪除就好, 但如果改變的代碼很多,開發者自己都忘了具體改了哪些代碼,這種做法就不方便了
- 使用git checkout – 文件名就可以直接撤銷修改了
- 如果寫亂了代碼,添加暫存區但還沒有commit提交。使用git reset HEAD 文件名取消暫存區添加,再git checkout – 文件名來撤銷修改
- 如果寫亂了代碼,添加暫存區并提交了。則使用版本回退。
誤刪恢復
1, 只要文件git add到了暫存區, 無論有沒有git commit提交。誤刪除后都可以使用 git checkout -- 文件名來恢復。[root@vm1 GitTest]# touch 2.py[root@vm1 GitTest]# git add 2.py[root@vm1 GitTest]# rm -rf 2.py[root@vm1 GitTest]# ls1.py[root@vm1 GitTest]# git checkout -- 2.py[root@vm1 GitTest]# ls1.py 2.py2, 如果文件沒有git add到暫存區, 誤刪除了就沒了。[root@vm1 GitTest]# touch 3.py[root@vm1 GitTest]# rm -rf 3.py下面命令恢復報錯[root@vm1 GitTest]# git checkout -- 3.pyerror: pathspec '2.py' did not match any file(s) known to git.
文件刪除
1, 沒有git add到暫存區的文件直接rm刪除就ok2, git add添加到暫存區,但沒有git commit提交的文件。需要rm刪除本地,還要git rm 文件名刪除[root@vm1 GitTest]# touch 3.py[root@vm1 GitTest]# git add 3.py[root@vm1 GitTest]# rm -rf 3.py[root@vm1 GitTest]# git rm 3.pyrm '3.py'3, git add添加到暫存區,并且已經git commit提交的文件。需要rm刪除本地,再git rm 文件名刪除,最后再提交刪除[root@vm1 GitTest]# touch 3.py[root@vm1 GitTest]# git add 3.py[root@vm1 GitTest]# git commit -m "提交了3.py"[master 0236aef] 提交了3.py1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 3.py[root@vm1 GitTest]# rm -rf 3.py[root@vm1 GitTest]# git rm 3.pyrm '3.py'[root@vm1 GitTest]# git commit -m "刪除了3.py"[master dc4ee5e] 刪除了3.py1 file changed, 0 insertions(+), 0 deletions(-)delete mode 100644 3.py
git分支管理
先來考慮一個問題: 開發者A開發軟件的某一個功能模塊, 還沒有開發完成,但害怕進度丟失就提交。假設另一位開發者B并不知道A沒有完成, 而直接使用了A開發的文件,這造成了問題。
解決方法: 開發者A創建一個屬于自己的分支,這個分支只屬于A,不會影響其他人。開發完成后,合并到項目主分支即可。
查看分支
默認只有一個master分支, 前面有*號的代表為當前分支。[root@vm1 GitTest]# git branch* master
創建分支
使用git branch 分支名來創建分支[root@vm1 GitTest]# git branch dev[root@vm1 GitTest]# git branch dev* master
切換分支
使用git checkout 分支名來切換分支[root@vm1 GitTest]# git checkout devSwitched to branch 'dev'[root@vm1 GitTest]# git branch * devmaster
合并分支
1, 在dev分支上新開發了一個代碼文件,添加并提交[root@vm1 GitTest]# git branch * dev 確認為dev分支master[root@vm1 GitTest]# echo "new feature" > 5.py[root@vm1 GitTest]# git add 5.py[root@vm1 GitTest]# git commit -m "增加了新特性"[dev 4a0c78e] 增加了新特性1 file changed, 1 insertion(+)create mode 100644 5.py2, 切換到master上分支后,卻發現根本沒有這個文件[root@vm1 GitTest]# git checkout masterSwitched to branch 'master'[root@vm1 GitTest]# cat 5.py cat: 5.py: No such file or directory3, 合并分支,再查看能在master分支上查看到了[root@vm1 GitTest]# git merge devUpdating dc4ee5e..4a0c78eFast-forward5.py | 1 +1 file changed, 1 insertion(+)create mode 100644 5.py[root@vm1 GitTest]# cat 5.py new feature
分支沖突
有些復雜的情況會造成沖突,這個時候git就不能幫我們自動的合并分支。我們就要手動處理沖突。