分布式版本控制Git

蒸汽
蒸汽
发布于 2024-11-07 / 8 阅读
0
0

分布式版本控制Git

git

git定义:分布式版本控制工具

github定义:代码托管平台

作用:

1.保存文件的所有修改记录

2.使用版本号进行区分(Hash:SHA1)

3.随时可浏览历史版本记录

4.可还原到历史指定版本

5.对比不同版本的文化差异

版本控制:

本地式:记录文件每次的更新,可以对每个版本做一一个快照,或是记录补丁文件,适合个人用,如RCS

image-20241107090635700.png

集中式:代表SVN,有一个中央服务器,所有内容都提交到这个服务器上

image-20241107090644690.png

分布式:代表git,每一台机器也是分布式的一个节点,有本地仓库,也有集中仓库

image-20241107090701785.png

4、Git与SVN最主要区别

SVN是集中式版本控制系统,版本库是集中放在中央服务器的而工 作的时候,用的都是 自己的电脑」所以首先要从中央服务器得到最新的版本,然后工作,完成工作后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,对网络带宽要求较高。
​
Git是分布式版本控制系统,没有中央服务器,每个人的电脑就是一个完整的版本库 ,工作的时候不需要联网了,因为版本都在自己电脑上。协同的方法是这样的:比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A ,这时,你们两之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
​
Git是目前世界上最先进的分布式版本控制系统。

基本概念

Git的组成

Git本地有三个工作区域:工作目录( Working Directory )、暂存区(Stage/Index)、 资源库(Repository或Git Directory)。如果在加上远程的==git仓库(Remote Directory)==就可以分为四个工作区域。文件在这四个区域之间的转换关系如下:

image-20241107090848055.png

  • Workspace :工作区,就是你平时存放项目代码的地方

  • lndex/ Stage :暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息

  • Repository :仓库区(或本地仓库) ,就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本

  • Remote :远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换,远程仓库别称:originimage-20241107091107438.png

  • Directory :使用Git管理的一一个目录,也就是- -个仓库 ,包含我们的工作空间和Git的管理空间。

  • WorkSpace :需要通过Git进行版本控制的目录和文件,这些目录和文件组成了工作空间。

  • .git:存放Git管理信息的目录,初始化仓库的时候自动创建。

  • Index/Stage :暂存区,或者叫待提交更新区,在提交进入repo之前,我们可以把所有的更新放在暂存区。

  • Local Repo :本地仓库, -个存放在本地的版本库; HEAD会只是当前的开发分支( branch)。

  • Stash :隐藏,是-一个工作状态保存栈,用于保存/恢复WorkSpace中的临时状态。

Git的配置:

协议

1.http

2.ssh

生成公钥和私钥地址

git keygen -t rsa -C "邮箱"

配置用户名和邮箱

git config --global user.name "jichao" #名称
git config --global user.email 799755381@qq.com #邮箱
​

Git工作流程

1、在工作目录中添加、修改文件;
2、将需要进行版本管理的文件放入暂存区域;
3、将暂存区域的文件提交到git仓库。

image-20241107091329542.png

暂存区:svn中没有暂存区,每次提交都是直接提交到中央,导致可能很多无意义的提交,暂存区就是为了统一提交,减少无用提交

项目搭建与常用命令

工作目录( WorkSpace)一般就是你希望Git帮助你管理的文件夹,可以是你项目的目录,也可以是一一个空目录 ,建议不要有中文。 日常使用只要记住下图6个命令:image-20241107091439333.png

git add [文件名] :添加到暂存区

git commit [文件列表] -m "注释" : 提交到本地仓库

git push origin master : push 到远程仓库(origin)的 master分支

git pull :从远程仓库拉取到工作区

版本号:40位哈希

head:一个指针指向最近一次提交的记录(当前检出记录的符号引用)

操作

基本操作

1、文件4种状态

版本控制就是对文件的版本控制,要对文件进行修改、提交等操作,首先要知道文件当前在什么状态,不然可能会提交了现在还不想提交的文件,或者要提交的文件没提交上。

  • Untracked:未跟踪,此文件在文件夹中,但并没有加入到git库,不参与版本控制通过git add状态变为Staged

  • Unmodify:文件已经入库,未修改,即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处,如果它被修改,而变为Modified. 如果使用 git rm移出版本库,则成为Untracked文件

  • Modified:文件已修改,仅仅是修改,并没有进行其他的操作.这个文件也有两个去处,通过git add可进入暂存staged 状态,使用git checkout则丢弃修改过,返回到-unmodify状态,这个git checkout即从库中取出文件,覆盖当前修改!

  • Staged:暂存状态.执行git commit则将修改同步到库中,这时库中的文件和本地文件又变为-致,文件为unmodify 状态.执行git reset HEAD filename 取消暂存,文件状态为Modified

2、查看文件状态

上面说文件有4种状态,通过如下命令可以查看到文件的状态:

#查看指定文件状态
git status [filename]
​
#查看所有文件状态
git status
​
#git add .                    添加所有文件 到暂存区
​
#git commit -m "消息内容"     提交暂存区中的内容到本地仓库-m 提交信息
​

