自学内容网 自学内容网

GIt (一) Git的安装,项目搭建,远程仓库,分支

一、 版本控制

版本控制可以帮助程序员进行代码的追踪、维护、控制等一系列操作。

最权威的资料——Git官网:https://git-scm.com/doc

1.1 集中式版本控制

集中式版本控制(Centralized Version Control Systems, 简称CVCS )的特点:

  • 采用一个集中管理的服务器,保存所有文件的修订版本
  • 问题是:中央服务器不能出现故障
    • 如果服务器宕机,那么谁都无法提交更新,也就无法协同工作。
    • 如果中心数据库发生损坏,没有备份的话,将丢失关键数据
      在这里插入图片描述

1.2 分布式版本控制

Git属于分布式版本控制系统 (Distributed Version Control System, 简称DVCS):

  • 客户端并不只提取最新版本的文件快照, 而是把代码仓库完整地镜像下
    来,包括完整的历史记录;
  • 任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复;
    (因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份)
    在这里插入图片描述

二、 Git的安装及配置

2.1 安装

  • git官网下载:https://git-scm.com/
  • 淘宝镜像下载:http://npm.taobao.org/mirrors/git-for-windows
    在这里插入图片描述

Git安装的几个工具

Git在安装时,也会安装如下几个工具,这几个工具的作用都是为了运行git命令。

  • Git Bash(推荐):就是一个shell,可执行Linux的命令行。GitBash是基于CMD的,在CMD的基础上增添一些新的命令;

  • Git CMD:命令行提示符(CMD)是Windows操作系统上的,Git CMD就是对其的进一步封装,就看做是Window上的CMD;

  • Git GUI:提供了一个图形用户界面来运行git命令

(设置环境变量是为了全局使用,而git可以在任何地方右击选择Git Bash使用,所以配或不配没啥大区别)

常用Linux命令

  1. cd:改变目录
  2. cd.. :回退到上一个目录,直接cd进入默认目录
  3. pwd : 显示当前所在的目录路径
  4. Is :都是列出当前目录中的所有文件
  5. touch :新建一个文件 比如 touch index.js
  6. rm : 删除一个文件 rm index.js
  7. mkdir: 新建一个目录,即新建一个文件夹
  8. rm -r:删除一个文件夹 如 rm -r src 删除src目录
  9. mv :移动文件,mv index.html --将index.js移动到src文件夹,这样写必须保证文件和目标文件夹在同一目录下
  10. reset : 重新初始化终端清屏
  11. clear:清屏
  12. history:查看历史命令
  13. help:帮助
  14. exit:退出
  15. #:注释

2.2 Git的配置

(1) 设置用户名和邮件地址(重要)

每一个 Git 提交都会使用这些信息,它们会写入到你的每一次提交中,不可更改;如果使用了 --global 选项,那么该命令只需要运行一次。

  • 设置用户名
    • git config-global user.name 'lxh'
    • git config-global user.email '邮箱地址@qq.com'

(2) 配置别名(可配可不配)

如果不想每次都输入完整的Git命令,可以为某些命令设置一个别名

$git config --global alias.br branch
$git config --global alias.ci commit
$git config --global alias.st status

别名的使用:
在这里插入图片描述

2.2 查看配置

  • 查看系统配置(系统给配置的东西)
    • git config --system --list
  • 查看本地配置(用户自己配置的)
    • git config --global --list
  • 查看配置所有配置(系统配置+本地配置)
    • git config -l
      在这里插入图片描述

三、 Git基本理论

3.1 工作区域

在这里插入图片描述

  • Workspace : 工作区,即平时存放项目代码的地方(项目文件)
  • Stage/Index:暂存(暂缓)区,用于临时存放你的改动,事实上他只是一个文件,保存即将提交到文件列表信息
  • Repository:仓库区(或本地仓库),即安全存放数据的位置,这里面有提交到所有版本的数据。其中HEAD指向最新放入仓库的版本
  • Remote远程仓库,托管代码的服务器(比如Gitee)。

3.2 文件状态

