购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.5 小说代码管理

安抚一下冲冲受伤的心灵,MOL又开始借题发挥了。

MOL:亲爱的同学们,你们写代码的时候一定要经常用Ctrl+S命令保存一下代码,就算下一秒是世界末日,也要把你的劳动成果保存下来。

冲冲:有一次,我的计算机丢了,心疼死了。倒不是心疼计算机,而是心疼里面的好多学习资料。

鹏辉:得了吧,你是心疼你那好几百GB的“学习资料吧”。

刘朋:瞎说啥实话。你把这些资料备份到网盘上不就得了?

冲冲:瞧你们一个个龌龌龊龊的样子,我的学习资料都是编程代码神马的。我还遇到一个问题,就是我在公司写的代码,如果要拿到家里看的话,就需要用U盘拷回家,或者用邮箱存储起来,这样拷贝非常不方便,并且很容易有错拷、漏拷的现象,想想还是有点小纠结的。如果有一个软件,可以记录我每次修改的时间和修改的内容,那就非常happy了。

MOL:世界上不缺乏美,而是缺少发现美的眼睛。你刚才说的这种软件很多,MOL接下来给大家展示一下这些软件。

2.5.1 什么是代码管理软件

MOL刚接触开发的时候,每天都要写大量的代码,当然就会遇到各种各样的情况,MOL简单说几个小场景。

1. 场景一

MOL:老板,登录的功能写完了,代码是这样的