逆向操作

image-20241107091820548.png

对于正向操作来说,Git 操作是由 workspace进行add操作进入Index,再commit到Repository,最后push到Remote。

但有时候也需要一些逆向操作,比如数据文件已经由 workspace进行add操作进入Index了,但是发现本次提交的数据有些问题,想把它撤回来,即撤到workspace中;或者数据文件已经commit到Repository了,但是,我们想把数据回退,将其回退到Index或 workspace,甚至删除提交记录等。这就需要逆向操作

逆向操作思维导图:

image-20241107091846669.png

本地仓库 到 暂存区、工作区及清空

如果数据已经由暂存区(Index)提交(commit)到本地仓库(Repository)了,现在想要回退,应该怎么操作?

可以使用git reset --soft, git reset --mixedgit reset --hard ,它们的区别在于它们对工作区、暂存区和提交历史的影响程度不同。

git reset --soft:主要是回退到 暂存区。

  • 影响范围:仅影响 HEAD 的位置。

  • 效果:不更改工作区和暂存区的内容,仅仅移动 HEAD 指针。

  • 适用场景:适合于需要修改最近提交历史的情况,但不想丢失当前工作区和暂存区的变更。

git reset --mixed:主要是回退到 工作区(workspace),--mixedgit reset命令的默认参数。

  • 影响范围:影响 HEAD 的位置和暂存区。

  • 效果:不更改工作区内容,但是会将 HEAD 移动到指定提交,同时将这个提交之后的修改放入暂存区。

  • 适用场景:当需要撤销提交并且希望保留更改但不立即提交时使用。可以重新选择要包含在下一次提交中的更改。

git reset --hard:完全取消提交和相关更改,就像重来没提交过一样。

  • 影响范围:影响 HEAD、暂存区和工作区。

  • 效果:将 HEAD 指向指定的提交,同时重置暂存区和工作区到该提交,丢弃所有未提交的更改。

  • 适用场景:适合于需要完全撤销到某个提交的情况,且不关心之前的修改。

git reset --soft命令用于重置当前分支的 HEAD 到一个指定的提交(commit),但不会更改工作区的文件或暂存区的内容。这个命令主要用于在不丢失当前工作内容的情况下,调整提交历史。因此--soft的方式是一种比较温和的方式进行重置。

语法:

git reset <--soft or --mixed or --hard> <commit or HEAD>
​

选择 git reset --soft 的场景:

修改最近的提交历史:当你需要修改最近的一个或多个提交时,可以使用 git reset --soft 将 HEAD 重置到相应的提交,然后重新组织和提交更改。

保留当前工作内容:如果你希望保留当前工作区和暂存区的内容,并在之后再次提交它们,git reset --soft 是一个不会丢失更改的选择。

合并多次提交:可以用 git reset --soft 将多个小的提交合并成一个更大的提交,这样可以保持提交历史的整洁性和可读性。

工作区清空

要将工作区的数据清空,可以使用git checkout命令。主要用于在不同的分支之间切换、恢复文件或提交状态,以及创建新分支。

git checkout命令可以丢弃未暂存的更改,但是不会删除新文件。例如:

# 丢弃所有未暂存的更改:
​
git checkout .
​
# 丢弃自上次提交以来对文件的所有未暂存更改
​
git checkout <file>

git checkout -f 是 Git 中用于强制切换分支或者恢复文件到某个状态的命令。

基本用法:

切换分支:当你想要切换到另一个分支,而当前分支上有未提交的更改时,执行 git checkout -f <branch> 会强制你切换到指定的 <branch>,并丢弃当前分支上的所有未保存的更改。也就是说,未提交的更改会被清除。

恢复文件:如果你想要恢复某些文件到最后一次提交的状态,可以使用 git checkout -f <file>。这也会丢弃该文件在工作区中的更改,恢复为上次提交的状态。但是不会删除新文件。

例子:

# 强制切换到分支 `feature-branch`
​
git checkout -f feature-branch
​
# 强制恢复文件 `example.txt` 到最后一次提交的状态
​
git checkout -f example.txt

问题:为什么不建议git rebase合并分支

常见场景:

两次merge:先切换到develop把master合并过来测试,没问题再切换回master把develop放过来合并

分支操作:

场景1:已有本地分支,远程需要新建对应同名分支

**git push --set-upstream origin** 本地分支名

命令含义:当前分支推送设置到上游 : origin 远程分支名。 作用:在远程新建一个同名分支,将本地的内容push到这个远程分支

image-20241107092855622.png

场景2:已有远程分支,本地需要新建对应同名分支 场景:假设同事在远程创建了分支branch_name,在你本地没有该分支。此时要拉取该分支怎么办?

        git checkout --track origin/远程分支名

命令含义:在本地创建一个同名新分支,切换到此分支,追踪到远程的对应分支 命令作用:在本地创建一个同名新分支,切换到此分支,追踪到远程的对应分支,将内容拉下来

image-20241107092941534.png

可能遇到的问题

场景3:已有不同名本地分支和远程分支,让他们track

git branch --set-upstream-to=origin/远程分支名 本地分支名
1

