SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。互联网上很多版本控制服务已从 CVS 迁移到 Subversion。说得简单一点 SVN 就是用于多个人共同开发同一个项目,共用资源的目的。
集中式管理的工作流程如下图:
集中式代码管理的核心是服务器,所有开发者在开始新一天的工作之前必须从服务器获取代码,然后开发,最后解决冲突,提交。
所有的版本信息都放在服务器上。如果脱离了服务器,开发者基本上可以说是无法工作的。下面举例说明: 开始新一天的工作:
1 从服务器下载项目组最新代码。
2 进入自己的分支,进行工作,每隔一个小时向服务器自己的分支提交一次代码(很多人都有这个习惯。因为有时候自己对代码改来改去,最后又想还原到前一个小时的版本,或者看看前一个小时自己修改了哪些代码,就需要这样做了)。
3 下班时间快到了,把自己的分支合并到服务器主分支上,一天的工作完成,并反映给服务器。 这就是经典的 svn 工作流程,从流程上看,有不少缺点,但也有优点。
下载地址:服务端 https://www.visualsvn.com/server/download/
客户端 https://www.visualsvn.com/visualsvn/download/tortoisesvn/
软件安装
一个项目组一般使用一个 svn 服务端,通常选择安装路径和仓库位置,端口一般使用默认端口,权限认证方式采用 svn 默认方式。
每个开发人员都需要安装 svn 客户端。安装完成后鼠标右键就会多出几个菜单。
点击 checkout(检出,get),第一次需要代码仓库的地址和服务分配的账号密码验证。验证通过后即可使用 update 与 commit 分别完成代码的拉取和提交。注意:在提交前先获取最新代码。
在 maven 项目开发中,.idea、target、*.iml 是不需要提交的,一旦提交会导致项目出错。一般通过设置让 svn 不提交该文件或文件夹。
在实际开发中,每个程序员负责自己的开发模块,一般不会同时修改一个类文件。如果两个开发人员修改了同一行代码,svn 服务器无法合并时会生成 3 个文件,分别代表最新没有冲突版本、你的版本和对方版本。此时需要仔细检查代码冲突部分,改正后将多生成的三个文件删除后才能提交。
Git 是目前世界上最先进的分布式版本控制系统(没有之一)。
历史:很多人都知道,Linus 在 1991 年创建了开源的 Linux,从此,Linux 系统不断发展,已经成为最大的服务器系统软件了。 Linus 虽然创建了 Linux,但 Linux 的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为 Linux 编写代码,那 Linux 的代码是如何管理的呢? 事实是,在 2002 年以前,世界各地的志愿者把源代码文件通过 diff 的方式发给 Linus,然后由 Linus 本人通过手工方式合并代码! 你也许会想,为什么 Linus 不把 Linux 代码放到版本控制系统里呢?不是有 CVS、SVN 这些免费的版本控制系统吗?因为 Linus 坚定地反对 CVS 和 SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。有一些商用的版本控制系统,虽然比 CVS、SVN 好用,但那是付费的,和 Linux 的开源精神不符。 不过,到了 2002 年,Linux 系统已经发展了十年了,代码库之大让 Linus 很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是 Linus 选择了一个商业的版本控制系统 BitKeeper,BitKeeper 的东家 BitMover 公司出于人道主义精神,授权 Linux 社区免费使用这个版本控制系统。 安定团结的大好局面在 2005 年就被打破了,原因是 Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发 Samba 的 Andrew 试图破解 BitKeeper 的协议(这么干的其实也不只他一个),被 BitMover 公司发现了(监控工作做得不错!),于是BitMover公司怒了,要收回 Linux 社区的免费使用权。 Linus 可以向 BitMover 公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的: Linus 花了两周时间自己用 C 写了一个分布式版本控制系统,这就是 Git!一个月之内,Linux 系统的源码已经由 Git 管理了!牛是怎么定义的呢?大家可以体会一下。 Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供 Git 存储,无数开源项目开始迁移至 GitHub,包括 jQuery,PHP,Ruby 等等。 历史就是这么偶然,如果不是当年 BitMover 公司威胁 Linux 社区,可能现在我们就没有免费而超级好用的 Git 了。
Git 安装
在 Windows 上使用 Git,可以从 Git 官网直接下载安装程序,然后按默认选项安装即可。
安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明 Git 安装成功!
版本库
什么是版本库呢?版本库又名仓库,英文名 repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被 Git 管理起来,每个文件的修改、删除,Git 都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
所以,创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录作为版本库:
第二步,通过 git init 命令把这个目录变成 Git 可以管理的仓库:
$ git init
Initialized empty Git repository in /Users/michael/learngit/.git/
瞬间 Git 就把仓库建好了,而且告诉你是一个空的仓库(empty Git repository),细心的读者可以发现当前目录下多了一个 .git 的目录,这个目录是 Git 来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把 Git 仓库给破坏了,下面是.git 的目录结构。
hooks 目录包含客户端或服务端的钩子脚本;
info 包含一个全局性排除文件
logs 保存日志信息 objects 目录存储所有数据内容;
refs 目录存储指向数据的提交对象的指针(分支)
config 文件包含项目特有的配置选项
description 用来显示对仓库的描述信息 HEAD 文件指示目前被检出的分支
index 文件保存暂存区信息
也不一定必须在空目录下创建 Git 仓库,选择一个已经有东西的目录也是可以的。不过,不建议你使用自己正在开发的公司项目来学习Git,否则造成的一切后果概不负责。
首先这里再明确一下,所有的版本控制系统,其实只能跟踪文本文件的改动,比如 TXT 文件,网页,所有的程序代码等等,Git 也不例外。
版本控制系统可以告诉你每次的改动,比如在第 5 行加了一个单词“Linux”,在第8行删了一个单词“Windows”。
而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。
不幸的是,Microsoft 的 Word 格式是二进制格式,因此,版本控制系统是没法跟踪 Word 文件的改动的,如果要真正使用版本控制系统,就要以纯文本方式编写文件。 因为文本是有编码的,比如中文有常用的 GBK 编码,日文有 Shift_JIS 编码,如果没有历史遗留问题,强烈建议使用标准的 UTF-8 编码,所有语言使用同一种编码,既没有冲突,又被所有平台所支持。
在版本库中创建文件,现在我们编写一个 readme.txt 文件,内容如下:
Git 是一个分布式版本控制系统。
Git 是一个开源软件。
把一个文件放到 Git 仓库只需要两步。
第一步,用命令 git add 告诉 Git,把文件添加到仓库:
$ git add readme.txt
执行上面的命令,没有任何显示,这就对了,Unix 的哲学是“没有消息就是好消息”,说明添加成功。
用命令 git commit 告诉 Git,把文件提交到仓库:
$ git commit -m "创建一个文件"
[master (root-commit) eaadf4e] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
简单解释一下 git commit 命令,-m 后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。 嫌麻烦不想输入-m "xxx"行不行?确实有办法可以这么干,但是强烈不建议你这么干,因为输入说明对自己对别人阅读都很重要。 git commit 命令执行成功后会告诉你:
1 file changed:1个文件被改动(我们新添加的 readme.txt 文件);
2 insertions:插入了两行内容(readme.txt 有两行内容)。
为什么 Git 添加文件需要 add,commit 一共两步呢?因为 commit 可以一次提交很多文件,所以你可以多次 add 不同的文件,
比如:
$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "添加3个文件"
如果你想全部添加,可以用
$ git add .
我们已经成功地添加并提交了一个 readme.txt 文件,现在,是时候继续工作了,于是,我们继续修改 readme.txt 文件。
现在,运行 git status 命令看看结果:
$ git status
On branch master
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")</file></file>
git status 命令可以让我们时刻掌握仓库当前的状态,上面的命令输出告诉我们,readme.txt 被修改过了,但还没有准备提交的修改。 虽然 Git 告诉我们readme.txt 被修改了,但如果能看看具体修改了什么内容,自然是很好的。比如你休假两周从国外回来,第一天上班时,已经记不清上次怎么修改的readme.txt,所以,需要用 git diff 这个命令看看:
$ git diff readme.txt
diff --git a/readme.txt b/readme.txt
index ce02b3e..9292a97 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,3 @@
Git 是一个分布式版本控制系统。
-Git 是一个开源软件。
\ No newline at end of file
+Git 是一个开源软件。
+Git 真心不错。
\ No newline at end of file
git diff 顾名思义就是查看 difference,显示的格式正是 Unix 通用的 diff 格式,可以从上面的命令输出看到,我们在第一行添加了一个 distributed 单词。 知道了对 readme.txt 作了什么修改后,再把它提交到仓库就放心多了,提交修改和提交新文件是一样的两步
第一步是 git add:
$ git add readme.txt
同样没有任何输出。在执行第二步 git commit 之前,我们再运行 git status 看看当前仓库的状态:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
modified: readme.txt</file>
git status 告诉我们,将要被提交的修改包括 readme.txt,下一步,就可以放心地提交了:
$ git commit -m "add distributed"
[master e475afc] add distributed
1 file changed, 1 insertion(+), 1 deletion(-)
提交后,我们再用 git status 命令看看仓库的当前状态:
$ git status
On branch master
nothing to commit, working tree clean
Git 告诉我们当前没有需要提交的修改,而且,工作目录是干净(working tree clean)的。
版本回退:现在,你已经学会了修改文件,然后把修改提交到 Git 版本库,现在,再练习一次,修改 readme.txt 文件然后尝试提交:
$ git add readme.txt
$ git commit -m "append GPL"
[master 1094adb] append GPL
1 file changed, 1 insertion(+), 1 deletion(-)
像这样,你不断对文件进行修改,然后不断提交修改到版本库里,就好比玩 RPG 游戏时,每通过一关就会自动把游戏状态存盘,如果某一关没过去,你还可以选择读取前一关的状态。有些时候,在打 Boss 之前,你会手动存盘,以便万一打 Boss 失败了,可以从最近的地方重新开始。Git 也是一样,每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在 Git 中被称为 commit。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失。
当然了,在实际工作中,我们脑子里怎么可能记得一个几千行的文件每次都改了什么内容,不然要版本控制系统干什么。版本控制系统肯定有某个命令可以告诉我们历史记录,在 Git 中,我们用 git log 命令查看:
$ git log
commit 81d50675a23756aa9dc8722fae288f697c95b38d (HEAD -> master)
Author: 愿化身石桥 <1533481985@qq.com>
Date: Tue Aug 17 14:58:31 2021 +0800
再最后修改一次
commit 0fee93644f066ebdb918c0583bf890435a88c216
Author: 愿化身石桥 <1533481985@qq.com>
Date: Tue Aug 17 14:53:20 2021 +0800
第二次提交
commit 808751cb89b84a8be945ee3750d34119a4b928f7
Author: 愿化身石桥 <1533481985@qq.com>
Date: Tue Aug 17 14:51:30 2021 +0800
第一次提交
git log 命令显示从最近到最远的提交日志,我们可以看到 3 次提交。如果嫌输出信息太多,看得眼花缭乱的,可以试试加上–pretty=oneline 参数:
$ git log --pretty=oneline
81d50675a23756aa9dc8722fae288f697c95b38d (HEAD -> master) 再最后修改一次
0fee93644f066ebdb918c0583bf890435a88c216 第二次提交
808751cb89b84a8be945ee3750d34119a4b928f7 第一次提交
需要友情提示的是,你看到的一大串类似 1094adb…的是 commit id(版本号),和 SVN 不一样,Git 的 commit id 不是 1,2,3……递增的数字,而是一个SHA1 计算出来的一个非常大的数字,用十六进制表示,而且你看到的 commit id 和我的肯定不一样,以你自己的为准。为什么 commit id 需要用这么一大串数字表示呢?因为 Git 是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用 1,2,3……作为版本号,那肯定就冲突了。
首先,Git 必须知道当前版本是哪个版本,在 Git 中,用 HEAD 表示当前版本,也就是最新的提交 1094adb…(注意我的提交 ID 和你的肯定不一样),
上一个版本就是 HEAD^,上上一个版本就是 HEAD^^,当然往上 100 个版本写 100 个^比较容易数不过来,所以写成 HEAD~100。
现在,我们要把当前版本 append GPL 回退到上一个版本 add distributed,就可以使用 git reset 命令:
$ git reset --hard HEAD^
HEAD is now at e475afc add distributed
文件果然被还原了!还可以继续回退到上一个版本,不过我们用 git log 再看看现在版本库的状态。最新的那个版本已经看不到了!好比你从 21 世纪坐时光穿梭机来到了 19 世纪,想再回去已经回不去了,怎么办? 办法其实还是有的,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个 commit id 是 1094adb…,于是就可以指定回到未来的某个版本:
$ git reset --hard 1094a
HEAD is now at 83b0afe append GPL
版本号没必要写全,前几位就可以了,Git 会自动去找。当然也不能只写前一两位,因为 Git 可能会找到多个版本号,就无法确定是哪一个了。
如果实在找不到版本号还是想回去怎么办?Git 提供了一个命令 git reflog 用来记录你的每一次命令,日志的前半截就是版本号
$ git reflog
e475afc HEAD@{1}: reset: moving to HEAD^
1094adb (HEAD -> master) HEAD@{2}: commit: append GPL
e475afc HEAD@{3}: commit: add distributed
eaadf4e HEAD@{4}: commit (initial): wrote a readme file
自然,你是不会犯错的。不过现在是凌晨两点,你正在赶一份工作报告,你在 readme.txt 中添加了一行:在你准备提交前,一杯咖啡起了作用,你猛然发现了stupid boss 可能会让你丢掉这个月的奖金! 既然错误发现得很及时,就可以很容易地纠正它。你可以删掉最后一行,手动把文件恢复到上一个版本的状态。如果用 git status 查看一下:
$ git status
On branch master
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")</file></file>
你可以发现,Git 会告诉你,git checkout – file 可以丢弃工作区的修改:
$ git checkout -- readme.txt
命令 git checkout – readme.txt 意思就是,把 readme.txt 文件在工作区的修改全部撤销,这里有两种情况:
一种是 readme.txt 自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是 readme.txt 已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次 git commit 或 git add 时的状态。 现在,文件内容果然复原了。 git checkout – file 命令中的–很重要,没有–,就变成了“切换到另一个分支”的命令,我们在后面的分支管理中会再次遇到 git checkout 命令。
线上一般有服务端完成版本记录,github、码云、gitlab 都遵循 git 的语法,提供 git 的服务。
首先我们需要在第三方平台上注册账号并创建仓库。创建完成后会得到仓库的地址:https://gitee.com/wpfhhh_admin/gittest.git
得到地址后使用 idea 将其克隆下来(克隆之前需要让 idea 识别到 git.exe 的安装位置)
对于修改或添加的文件本地常见的两种操作可以通过可视化界面完成。
最后需要推送到线上服务器使用 push 操作。
centos7 安装部署 gitlab 服务端。
1.安装依赖软件
yum -y install policycoreutils openssh-server openssh-clients postfix
2.设置 postfix 开机自启,并启动,postfix 支持 gitlab 发信功能
systemctl enable postfix && systemctl start postfix
3.下载 gitlab 安装包,然后安装
下载 rpm 包并安装:
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-8.0.0-ce.0.el7.x86_64.rpm
rpm -i gitlab-ce-8.0.0-ce.0.el7.x86_64.rpm
git 默认使用 80 端口,如果该端口需要修改端口如下
vim /etc/gitlab/gitlab.rb
external_url 'http://localhost:8089'
重置并启动 GitLab
执行以下命令
gitlab-ctl reconfigure
gitlab-ctl restart