SVN 与 Git

这篇具有很好参考价值的文章主要介绍了SVN 与 Git。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、SVN 简介和服务端安装

  SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。互联网上很多版本控制服务已从 CVS 迁移到 Subversion。说得简单一点 SVN 就是用于多个人共同开发同一个项目,共用资源的目的。

集中式管理的工作流程如下图:
SVN 与 Git
  集中式代码管理的核心是服务器,所有开发者在开始新一天的工作之前必须从服务器获取代码,然后开发,最后解决冲突,提交。

  所有的版本信息都放在服务器上。如果脱离了服务器,开发者基本上可以说是无法工作的。下面举例说明: 开始新一天的工作:

  1 从服务器下载项目组最新代码。
  2 进入自己的分支,进行工作,每隔一个小时向服务器自己的分支提交一次代码(很多人都有这个习惯。因为有时候自己对代码改来改去,最后又想还原到前一个小时的版本,或者看看前一个小时自己修改了哪些代码,就需要这样做了)。
  3 下班时间快到了,把自己的分支合并到服务器主分支上,一天的工作完成,并反映给服务器。 这就是经典的 svn 工作流程,从流程上看,有不少缺点,但也有优点。

  下载地址:服务端 https://www.visualsvn.com/server/download/
     客户端 https://www.visualsvn.com/visualsvn/download/tortoisesvn/
软件安装

  一个项目组一般使用一个 svn 服务端,通常选择安装路径和仓库位置,端口一般使用默认端口,权限认证方式采用 svn 默认方式。
SVN 与 Git

二、SVN 客户端安装

  每个开发人员都需要安装 svn 客户端。安装完成后鼠标右键就会多出几个菜单。
SVN 与 Git
  点击 checkout(检出,get),第一次需要代码仓库的地址和服务分配的账号密码验证。验证通过后即可使用 update 与 commit 分别完成代码的拉取和提交。注意:在提交前先获取最新代码。

  在 maven 项目开发中,.idea、target、*.iml 是不需要提交的,一旦提交会导致项目出错。一般通过设置让 svn 不提交该文件或文件夹。

SVN 与 Git

三、SVN 版本管理

  在实际开发中,每个程序员负责自己的开发模块,一般不会同时修改一个类文件。如果两个开发人员修改了同一行代码,svn 服务器无法合并时会生成 3 个文件,分别代表最新没有冲突版本、你的版本和对方版本。此时需要仔细检查代码冲突部分,改正后将多生成的三个文件删除后才能提交。

四、GIT 简介和安装

  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 安装成功!
SVN 与 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,否则造成的一切后果概不负责。

五、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 .

六、GIT 本地版本管理

  我们已经成功地添加并提交了一个 readme.txt 文件,现在,是时候继续工作了,于是,我们继续修改 readme.txt 文件。

  现在,运行 git status 命令看看结果:

$ 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:   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 <file>..." 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 <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")</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 命令。

七、GIT 线上版本管理

  线上一般有服务端完成版本记录,github、码云、gitlab 都遵循 git 的语法,提供 git 的服务。

  首先我们需要在第三方平台上注册账号并创建仓库。创建完成后会得到仓库的地址:https://gitee.com/wpfhhh_admin/gittest.git

SVN 与 Git
  得到地址后使用 idea 将其克隆下来(克隆之前需要让 idea 识别到 git.exe 的安装位置)
SVN 与 Git
  对于修改或添加的文件本地常见的两种操作可以通过可视化界面完成。
SVN 与 Git
  最后需要推送到线上服务器使用 push 操作。
SVN 与 Git

八、安装私有 GIT 服务端(自)

  centos7 安装部署 gitlab 服务端。

  1.安装依赖软件

yum -y install policycoreutils openssh-server openssh-clients postfix

  2.设置 postfix 开机自启,并启动,postfix 支持 gitlab 发信功能

systemctl enable postfix &amp;&amp; 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

  执行以下命令文章来源地址https://www.toymoban.com/news/detail-438912.html

gitlab-ctl reconfigure
gitlab-ctl restart

