目前最流行的版本控制软件:Git的基本使用

目前最流行的版本控制软件:Git的基本使用

知识分子没文化
2021-09-14 / 0 评论 / 14 阅读 / 正在检测是否收录...

目录:

写在前面

1、关于版本控制系统

定义

版本控制(Version control)是维护项目的标准作法,能追踪项目从诞生一直到定案的过程。此外,版本控制也是一种软件工程技巧,借此能在软件开发的过程中,确保由不同人所编辑的同一程序文件都得到同步,记录项目内各个模块的改动历程,并为每次改动都编上序号。

一种简单的版本控制形式如下:工程的初代版本为“1.0”,当做了第一次改变后,版本等级改为“1.1”,以此类推。因此,版本控制能提供给开发者将项目恢复到之前任一状态的选择权,这种选择权在设计过程进入死胡同时特别重要。

版本控制的必要性:
  • 常会利用版本控制来追踪维护源代码、文件以及配置文件等的改动,并且提供控制这些改动控制权的程序;

  • 有时候,一个程序同时存有两个以上的版本,例如:在一个稳定版本中程序错误已经被修正、但没有加入新功能;在另一个开发版本则有新的功能正在开发、也有新的错误待解决,这使得同时间需要不同的版本;

  • 此外,为了找出只存在于某一特定版本中(由于修正了某些问题、或新加功能所导致)的程序错误,或找出程序错误出现的版本,开发者也需要比对不同版本的代码以找出问题的位置。

常见的版本控制系统
  1. 集中式版本控制系统:由一台或多台主计算机组成中心服务器,所有业务单元和项目版本库都集中存储在这个中心服务器上,开发时,要先从中央服务器取得项目最新的版本,一次开发完毕之后,再将工作量推送给中央服务器。就像是一个图书馆,如果要改一本书的内容,则需要把书先从图书馆借出来,然后修改,改完之后再放回图书馆。

    因此,集中式版本控制系统最的大缺点就是中央服务器出了问题,所有人都没法工作了。

    常见的集中式版本控制系统有SVN、CVS等。

  2. 分布式版本控制系统:分布式版本系统没有绝对的中央服务器,每个人的电脑上都是一个完整的版本库,多个人进行协同工作时,只需将自己的修改与其他人的修改进行交换即可

    和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,其中一个人的电脑坏了不要紧,从其他人那里复制一个就可以了。

    Git就是常见的分布式版本控制系统之一,也是目前最流行的版本控制系统。

2、Git与Github

准确地说,GitGithub根本不是同一个概念。

Git是指由Linus(就是那位二十多年前徒手撸出Linux内核的大佬)编写的分布式版本控制系统,于2005年以GPL发布。最初目的是为了更好地管理Linux内核开发。

自2002年以来,Linus一直使用BitKeeper作为Linux内核主要的版本控制系统以维护代码。在Linux社区中,主张应该使用开放源代码的软件来作为Linux内核的版本控制系统。Linus曾考虑过采用现成软件作为版本控制系统(例如Monotone),但这些软件都存在一些问题,特别是性能不佳。

2005年,Linux社区中的安德鲁·垂鸠写了一个可以连接BitKeeper的存储库的简单程序,BitKeeper著作权拥有者拉里·麦沃伊便认为安德鲁·垂鸠对BitKeeper内部使用的协议进行了逆向工程,决定收回无偿使用BitKeeper的许可。Linux内核开发团队与BitMover公司进行磋商无果后,Linus决定自行开发版本控制系统以替代BitKeeper,在十天的时间编写出git第一个版本。于是,世界上最流行的版本控制系统就这么戏剧式地诞生了。

GitHub是通过Git进行版本控制的软件源代码托管服务平台,由GitHub公司(曾称Logical Awesome)的开发者Chris WanstrathP. J. HyettThomas Preston-Werner使用Ruby on Rails编写而成,于2007年10月1日开始开发。beta版本开始上线于2008年2月,4月份正式上线。这是他们的logo,名字叫Octocat:

01

截止到2020年1月,GitHub已经有超过4000万注册用户和1.9亿代码库(包括至少2800万开源代码库),事实上已经成为了世界上最大的代码存放网站和开源社区,国内很多人戏称为“全球最大同性交友网站”。

2018年6月4日晚,微软宣布以75亿美元的股票收购GitHub。