对文件划分不同的状态,以确定这个文件是否已经归于Git仓库的管理

  • 未跟踪(Untracked):并未加入git库中,通过git add 状态变为 Staged
  • 已跟踪:添加到Git仓库管理的文件处于已跟踪状态,已跟踪状态的文件又可细分为以下几个状态
    • Unmodifed:未修改状态;文件已提交到git仓库,且为修改
    • Modified:文件已修改,但并未进行其他操作
    • Statged:暂存状态

在这里插入图片描述

查看文件状态

#查看指定文件状态
git status [filename]
    
#查看所有文件状态
git status

# 查看更简洁的状态信息
git status -s

在这里插入图片描述

简洁信息 ,左侧表示暂存区状态,右侧表示工作区的状态:

在这里插入图片描述

四、Git项目的搭建与操作

可将VSCode的默认终端设置为bash,这样每次打开终端都是bash
在这里插入图片描述

4.1 初始化Git仓库

在创建一个新项目时,需要初始化本地仓库;(很多脚手架在创建项目时都会默认创建一个Git仓库)

$ git init
Initialized empty Git repository in xxxx

git init命令将创建一个名为.git的子目录,含有Git仓库所必须的文件
在这里插入图片描述

4.2 常见的操作

4.2.1 文件添加到暂存区

  • 跟踪新文件(将新文件添加到暂存区)
    • git add 文件名
  • 如果已经跟踪了一个文件,该文件修改之后处于modified状态。也需要重新添加到暂存区
  • 将当前目录的所有文件添加到暂存区(.是当前目录的意思)
    • git add .

4.2.2 文件提交更新

  • git commit将暂存区的所有文件提交到本地仓库中;(建议在提交之前,先用git status检查是否所需文件都在暂存区)
  • 提交信息时,写上参数-m来备注提交信息
    • git commit -m '提交信息'
    • git commot 文件名 -m '提交信息',提交某个单独的文件
  • 添加到暂存区,提交到仓库,两个命令可以用一行来代替
    • git commit -a -m '提交信息'
    • 等价于git add .+git commit -m '提交信息'

4.2.3 查看历史提交记录

git log查看历史提交记录,在不传入任何参数的默认情况下,git log会按时间先后顺序列出所有的提交,最近的更新排在最上面。

在这里插入图片描述

# 简单打印历史记录
git log --pretty=oneline 

# 以图的方式打印历史记录
git log --pretty=oneline --graph

在这里插入图片描述

前边黄色的一大长串的字符是校验和,每次提交生成的校验和是不一样的,也被称做commit ID,用来标识每次的提交。

4.2.4 版本回退

Git通过HEAD指针记录当前版本,HEAD总是指向该分支上的最后一次提交。我们可以通过HEAD来改变Git目前的版本指向;

在这里插入图片描述

  • 通过HEAD改变Git版本的方式
git reset --hard HEAD^     //  回退到上一个版本
git reset --hard HEAD~1000 //  回退到上1000个版本
git reset --hard 校验和ID   //  指定回退到某一个版本

在这里插入图片描述

  • 当通过校验和指定回退的版本时,只写前几位,能定位到具体的提交版本即可,不用全写
    在这里插入图片描述
    如果想恢复最新的版本,通过git log已经看不到回退之前的版本了,可通过git reflog查看目前做过的所有操作。
    在这里插入图片描述
    ​ 这样可以查看到回退HEAD之前的某些版本的校验和,进而进行版本回退
    在这里插入图片描述

2.5 .gitignore配置文件

  有些文件无需纳入Git的管理,也不希望它们出现在未跟踪文件列表里;因此可创建.gitignore文件,列出要忽略的文件。
  这个文件一般不需要自己写,直接用网上的模板即可。github官方给出了一些模板:

链接:github-gitignore
在这里插入图片描述

五、远程仓库

多人合作开发项目时,会将代码共享到远程仓库中。所以需要在Git服务器上搭建一个远程仓库。

目前使用Git服务器的方式

  • 使用第三方的Git服务器:GitHub,Gitee,Gitlab等
  • 在自己的服务器搭建一个Git服务器。
    • 在云服务器上,通过某些软件,搭建Git服务器;Git服务器里可以创建很多的远程仓库。

