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

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

知识分子没文化
2021-09-14 / 0 评论 / 965 阅读 / 4,220 字数 / 正在检测是否收录...
温馨提示:
本文最后更新于2022年12月28日,已超过485天没有更新,如存在内容错误、图片加载失败、链接失效等问题,请留言反馈,博主将在第一时间进行修改。

前排提示:

本篇博客篇幅较长,建议结合目录查看!

目录:

写在前面

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)

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要怎么知道是我们提交的代码,而不是别人提交的呢,所以就需要进行授权来确认我们的身份。

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

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

  • 生成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

    从2020年10月开始,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 .
  • 确认提交暂存区中的文件:

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

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

  • 最后将代码推送到远程仓库指定分支,即可完成一次代码提(其中注意,最后提交时Gitee与Github的分支名有所不同):

    # 推送代码到指定分支
    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的原因。

而Gitee的主分支名称依然是master。

查看分支

查看本地分支列表:

git branch

查看远程分支列表:

git branch -r

建立新分支

git branch [分支名]

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

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

切换分支

git checkout [分支名]

# 切换到新分支之后手动拉取最新内容
git pull origin [分支名]

此时进行的改动就是在新分支下面了。当然,也有办法一步到位,加入-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 支持两种标签:附注标签(annotated)与轻量标签(lightweight)。

附注标签

附注标签是存储在Git数据库中的一个完整对象, 它们是可以被校验的,其中包含打标签者的名字、邮件地址、日期时间, 此外还有一个标签信息,并且可以使用GNU Privacy Guard(GPG)签名并验证。

通常建议创建附注标签,这样就可以拥有以上所有信息

添加附注标签信息用这条命令:

git tag -a [标签名] -m "标签信息"

-m参数为可选的,表示指定一条存储在标签中的信息。如果省略-m参数,那么Git会自动打开编辑器,让我们写一句标签信息,就像给提交写注解一样。

利用git show命令可以查看标签信息与对应的提交信息:

git show [标签名]

输出会显示打标签者的信息、打标签的日期时间、附注信息与具体的提交信息。

轻量标签

如果只是想用一个临时的标签, 或者因为某些原因不想要保存这些信息,那么就可以用轻量标签。

轻量标签很像一个不会改变的分支——它只是某个特定提交的引用。本质上是将提交校验和存储到一个文件中——没有保存任何其他信息。 创建轻量标签,不需要使用 -a-s-m 选项,只需要提供标签名:

git tag [标签名]

同样的,利用git show命令查看标签信息与对应的提交信息,输出只会显示出提交信息,不会看到额外的标签信息。

切换标签

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

git checkout [标签名];

推送标签

同样的,向远程仓库推送单个标签的命令与推送分支也是类似的:

git push origin [标签名]

如果一次推送多个标签,可以使用带有--tagsgit push命令:

git push origin --tags

这条命令会将所有不在远程仓库服务器上的标签全部推送到远程仓库。

删除标签

删除本地标签:

git tag -d [标签名]

上述命令并不会从远程仓库中移除这个标签,从远程仓库移除标签有两种办法:

  • git push <remote> :[标签名称]

    这种操作的含义是,将冒号前面的空值推送到远程标签名,从而实现删除的效果。

  • 第二种方式相对来说更直观:

    git push origin --delete [标签名]

查看所有标签

执行git tag命令,就可以列出所有标签:

git tag

默认是以字母顺序排列标签。

当然,可带上可选的 -l 选项或者 --list选项,以匹配特定标签名:

git tag -l "通配符"
# 或者
git tag --list "通配符"

例如,只查阅v2.*版本的标签名:

git tag -l "v2.*"

给提交打标签

假设在过去某一个时刻提交了项目更改,后期才想起来忘记给项目打标签了,那么也可以在之后补上标签:

git tag -a [标签名] [校验和]

与创建标签命令不同,需要在标签名之后添加一个校验和选项(也可以是部分校验和)。

通过以下命令可以查看每一次提交的校验和与对应的提交信息:

git log --pretty=oneline

参考资料:

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

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

Git - Book (git-scm.com)

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

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

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

0

评论 (0)

取消