版本控制与GIT的基础操作

一、git的由来

1.1 版本控制(Revision control)

假如,我们在开发一个产品的过程中,产品经理过来提了一个需求让我们完成。虽然一看就是个没卵用的功能,但我们还是去做了。果不其然,废了九牛二虎之力完成后,产品经理说这功能不好用又给砍掉了,要我们把源码恢复到之前的状态。没办法,这就是咱的命,老老实实做呗。

之后,我们的工作就分为两种情况:

  • 如果没用版本控制,项目源码就一份,来来回回改:

    完蛋,我们只能又去删除那些辛辛苦苦写出来的代码,各种接口一个个改回来,一个个修bug。(最要命的是,删完之后,产品经理又想要那个功能了😾)

  • 如果用了版本控制,项目源码在开发这个倒霉的功能之前,就另外存储了一份:

    只需要恢复到另外存储的那一份即可。(产品经理又想要也不怕,原来那份我们压根没删😎)

这就是版本控制最基本的用法和原理。

1.2 集中式和分布式

上面的例子中,我们是手动另存了一份源码,这只适用于简单的版本控制,版本多了之后就会使不版本库杂乱,不好控制,最重要的是不适合团队开发。于是,就有大佬们开发了一些专门用于版本控制的软件,称为版本控制系统。比如,集中式版本控制系统:CVS、SVN等,分布式版本控制系统:GIT(我们的主角)、Mercurial等。

1.2.1 集中式

集中式版本控制系统需要一个中央服务器,版本库存放在中央服务器中。开发的时候,大家从中央服务器获取一份源码到自己电脑上,开发完了就放回去。

但它有一个很大的缺点,那就是中央服务器要保护好,它要是坏了,那所有的一切就都完了。

1.2.2 分布式

分布式版本控制系统中,在每个开发人员的电脑上都有一份完整的版本库,而中央服务器是不存在的。但通常会有一个服务器充当一下“中央服务器”,被称为远程仓库,用来保证代码的安全,以及团队开发时,开发人员之间版本库的同步。

二、git的安装与配置

2.1 Ubuntu下安装

在终端中执行:

sudo apt-get install git

完成。

2.2 windows安装

到官网下载安装包:传送门,选择 Setup版本的。运行安装包,一直点下一步(next)即可。

2.3 配置

  • 用户信息:

    git是支持多人协作的,所以需要先配置一下我们自己的用户名和电子邮箱,用来标记更新是谁提交的(出了问题好找他算账😨)。

    终端中运行:

    git config --global user.name "用户名"
    git config --global user.email 电子邮箱
    
  • 文本编辑器:

    如果git需要我们输入一些内容的时候,就会调用配置的编辑器。

    git config --global core.editor emacs  # 如Emacs
    
  • 差异分析工具:

    解决冲突用的工具。

    git config --global merge.tool vimdiff  # 如vimdiff
    
  • 查看配置信息:

    git config --list
    
    

三、git的仓库结构

在这里插入图片描述

  • 工作区:就是我们写代码的地方,用不用git都没有变化;
  • .git文件夹:使用git初始化仓库后出现的东西,就是存放版本库的文件夹;
  • 暂存区:也叫待提交区,在正式提交到版本库之前,暂时将改动后的代码通过git命令放在这里;
  • 版本库:暂存区的代码通过git命令被正式提交后就会保存在这里。

另外,通常情况下还会有一个远程仓库(中央服务器)。版本库可以在远程仓库存放一份,方便团队开发和代码的安全。远程仓库可以使用现成的,比如:github(全球最大)、码云(国内常用)等,也可以公司内部使用gitlab自己搭建。

四、git基础

git既可以通过一些软件的图形界面来使用,也可以通过终端命令进行使用。(我们当然要学命令啦,虽然图形界面用的更多😟)

4.1 提交操作

  • 初始化:

    开始使用git进行版本控制。

    git init 项目路径  # 不写路径,代表控制当前目录
    
  • 查看状态:

    确定哪些文件当前处于什么状态。

    git status
    

    假设目录下只有一个a.txt文件,则输出如下:

    位于分支 master
    
    尚无提交
    
    未跟踪的文件:
      (使用 "git add <文件>..." 以包含要提交的内容)
            a.txt
    
    提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪)
    

    表示当前没有提交过任何更新,并且a.txt没有被git所追踪(即没被管理)。若要追踪(即进行管理),使用git add命令。

    ps:空文件夹默认会被忽略。

  • 提交到暂存区(建立追踪):

    git add a.txt  # 将a.txt添加到暂存区
    

    这就表示a.txt从此以后就由git进行版本控制了。如果没有这一步,a.txt的内容无论怎么修改,git一律不会管,只会显示a.txt未追踪。

    如果要建立追踪的文件很多,可以用引文句号.代替具体文件,表示对目录下所有文件建立追踪:

    git add . 
    
  • 提交到版本库:

    提交到版本库时,只会提交暂存区的所有文件

    git commit -m "提交说明,描述本次提交的更新内容" 
    

    没有-m和说明会报错。