在这里插入图片描述

比如刚入职时,初始化本地仓库,可用命令git clone将远程仓库的内容拉取到本地。如果远程仓库是一个私人仓库,则需要进行身份认证。

5.1 身份认证

对于私人的远程仓库,想要进行操作时,远程仓库会对我们的身份进行验证。目前Git服务器验证手段有两种:

  • 方式一:基于HTTP的凭证存储(Credential Storage)
  • 方式二:基于SSH的密钥

5.1.1 HTTP凭证

HTTP协议本身是无状态的连接,也就是说,第一次连接时,需要输入用户名和密码;第二次连接时,Git服务器并不会记录是否曾经连接过,所以还是需要输入用户名和密码;每一次连接都需要用户名和密码

好在Git有一个凭证系统来处理这个事
在这里插入图片描述
Git Credential Manager for Windows会将凭证以加密的方式缓存起来。在安装Git时,选择对应的选项,就会自动顺便下载这个工具。

# 输入这行命令来检查电脑的Windows系统中是否安装了这个工具
git config credential.helper
manager # 命令行输出这一句则表示已安装

使用步骤:

  • 在第一次拉取远程仓库的代码时,需要输入账号密码,生成凭证,后续就不需要重复输入了。
    在这里插入图片描述
    在控制面板里可以查看或删除凭证(也叫凭据)
    在这里插入图片描述
  • 然后在终端 执行这行命令,即可拉取远程仓库代码到本地
    在这里插入图片描述