01  //登录方法 
02  public ActionResult Login() 
03  { 
04  //用户输入的用户名 
05  string userName=Request["user"]; 
06  //用户输入的密码 
07  string passWord=Request["pwd"]; 
08  //查询用户是否存在的SQL语句 
09  string sql=String.Format("select count(1) from t_user_TB where
    username={0} and passWord={1}",userName,passWord); 
10  //定义一个数据集用来存放查询结果 
11  DataSet ds=new DataSet(); 
12  //开始在数据库中查询 
13  using(SqlConnection con=new SqlConnection("SQL连接字符串")) 
14  { 
15      SqlDataAdatper ada=new SqlDataAdatper(sql,con);     
16      ada.Fill(ds); 
17  } 
18  if(ds.Tables.Count<1||ds.Tables[0].Rows.Count<1) 
19  { 
20      //没有查询到合法的用户 跳转到登录页面 
21      Redirect(@"/Login/Index"); 
22  } 
23  else 
24  { 
25      //用户输入的用户名和密码在数据库中存在,跳转到主页 
26      Redirect(@"/Main/Index"); 
27  } 
28  } 

老板:写得很快嘛。但是(领导发言,一般都是有“但是”的),我们不能仅仅只有用户名和密码,我们还需要有手机号、邮箱……来作为用户名。

MOL:明白,稍等片刻,我改改就来。

一分钟后……

MOL:老板,只需要把SQL语句改一下就可以了。修改后的SQL语句如下:

//查询用户是否存在的SQL 语句
string sql=String.Format("select count(1) from t_user_TB where (username=
{0} or phone={0} or mail={0}) and passWord={1}",userName,passWord);

老板:不错,那我们登录界面上是不是应该还会有“记住我”的功能啊。

MOL:明白,那就在登录成功以后,把用户信息写入到cookie中。代码如下:

//登录成功以后
//把用户名写入cookie
Response.Cookie["user"]=userName;
//把密码写入cookie
Response.Cookie["pwd"]=passWord;

老板:cookie是保存在客户端的,那我们怎么能把明文密码保存在客户端呢?这样是非常危险的。

MOL:明白……

一个小时后……

MOL:没想到一个简单的登录功能还有这么多名堂。

老板:这个登录功能做完了,做一下总结吧,从最开始写的代码开始梳理。

MOL脸上出现了一个大写的“懵”, 我也记不住我都改了多少啊,没用的代码我都删除掉了……

2. 场景二

MOL开发完登录功能了,MOL的同事(暂且叫他Jack)的注册功能也开发完了。我们需要把这两个功能合并到项目中,于是……

MOL:Jack,把你写的注册功能的代码发给我,我要合并到我的代码中。

Jack:好嘞。

没过一会,MOL就把注册功能合并到了自己的代码中,按F5键运行,走你!

MOL:Jack,你怎么也写了一个Login()函数?这和我的代码冲突了啊。

Jack:我写的Login()函数是用来登录数据库的,并不是用户的登录。

MOL脸上出现了一个大写的“懵”,我把Jack写的函数改成Login2()?

3. 场景三

老板:这个订单浏览的功能是谁写的?出Bug了,快去处理一下。

MOL:Jack写的吧,我没有写过这个系统的订单功能。

Jack:MOL,肯定是你写的,你上次还问我怎么清空缓存来着,你忘了?

MOL脸上出现了一个大写的“懵”, 到底是谁写的代码呢?

4. 场景四

相信大家都会有这样的体会,在公司写程序时没有写完,就拷贝回家接着写,第二天再带到公司覆盖昨天未完成的代码。或者是我们在写代码的时候,总会被这样或那样的事情打断,比如老板让你去拖地,或者女朋友吵着要买包……

这样的次数多了以后,我们根本无法知道哪些代码是新增加的,哪些代码是什么时候为什么增加或删除的。这是一个非常头疼的事情。

那我们每行代码到底 是什么时候、为什么要写呢?

5. 场景五

我们做的系统上线了,大家还没来得及高兴,就被老板通知:新加的会员管理的功能不要了,赶紧从系统中删除。

MOL和Jack开始报怨了,要删除好多代码,一不小心删除错了还会影响其他的功能。

如何恢复到上一个可用的系统版本呢?

MOL抛出了这么多问题,就是为了引出“代码管理”,代码管理也叫版本管理,它的功能是管理文件的版本,这里说的“文件”可以是代码文件(如.CS、.ASPX等)也可以是Office文件(如Word、Excel等)。编写这些文件的人可能是一个或多个,那么代码管理软件也要对每个人的文件版本进行管理,还需要解决多个人修改同一个文件的冲突。通过代码管理,就可以很清晰地追溯到每一行代码是什么时间、哪个人、为什么写的;还可以知道哪些代码被删除了;如果有需求变更,可以很方便、快捷地恢复到以前的某个版本。

其实代码管理的好处还有很多,MOL在这里就不一一细说了。

常见的代码管理软件有TFS、SVN、Git、VSS、CSV……,其中,VSS和CSV属于“过气”的软件,所以本书中不会介绍它们。下面我们来看一下TFS、SVN、Git这几个软件。

2.5.2 TFS管理软件

TFS(Team Foundation Server)是.NET程序员最常用到的一个代码版本管理软件。TFS由服务端和客户端两部分组成,服务端一般是由公司的网管或者项目经理来搭建并管理,而程序员只需要使用客户端就可以了。TFS的客户端已经被集成到Visual Studio 2010以上的开发环境,在Office中也可以很方便地使用TFS,甚至在浏览器中输入TFS的地址,也可以进入TFS的管理界面,可以说TFS的使用已经非常方便。接下来,我们来看一下如何使用TFS客户端。

打开Visual Studio 2015(或者读者自己的Visual Studio),找到“团队资源管理器”,如果主界面上没有“团队资源管理器”,可以通过选择“视图→团队资源管理器”选项来显示,如图2-17所示。

图2-17 “团队资源管理器”界面

单击“团队资源管理器”中最上方的插销图标,然后单击“连接”按钮,打开连接TFS对话框,如图2-18所示。

图2-18 打开连接TFS对话框

单击对话框右上角的“服务器”按钮,在新弹出的对话框中单击“添加”按钮,并输入TFS服务器的地址(这个地址一般由项目经理或开发经理来提供),如图2-19所示。

图2-19 输入TFS服务地址

输入地址以后单击“确定”按钮,Visual Studio会提示需要输入对应的用户名和密码。完成这一切以后,再回到TFS的主对话框,可以在“团队项目集合”中选择要连接的项目,然后单击“连接”按钮,如图2-20所示。

图2-20 选择要连接的项目

在“团队资源管理器”中,选择“源控件资源管理器”选项,在主界面中选择要下载的项目,右击,在弹出的快捷菜单中选择“获取最新版本”命令,如图2-21所示。

图2-21 获取源码

经过上面的操作后,就可以在本地获取项目了。

在本地获取项目以后,可以对代码进行增加、修改、删除的操作。操作完成以后,可以把这些修改后的代码提交到TFS上。例如,新加了一个Elands.ChuanCard.UI.MVC的项目,那么就可以在这个项目上右击,然后在弹出的快捷菜单中选择“源代码管理”→“提交”命令。提交以后,其他人连接到TFS上后就可以获取项目了,如图2-22所示。

图2-22 提交代码

如果在家中,用家中的计算机连接到TFS上,也可以进行代码的修改和提交。这样是不是很方便呢?

如果一个文件被修改了很多次,那么怎样看出每次都是谁在什么时候为什么修改呢?很简单,找到要查看的文件,右击,在弹出的快捷菜单中选择“查看历史记录”命令,这些信息就会显示出来,如图2-23和图2-24所示。

图2-23 查看历史记录

图2-24 历史记录的详细信息

双击某个版本,可以看到这个版本的内容。选中两个版本,右击,选择右键快捷菜单中的“比较”命令,可以查看这两个版本中不同的内容,如图2-25所示。

图2-25 比较两个版本

选择某个版本,右击,然后在弹出的快捷菜单中选择“获取此版本”命令,可以获取到特定的版本。这样就可以实现版本回退的功能。

如果提交代码的时候,发现自己写的代码和其他人写的代码有冲突,TFS还提供了合并冲突的功能。

如此一来,TFS就可以解决前面描述的场景中遇到的问题。

PS:TFS服务端的安装步骤相对比较麻烦,但TFS客户端的使用确实是很简单。而且,如果不想安装TFS服务端的话,还可以使用微软提供的在线TFS,这样可以省去安装过程而直接使用,当然,它的获取速度和提交速度都是非常慢的。MOL在上文中演示的TFS就是微软提供的在线TFS。

2.5.3 SVN管理软件

TFS对于.NET开发来说,有着得天独厚的优势,因为它本身就是微软家族的一员,所以在Visual Studio中使用TFS来说是非常方便的。但TFS也有它的缺点。如果用PHP或者Python来开发项目,那么没必要再装一个TFS,如果是在Linux下开发的,那么TFS就不能发挥它的长处了。

鉴于此,MOL给大家推荐另一款代码管理软件,即SVN。

接下来讲会简单地说一下SVN的使用,而且比你想得要简单得多,因为在后面的章节中并不会用SVN去管理代码。

安装客户端的过程非常简单,从网上下载一个SVN客户端(别问MOL从哪里下载,从SVN官网或者通过搜索引擎都可以很轻松得得到客户端的安装包),然后直接选“下一步”→“下一步”……

安装完成以后,右击,你会发现右键快捷菜单中多了一些关于SVN的操作,如图2-26所示。

图2-26 右键快捷菜单中

SVN Checkout命令是用来获取代码的。如果知道代码的SVN路径,那么可以直接使用这个功能来获取。选择SVN Checkout命令后,在弹出的对话框中输入代码的SVN路径,然后一直单击“确定”按钮,就可以在当前目录获取代码了。

TortoiseSVN命令中包含了很多关于SVN的操作,如图2-27所示。

图2-27 TortoiseSVN命令下的各子命令

到此为止,SVN就介绍完了。如果大家有兴趣,可以自己搭建一个SVN练习一下。

PS:SVN还可以作为一个插件嵌入到Visual Studio中。

2.5.4 Git管理软件

TFS功能强大,但它只能依赖于微软自己的产品。

SVN不依赖于任何产品,任何操作系统,但它在.NET开发中的表现又没有TFS那么优秀。

正所谓鱼和熊掌不能兼得,但MOL就是这样一个不满足的人。有没有这样一种软件,既可以有TFS一样的表现,又不依赖任何产品?当然有啦,要不然MOL也不会说这么多了。下面就该GIT闪亮登场了。

TFS和SVN都属于集中版本控制系统,就是说代码是保存在服务器上的,开发时需要先从服务器上签出(check out俗称“获取”)操作,开发完成以后或阶段性完成之后,再进行签入(check in俗称“上传”)操作。签入和签出都是依赖网络的,不管是局域网还是Internet。我们设想这样一种情况:一个在TFS平台上开发的团队,进展非常顺利,有一天公司的路由器坏了,导致所有人的代码无法提交,领导无法查看所有人的进度,那么在路由器坏掉的这一段时间内,这个TFS平台上的项目是处于无法维护的状态。

Git是一个分布式的版本管理系统,它没有一个固定的代码服务器,每一台安装了Git的机器都是一个服务器。在英语中,Git表示“一个不开心的人”,翻译成中文也叫“二货”,这恐怕是Git的发明人——Linus Trovald当时自嘲的真实写照吧。这个GIT的发明人是不是听起来非常耳熟?没错,他就是Linux的发明人,所以在使用Git的时候,经常可以发现一些Linux的元素。

题外话:关于Linux

说到Linux,ML不得不提一下。很多.NET程序员是比较排斥Linux系统的,或者只会用一些Ubuntu上的图形界面,这是非常不好的心态。Linux的设计理念是非常强大的,如常见的文件系统,它在操作系统的底层并不像我们在Windows中看到的一个个的文件夹;如文件的管理权限并不是我们在Windows中见到的Administrator和Guester。如果你可以坚持使用Linux长达一个月的时间,那你将会明白很多你潜意识里觉得“是这样”的一些知识。

有人可能要说了,.NET程序员开发的时候肯定是用Visual Studio作为IDE(Interface Developer Enviorment)的,那在Linux上面就不能开发了啊。

相信很多程序员就是因为有这样的问题,才会抛弃Linux的。随便搜索一下,其实Linux下也是有很多优秀的开发平台,如Mono。如果你对程序开发的本质比较了解(涉及CLR和编译原理的知识),那么就会明白,所有的程序,其实就是一大堆文本文件,由编译器将它们转换成中间语言。既然程序是文件文件,那么完全可以用文本程序来编写代码。Windows下的记事本、Notepad++、EditPlus等都是非常优秀的软件。在Linux下,Vi(Visual Identity,简称Vi)是最强大的文本软件,没有之一。如图2-28所示为MOL用Vi写的一个HelloWorld程序。

图2-28 简单的Vi示例

它看起来非常像是Windows下面的CMD程序。但Vi要比你想像的强大得多。

Linux有着非常高的安全性的配置,而且Linux对硬件的要求并不高,可以很轻松地用一些低配的机器来搭建一个非常稳定的服务器集群。如果你家里还有一些奔腾时代的计算机,就让它们重新焕发活力吧。MOL没有多余的计算机,所以MOL的计算机上有好多个虚拟机上装了Linux,它们可以充当Web服务器(Apache、Nginx)、缓存服务器(Redis)、数据库服务器(MySQL、MongoDB)。每台服务器的配置都是单核CPU+256MB的内存,如图2-29所示。

图2-29 Linux虚拟机示例

好了,关于Linux的题外话就说到这里。希望大家不要只局限于微软的技术。世界很大,多看看总是好的。

接着来说Git。Git的安装步骤非常简单,主要分两大步(其实只需要第一步,为了让初学者更好地接受Git,MOL增加了关于TortoiseGit的描述)。第一步安装Git,安装包可以从搜索引擎上搜索,如果你懒得搜索,也可以下载MOL在本书配套资源中提供的“安装包/Git/Git_V2.5.1_64_bit_setup.1441791170.exe”进行安装。安装过程非常简单,一直选“下一步”就可以。安装完Git以后,进入第二步,第二步是安装Git的图形界面,找到安装包(可以从搜索引擎上搜索,也可以使用上述安装包目录下的TortoiseGit-1.8.16.0-64bit.msi和TortoiseGit-LanguagePack-1.8.16.0-64bit-zh_CN.msi。TortoiseGit-1.8.16.0-64bit.msi是图形界面的安装包,TortoiseGit-LanguagePack-1.8.16.0-64bit-zh_CN.msi是中文语言包的安装包。安装过程也是一直选“下一步”即可。由于安装过程太过简单,所以这里就直接略过了,相信大家都可以正确安装。

安装完成后,去开源中国或者Git Hub上注册一个账号,注册完成以后,可以得到一个免费的空间用来存放代码。这里以开源中国进行讲解。

开源中国关于Git的注册网址为 https://git.oschina.net/signup ,注册过程也比较简单,这里不再赘述。登录Git服务,登录地址为 https://git.oschina.net/login 。登录后的主界面上,会显示最近提交的项目、我的项目等,如图2-30所示。

图2-30 开源中国的Git主界面

单击主界面右上角的加号,然后选择“新建项目”,如图2-31所示。

图2-31 新建项目

然后填写自己项目的信息,填写完成以后单击“创建”按钮,就可以创建一个项目的Git服务了,如图2-32所示。

图2-32 填写项目信息

创建好以后,会展示项目的基本信息,找到页面右上角关于项目的服务地址并复制,如图2-33所示。

图2-33 复制Git地址

这个被复制的地址就描述了一个代码仓库,这个代码仓库是存放在开源中国的服务器上的,现在要把这个代码仓库中的代码(或其他的文件)“搬”到自己的计算机上。选择一个要存放代码的文件夹,右击这个文件夹,在弹出的快捷菜单中选择Git Clone命令,如图2-34所示。

图2-34 选择Git Clone命令

选择Git Clone命令以后,会弹出一个对话框,如图2-35所示。

图2-35 弹出的对话框

可以看到,Git还是比较智能的,它已经自动从剪贴板中取到了刚才复制的代码仓库的URL,所以我们不需要做其他的操作,直接确定即可。确定以后,代码就会被下载到指定的文件夹中,下载完成后,Git会有友好的提示,如图2-36所示,直接单击Close按钮关闭即可。

图2-36 下载完成的提示

关闭对话框以后,可以看到一个名为Git_Test_Project的文件夹已经存在了,这个文件夹名和代码仓库中的项目名称是一样的,如图2-37所示。

图2-37 下载得到的文件夹

鹏辉:这个文件夹有点怪怪的啊,图标上面绿色的勾是什么?

刘朋:我昨天在做练习的时候遇到过这个图标,就是我在下载完SVN管理的代码以后,也会出现这样一个图标。

MOL:非常好,我就喜欢你们这种没有见过世面的样子。

一个带有对勾的文件夹表示当前文件夹是与代码仓库中的内容是一样的。现在我们在这个文件夹中随便放一个文件add.txt,这个新加的add.txt文件的图标上面会加上一个问号,如图2-38所示。

图2-38 新增一个文件

这个带问号的图标表示是新加的文件,接下来在add.txt文件上右击,选择右键快捷菜单中的TortoiseGit→Add命令,并在弹出的对话框中一路单击OK按钮,如图2-39所示。

图2-39 添加文件到

操作完成后,add.txt的图标上面的问号就消失了,取而代之的是一个加号。这个加号表示add.txt文件已经加入到本地的Git项目中,但是还没有提交到Git代码库中。

在add.txt文件上右击,选择右键快捷菜单中的Git Commit→master命令,如图2-40所示。

图2-40 提交到本地库

在弹出的对话框中输入对当前操作的描述,并单击Commit按钮,如图2-41所示。

图2-41 提交更改

提交以后,会弹出一个新的对话框,该对话框会显示提交的进度,当然,本地提交是非常快的。进度完成后,关闭对话框即可。

PS:每次提交的时候,一定要写好当前提交的内容和目的,以便代码管理的时候进行查看。

根据提示可以猜测出,这个操作就是要提交更改,当然,事实也是如此。需要注意的是这里并没有提交到开源中国的代码仓库,而是提交到本地的代码仓库。这一步是不需要联网的,也就意味着如果断网了,提交操作是可以照常进行的。

这一步是特别需要注意的,用过TFS或SVN这样集中代码管理软件的程序员尤其要注意,这里的提交本质就是在本地做一个代码管理,这也是分布式代码管理软件的特点。每一个程序员的计算机都是一个代码仓库,只有在需要的时候,才会把本地代码仓库“推”到一个特定的代码仓库上(本书中特定的代码仓库默认是开源中国的代码仓库)。这个“推”字非常传神,它形象地表达了我们将本地代码库提交到特定代码库的目的和过程。那“推”是如何操作的呢?

在项目文件夹上右击,然后在右键快捷菜单中选择TortoiseGit→Push命令,如图2-42所示。

图2-42 推送第一步

在弹出的对话框中,直接单击OK按钮,然后再在弹出的对话框中输入用户名和密码,之后一直单击OK按钮就完成了“推”的操作,如图2-43所示。

图2-43 推送第二步

在图2-43中有两个地方需要注意一下,第一处是Local,表示当前提交项目的分支;第二处是Remote,表示目标代码库的分支。在本例中只有master一个分支,所以保持默认就可以了。在实际的工作中,需要根据管理员分配给你的具体分支来提交。

经过上面的操作,我们就把代码提交到了开源中国的代码库中。打开开源中国的代码管理页面会发现,我们提交的文件已经被开源中国的代码库管理起来了,如图2-44所示。

图2-44 推送后的页面

在Visual Studio 2013中,已经集成了对Git的支持,因此可以更容易地使用Git了。接下来,MOL演示一下如何在Visual Studio 2013中使用Git。

按照前面所讲的方法,新建一个项目解决方案TestProjectSLN,这个项目中只有一个控制台程序。创建好以后,同步到开源中国。打开这个项目,并修改Main方法,添加一条打印语句:

Console.WriteLine("这世界,我来了!");

修改完成并保存后,Visual Studio中的Program.cs前面就会多出一个红色的对勾,表示已经对当前文件做了代码修改,但还没有提交,如图2-45所示。

图2-45 修改代码后的文件图标

在修改文件上右击,在弹出的快捷菜单中选择“提交”命令,如图2-46所示。

填写操作注释,然后单击“提交”按钮,如图2-47所示。

图2-46 提交修改的代码

图2-47 在Visual Studio中提交变更

这样就完成了在Visual Studio中提交变更的操作。

如果对多个文件都做了更改,那么可以在解决方案上右击,在弹出的快捷菜单中选择“提交”命令,之后的操作同单文件提交是一样的,不再赘述。 Jq6B+9pAJQW3rVlwdDrFbI8hA1blVhlucZo9DVWHtBQpiJzx4SE6Zw+cUN8lLVQa

点击中间区域
呼出菜单
上一章
目录
下一章
×