Git版本控制系统
版本控制系统简介
版本控制系统是一种记录一个或若干个文件内容变化,以便将来查阅特定版本内容情况的系统
记录文件的所有历史变化
随时恢复到任何一个历史状态
多人协作开发
常见版本管理工具
SVN
集中式的版本控制系统,只有一个中央数据仓库,如果中央数据仓库挂了或者不可访问,所有的使用者无法使用SVN,无法进行提交或备份文件。
Git
分布式的版本控制系统,在每个是使用者电脑上就有一个完整的数据仓库,没有网络仍然可以使用Git,当然为了习惯及团队协作,会将本地数据同步到Git服务器或者Github等代码仓库
Git安装
系统环境准备
[root@git ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
[root@git ~]# uname -r
3.10.0-693.el7.x86_64
[root@git ~]# getenforce
Disabled
[root@git ~]# systemctl stop firewalld
[root@git ~]#
Git安装部署
[root@git ~]# yum -y install git
[root@git ~]# git config
--global use global config file 使用全局配置文件
--system use system config file 使用系统级配置文件
--local use repository config file 使用版本库级配置文件
[root@git ~]# git config --global user.name 'opesn'
[root@git ~]# git config --global user.email 'opesn@qq.com'
[root@git ~]# git config --global color.ui true
[root@git ~]#
[root@git ~]# git config --list
user.name=opesn
user.email=opesn@qq.com
color.ui=true
[root@git ~]#
[root@git ~]# cat .gitconfig
[user]
name = opesn
email = opesn@qq.com
[color]
ui = true
[root@git ~]#
Git初始化
[root@git ~]# mkdir /data
[root@git ~]# cd /data/
[root@git data]# git init #初始化仓库,把一个目录初始化为版本仓库(可以是空目录,也可以是带内容的目录)
Initialized empty Git repository in /data/.git/
[root@git data]# ll -a
total 0
drwxr-xr-x 3 root root 18 Aug 25 13:19 .
dr-xr-xr-x. 18 root root 256 Aug 25 13:19 ..
drwxr-xr-x 7 root root 119 Aug 25 13:19 .git
[root@git data]#
#出现.git代表成为仓库了
[root@git data]# git status #查看当前仓库的状态
# On branch master
#
# Initial commit
#
nothing to commit (create/copy files and use "git add" to track)
[root@git data]#
[root@git data]# cd .git/
[root@git .git]# ll
total 12
drwxr-xr-x 2 root root 6 Aug 25 13:19 branches
-rw-r--r-- 1 root root 92 Aug 25 13:19 config
-rw-r--r-- 1 root root 73 Aug 25 13:19 description
-rw-r--r-- 1 root root 23 Aug 25 13:19 HEAD
drwxr-xr-x 2 root root 242 Aug 25 13:19 hooks
drwxr-xr-x 2 root root 21 Aug 25 13:19 info
drwxr-xr-x 4 root root 30 Aug 25 13:19 objects
drwxr-xr-x 4 root root 31 Aug 25 13:19 refs
[root@git .git]# tree
#隐藏文件介绍:
branches #分支目录
config #定义项目特有的配置选项
description #仅供git、web程序使用
HEAD #指示当前的分支
hooks #包含git钩子文件
info #包含一个全局排除文件(exclude文件)
objects #存放所有数据内容,有info和pack两个子文件夹
refs #存放指向数据(分支)的提交对象的指针
index #保存暂存区信息,在执行git init的时候,这个文件还没有
Git常规使用
命令 | 命令说明 |
---|---|
add | 添加文件内容至暂存区 |
bisect | 通过二分查找定位引入 bug 的变更 |
branch | 列出、创建或删除分支 |
checkout | 检出一个分支或路径到工作区 |
clone | 克隆一个版本库到一个新目录 |
commit | 记录变更到版本库 |
diff | 默认比对工作目录和暂存区有什么不同 |
fetch | 从另外一个版本库下载对象和引用 |
grep | 输出和模式匹配的行 |
init | 创建一个空的 |
Git | 版本库或重新初始化一个已存在的版本库 |
log | 显示提交日志 |
merge | 合并两个或更多开发历史 |
mv | 移动或重命名一个文件、目录或符号链接 |
pull | 获取并合并另外的版本库或一个本地分支 |
push | 更新远程引用和相关的对象 |
rebase | 本地提交转移至更新后的上游分支中 |
reset | 重置当前HEAD到指定状态 |
rm | 从工作区和暂存区中删除文件 |
show | 显示各种类型的对象 |
status | 显示工作区状态 |
tag | 创建、列出、删除或校验一个GPG签名的 tag 对象 |
创建代码文件
#创建三个代码文件
[root@git data]# touch a b c
[root@git data]# git status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# a
# b
# c
nothing added to commit but untracked files present (use "git add" to track)
[root@git data]#
将文件添加到暂存区
#将a文件添加到暂存区
[root@git data]# git add a
[root@git data]# git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: a
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# b
# c
[root@git data]#
#git add .或*添加当前所有文件到暂存区
[root@git data]# git add .
[root@git data]# git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: a
# new file: b
# new file: c
#
[root@git data]#
#将文件撤出暂存区
[root@git data]# git rm --cached c
rm 'c'
[root@git data]# git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: a
# new file: b
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# c
[root@git data]#
删除文件
1.先从暂存区撤回到工作区、然后直接删除文件
[root@git data]# git rm --cached c
[root@git data]# rm -f c
[root@git data]# git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: a
# new file: b
#
[root@git data]#
2.直接从暂存区域同工作区域一同删除文件
[root@git data]# git rm -f b
rm 'b'
[root@git data]# git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: a
#
[root@git data]#
将暂存区内容提交到本地仓库
[root@git data]# git commit -m "add newfile a" a
[master (root-commit) 969f0fd] add newfile a
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 a
[root@git data]# git status
# On branch master
nothing to commit, working directory clean
[root@git data]#
git重命名
[root@git data]# git mv a a.txt
[root@git data]# git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: a -> a.txt
#
[root@git data]#
[root@git data]# git commit -m "mv a a.txt"
[master a6629c5] mv a a.txt
1 file changed, 0 insertions(+), 0 deletions(-)
rename a => a.txt (100%)
[root@git data]#
文件对比
#git diff 默认比对工作目录和暂存区有什么不同
[root@git data]# echo index >a.txt
[root@git data]# git diff
diff --git a/a.txt b/a.txt
index e69de29..9015a7a 100644
--- a/a.txt
+++ b/a.txt
@@ -0,0 +1 @@
+index
[root@git data]#
[root@git data]# git diff --cached
[root@git data]#
#git diff --cached 比对暂存区域和本地仓库
[root@git data]# git add a.txt
[root@git data]# git diff
[root@git data]# git diff --cached
diff --git a/a.txt b/a.txt
index e69de29..9015a7a 100644
--- a/a.txt
+++ b/a.txt
@@ -0,0 +1 @@
+index
#将修改的文件上传到本地仓库后进行比对
[root@git data]# git commit -m "add index"
[master 62cf747] add index
1 file changed, 1 insertion(+)
[root@git data]# git diff
[root@git data]# git diff --cached
[root@git data]#
#如果某个文件已经被仓库管理,如果在更改此文件,直接需要一条命令提交即可
[root@git data]# git commit -am "add 123"
[master 9c65ca6] add 123
1 file changed, 1 insertion(+)
[root@git data]#
查看历史信息
#查看历史提交过的信息
[root@git data]# git log
commit 9c65ca6e220071fc871e89bb339d01f4c877c3c4
Author: opesn <opesn@qq.com>
Date: Sun Aug 25 14:12:38 2019 +0800
add 123
commit 62cf7473077b4a17b5acbe262d45b601f0284f23
Author: opesn <opesn@qq.com>
Date: Sun Aug 25 14:06:56 2019 +0800
add index
commit a6629c59c19c9dc86bdc8436d80277df5b3111f4
Author: opesn <opesn@qq.com>
Date: Sun Aug 25 13:59:04 2019 +0800
mv a a.txt
commit 969f0fd36a07245d1cc34f7c34538d72572b9270
Author: opesn <opesn@qq.com>
Date: Sun Aug 25 13:49:23 2019 +0800
add newfile a
[root@git data]#
#一行显示详细信息
[root@git data]# git log --oneline
9c65ca6 add 123
62cf747 add index
a6629c5 mv a a.txt
969f0fd add newfile a
[root@git data]#
#显示当前的指针指向哪里
[root@git data]# git log --oneline --decorate
9c65ca6 (HEAD, master) add 123
62cf747 add index
a6629c5 mv a a.txt
969f0fd add newfile a
[root@git data]#
#显示具体内容的变化
[root@git data]# git log -p
#显示最近一次内容
[root@git data]# git log -1
恢复历史数据
#回滚数据到某一个提交
[root@git data]# git log --oneline
9c65ca6 add 123
62cf747 add index
a6629c5 mv a a.txt
969f0fd add newfile a
[root@git data]# git reset --hard 969f0fd
HEAD is now at 969f0fd add newfile a
[root@git data]# git log
commit 969f0fd36a07245d1cc34f7c34538d72572b9270
Author: opesn <opesn@qq.com>
Date: Sun Aug 25 13:49:23 2019 +0800
add newfile a
[root@git data]# git status
# On branch master
nothing to commit, working directory clean
[root@git data]# cat
a .git/
[root@git data]# cat a
[root@git data]# ll
total 0
-rw-r--r-- 1 root root 0 Aug 25 14:21 a
[root@git data]#
#回滚到最新版本
[root@git data]# git reflog
969f0fd HEAD@{0}: reset: moving to 969f0fd
9c65ca6 HEAD@{1}: reset: moving to 9c65ca6
969f0fd HEAD@{2}: reset: moving to 969f0fd
9c65ca6 HEAD@{3}: commit: add 123
62cf747 HEAD@{4}: commit: add index
a6629c5 HEAD@{5}: commit: mv a a.txt
969f0fd HEAD@{6}: commit (initial): add newfile a
[root@git data]# git reset --hard 9c65ca6
HEAD is now at 9c65ca6 add 123
[root@git data]# git log --oneline
9c65ca6 add 123
62cf747 add index
a6629c5 mv a a.txt
969f0fd add newfile a
[root@git data]# cat a.txt
index
123
[root@git data]#
git分支
分支即是平行空间,假设你在为某个手机系统研发拍照功能,代码已经完成了80%,但如果将这不完整的代码直接提交到git仓库中,又有可能影响到其他人的工作,此时我们便可以在该软件的项目之上创建一个名叫“拍照功能”的分支,这种分支只会属于你自己,而其他人看不到,等代码编写完成后再与原来的项目主分支合并下即可,这样既能保证代码不丢失又,不影响其他人的工作。
一般再实际的项目开发中,我们要尽量保证master分支是非常稳定的,仅用于发布新版本,平时不要随便直接修改里面的数据文件,而工作的时候则可以新建不同的工作分支,等到工作完成后在合并到master分支上面,所以团队的合作分支看起来会像上面图那样。
创建分支
#创建分支
[root@git data]# git branch testing
#查看分支
[root@git data]# git branch
* master
testing
[root@git data]#
切换分支
[root@git data]# git checkout testing
Switched to branch 'testing'
[root@git data]# git branch
master
* testing
[root@git data]#
#创建并切换到testing分支
[root@git data]# git checkout -b testing
删除分支
[root@git data]# git checkout master
Switched to branch 'master'
[root@git data]# git branch -d testing
Deleted branch testing (was e4df6b7).
[root@git data]# git branch
* master
[root@git data]#
在分支上创建代码文件
[root@git data]# git checkout -b testing
Switched to a new branch 'testing'
[root@git data]# git log --oneline --decorate
9c65ca6 (HEAD, testing, master) add 123
62cf747 add index
a6629c5 mv a a.txt
969f0fd add newfile a
[root@git data]# touch test-ddd
[root@git data]# git add .
[root@git data]# git commit -m "add newfile test-add"
[testing 6f007e1] add newfile test-add
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test-ddd
[root@git data]# git branch
master
* testing
[root@git data]# git log --oneline --decorate
6f007e1 (HEAD, testing) add newfile test-add
9c65ca6 (master) add 123
62cf747 add index
a6629c5 mv a a.txt
969f0fd add newfile a
在主分支上创建代码文件
[root@git data]# git checkout master
Switched to branch 'master'
[root@git data]# ll
total 4
-rw-r--r-- 1 root root 10 Aug 25 15:30 a.txt
[root@git data]# git branch
* master
testing
[root@git data]# git log --oneline --decorate
9c65ca6 (HEAD, master) add 123
62cf747 add index
a6629c5 mv a a.txt
969f0fd add newfile a
[root@git data]# touch master-eee
[root@git data]# git add .
[root@git data]# git commit -m "add newfile master-eee"
[master 550b008] add newfile master-eee
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 master-eee
[root@git data]# git log --oneline --decorate
550b008 (HEAD, master) add newfile master-eee
9c65ca6 add 123
62cf747 add index
a6629c5 mv a a.txt
969f0fd add newfile a
合并分支
[root@git data]# git merge testing
Merge branch 'testing'
merge testing
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
".git/MERGE_MSG" 7L, 263C written
Merge made by the 'recursive' strategy.
test-ddd | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test-ddd
[root@git data]# ll
total 4
-rw-r--r-- 1 root root 10 Aug 25 15:30 a.txt
-rw-r--r-- 1 root root 0 Aug 25 15:35 master-eee
-rw-r--r-- 1 root root 0 Aug 25 15:37 test-ddd
[root@git data]# git log --oneline --decorate
1ff695c (HEAD, master) Merge branch 'testing' merge testing
550b008 add newfile master-eee
6f007e1 (testing) add newfile test-add
9c65ca6 add 123
62cf747 add index
a6629c5 mv a a.txt
969f0fd add newfile a
[root@git data]#
冲突合并
主分支创建文件
[root@git data]# git checkout master
Switched to branch 'master'
[root@git data]#
[root@git data]# ll
total 4
-rw-r--r-- 1 root root 10 Aug 25 16:11 a.txt
-rw-r--r-- 1 root root 0 Aug 25 15:45 master-eee
w-r--r-- 1 root root 0 Aug 25 15:37 test-ddd
▽root@git data]# echo "master" >>aaa
[root@git data]# git add .
[root@git data]# git commit -m "master"
[master 4f20c2a] master
1 file changed, 1 insertion(+)
create mode 100644 aaa
[root@git data]#
分支上创建文件
[root@git data]# git checkout testing
Switched to branch 'testing'
[root@git data]# ll
total 4
-rw-r--r-- 1 root root 10 Aug 25 16:11 a.txt
-rw-r--r-- 1 root root 0 Aug 25 15:45 master-eee
-rw-r--r-- 1 root root 0 Aug 25 15:37 test-ddd
[root@git data]# echo "testing" >>aaa
[root@git data]# git add .
[root@git data]# git commit -m "testing"
[testing 9b6e234] testing
1 file changed, 1 insertion(+)
create mode 100644 aaa
[root@git data]#
解决冲突合并
[root@git data]# git merge testing
Auto-merging aaa
CONFLICT (add/add): Merge conflict in aaa
Automatic merge failed; fix conflicts and then commit the result.
[root@git data]# git branch
* master
testing
[root@git data]# git status
# On branch master
# You have unmerged paths.
# (fix conflicts and run "git commit")
#
# Unmerged paths:
# (use "git add <file>..." to mark resolution)
#
# both added: aaa
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@git data]# cat aaa
<<<<<<< HEAD
master
=======
testing
>>>>>>> testing
[root@git data]# vim aaa
master
testing
[root@git data]# git commit -am "merge testing"
[master 8b338fa] merge testing
git标签使用
标签也是指向一次commit提交,是一个里程碑式的标签,回滚打标签直接加标签号,不需要加唯一字符串
指定标签
[root@git data]# git tag -a v1.0 -m "tag v1.0 add index"
指定某一次的提交为标签
[root@git data]# git tag -a v1.0 62cf747 -m "tag v1.0 add index"
查看v1.0的信息
[root@git data]# git show v1.0
tag v1.0
Tagger: opesn <opesn@qq.com>
Date: Sun Aug 25 16:49:09 2019 +0800
tag v1.0 add index
commit 62cf7473077b4a17b5acbe262d45b601f0284f23
Author: opesn <opesn@qq.com>
Date: Sun Aug 25 14:06:56 2019 +0800
add index
diff --git a/a.txt b/a.txt
index e69de29..9015a7a 100644
--- a/a.txt
+++ b/a.txt
@@ -0,0 +1 @@
+index
[root@git data]#
直接还原数据到v1.0
[root@git data]# git reset --hard v1.0
HEAD is now at 62cf747 add index
[root@git data]# ll
total 4
-rw-r--r-- 1 root root 6 Aug 25 16:49 a.txt
[root@git data]#
查看标签
[root@git data]# git tag
v1.0
[root@git data]#
删除标签
[root@git data]# git tag -d v1.0
Deleted tag 'v1.0' (was dfb0687)
[root@git data]#
Gitlab私有仓库
Gilab介绍
GitLab是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务。
可通过web界面进行访问公开的或者私人项目。它拥有与github类似的功能,能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库。团队成员可以利用内置的简单聊天工具(wall)进行交流。它还提供了一个代码片段收集功能可以轻松实现代码复用。
国内镜像站:https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/
Gitlab安装
[root@git ~]# yum install -y curl policycoreutils-python openssh-server
[root@git ~]# rpm -Uvh https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-10.2.2-ce.0.el7.x86_64.rpm
[root@git ~]# grep '^[a-Z]' /etc/gitlab/gitlab.rb
external_url 'http://10.0.1.90'
[root@git ~]#
#更改配置文件后需重新配置
[root@git ~]# gitlab-ctl reconfigure
#查看状态
[root@git ~]# gitlab-ctl status
run: gitaly: (pid 6446) 96s; run: log: (pid 5945) 511s
run: gitlab-monitor: (pid 6484) 83s; run: log: (pid 6009) 479s
run: gitlab-workhorse: (pid 6431) 98s; run: log: (pid 5900) 529s
run: logrotate: (pid 5929) 522s; run: log: (pid 5928) 522s
run: nginx: (pid 5907) 528s; run: log: (pid 5906) 528s
run: node-exporter: (pid 5987) 490s; run: log: (pid 5986) 490s
run: postgres-exporter: (pid 6509) 79s; run: log: (pid 6197) 296s
run: postgresql: (pid 5679) 618s; run: log: (pid 5678) 618s
run: prometheus: (pid 6495) 80s; run: log: (pid 6093) 386s
run: redis: (pid 5619) 624s; run: log: (pid 5618) 624s
run: redis-exporter: (pid 6034) 415s; run: log: (pid 6033) 415s
run: sidekiq: (pid 5884) 536s; run: log: (pid 5883) 536s
run: unicorn: (pid 5845) 542s; run: log: (pid 5844) 542s
[root@git ~]#
#gitlab目录介绍
/opt/gitlab #gitlab的程序安装目录
/var/opt/gitlab #gitlab的数据目录
/var/opt/gitlab/git-data #存放仓库数据
#gitlab状态信息
gitlab-ctl status #查看目前gitlab所有服务运行状态
gitlab-ctl stop #停止gitlab服务
gitlab-ctl stop nginx #单独停止某个服务
gitlab-ctl start #启动gitlab服务
gitlab-ctl start nginx #单独启动某个服务
gitlab-ctl tail #查看所有服务的日志
#gitlab服务构成
nginx: 静态web服务器
gitlab‐workhorse: 轻量级的反向代理服务器
logrotate:日志文件管理工具
postgresql:数据库
redis:缓存数据库
sidekiq:用于在后台执行队列任务(异步执行)。(Ruby)
unicorn:An HTTP server for Rack applications,GitLab Rails应用是托管在这个服务器上面的。(Ruby
Web Server,主要使用Ruby编写)
浏览器访问
浏览器输入:10.0.1.90
gitlab创建组
创建项目
设置SSH-key并推送代码
[root@git ~]# ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/root/.ssh/id_dsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_dsa.
Your public key has been saved in /root/.ssh/id_dsa.pub.
The key fingerprint is:
SHA256:9Op8uJegbn2ifcaZlqrTt+Iv38Kc2wQMGlToHrB9HjU root@git
The key's randomart image is:
+---[DSA 1024]----+
| .o. |
| ... E |
| =. o. . |
| . ++o+ |
| ..+S.+ |
| . o. . |
| +.* *. |
| ++B ^+ |
| o+=B^=+o |
+----[SHA256]-----+
[root@git ~]#
[root@git ~]#
[root@git ~]# cd /data/
[root@git data]# git remote add origin git@10.0.1.90:test/git_data.git
[root@git data]# git push -u origin master
The authenticity of host '10.0.1.90 (10.0.1.90)' can't be established.
ECDSA key fingerprint is SHA256:rX2R8bNZhcpCdMhgq4ysrM7jJ1W/0wsI/WEQrIbMhVA.
ECDSA key fingerprint is MD5:77:70:5f:63:fb:63:13:09:b2:77:3e:79:0f:66:90:f8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.0.1.90' (ECDSA) to the list of known hosts.
Counting objects: 55, done.
Compressing objects: 100% (44/44), done.
Writing objects: 100% (55/55), 5.12 KiB | 0 bytes/s, done.
Total 55 (delta 11), reused 0 (delta 0)
To git@10.0.1.90:test/git_data.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
[root@git data]#