5.1.2 SSH密钥

  Secure Shell(安全外壳协议,简称SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。

  SSH以非对称加密实现身份验证。 其中一种方法是人工生成一堆公钥和私钥,通过生成的密钥进行认证,这样就可以在不输入密码的情况下登录。

以SSH的方式访问Git仓库,就需要生成对应的公钥和私钥;接下来以Gitee种的远程仓库为例,进行配置SSH的说明(gitee官网公钥设置全流程):

SSH使用步骤:

  • 生成密钥

    ssh-keygen -t ed25519 -C  '注释xxxx'
    // 或者
    ssh-keygen -t rsa -C 'xxxx'
    

    -t:生成的key的类型
    -C:注释
    在这里插入图片描述

  • 生成的公钥和私钥文件:
    在这里插入图片描述

  • 将生成的公钥(打开文件,复制粘贴) 添加到Gitee账户中。
    在这里插入图片描述

  • 最后,执行这行命令拉取远程仓库的代码
    在这里插入图片描述

分析一篇博客::Github配置ssh key的步骤(大白话+包含原理解释)
需要注意:后续在连接github远程仓库时碰到这个错误(代理问题)

$ git fetch origin main
fatal: unable to access 'https://github.com/keke474/remote-unsame.git/': Empty reply from server

解决方法:在与远程仓库建立连接时,选用SSH,而非HTTP验证

5.2 管理远程仓库(添加)

现有两个项目,一个项目的仓库是本地初始化的;一个项目是从远程仓库clone拉取下来的
在这里插入图片描述

  • 查看某个项目连接的远程仓库

    • git remote, 列出该项目连接的远程仓库

    • git remote -v,显示远程仓库的详细信息

      (clone下来的项目的远程仓库名称默认为origin)
      在这里插入图片描述

  • 添加远程仓库(让本地仓库与远程仓库建立连接)

    • git remote add 自定义远程仓库名称 地址
      在这里插入图片描述

    01_GitDemo与远程仓库建立连接; (一个本地仓库可以连接多个远程仓库

  • 重命名远程仓库git remote rename gitlab glab(将名字gitlab改为glab)

  • 移除远程仓库git remote remove 仓库名

5.3 与远程仓库的交互

  • 从远程仓库clone代码
    • git clone xxxx项目地址
  • 将本地仓库的代码推送到远程仓库中
    • git push <远程仓库名> 当前分支名:远程仓库分支名,将当前分支推送到远程仓库的某个远程分支中
    • 简单写法:git push,将代码推送到远程仓库(5.4会详细讲这个命令)
  • 从远程仓库fetch代码:从远程仓库获取最新的代码
    • git fetch,默认从origin中获取代码
    • git fetch xxx,从指定的仓库中获取代码
  • 获取到代码后默认并没有合并到本地仓库,需要通过merge合并
    • git merge
  • 从远程仓库pull代码:pull等价于fetch+merge
    • git pull

5.4 pull与push可能会出现的错误

先把 第6节 Git分支的内容看个大概,再来看下边的内容
以下错误,都是先建立本地仓库,后连接远程仓库造成的;

5.4.1 git pull时会出现的错误

​ 先创建本地仓库,然后将本地仓库01_GitDemo与远程仓库建立连接,在将本地代码push到远程仓库之前,要先拉取(pull)一下远程仓库的代码。但是执行git pull时会报错
在这里插入图片描述
问题背景:先建立本地仓库,后连接远程仓库,二者默认分支都名为master

  • 问题一:未指定要跟踪的分支。

    本地仓库和远程仓库通过git remote建立了连接,但是仓库里有很多分支,并未指定本地仓库的哪个分支与远程仓库的哪个分支有链接,所以pull代码时,不知道要从哪个仓库的哪个分支里拉取代码。

    • 方案一:指定仓库分支
      git pull <remote> <branch>  #指定从哪个仓库哪个分支拉取代码
      

    在这里插入图片描述

    • 方案二:指定上游分支(采用这个)

      远程仓库里的某个分支 指定为 本地仓库当前的分支(master)的一个上游分支(跟踪分支)。

      # 指定origin仓库的master分支作为上游分支
      $ git branch --set-upstream-to=origin/master
      Branch 'master' set up to track remote branch 'master' from 'origin'.
      

      以后每次pull代码只需执行git pull即可

  • 问题二:合并远程分支时,拒绝合并历史不相干的分支

    pull = fetch+merge, 这个问题出现在merge合并阶段。
    在这里插入图片描述
    历史不相干的意思是:
      远程仓库有很多次commit,本地仓库也有很多次commit;这两个仓库的提交历史没有交接的地方(没有共同的base基础),就是历史不相干。
      比如:当远程仓库R4和本地仓库的L5要合并时,由于它们两个历史不相干,所以会出现上述错误;而L5T101因为有共同的base L4,历史相干,所以这两个合并时不会出错。
    在这里插入图片描述
    解决方法:加参数--allow-unrelated-histories

    在已经确定了上游分支后,执行这行代码,远程仓库的代码会成功出现在本地仓库中

    $ git pull --allow-unrelated-histories
    # 或者
    $ git fetch
    $ git merge --allow-unrelated-histories
    

    再执行git push,本地的代码则成功上传到远程仓库。

中间也出现过这种问题:git fatal: branch ‘master‘ does not exist
解决方法:git checkout master(具体见博客)

5.4.2 git push时会出现的错误

问题背景:先创建本地仓库,后连接远程仓库,二者默认分支名不同(本地:master,远程:main)

现新建项目remote_branch, 进行以下操作

$ git init                   # 初始化仓库
$ git add . # 添加到暂存区
$ git commit -m 'aaa.js'     # 提交
$ git remote add origin git@github.com:keke474/remote-unsame.git  # 连接远程仓库
$ git branch --set-upstream-to=origin/main # 设置上游分支
$ git pull --allow-unrelated-histories     # 拉代码

接下来将本地的代码push到远程仓库中(是想把aaa文件push到远程仓库中)
在这里插入图片描述

解决方案一: 写完整版的push命令

# 将本地的master分支内容 push 到远程仓库的main分支
$ git push origin matser:main 

在这里插入图片描述

但是每次都push都需要写完整版的命令比较麻烦 如果简写为:

$ git push origin matser

则是将本地master分支的内容,push到远程仓库origin的master分支上。(远程仓库没有master分支,则执行命令时会自动创建一个master分支)

在这里插入图片描述
解决方案二:设置push

既然设置了上游分支,我们更希望git push默认会将当前分支的内容提交到上游分支中。

查看文档可知push.default的默认值为simple

在这里插入图片描述
也就说明git push默认情况下是将当前分支的内容推送到远程的同名分支中。所以需要改一下配置
在这里插入图片描述

# 设置默认将当前分支推送到上游分支
$ git config push.default upstream
# 然后只需运行git push命令即可
git push

在这里插入图片描述

另外科普一下这两个配置

# 设置将当前分支的内容推送到远程仓库的同名分支中,若远程仓库没有同名分支,则新建一个
$ git config push.default current
# 设置将当前分支的内容推送到远程仓库的同名分支中,若远程仓库没有同名分支,则报错
$ git config push.default simple

此时若新建一个分支dev,修改代码并commit后,进行push。也会报错

$ git push
fatal: The current branch dev has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin dev

最开始设置的上游分支是master的上游分支,所有dev需要重新设置上游分支。设置上游分支即可。

如果修改push默认配置为current,则远程仓库会新建一个dev分支

在这里插入图片描述

5.5 项目开发可能的流程

情况一:接触的项目已有远程仓库了
1. 克隆到本地 git clone xxx
2. 进行开发
git add .
git commit -m 'xx'
git pull
git push
情况二:要搭建一个全新的项目
1. 创建一个远程仓库(去github上新建一个远程仓库)
2. 方案一:
2.1 克隆到本地 git clone,在clone下来的文件夹中搭建整个项目
2.2 进行开发
        git add .
        git commit -m 'xxx'
        git push
        方案二:
        2.1 搭建本地项目,在项目中创建一个本地仓库(git init)
        2.2 与远程仓库建立连接 git remote add orign xxx
        2.3 建立上游分支      git branch --set-upstream-to=origin/master
        2.4 拉取代码         git fetch
        2.5 设置允许历史不相干的合并  git merge --allow-unrelated-histories
        2.6 上传本地代码 git push

5.6 常见的开源协议

在创建开源的远程仓库时,会选择开源协议;比如Vue.js是一个开源项目,开源协议就是规定,当别人用Vue开发别的项目时,需要遵守的一些约定。

在这里插入图片描述

六、 Git分支

6.1 校验和

Git中所有的数据在存储前都计算校验和,然后以校验和来引用
在这里插入图片描述
校验和作为本次提交的唯一ID,所以每次提交的校验和都是不一样的。如果回看历史记录,想知道某次提交都提交了什么文件,则该次提交的校验和作为索引值去查找。

6.2 Git的提交对象(commit object)及底层原理

结合具体例子更好的理解提交对象及底层原理:

  • 新建本地仓库,并将111.js222.js通过add命令存入暂缓区,此时,在.git/objects文件夹里,生成了两个新的文件0c3e
    在这里插入图片描述

  • 通过git cat-file -p读取0c 和3e里的这两个文件。
    在这里插入图片描述

      这个命令会自动去.git/objects文件夹里找到对应的文件(3e0017,就是指objects文件夹里名为3e的文件的 0017的文件)。读取出来发现这两个文件记录的分别是111.js222.js两个文件的内容。

  • 现通过commit将这两个js文件提交到本地仓库,会发现objects文件夹里又多了两个文件6b48

在这里插入图片描述
读取6b文件,列出了本次提交的注释等信息,以及一个tree,而tree后边指向的正是48这个文件
在这里插入图片描述
读取48文件,又列出了刚才生成的0c3e两个文件。
在这里插入图片描述
其实这些文件的名称都是唯一的,都是校验和。

总结来说,Git底层存东西原理:

每次commit提交,Git都会保存一个提交对象(Commit Object),
在这里插入图片描述

通过git log获取到该次提交的校验和,就能获取到这次提交的Commit Object。

$  git log --pretty=oneline
6bf8c7627e630f6bea80171a58dc34eeef249534 (HEAD -> master) 提交111与222js文件

提交对象里存在tree属性,而该属性的值也是一个校验和,根据该校验和可到这次提交所依赖的文件(二进制形式的111.js和222.js)。

除了第一次提交之外,后面每次提交的Commit Object对象里,都会有parent属性,指向上一次的提交对象。当执行git log时,找到的是最后一次提交的对象,然后根据parent属性,一步步找到前边提交的所有对象,然后依次列出来。

在这里插入图片描述

当将新建的ccc和ddd文件,git add .添加到暂缓区时,Git仅仅时将这两个文件作为二进制文件,保存在objects文件夹里面,并没有对应的提交对象指向这两个文件;

当执行commit命令时,才会通过提交对象的tree属性将这两个文件与提交对象联系在一起;

在这里插入图片描述

6.3 Git创建tag标签

对于重大版本,我们常常会打上一个标签,比如用标签标记发布节点(v1.0,v2.0)

  • 创建标签

    • git tag v1.0
    • git tag -a v1.1 -m '额外信息'
  • 将标签push到远程仓库

    • 默认情况下,git push不会将标签传送到远程仓库,需要指定
    • git push 仓库名 v1.0
  • 删除标签

    • 删除本地仓库标签: git tag -d v1.1
    • 删除远程仓库标签:git push 仓库名 --delete v1.1
  • 检出tag(就是切换到某一个tag节点)

    • git checkout v1.0.0

举个例子:从github 克隆空白项目到本地(github远程仓库的默认分支叫main,不是master),提交四次,并push到远程仓库中;目前HEAD指向最新节点444

在这里插入图片描述

# 将本地打的标签提交到远程仓库
$ git push origin v1.0.0
# 检出tag
$ git checkout v1.0.0
HEAD is now at c3ffb8e 333
# 当切换到v1.0.0时,一般是要创建分支,在该分支上继续别的开发,最后合并时,切回到main分支上
$ git checkout main
Switched to branch 'main'   # 切回之后,HEAD不是指向c3ffb8e了,而是最新节点555

6.4 认识Git分支

  • 在Git中,默认有一个HEAD指针指向默认分支master; Git通过Head指针判断当前处于哪个指针

  • Git的分支,本质上是一个指向Commit Object的可变指针;Git默认的分支名字是master,master分支并不是一个特殊分支,这个分支是命令git init默认创建的分支。

比如:现初始化一个项目,并commit了三次,并在提交333时,创建了一个tag;
在这里插入图片描述

此时通过git branch xxx创建分支,并通过git checkout xxx切换到该分支。

在这里插入图片描述

多个分支的来回切换,本质是改变HEAD指针的指向
在这里插入图片描述
可以看出,分支testing目前指向的是333这个节点;

当在testing分支提交test1,master分支提交444时:
在这里插入图片描述
结构变为:
在这里插入图片描述

6.5 Git分支的操作

git branch 分支名    # 创建Git分支
git checkout xxx    # 切换到xxx分支
git checkout -b xxx # 创建的同时切换分支
git merge hotfix  # 合并分支
git branch     # 查看当前所有的分支
git branch -v    # 同时查看最后一次提交
git branch --merge  # 查看所有合并到当前分支的分支
git branch --no-merge  # 查看所有未合并到当前分支的分支
git branch -d xxx   # 删除xxx分支
git branch -D xxx   # 强制删除xxx分支

6.5.1 开发项目(master分支上提交)

列举一个实际工作中的类似的工作流:

  • 开发某个项目,在默认分支master上进行发布;
  • 实现项目的功能需求,不断提交;
  • 并在一个大的版本完成时,发布版本,打上一个tagV1.0.0
  • 然后继续开发新功能
$ git init
$ git add .
$ git commit -m '111'
$ git commit -a -m '222'
$ git commit -a -m '333'
$ git tag V1.0.0
$ git commit -a -m '444'
$ git commit -a -m '555'

在这里插入图片描述

6.5.2 中途修复bug (创建并切换分支)

在继续开发后面的功能时,要求修复V1.0.0的bug

  • 切换到标签V1.0.0的节点
  • 创建hotfix分支并切换到该分支
  • 在新创建的分支上修复bug
  • 完成工作后,打上标签tag V1.0.1
$ git checkout V1.0.0    # master指向V1.0.0的版本
$ git checkout -b hotfix    # 创建并将HEAD指针切换到hotfix分支
$ git commit -a -m 'fix_01' # 提交修复后的代码
$ git commit -a -m 'fix_02' # 提交修复后的代码
$ git tag V1.0.1            # bug修复完,在该节点打标签

在这里插入图片描述
做完这些操作后,结构为:
在这里插入图片描述

6.5.3 bug修复完,合并分支,继续后续的开发

bug修复完之后,hotfix分支的fix_02与master分支的555需要合并,才能保证master后续的开发没有该bug;

  • 切换回master分支;
  • 合并hotfix分支,解决合并分支产生的冲突(修改代码)
  • commit提交修改后的文件
$ git checkout master   # 切换回master分支,此时HEAD指针指向的是最新版本(555)
$ git merge hotfix      # 在master分支上(当前处于master分支) 合并hotfix分支

合并之前,两个分支的代码分别为:
在这里插入图片描述

两个文件第7行和第9行代码不一致,合并的话这里会有冲突;合并时,Git会在文件中标明冲突的地方(有背景色的地方)
在这里插入图片描述

$ git commit -a -m '解决合并冲突'  # 提交解决冲突后的代码
$ git log --pretty=oneline --graph     # 图的方式查看一下提交记录

在这里插入图片描述
全程结构为:

在这里插入图片描述

七、 远程分支

远程分支也是一种分支结构。

7.1 远程分支的基本操作

  • 推送分支到远程仓库
    • git push <remote> <branch>
  • 跟踪远程分支
    • git checkout --track <remote/branch>
    • git checkout <branch>
  • 删除远程分支
    • git push <remote> --delete <branch>

7.2 举例

(1) 新建项目

$ git init #初始化
$ git add .
$ git commit -m 'branch.html'
$ git remote add origin git@github.com:keke474/remotebranch.git

# 设置上游分支,报错
$ git branch --set-upstream-to=origin/main   

原因是不知道远程仓库有origin/main分支。

在这里插入图片描述

方案一

所以需要先$ git fetch origin main, 这个命令的本质是拉取远程仓库mai分支的内容到自动创建的本地origin/main分支上。
在这里插入图片描述

接下来再设置上游分支

$ git branch --set-upstream-to=origin/main   # 设置上游分支,报错
# 合并的完整命令:git merge 分支名;这里不加分支名,则默认将当前分支内容与上游分支内容合并
$ git merge --allow-unrelated-histories 
# 由于本地仓库与远程仓库默认分支名称不一致,改变push的默认设置
$ git config push.default upstream
$ git push

方案二:

一切都是因为两个仓库的默认分支名不一样。执行下行命令

$ git checkout --track origin/main 

创建并切换到main分支,并且跟踪origin/main分支。此后本地仓库默认分支也叫main,就不用修改push默认配置了。直接执行git pull或者git push即可

在这里插入图片描述
注意:

  • 在执行track时,要保证本地有名为origin/main的分支,所以必须要fetch,因为fetch会创建origin/main的分支(见方案一)。
  • 保证当前仓库的内容与远程仓库一致,比如提前push,保证内容一致。否则track时,切换到main之后,本地仓库的内容将完全变成origin/main分支的内容(也就是fetch从远程仓库拉取的内容),本地的branch.html文件就没了。

(2) 新建dev分支进行开发

# 创建并切换到dev分支进行下一步开发
$ git checkout -b dev
$ git commit -a -m 'dev1'
$ git push origin dev     # 推送分支到远程,远程仓库就多了个dev分支
$ git commit -a -m 'dev2'
$ git push --set-upstream origin dev   # 再次git push还是要设置上游分支
$ git commit -a -m 'dev333'   # 开发并提交
$ git push   # 直接push推送

(3) 一位新入职的员工需要在dev分支上进行开发

$ git clone git@github.com:keke474/remotebranch.git  # 克隆项目到本地,
$ git branch  # 但是克隆下来的只有main分支
* main

$ git checkout dev             # 执行这行命令 等价于 git checkout --track origin/dev

这行命令进行了如下几步操作

  • 检查远程是否存在 origin/dev分支
  • 有的话在本地创建并切换到dev分支,并跟踪远程的origin/dev
  • 远程没有origin/dev且本地没有dev分支, 就报错
  • 本地有dev,这行命令就是切换分支


原文地址:https://blog.csdn.net/qq_44285582/article/details/144214925

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!