集中式vs分布式
-
集中式CVS、SVN
- 速度慢蛹批,必須聯(lián)網(wǎng)仰泻,開源精神不符
- 版本庫集中放在中央服務(wù)器荆陆,工作時,獲取最新版本集侯,工作完成后被啼,再推送給中央服務(wù)器帜消!
-
分布式
- 無中央服務(wù)器,每個人的電腦都是一個完整的版本庫
- 安全性能更高
- 通常有一臺充當“中央服務(wù)器”的電腦浓体,僅僅作為方便“交換”大家的修改
安裝使用
Yum安裝:
[root@node1 ~]# yum install git -y
為node1上所有的git倉庫設(shè)置用戶名和Email
[root@node1 ~]# git config --global user.name "Your Name"
[root@node1 ~]# git config --global user.email "email@example.com"
創(chuàng)建并初始化版本庫
[root@node1 ~]# mkdir firstgit && cd firstgit/ && git init && ls -ah
Initialized empty Git repository in /root/firstgit/.git/
. .. .git
.git目錄作用:跟蹤管理版本庫
- 所有的版本控制系統(tǒng)泡挺,其實只能跟蹤文本文件的改動,比如TXT文件命浴,網(wǎng)頁粘衬,所有的程序代碼等等,Git也不例外咳促。版本控制系統(tǒng)可以告訴你每次的改動,圖片勘伺、視頻這些二進制文件跪腹,雖然也能由版本控制系統(tǒng)管理,但沒法跟蹤文件的變化飞醉,只能把二進制文件每次改動串起來冲茸,也就是只知道圖片從100KB改成了120KB,但到底改了啥缅帘,版本控制系統(tǒng)不知道轴术,也沒法知道。
常規(guī)操作
1.把文件添加到倉庫中
[root@node1 firstgit]# echo "hello world" > readme.txt
[root@node1 firstgit]# git add readme.txt # 添加到倉庫中
[root@node1 firstgit]# git commit -m "write a readme.txt file" #提交并通過-m參數(shù)說明
[master (root-commit) e380d2c] write a readme.txt file
1 file changed, 1 insertion(+)
create mode 100644 readme.txt
2.修改文件內(nèi)容钦无,查詢內(nèi)容和狀態(tài)并提交
[root@node1 firstgit]# echo "hello eagleslab" > readme.txt
[root@node1 firstgit]# git status # 查詢當前git倉庫狀態(tài)逗栽,readme.txt 需要添加和提交
# 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: readme.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@node1 firstgit]# git diff readme.txt # 變化的內(nèi)容
diff --git a/readme.txt b/readme.txt
index aa982b7..8d0e700 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1 +1 @@
-hello world\n hello git
+hello eagleslab
[root@node1 firstgit]# git add readme.txt
[root@node1 firstgit]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: readme.txt
#
[root@node1 firstgit]# git commit -m "change messages"
[master 7b92afb] change messages
1 file changed, 1 insertion(+), 1 deletion(-)
[root@node1 firstgit]# git status
# On branch master
nothing to commit, working directory clean
3.查詢歷史記錄并版本退回
[root@node1 firstgit]# git log
commit 3efa7f0fc058f00b0a98171fb77b44ab31481c87 # 版本ID
Author: Cokeku <1154283293@qq.com>
Date: Mon Mar 18 22:42:38 2019 -0400
add zj
commit 7b92afbb9f118f7ae10c49abc3114e4ee91ed26a
Author: Cokeku <1154283293@qq.com>
Date: Mon Mar 18 22:37:05 2019 -0400
change messages
commit e380d2cc936e01e17065408000c42c21f114321a
Author: Cokeku <1154283293@qq.com>
Date: Mon Mar 18 22:31:25 2019 -0400
write a readme.txt file
[root@node1 firstgit]# git reset --hard e380d2cc936e01e17065408000c42c21f114321a # 退回指定版本
HEAD is now at e380d2c write a readme.txt file
[root@node1 firstgit]# cat readme.txt
hello world
[root@node1 firstgit]# git reset --hard 3efa7f0fc058f00b0a98171fb77b44ab31481c87
HEAD is now at 3efa7f0 add zj
[root@node1 firstgit]# cat readme.txt
hello eagleslab zhengjiang!
記錄每一次的命令:
[root@node1 firstgit]# git reflog
3efa7f0 HEAD@{0}: reset: moving to 3efa7f0fc058f00b0a98171fb77b44ab31481c87
e380d2c HEAD@{1}: reset: moving to e380d2cc936e01e17065408000c42c21f114321a
3efa7f0 HEAD@{2}: commit: add zj
7b92afb HEAD@{3}: commit: change messages
e380d2c HEAD@{4}: commit (initial): write a readme.txt file
- 控制版本歷史記錄:因為git內(nèi)部有個Head指針指向當前的版本,如果需要退回版本失暂,只需要將Head指針指向相對應(yīng)的版本號彼宠,并且更新工作區(qū)文件。
工作區(qū)和暫存區(qū)
工作區(qū):當前所在的firstgit目錄就是一個工作區(qū)
-
.git不算工作區(qū)弟塞,只是Git的版本庫
- 版本庫中有暫存區(qū)和自動創(chuàng)建的master分支及指向master的一個指針HEAD]
- git add:將修改后文件添加到暫存區(qū)
- git commit:將暫存區(qū)的所有文件提交到master分支上
- git跟蹤的是每次修改而不是文件凭峡,如果不將修改添加到暫存區(qū)是無法加入commit中的
-
撤銷修改
- 場景1:當你改亂了工作區(qū)某個文件的內(nèi)容,想直接丟棄工作區(qū)的修改時决记,用命令git checkout -- file
- 場景2:當你不但改亂了工作區(qū)某個文件的內(nèi)容摧冀,還添加到了暫存區(qū)時,想丟棄修改系宫,分兩步索昂,第一步用命令git reset HEAD <file>,就回到了場景1笙瑟,第二步按場景1操作
- 場景3:已經(jīng)提交了不合適的修改到版本庫時楼镐,想要撤銷本次提交,版本退回即可往枷,不過前提是沒有推送到遠程庫
刪除文件
[root@node1 firstgit]# git status
# On branch master
# Changes not staged for commit:
# (use "git add/rm <file>..." to update what will be committed) # 先刪除再提交
# (use "git checkout -- <file>..." to discard changes in working directory) # 將版本庫中的最新內(nèi)容同步到工作區(qū)
# deleted: readme.tx
*遠程倉庫
Git是分布式版本控制系統(tǒng)框产,同一個Git倉庫凄杯,可以分布到不同的機器上。有一臺機器有一個原始版本庫秉宿,別的機器可以“克隆”這個原始版本庫戒突,而且每臺機器的版本庫其實都是一樣的,并沒有主次之分描睦。
1.注冊Github賬號
2.創(chuàng)建SSH Key
$ ssh-keygen -t rsa -C "youremail@example.com"
3.登陸Github將id_rsa.pub文件的內(nèi)容添加到SHH Key頁面中
PS:
GitHub需要識別出你推送的提交確實是你推送的膊存,而不是別人冒充的,而Git支持SSH協(xié)議忱叭,所以隔崎,GitHub只要知道了你的公鑰,就可以確認只有你自己才能推送韵丑。
當然爵卒,GitHub允許你添加多個Key。假定你有若干電腦撵彻,你一會兒在公司提交钓株,一會兒在家里提交,只要把每臺電腦的Key都添加到GitHub陌僵,就可以在每臺電腦上往GitHub推送了轴合。
-
添加遠程倉庫
注冊登錄Github
根據(jù)提示信息:- 在命令行中創(chuàng)建新的倉庫并關(guān)聯(lián)
- 在命令行中關(guān)聯(lián)已經(jīng)存在的倉庫
- git push命令:把當前分支master推送到遠程
-
從遠程庫克隆
- 先前我們都是先創(chuàng)建本地庫然后關(guān)聯(lián)遠程庫
- 現(xiàn)在最佳實踐是先創(chuàng)建遠程庫然后克隆到本地,但是創(chuàng)建遠程庫的時候選Initialize this repository with a README碗短,這樣GitHub會自動為我們創(chuàng)建一個README.md文件受葛。
分支管理
問題:假設(shè)你準備開發(fā)一個新功能,但是需要兩周才能完成偎谁,第一周你寫了50%的代碼奔坟,如果立刻提交,由于代碼還沒寫完搭盾,不完整的代碼庫會導(dǎo)致別人不能干活了咳秉。如果等代碼全部寫完再一次提交,又存在丟失每天進度的巨大風(fēng)險鸯隅。
分支的作用:創(chuàng)建了一個屬于你自己的分支澜建,別人看不到,還繼續(xù)在原來的分支上正常工作蝌以,而你在自己的分支上干活炕舵,想提交就提交,直到開發(fā)完畢后跟畅,再一次性合并到原來的分支上咽筋,這樣,既安全徊件,又不影響別人工作奸攻。
快速合并
創(chuàng)建與合并分支
[root@node1 Shell]# git checkout -b dev
Switched to a new branch 'dev'
[root@node1 Shell]# git branch
* dev
master
[root@node1 Shell]# cat 1.txt
[root@node1 Shell]# echo "This is dev operation" > 1.txt
[root@node1 Shell]# git add 1.txt
[root@node1 Shell]# git commit -m "eagels"
[dev 1a3e0b5] eagels
1 file changed, 2 insertions(+)
[root@node1 Shell]# git checkout master
[root@node1 Shell]# cat 1.txt
[root@node1 Shell]# git merge dev
Updating d55b0d3..1a3e0b5
Fast-forward
1.txt | 2 ++
1 file changed, 2 insertions(+)
[root@node1 Shell]# cat 1.txt
This is dev operation
hello
[root@node1 Shell]# git branch -d dev
Deleted branch dev (was 1a3e0b5)
命令:
查看分支:git branch
創(chuàng)建分支:git branch <name>
切換分支:git checkout <name>
創(chuàng)建+切換分支:git checkout -b <name>
合并某分支到當前分支:git merge <name>
刪除分支:git branch -d <name>
沖突合并
[root@node1 Shell]# git checkout -b test
Switched to a new branch 'test'
[root@node1 Shell]# echo "test1" >> 1.txt
[root@node1 Shell]# git add .
[root@node1 Shell]# git commit -m "add test1"
[test 0b919fa] add test1
1 file changed, 1 insertion(+)
[root@node1 Shell]# git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
[root@node1 Shell]# echo "test2" >> 1.txt
[root@node1 Shell]# git add 1.txt
[root@node1 Shell]# git commit -m "test2"
[master fe224bc] test2
1 file changed, 1 insertion(+)
[root@node1 Shell]# git merge test
Auto-merging 1.txt
CONFLICT (content): Merge conflict in 1.txt
Automatic merge failed; fix conflicts and then commit the result.
合并失斔馕!:因為現(xiàn)在test分支和master分支同級!
解決:
[root@node1 Shell]# git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
# (use "git push" to publish your local commits)
#
# You have unmerged paths.
# (fix conflicts and run "git commit")
#
# Unmerged paths:
# (use "git add <file>..." to mark resolution)
#
# both modified: 1.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@node1 Shell]# cat 1.txt
This is dev operation
hello
<<<<<<< HEAD
test2
=======
test1
>>>>>>> test
修改1.txt沖突的內(nèi)容睹耐,然后再次添加和提交
[root@node1 Shell]# git add 1.txt
[root@node1 Shell]# git commit -m "test12"
[master deedd5e] test12
[root@node1 Shell]# cat 1.txt
This is dev operation
hello
test12
查看分支合并情況:
[root@node1 Shell]# git log --graph --pretty=oneline --abbrev-commit
* deedd5e test12
|\
| * 0b919fa add test1
* | fe224bc test2
|/
* 1a3e0b5 eagels
* d55b0d3 add 1.txt file
* 237e280 Initial commit
Bug分支
環(huán)境:當我們正在dev開發(fā)新功能的時候辐赞,突然有個緊急bug110需要修復(fù),這是我們就需要將當前dev分支stash硝训,然后假設(shè)去修改master分支上的bug响委,然后就需要切換到master分支創(chuàng)建issue-110,進行修復(fù)窖梁。
創(chuàng)建test分支赘风,修改1.txt文件,然后stash將現(xiàn)場快照
[root@node1 Shell]# git checkout -b test
Switched to a new branch 'test'
[root@node1 Shell]# echo "111" > 1.txt
[root@node1 Shell]# git stash # 打快照
Saved working directory and index state WIP on test: 37e752c money
HEAD is now at 37e752c money
創(chuàng)建issue-111分支纵刘,修復(fù)bug(修改money.txt)的內(nèi)容贝次,然后add,commit
[root@node1 Shell]# git checkout -b issue-111
Switched to a new branch 'issue-111'
[root@node1 Shell]# echo "111" > money.txt
[root@node1 Shell]# git add money.txt
[root@node1 Shell]# git commit -m "change 111"
[issue-111 3422006] change 111
1 file changed, 1 insertion(+), 1 deletion(-)
[root@node1 Shell]# git status
# On branch issue-111
nothing to commit, working directory clean
合并分支
[root@node1 Shell]# git merge issue-111
切換回test分支彰导,恢復(fù)快照,繼續(xù)工作
[root@node1 Shell]# git checkout test
Switched to branch 'test'
[root@node1 Shell]# git status
# On branch test
nothing to commit, working directory clean
[root@node1 Shell]# git stash list
stash@{0}: WIP on test: 37e752c money
[root@node1 Shell]# git stash pop # 恢復(fù)快照
# On branch test
# 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.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (ffbba1442a3a3b6cbda32b7ffa3e131f46b60a38)
[root@node1 Shell]# cat 1.txt
111
[root@node1 Shell]# git add 1.txt
[root@node1 Shell]# git commit -m "change 1.txt"
[test a6e4e7c] change 1.txt
1 file changed, 1 insertion(+), 4 deletions(-)
[root@node1 Shell]# git checkout master
Switched to branch 'master'
[root@node1 Shell]# git status
# On branch master
nothing to commit, working directory clean
若要刪除一個還未合并的feature分支敲茄,可以通過git branch -D <name>強行刪除位谋!
多人協(xié)作:
- 查看遠程庫信息,使用git remote -v
- 本地新建的分支如果不推送到遠程堰燎,對其他人就是不可見的 從本地推送分支掏父,使用git push origin branch-name,如果推送失敗秆剪,先用git pull抓取遠程的新提交赊淑;
- 在本地創(chuàng)建和遠程分支對應(yīng)的分支,使用git checkout -b branch-name origin/branch-name仅讽,本地和遠程分支的名稱最好一致陶缺;
- 建立本地分支和遠程分支的關(guān)聯(lián),使用git branch --set-upstream branch-name origin/branch-name洁灵;
- 從遠程抓取分支饱岸,使用git pull,如果有沖突徽千,要先處理沖突苫费。
rebase作用:
- rebase操作可以把本地未push的分叉提交歷史整理成直線
- rebase的目的是使得我們在查看歷史提交的變化時更容易,因為分叉的提交需要三方對比
標簽管理
創(chuàng)建標簽
- 命令git tag <tagname>用于新建一個標簽双抽,默認為HEAD百框,也可以指定一個commit id;
- 命令git tag -a <tagname> -m "blablabla..."可以指定標簽信息牍汹;
- 命令git tag可以查看所有標簽铐维。
管理標簽
- 命令git push origin <tagname>可以推送一個本地標簽柬泽;
- 命令git push origin --tags可以推送全部未推送過的本地標簽;
- 命令git tag -d <tagname>可以刪除一個本地標簽方椎;
- 命令git push origin :refs/tags/<tagname>可以刪除一個遠程標簽聂抢。
搭建Git服務(wù)器
方案1:
[root@node2 ~]# yum install git -y
[root@node2 ~]# adduser git
[root@node2 git]# mkdir .ssh/
放入公鑰并初始化:
[root@node2 git]# vim .ssh/authorized_keys
[root@node2 git]# cd /srv/
[root@node2 srv]# git init --bare sample.git
[root@node2 srv]# chown -R git:git sample.git/
克隆倉庫:
[root@node1 ~]# git clone git@node2:/srv/sample.git
方案2:
GitLab安裝
環(huán)境準備:
[root@node1 ~]# yum install -y curl policycoreutils-python openssh-server
[root@node2 ~]# systemctl enable sshd
[root@node2 ~]# systemctl start sshd
[root@node2 ~]# firewall-cmd --permanent --add-service=http
[root@node2 ~]# systemctl reload firewalld
郵箱服務(wù):
[root@node2 ~]# yum install postfix -y
[root@node2 ~]# systemctl enable postfix
[root@node2 ~]# systemctl start postfix
配置YUM源:
[root@node2 ~]# cat > /etc/yum.repos.d/gitlab_ce.repo << EOF
> [gitlab-ce]
> name=Gitlab CE Repository
> baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/
> gpgcheck=0
> enabled=1
> EOF
[root@node2 ~]# yum makecache
[root@node2 ~]# yum install gitlab-ce -y
[root@node2 ~]# sed -i "s/^external_url.*/external_url 'http:\/\/$Host_IP:8090'/g" /etc/gitlab/gitlab.rb
注意:gitlab本身采用80端口,如安裝前服務(wù)器有啟用80棠众,安裝完訪問會報錯琳疏,需更改gitlab的默認端口。
注意:unicorn本身采用8080端口闸拿,如安裝前服務(wù)器有啟用8080空盼,安裝完訪問會報錯,需更改unicorn的默認端口新荤。
每次更改后使配置生效:
[root@node2 ~]# gitlab-ctl reconfigure
gitlab 日常管理命令:
gitlab-ctl start
gitlab-ctl stop
gitlab-ctl status
gitlab-ctl restart
gitlab-ctl reconfigure
最后通過瀏覽器:http://$Host_IP:8090
默認root用戶揽趾,并且重置密碼