当前位置:   article > 正文

从零开始学Git(包括原理和代码合并思路_git 合并代码逻辑

git 合并代码逻辑

简介

作为一个以学习贯穿一生的程序员,每学习一门技术或者知识,应该静下心,学习好每个知识点,而不是只学习个皮毛而洋洋自得,所以今天从新学习下Git,以便工作中使用,面试前复习。

1.Git概念

Git是一个免费的、开源的分布式版本控制系统,可以快速高效地进行代码管理。具有廉价本地库(硬盘存储),方便的暂存区和多个工作流分支等特性。Git官网

1.1何为版本控制

版本控制是能够记录文件各个版本以及查看每个版本修改历史的系统。最重要的就是记录文件的修改记录,可以查看历史版本的同时还能切换至各个版本。

1.2 为什么需要版本控制

团队开发中,多人同时修改,无法保证代码正确同步和修改。

1.3 分布式 VS 集中式

集中式:SVN(典型)
原理:所有人代码保存在一个地方,所有人修改的都是这个地方的代码
好处:管理员和开发者都可以显著看到所有代码的修改
坏处:单点故障导致其他所有人都无法正常工作

分布式:Git
原理:每个人本地都是一个代码库,都可以做版本迭代。同时还有一个远程库。每个人都可以从这个远程库下载或者上传代码。
好处:断网时还可以做版本记录,每个人也都有完整的代码
坏处:比SVN这种集中式系统更复杂,上手难度偏高。

1.4 工作机制

在这里插入图片描述
工作区:本地文件,类似你的windows系统上的文件夹
暂存区:记录你本地的代码修改
本地库:本地定版的各个版本存档的版本库

1.5 远程库

本地库的代码可以提交到远程库(远程代码仓库)后,有远程库访问权限的人,都可以看到这个远程库代码里的修改历史和版本了。而代码托管中心则是基于网络服务器的远程库,你可以通过局域网或互联网访问到这个远程库。
基于局域网的代码托管中心:
GitLab
基于互联网的代码托管中心:
GitHub、Gitee

1.6 Git 安装

系统配置

在这里插入图片描述
默认编辑器配置
在这里插入图片描述
创建分支时的命名,master或者自定义
在这里插入图片描述
是否修改环境变量 第一个不修改,第二个选中后可以在命令行或者其他第三方工具中使用git bash,选一个就行
在这里插入图片描述
选择客户端安全协议,第一个
在这里插入图片描述
配置换行符,第一个(帮你选择,windows默认CRLF,Linux默认LF)
在这里插入图片描述
git bash里使用什么类型终端,第一个
在这里插入图片描述

代码冲突的默认合并方式,第一个
在这里插入图片描述
选择凭据管理器,第一个
在这里插入图片描述
其他配置,都选中
在这里插入图片描述实验室功能,不选
在这里插入图片描述
安装好验证
在这里插入图片描述

2. Git 常用命令

2.1 设置用户签名

提交代码前需要登记用户名和邮箱(与GitHub等代码托管中心的账号没有关系),首次安装必须设置

设置用户名
git config --global user.name 用户名
设置邮箱
git config --global user.email 邮箱
  • 1
  • 2
  • 3
  • 4

查看用户名和邮箱

cat git根目录/.gitconfig
  • 1

2.2 初始化本地库

在你想进行版本控制的文件夹下执行:
git init
执行后在该文件夹下生成 .git 文件夹,默认隐藏
  • 1
  • 2
  • 3

2.3 查看本地库状态、文件放至暂存区、提交文件、查看日志

查看 git 状态
git status 
将文件或文件夹存放到暂存区
git add file   
删除暂存区中的文件或文件夹
git rm --cached file
提交到本地库
git commit -m "日志信息"  file (file可累加,空格间隔)
查看引用日志
git reflog 
查看详细日志
git log
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2.4 版本穿梭

指针指向历史版本号,可以穿梭回过去,还可以穿梭回来
git reset --hard 版本号
  • 1
  • 2

3. 分支

在版本控制过程中,同时推进多个任务,为每个任务创建单独的分支。使用分支可以将自己的工作独立于主分支,在这个分支上操作不会影响主分支。在工作完成后,还可以将分支上的修改合并到主分支上。
分支的好处:可以同时开展多项任务,互不影响,提高效率

查看当前分支
git branch -v
在当前分支上创建分支(不修改当前所在的分支)
git branch 分支名
切换到目标分支
git checkout 目标分支名
把指定的分支合并到当前分支上(先切换到当前分支上)
git merge 分支名
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

如果合并过程发生冲突,需要手动合并(删除<<< === >>>部分,保留最终想要的代码样子),重新 add 到暂存区,再 commit 到本地库(此时不需要添加 file )

查看当前所有远程分支别名
git remote -v
创建远程库的别名
git remote add 别名 https://github.com/*****
推送代码
git push 别名 本地分支名
git push https://github.com/***** 本地分支名
拉取代码
git pull 别名 本地分支名
克隆代码
git clone https://github.com/*****
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

4. Git 配置忽略文件

4.1 为什么要忽略文件

有些文件与项目实际无关,不参与服务器上部署运行,忽略它们能屏蔽IDE工具之间的差异。

4.2 怎么忽略

  1. 创建忽略文件 git.ignore,在文件中添加想忽略的文件
# 忽略所有 jar 文件
*.jar
#......
  • 1
  • 2
  • 3
  1. 在.gitconfig文件中添加
[core]
excludesfile = C:C:/Users/git.ignore
  • 1
  • 2

以上是 Git 基础的常用命令,如果是在一两个分支或者只有少量开发人员的情况,使用和SVN几乎没有区别,但是在多个部门合作、较多人员同时开发且版本迭代较快的情况下,会同时有很多分支,这时合并分支时会有一些问题,这也是我写这个帖子的主要原因,用来梳理一些思路,以免工作中思路不清晰导致一些难以挽回的结果。

5. 多分支开发下,一些关于分支的思路

5.1 从远程分支拉取分支时,实际发生了什么

命令:

# 从远程仓库拉取feature-branch分支的内容,并在本地创建一个新的分支my-feature
git fetch origin feature-branch:my-feature
# 从远程仓库拉取feature-branch分支的内容,并在本地创建一个新的分支my-feature并切换
git fetch origin feature-branch:my-feature && git checkout my-feature
  • 1
  • 2
  • 3
  • 4

可以看出,从远程拉取分支需要指定远程分支和本地分支,从此看出,通常本地分支和远程分支有一对一的关系,一个本地分支对应一个远程跟踪分支。本地分支可以与远程分支关联,成为远程分支的本地表现,这使得你可以在本地进行修改,然后通过push将这些修改上传到远程仓库。当然,一个本地仓库也可能添加多个远程仓库,但一般不会这样操作。

5.2 merge的原理

Git中的合并(merge)操作是将两个不同分支的修改集成到一起。合并原理设计三方面内容:基地(base)、源分支(source branch)、目标分支(targe branch)。

  1. 基底 (base)

合并操作的基础是有源分支和目标分支有一个共同的祖先,这个祖先即为基底。基底是两个要合并的分支的最近的共同祖先。
Git通过找到这个共同的祖先来确定两个分支的修改点。这样合并操作就知道了基底之后分别有哪些修改。

  1. 合并算法

Git 使用第三方合并算法来执行合并操作。这个算法会比较基底、源分支和目标分支的差异,然后尝试自动合并这些差异。
如果在基底之后,源分支和目标分支都没有修改同一行代码,Git 会自动完成合并,产生一个新的提交,表示两个修改分支已经成功合并
如果在同一行代码发生不同修改,Git 会标记这个地方发生了冲突,需要人工合并。

  1. 合并冲突

合并冲突表示在同一位置有两个不同的修改,Git 无法自动决定应该选择哪一个。
在合并冲突状态下,你需要手动解决冲突。你可以编辑文件,选择要保留的修改,然后提交解决冲突的结果。

  1. 如何知道两个分支是否可以进行合并

① 最直接方式就是尝试执行合并操作
git merge 源分支 目标分支
② git log 命令查看源分支和目标分支的提交历史,确保它们有一个共同的祖先
git log --oneline --graph --all
在这里插入图片描述

5.3 merge 和 rebase 区别

merge 合并:

  1. 合并方式:
    merge 会创建一个新的合并分支,将两个分支的修改整合在一起。这个合并提交有两个父提交,分别来自两个要合并的分支
  2. 提交历史:
    merge会保留分支的独立性,合并后的历史会显示出分支的合并点。这样可以清楚地看到分支的演进。但有时会导致提交历史较为复杂
  3. 冲突处理:
    如果合并过程发生冲突,需要手动解决冲突,然后提交解决方案

rebase 变基:

  1. 合并方式:rebase 会将你的本地修改在目标分支上逐个应用,实际上它会将你的提交按照顺序逐个取出,然后再目标分支上应用,最后将目标分支指向最新的提交
  2. 提交历史:
    rebase会使提交历史更加线性,因为它不会创建合并提交,相对于merge,rebase产生的提交历史相对简洁
  3. 冲突处理:
    如果在rebase 过程中发生冲突,你也需要手动解决冲突,但与merge不同的是,你需要在每一次提交应用过程中解决冲突

总的来说: merge通常用于整合共享的分支(如主分支),而rebase则用户整理个人分支的提交历史。

5.4 切换分支有时会让你merge代码?

在Git中,当有未提交的更改,而这些更改与你要切换到的分支上某些更改存在冲突,Git不会自动合并这些修改。在这种情况,你可以选择的解决办法。

  1. 丢弃更改
    删除当前分支与目标分支冲突的修改部分
  2. 提交到本地库
  3. 暂存(stash)
    git stash
    将未提交的更改保存到一个新的statsh,并将工作区恢复到上一次提交的状态
    git stash save “stash message”
    将未提交的更改保存到一个新的stash中,并添加一条描述性消息
    git stash list
    列出当前所保存的stash
    git stash apply
    应用最新的 stash 到当前分支,并保留stash
    git stash apply stash@{n}
    应用指定索引号的stash到当前分支
    git stash pop
    应用最新的stash到当前分支,并删除stash
    git stash drop
    删除最近的stash
    git stash drop stash@{n}
    删除指定索引号的stash
    git stash clear
    删除所有保存的stash
    git stash branch branch_name
    创建一个新分支并将最近的stash应用到新分支上
    git stash show
    显示最近的stash的diff
    git stash show -p stash@{n}
    显示指定stash 的diff

暂存其实还是丢弃更改,只不过将更改从工作区丢弃,暂时放在别的地方而已
4. 强行切换分支(会导致未提交部分更改丢失)
git checkout -f targe_branch
5. 让git 尝试自动合并未提交的修改(可能导致冲突)
git checkout --merge target_branch

理解解决办法前,必须要理解工作区、暂存区、分支的本质。当前分支未提交的代码是在工作区(比如在文件末尾加了1),如果切换分支,git 会将你在工作区的代码和目标分支对比(比如目标分支文件末尾加了2),这时工作区和分支上都修改了同一个地方,git不确定使用哪个。理解这个后,就能理解为什么要使用上面的解决方法。

6. 较复杂的Git 命令

# --oneline 选项将每个提交显示为一行。
# --graph 选项以图形形式显示分支和合并历史。
# --all 选项显示所有分支的历史。
git log --oneline --graph --all
# 显示分支之间的关系
git show-branch
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号