命令含义:本地分支设置上游to : origin/远程分支名

这种情况下的push要注意,不能直接git push,要像下面这样

    git push origin head:远程分支名
    # 将本地的head指针前的内容推送到远程分支

例如:将本地的test2分支追踪到远程的test分支

image-20241107093026436.png

更新提交

image-20241107093035206.png

不推荐第三种,一般都是本地与远程分支名对应

冲突处理:

在多人协作的软件开发中,通常会使用分支来并行开发不同的功能或修复bug。当一个分支上的修改与另一个分支上的修改发生冲突时,就会出现分支冲突。这种情况需要开发者手动干预,解决冲突并合并代码。

image-20241107093211547.png

2 解决办法

方法1)使用开发工具命令解决分支冲突-回退到上一个指定版本

git reset

image-20241107093531592.png

查看结果已回退

git reflog

image-20241107093432425.png

注意:使用 git reset 命令回滚到指定的版本。有两种模式可供选择:

请注意,使用--hard 选项会彻底删除未提交的更改,请谨慎使用。

<commit_hash> 是您想回滚到的提交的哈希值。

软重置(soft reset):这种方式会保留更改,但是会取消上一次提交。使用以下命令:

bashCopy Code

git reset --soft <commit_hash>

硬重置(hard reset):这种方式会放弃所有更改,回滚到指定版本。使用以下命令:

bashCopy Code

git reset --hard <commit_hash>

方法2)切换版本解决分支冲突-新建分支新开发

git checkout -b 

image-20241107093531592.png

注意:新分支要基于干净的分支来拉取,然后名字要区分已经存在的旧分支

如果远程分支中存在与本地分支不兼容的更改,您可以使用以下命令将远程分支的更改合并到本地分支并解决冲突:

  1. 首先,确保您在本地分支上操作。如果不在本地分支上,请使用以下命令切换到本地分支:

git checkout feature_20240124_20240126_v2_添加统计图表

  1. 接下来,运行以下命令拉取远程分支的最新更改并合并到本地分支:

git pull origin feature_20240124_20240126_添加统计图表
​

这将从远程仓库(origin)拉取远程分支(feature_20240124_20240126添加统计图表)的最新更改,并尝试将其合并到本地分支(feature_20240124_20240126_v2添加统计图表)中。

如果在合并过程中发生冲突,您需要手动解决冲突。Git 会在冲突部分标记出 <<<<<<<=======>>>>>>>,您需要根据需要编辑文件,然后保存修改。

  1. 解决冲突后,运行以下命令将解决后的更改推送到远程分支:

git push origin feature_20240124_20240126_v2添加统计图表:feature_20240124_20240126添加统计图表

方法3)删除本地分支,重新拉取远程的分支

git branch -d 和git branch -D

git branch -dgit branch -D 是用于删除本地分支的 Git 命令。它们之间的区别在于删除分支时对于未合并的更改的处理方式。

  • git branch -d <branch_name>:这个命令会删除指定的本地分支 <branch_name>。但是,如果该分支有未合并的更改,Git 会阻止删除,并给出警告。您需要先将未合并的更改合并到其他分支或放弃它们,然后再执行删除操作。

  • git branch -D <branch_name>:这个命令会强制删除指定的本地分支 <branch_name>,即使它有未合并的更改。使用该命令会立即删除分支,而不管是否有未合并的更改。

请注意,使用 -D 命令删除分支时要谨慎。如果您误删除了一个有重要更改的分支,这些更改可能会永久丢失。因此,在使用 -D 命令之前,请确保您已备份或保存了所有重要的更改。

总结来说,git branch -d 是安全的删除本地分支的方式,会防止意外删除尚未合并的更改。而 git branch -D 是强制删除本地分支的方式,即使有未合并的更改也会立即删除分支。

冲突实例:

pull

image-20241107100208105.png

造成这种情况是因为,本地master分支修改了A.txt文件,并且远程master的A.txt文件也被修改了(此时我不知道远程被改了)。 解决方案就是(其实报错截图很清楚了,在push之前先pull一下),当我们pull完之后会发现本地分支的A.txt文件有变化如下图,然后手动选择一个要保留的,是保留第二行还是保留第四行,然后删除其他所有行,保存后执行命令add、commit(会弹出对话框提示冲突信息,直接:q即可)。然后git push即可 image-20241107100225373.png

merge

image-20241107100237580.png

造成这种情况的原因是,我在本地分支master上修改了B.txt文件(修改内容echo b >> B.txt),然后add、commit。然后本地分支conflict也修改了B.txt文件(修改内容echo a >> B.txt),然后add、commit。接下来我就切换到本地master分支执行merge,报错。 解决方案就是,当你执行merge后,查看本地master分支的B.txt文件发现有变化如下图,选择保留第二行还是保留第四行,然后删除其他所有行,保存后执行命令add、commit(会弹出对话框提示冲突信息,直接:q即可)。到此代码合并完毕。

image-20241107100258105.png

注意,解决冲突时会弹出冲突信息的对话框,直接:q即可

image-20241107100324605.png

使用规范

项目对象:

后续补充

分支管理:

后续补充

实际分支模型

后续补充


评论