4.2 撤销操作

  • 取消暂存:

    git restore --staged 文件路径
    

    会从暂存区删除文件,不影响工作区。

  • 放弃修改:

    在工作区做了修改,但想丢弃这些改动,未添加到暂存区的,可以使用以下命令直接放弃。

    git restore 文件路径
    

    添加到了暂存区的,要先取消暂存。

  • 查看提交历史:

    git log
    

    默认不用任何参数的话,git log 会按提交时间列出所有的更新,最近的更新排在最上面。输出结果如下:

    commit 0d3b6f05fe26d8837a43f88aff5a682dc84aba5f (HEAD -> master)
    Author: hugh <ma.hugh@foxmail.com>
    Date:   Fri Jan 7 11:01:40 2022 +0800
    
        提交说明,描述本次提交的更新内容
    

    每一行分别是提交的ID(一个SHA-1 校验和)、作者的名字和电子邮件地址、提交时间以及提交说明。

    -p 选项展开显示每次提交的内容差异,用 -2 则仅显示最近的两次更新。--pretty=oneline简化输出内容。

  • 恢复到指定版本:

    如果想要恢复到版本库中的某个版本,可以使用下面的命令,它会将指定版本放到暂存区中。

    使用提交ID指定要恢复的版本,取前面若干位即可(能和别的版本区别开即可),无需写全部。

    git reset 0d3b6f05
    

    也可以使用HEAD^符号指定,HEAD后面跟一个^代表向前一个版本,2个代表向前回退2个版本。比如回退到倒数第2个版本:

    git reset HEAD^^
    git reset HEAD~100  # 回退100个版本
    

    reset选项后面添加--hard参数,会直接将指定版本放到工作,覆盖工作区的数据并“删除”(实际是隐藏)回退版本之后的所有信息,所以要慎用!!!

  • 查看完整的提交历史:

    在回退到指定版本后,发现回退版本之后的版本信息都不见了,不用害怕,用下面的命令,它会输出所有的操作记录。

    git reflog
    

4.3 忽略文件

项目目录下有一些特殊文件其实是不属于我们项目的,比如:node_modules模块文件夹、env虚拟环境文件夹、.pyc编译文件等等。这些文件和文件夹并不需要被git追踪管理,所以我们要进行配置,让git忽略这些文件和文件夹。

配置很简单,只需要在==.git文件夹的同级目录下==创建一个.gitignore文件,将要忽略的文件或文件夹写进去即可。并且github提供了大量的模板,我们可以直接复制下来,不需要从头开始写:传送门

.gitignore的语法:

  • #开头代表注释:# 注释
  • 文件夹名代表忽略该文件夹:env
  • 文件名代表忽略该文件:hugh.log
  • 可以指定文件夹或文件的路径,绝对或者相对路径都可以:/home/hugh/env
  • 可以使用通配符*,比如忽略所有文件夹下的.pyc文件:*.pyc

五、分支管理

分支可以理解为科幻电影中时间线,一个分支就是一条时间线,我们在A时间线上做的任何事都不会影响到B时间线中的任何事物。也就是说,我们在A分支上提交修改,不会影响到B分支中的内容,B原来啥样现在还是啥样。

之前我们来来回回执行提交、撤销等操作,都是在默认的master分支上,它是在初始化仓库时就创建好的。当然,我们可以自己创建、切换、删除分支,还可以合并分支。

  • 查看分支:

    git branch
    

    如果分支有多个,那么前面带*号的,便是我们当前所在的分支。

  • 创建分支:

    git branch 分支名称
    
  • 切换分支:

    git checkout 分支名称
    
  • 删除分支:

    git branch -d 分支名称
    

    注意:删除当前所在的分支会报错。

  • 合并分支:

    gir merge 要合并过来的分支
    

    合并后,当前分支就会多了上面命令所指定分支的修改内容。

六、远程仓库

国内建议使用码云,因为访问速度要比GitHub快。不过GitHub毕竟是全球最大的代码托管服务平台,全球的大佬都会把自家开源的东西放在上面。所以,GitHub之后我们要用的比码云多。

6.1 远程仓库基础