Github服务器在国外,处于半被墙的状态,有时正常访问,有时又打不开。与之类似的代码托管平台Gitee可以看做是国内版的Github,缺点是开源项目不如Github丰富,当然,由于在访问时速度更快,更适合国内用户托管代码。而且,部分开源项目是同时托管在这两个平台上的,所以碰到无法打开的Github项目时,在Gitee上找找也许会有惊喜。

0x01.安装Git

Git在全平台均可使用。

Git官网:Git (git-scm.com)

官方中文文档:[Git - Book (git-scm.com)](https://git-scm.com/book/zh/v2)

Windows系统Git安装包下载链接:Git - Downloads

Linux系统安装Git:Git - Download for Linux and Unix

Mac系统安装Git:Git - Download for macOS

安装完成之后在控制台中输入git,如果出现如下输出说明安装成功:

02

前面提到过,Git只是一个分布式版本管理软件,每个人的计算机都是一份完整的版本库,对这份版本库进行修改之后,将每个人的修改进行合并。但是如果不在同一个内网中,合并修改就会变得困难。此时也需要一个中央服务器来辅助进行代码的合并。这也就是Github、Gitee、Gitlab等平台最基本的作用。

因此,我们还需要注册一个Github/Gitee账号,将我们的代码托管到平台上面(从某种角度上将它看成一个专门存放代码的云盘也未尝不可)。Github注册账号及用户界面介绍可以参考这篇文章:从0开始学习 GitHub 系列之「加入 GitHub」 (qq.com),本篇博客不再介绍。

0x02.Github中的一些基本概念

Repository

仓库,即项目,要在GitHub上开源一个项目,那就必须要新建一个Repository。

Issue

问题的意思,举个例子,比如开源的项目,别人发现项目中有bug,或者哪些地方做的不够好,他就可以提个Issue,即问题,提的问题多了,也就是 Issues ,然后开发者看到了这些问题就可以去逐个修复,修复ok了就可以一个个的Close掉。

Star

就是给项目点赞,这个star的含金量还是挺高的。

Fork

这个可以翻译成分叉,你想在某个开源项目的基础上做些改进,然后应用到自己的项目中,这个时候就可以Fork这个项目,与此同时你的GitHub主页上就多了一个项目,只不过这个项目是基于这个开源项目(本质上是在原有项目的基础上新建了一个分支)。而你就可以随心所欲的去改进这个项目了,丝毫不会影响原有项目的代码与结构。

Pull Request

发起请求,这个其实是基于Fork的,还是上面那个例子,如果你在项目基础上做了改进,就可以把自己的改进合并到原有项目里,这个时候你就可以发起一个Pull Request(简称PR),原有项目开发者会收到这个请求,这个时候他会review代码,并且测试觉得OK了,就会接受PR,这个时候新的改进会被合并进原有项目。

Watch

可以理解为观察,如果Watch了某个项目,以后如果这个项目有更新,都会收到关于这个项目的通知提醒。

Wiki

一般来说,项目的主页有README文件基本就够了,但是有些时候项目的一些用法很复杂,就需要有详细的说明文档给使用者。这个时候就可以用Wiki,使用markdown语法即可进行编写。

Gist

如果没有项目可以开源,只是单纯的想分享一些代码片段,那这个时候Gist就派上用场了。

0x03.添加SSH key

当我们对代码进行提交时,Github/Gitee要怎么知道是我们提交的代码,而不是别人提交的呢,所以就需要进行授权来确认我们的身份。

SSHSecure Shell)是一种建立在应用层基础上的安全协议,一般用于远程登录会话和其他网络服务。由于在传输过程中对数据进行了加密和压缩,因此可以有效防止远程管理过程中的“中间人攻击”,传输速度也会更快,还能够防止”DNS欺骗“和”IP欺骗“等。

Github和Gitee服务器可以选择使用SSH公钥或GPG公钥来进行授权,这里采用SSH授权方式,提交代码之前需要先添加SSH key配置。大概步骤就是先在本地生成SSH key,然后将本地生成的SSH key添加到Github或者Gitee上。

  • 生成SSH密钥:

    ssh-keygen -t rsa

    这句命令的意思是用RSA算法生成密钥(windows系统最好在Git Bash下执行,cmd终端可能并没有安装ssh),执行后出来三次提示均按回车,命令执行完会生成id_rsa(密钥)和id_rsa.pub(公钥)这两个文件。Linux/Mac系统在~/.ssh下,windows系统在C:\Users\用户名\.ssh(用户名是自己电脑的用户名)下,需要设置显示隐藏文件选项才能看到。

    id_rsa.pub用文本编辑器打开,复制里面的内容。

  • 添加公钥到Github/Gitee:

    进入Github/Gitee的设置界面,在左侧选项列表找到SSH keys选项

    03

    将刚才复制的公钥粘贴上去,公钥标题可写可不写,保存即可。这样以后提交代码,远程服务器就能确认我们的身份了。