到了这里,关于SVN 与 Git的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 将本地项目上传到svn服务端和git

    一、SVN 1.创建svn库,下面生成了三个文件夹,branches指分支,trunk下可以放项目 2.在本地checkout,填入svn库的地址,因为是新建的,所以checkout的是空文件夹 把自己的项目复制到trunk下,在项目上 右键-TortoiseSVN-add add完之后 右键-svn commit 3.idea打开这个项目,将项目跟svn关联起来 (1)File-sett

    2024年02月22日
    浏览(51)
  • 安装 SVN 中文语言包和 Git

    SVN 中文语言包安装: Subversion(简称 SVN)是一个开源版本控制系统,用于协助开发团队管理和跟踪文件的变化。默认情况下,SVN 使用英文界面,但你也可以安装中文语言包以获得更适合中文用户的界面。下面是安装 SVN 中文语言包的步骤: 下载语言包:首先,你需要从 Sub

    2024年02月05日
    浏览(38)
  • 【docker】部署svn服务器,docker安装部署svn服务器

    话不多说直接上步骤! 以上代码中,在容器中的/home/svn/test目录创建代码仓库,会同步到本机的/var/svn目录。我们先进行svn仓库配置。 SVN库中的配置目录 conf 有三个文件: 配置权限配置文件 authz 编辑 authz ,内容参考如下: 配置账号密码文件 passwd 编辑 passwd ,内容参考如下:

    2024年02月02日
    浏览(56)
  • 【云原生技术】云计算与网络:弹性伸缩(Auto Scaling,简称AS)简介

    弹性伸缩(Auto Scaling,简称AS)是云计算中一项重要的功能,它使得云基础设施能够根据负载的变化自动调整资源。这不仅提高了资源利用效率,还有助于优化成本和提供更稳定的服务。以下是关于弹性伸缩的详细介绍: 定义和目的 弹性伸缩是一种自动化机制,它根据预设的

    2024年02月02日
    浏览(56)
  • Git的安装和常用命令&Git与SVN的区别&Gitee远程仓库团队开发代码共享演示

    目录 一、Git入门 1.1 Git简介 1.2 Git与SVN的区别 1.2.1 详解 1.2.2 图解  1.3 Git相较于SVN的优势与劣势 1.3.1 Git的优势与劣势 1.3.2 SVN的优势与劣势 1.4 Git的工作流程 1.4.1 图解 1.4.2 详解 二、Git的安装以及常用命令 2.1 Git官网链接 2.2 安装步骤 2.3 Git的常用命令 2.3.1  常用命令概览 2.4 使

    2024年02月03日
    浏览(53)
  • Linux CentOS 8 编译安装Apache Subversion

    距离上一篇发表已经过去了5年零2个多月,这次重新开始写技术博客,理由和原来一样,也就是想把自己学习和工作中遇到的问题和知识记录下来,今天记录一下Linux CentOS 8通过编译安装 svn 的过程。 下载地址:链接: https://subversion.apache.org/download.cgi 进入下载页面后,我们可以

    2024年02月15日
    浏览(56)
  • SVN下载安装(服务器与客户端)

    svn全称SubVersion,支持windows,linux, mac。分为服务器与客户端。 服务器下载:Download | VisualSVN Server 客户端下载:自行查找 双击执行  运行  下一步 同意下一步  下一步 选中安装目录   下载地址:http://tortoisesvn.net/downloads 双击执行  下一步           文件夹右键     

    2024年02月03日
    浏览(58)
  • 【SVN】windows SVN安装使用教程(服务器4.3.4版本/客户端1.11.0版本)

    介绍 这里是小编成长之路的历程,也是小编的学习之路。希望和各位大佬们一起成长! 以下为小编最喜欢的两句话: 要有最朴素的生活和最遥远的梦想,即使明天天寒地冻,山高水远,路远马亡。 一个人为什么要努力? 我见过最好的答案就是:因为我喜欢的东西都很贵,

    2024年02月08日
    浏览(91)
  • python flask生成被控服务端 开放接口 可以调用本地程序启动D盘的app.py文件,并生成一个前端文件,有一个启动按钮

    要创建一个使用 Flask 的被控服务端,开放接口以调用本地程序并启动 D 盘的  app.py  文件,以及生成一个带有启动按钮的前端文件,你需要做以下几个步骤: 设置 Flask 服务端 :创建一个 Flask 应用,并定义一个 API 接口来接收请求。 执行本地程序 :在 Flask 应用中,使用 

    2024年04月15日
    浏览(56)
  • CuteHttpFileServer(简称chfs)本地文件共享服务器搭建笔记

    一、chfs简介(摘自开发者网站) CuteHttpFileServer/chfs是一个免费的、HTTP协议的文件共享服务器,使用浏览器可以快速访问。它具有以下特点: 单个文件,核心功能无需其他文件 跨平台运行,支持主流平台:Windows,Linux和Mac 界面简洁,简单易用 支持扫码下载和手机端访问,手

    2024年02月04日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包