注册登陆后,新建远程仓库:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-keDplfvq-1641692443488)(git的由来.assets/gitee新建仓库.jpeg)]

  • 设置远程仓库的地址:

    • 已有本地仓库:

      如果已经有了本地仓库,就不要选初始化仓库、设置模板、选择分支模型,容易与本地的文件产生冲突。要是勾选了也没关系,冲突是可以解决的,我们会在后面学习。

      git remote add 远程仓库的别名 https://gitee.com/xxxxxxxx/xxxxxxxxx.git  # 注意是远程仓库的url不是浏览器地址栏的url
      

      在新建完仓库后,码云会跳转到一个帮助页面,上面的命令可以在该页面上找到,包括远程仓库的URL。或者在远程仓库的首页-->“克隆/下载”按钮-->“HTTPS”找到远程仓库的URL。

    • 没有本地仓库:

      那就有两种解决办法:

      • 新建本地仓库,然后执行上面那条命令(不推荐)。

      • 克隆远程仓库到本地:

        其实就是下载远程仓库到本地。

        git clone https://gitee.com/xxxxxxxx/xxxxxxxxx.git  # 还是之前那个url
        
  • 查看远程仓库:

    git remote
    

    输出远程仓库的别名。

  • 推送本地仓库到远程仓库:

    在本地仓库做的任何修改,需要手动推送才能保存到远程仓库。

    git push -u 远程仓库的别名 "分支的名称"
    

    然后会git会提示我们输入码云账户的用户名和密码,输入即可。

  • 拉取远程仓库到本地仓库:

    与推送对应,他人提交到远程仓库的修改,需要我们手动拉去才能保存到本地仓库。

    git pull
    

注意:为了避免冲突,建议在每次提交推送之前,先拉取一下!!!

6.2 使用SHH协议连接远程仓库

目前,我们连接远程仓库用的是HTTPS协议,它不需要额外的配置,但是每次都需要输入用户名和密码(有些IDE或编辑器可能会优化这一操作),十分麻烦。与之对应的是SSH协议,它需要事先配置一下,但好处是一劳永逸,以后都不用再输入用户名和密码了。

6.2.1 生成公钥

在终端中执行:

ssh-keygen -t ed25519 -C "xxxxx@xxxxx.com"  

ed25519是数字签名算法,最后面的字符串参数是我们的邮箱。

然后选择密钥的保存位置,默认是:/home/用户主目录/.ssh/id_ed25519,可以直接回车,然后提示输入密码,直接忽视,按两次回车,完成!

6.2.2 添加公钥

/home/用户主目录/.ssh/目录下,id_ed25519文件是私钥,id_ed25519.pub就是我们要用到的公钥,使用cat命令查看并复制下来:

cat ~/.ssh/id_ed25519.pub

输出的内容就是公钥,将其复制下来。

点击右上角的头像,设置-->SSH公钥,然后将复制的内容粘贴进去,标题默认会使用我们生成公钥时输入的邮箱地址。

现在,执行以下命令,测试公钥有没有添加成功:

ssh -T git@gitee.com

如果成功会输出:Hi Anonymous! You've successfully authenticated, but GITEE.COM does not provide shell access.,否则就是失败了。

添加成功后,就可以使用SSH协议对仓库进行操作了。

PS:如果本地仓库之前使用HTTPS连接过远程仓库,建议在使用SSH协议之前,先用HTTPS全部推送到远程仓库,然后再克隆下来,这样可以免去一些配置问题。

七、冲突解决

假设有一个仓库有两条分支dev和master,且都用一个a.txt文件:

  • 我们在dev分支上a.txt文件的第一行添加了:“ABC”;
  • 而同事则在master分支上a.txt文件的第一行添加了:“BCD”。

然后我们进行分支合并,就会发现git在终端中提示我们出现了冲突,让我们解决完冲突再去提交合并后的内容。

而且,git还会用下面的格式,在a.txt标记出冲突的地方:

<<<<<<<  HEAD
我们的代码
=======
同事的代码
>>>>>>> origin/master

我们可以通过提交历史,找到那位同事,和他商量着修改文件的内容以解决冲突。

八、标签管理

标签(tag)就是对某一个的特殊记号。通常在发布一个版本时,会在版本库中打一个标签,这样以后想要找这个版本,通过标签很容易就能找到,而不像提交ID那么难记。

  • 创建标签:

    git tag 标签
    

    标签默认是打在最新一次提交上的。如果想对指定的某一次提交打标签,可以指定提交ID:

    git tag 标签 提交ID
    
  • 查看标签:

    git tag
    
  • 查看标签详细信息:

    git show 标签
    
  • 删除标签:

    git tag -d 标签
    
  • 推送指定标签:

    git push origin 标签
    
  • 推送全部标签:

    git push origin --tags
    
  • 删除远程标签:

    git push origin :refs/tags/标签
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花_城

你的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值