0x04.克隆仓库

说来惭愧,这是我接触到Github之后很长时间内最常用的操作(因为就只会这一个操作)。命令很简单:

git clone [仓库链接]

这个命令的作用就是从Github云端下载别人仓库的项目文件,可能是从clone直接音译过来的原因,这个操作一般都称克隆,而不叫下载。

克隆操作只需要有远程仓库链接即可,不需要Github账户也可以进行。克隆完之后项目文件的位置就是执行命令时所处的文件夹。

远程仓库链接在项目主页就可以找到:

04

0x05.初始化仓库

所谓初始化本地仓库,个人理解就是向本地的项目根目录文件夹中加入一些Git配置文件,使其可以被Git识别以进行版本控制,因为项目文件夹是不能直接进行版本控制的。

初始化本地仓库命令很简单,进入本地项目文件夹(或者用空文件夹),在该目录下执行:

git init

也可以在命令后面加入文件夹路径,将指定文件夹初始化成本地仓库:

git init [项目文件夹名路径]

项目初始化成功会有Initialized empty Git repository in xxxxxxx的提示,原项目文件夹中多出一个.git隐藏文件夹。此时初始化的本地项目还没有关联到远程仓库。

当然,有本地仓库还不行,我们本意是要把本地仓库推送到远程仓库,因此,还需要在Github/Gitee上建一个远程仓库。点击网站右上角加号,找到“New Repository新建仓库)”

05

上图最后三项是用来初始化远程仓库的,如果这三项都不选就创建了仓库,就会提示用命令行来手动初始化仓库(所以建议对命令行不感冒的同学直接使用自带的初始化操作)。来记录一下这个步骤:

  • 先在本地初始化好的Git项目中新建一个README.md项目说明文件(也可以是别的文件名)

  • 在项目目录下执行命令与远程仓库进行关联:

    git remote add origin [远程仓库链接]
  • 依次执行以下命令向暂存区加入修改文件以及编辑提交信息

    git add README.md
    # 引号中就是本次提交信息,可修改
    git commit -m "first commit"
  • 向远程仓库推送本地仓库文件:

    Gitee只执行这条命令即可推送:

    git push -u origin master

    由于Github的默认分支从master变成了main,因此还需要将本地默认主分支重命名为main才能推送成功:

    git branch -M main
    git push -u origin main

    如果不重命名主分支,就会出现“error: src refspec main does not match any,error: failed to push some refs to ..”的错误。

上述命令执行完之后,再刷新远程仓库界面,就进入了初始化好的远程仓库:

06

对于都已经初始化过的本地空仓库与远程仓库,使其建立关联可以这样做:

# 先关联远程仓库git remote add origin [仓库远程链接]# 再将远程仓库内容拉取到本地git pull origin master

0x06.提交修改

所谓修改,就是相对于上次提交之后项目发生的改变(项目文件的增、删、改)。

其中要涉及到pushpull这两个互为相反的概念:

  • Push:直译就是“”的意思,这个操作可以把本地代码推到远程仓库,这样本地仓库跟远程仓库就可以保持同步了。
  • Pull:直译为“”的意思,如果别人提交代码到远程仓库,这个时候本地仓库代码与远程仓库代码并不一致,所以需要把远程仓库的最新代码拉下来,以保证两端代码的同步。

同时,提交代码前最好设置一下提交者的名字与邮箱,方便在commit记录里显示:

git config —global user.name "名字"git config —global user.email "邮箱"

通常一次完整的提交过程如下:

  • 将修改过的文件加入暂存区:

    git add [修改的文件或者目录]# .表示此目录下所有文件,一次提交的文件较多时,可以使用此命令git add .
  • 确认提交暂存区中的文件:

    git commit -m "提交信息"# -m表示附加提交信息,后面的内容是关于提交的信息说明

    git add是先把改动添加到一个“暂存区”,可以理解成是一个缓存区域,临时保存改动,而git commit才是最后真正的提交。这样做的好处是防止误提交。

  • 最后将代码推送到远程仓库指定分支,即可完成一次代码提交:

    # 推送代码到指定分支git push origin [分支名]# Github默认分支是main,用以下命令:git push origin main# Gitee默认分支是master,用以下命令:git push origin master

    这里的origin是给远程仓库起的名字,当然名字并不唯一,可以是其他名字,只是因为习惯,一般都起名为origin

一般在多人协作时,为了不产生代码冲突,提交代码前最好进行一次Pull操作:

git pull origin [分支名]

查看git仓库当前状态,比如当前所在分支、被修改过的文件、未提交的文件等等:

git status

查看提交时产生的所有commit记录:

git log

0x07.分支操作

branch即分支的意思,分支的概念在团队协作的时候很重要,假设两个人都在做同一 个项目,这个时候分支就是保证两人能协同合作的最大利器了。举个例子,A, B两人都 在做同一个项目,但是不同的模块,这个时候A新建了一个分支叫a,B新建了一个分支叫b,这样 A、B做的所有代码改动都在各自的分支上,互不影响,等到都把各自的模块做完 了,最后再统一把分支合并到master主分支。

在本地执行git init命令初始化仓库时默认生成一个主分支master,曾经Github远程仓库的默认主分支也是master,但是去年(2020)10月份之后Github将默认主分支名称从master改成了main(据说是因为master这个词意为奴隶的主人,含有种族歧视意味),这也是在前面手动初始化Github仓库时要将主分支名重命名为main的原因。

查看分支

查看本地分支列表:

git branch

查看远程分支列表:

git branch -r

建立新分支

git branch [分支名]

需要注意的是,新分支的内容与当前所在的分支的内容相同,即新分支是基于当前所在的分支而创建的。

当我们建立了新分支以后,默认不会切换到新分支上,当前做出的任何更改还是基于原来分支的,所以需要切换分支。

切换分支

git checkout [分支名]

此时进行的改动就是在新分支下面了。当然,也有办法一步到位,加入-b参数即可。

建立并切换到新分支

git checkout -b [分支名]

推送本地分支到远程仓库

在本地建完新分支之后,就可以将本地新分支推送到远程仓库了,以保证两端同步

git push origin [新分支名]

如果本地推送到远程的分支想取另一个名字,那么可以用这条命令:

git push origin [本地分支名]:[远程新分支名]

但是强烈不建议这样,这会导致管理混乱,建议本地分支跟远程分支名要保持 一致。

合并分支

当团队中不同成员都完成了开发之后,就可以将改动都合并到一块了。

# 首先切换到要合并到的分支上来,比如master(main)分支或是指定分支git checkout [分支名]/main/master# 进行合并,将指定分支合并到当前所在的分支(即上一步切换到的分支)上来git merge [指定分支]

在没有冲突的情况下,代码就可以合并完成了。合并完记得把新代码push到远程仓库。

删除分支

分支建错或者该分支的代码已经顺利合并到其他分支的时候,就可以删除分支了:

git branch -d [分支名]

有些时候可能会删除失败,比如该分支的代码还没有合并到master或者其他分支,执行删除分支操作就会失败,Git会智能的提示这个分支上还有未合并的代码,但是也可以强制删除分支:

git branch -D [分支名]

以上为仅仅为删除本地分支,若要删除远程分支可以可以运行带有 --delete 选项的 git push 命令:

git push origin --delete [远程分支名]

重命名分支

将A分支重命名为B分支:

git branch -m A B

类似于删除分支,无法重命名时,也可以强制重命名:

git branch -M A B

如果是重命名远程分支,推荐的做法是:

  1. 删除远程待修改分支
  2. push本地新分支名到远程

0x08.标签

开发的时候经常有版本的概念,比如v1.0、v1.1之类的,不同的版本肯定对应不同的代码,所以就可以给我们的代码打上标签:

git tag [-a] [标签名称]

-a参数为可选的,意为"创建一个带注解的标签"。 加-a参数,就会记录这标签是什么时候打的,谁打的,同时Git会自动打开编辑器,让我们可以写一句标签注解,就像给提交写注解一样。

执行git tag时,就可以看到设置的所有标签了

指定标签信息用这条命令:

git tag -a <tagname> -m "标签信息"

当要切换到某个tag时,与切换分支类似:

git checkout [标签名];

参考资料:

微信公众号 - stormzhang:从0开始学习Github系列文章

Git 教程 | 菜鸟教程 (runoob.com)

版本控制 - 维基百科,自由的百科全书 (wikipedia.org)

git - 维基百科,自由的百科全书 (wikipedia.org)

GitHub - 维基百科,自由的百科全书 (wikipedia.org)

0

评论 (0)

取消