Git基础操作及其分支管理

目录

一、git的用处?

1.1 git也不是银弹

二、安装git

三、git基础操作

3.1 创建git本地仓库

3.2 配置Git

 3.3 认识工作区、暂存区、版本库

3.4 添加文件

3.5 Git文件目录

3.6 版本回退

3.7 撤销修改

3.7.1 对于工作区的代码,还没有进行add操作

3.7.2 已经 add,但没有 commit

 3.7.3 已经add,并且也 commit了

3.8 删除文件

四、Git分支管理

4.1 理解分支

4.2 创建分支(图的dev分支即为代码的test-branch分支)

4.3 切换分支

4.4 合并分支

4.5 删除分支

4.6 合并冲突

4.7 分支管理策略

4.8 分支策略 

4.8.1 master遇到bug并且分支正在开发该怎么处理?

4.8.2 删除临时分支

五、总结


一、git的用处?

提出问题

不知道你工作或学习时,有没有遇到这样的情况:我们在编写各种⽂档时,为了防止文档丢失,更改 失误,失误后能恢复到原来的版本,不得不复制出⼀个副本,

比如:

“报告-v1”

“报告-v2”

“报告-v3”

“报告-确定版”

“报告-最终版”

“报告-究极进化版”

每个版本有各⾃的内容,但最终会只有⼀份报告需要被我们使用。 但在此之前的工作都需要这些不同版本的报告,于是每次都是复制粘贴副本,产出的文件就越来越多,⽂件多不是问题,问题是:随着版本数量的不断增多,你还记得这些版本各自都是修改了什么吗? 文档如此,我们写的项目代码,也是存在这个问题的!!

如何解决——版本控制器

为了能够更方便我们管理这些不同版本的⽂件,便有了版本控制器。所谓的版本控制器,就是能让你 了解到⼀个文件的历史,以及它的发展过程的系统。通俗的讲就是⼀个可以记录工程的每⼀次改动和 版本迭代的⼀个管理系统,同时也方便多人协同作业。 目前最主流的版本控制器就是Git。Git可以控制电脑上所有格式的⽂件,例如doc、excel、dwg、 dgn、rvt等等。对于我们开发⼈员来说,Git 最重要的就是可以帮助我们管理 软件开发项目 中的 源代码 文件!

1.1 git也不是银弹

需要注意的是:

还需要再明确⼀点,所有的版本控制系统,Git也不例外,其实只能跟踪⽂本⽂件的改动,⽐如TXT⽂ 件,网页,所有的程序代码等等。版本控制系统可以告诉你每次的改动,⽐如在第5⾏加了⼀个单词 “Linux”,在第8⾏删了⼀个单词“Windows”。 ⽽图⽚、视频这些⼆进制⽂件,虽然也能由版本控制系统管理,但没法跟踪⽂件的变化,只能把⼆进 制⽂件每次改动串起来,也就是只知道图⽚从100KB改成了120KB,但到底改了啥,版本控制系统不 知道,也没法知道。

二、安装git

这里以centos为例,安装之前先检查一下是否已经安装:

命令行:

git --version

 如果以安装会显示相关版本号: 

安装git 命令行如下:

sudo yum install git -y

三、git基础操作

3.1 创建git本地仓库

创建一个Git本地仓库对应的命令为:git init,注意该命令是需要在文件目录下执行的:

创建后使用 ll -a 来查看.git文件。

ll -a

拆解一下:

  1. ll 是 ls -l 的别名,用于列出目录中的文件和子目录,并显示它们的详细信息,如权限,所有者,组,大小和最后修改时间。
  2. -a 是ls命令的一个选项,代表all,表示显示所有文件,包括以.开头的隐藏文件。

当然也可以使用 tree 命令查看 .git 里面是什么(前提:tree 命令需要手动安装)

 不要手动 修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。

3.2 配置Git

当安装Git后首先要做的事情是设置您的 用户名称 和 e-mail 地址。这是`非常重要的。配置命令为:

git config [--global] user.name 'your name'

git config [--global] user.email 'email@example.com'

其中 --global 是⼀个可选项。如果使用了该选项,表示这台机器上所有的Git仓库都会使用这个 配置。如果你希望在不同仓库中使用不同的 name 或 注意的是,执行命令时必须要在仓库里。

使用 git config -l 来查看当前git的配置。

以下是非全局的配置:

如果是想取消配置,那么如下:

以下是全局git的配置:

当然,如果是全局配置的话,想要删除这个配置,那么同样也要加上 --global,否则删除失效。

 3.3 认识工作区、暂存区、版本库

  • 工作区:是在电脑上你要写代码或文件的目录。
  • 暂存区:英文叫 stage 或 index。⼀般存放在 .git 目录下的index文件(.git/index)中,我们把暂存区有时也叫作索引(index)。
  • 版本库:又名仓库,英文名repository 。工作区有⼀个隐藏目录.git ,它不算工作区,而是Git的版本库。这个版本库里面的所有文件都可以被Git管理起来,每个⽂件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。下⾯这个图展示了工作区、暂存区和版本库之间的关系:

图中左侧为工作区,右侧为版本库。Git 的版本库里存了很多东西,其中最重要的就是暂存区。

  • 在创建Git版本库时,Git会为我们自动创建⼀个唯⼀的 master 分支,以及指向master的⼀个指针叫HEAD。(分支和HEAD的概念后面再说)。
  • 当对工作区修改(或新增)的文件执行 git add 命令时,暂存区目录树的⽂件索引会被更新。
  • 当执行提交操作 git commit 时,master 分支 会做相应的更新,可以简单理解为暂存区的目录树才会被真正写到版本库中。

由上述描述我们便能得知:通过新建或粘贴进目录的文件,并不能称之为向仓库中新增文件,而只是在工作区新增了文件。必须要通过使用 git add 和 git commit  命令才能将文件添加到仓库中
进行管理!!!

3.4 添加文件

在包含.git的目录下新建⼀个 ReadMe 文件,我们可以使用 git add 命令将文件添加到暂存区:

  • 添加⼀个或多个⽂件到暂存区: git add [file1] [file2] ...
  • 添加指定目录到暂存区,包括子目录: git add [dir]
  • 添加当前目录下的所有⽂件改动到暂存区: git add .

再使用 git commit 命令将暂存区内容添加到本地仓库中:
提交暂存区全部内容到本地仓库中: git commit -m "message" 
提交暂存区的指定文件到仓库区: git commit [file1] [file2] ...  -m "message"

注意 git commit 后⾯的 -m 选项,要跟上描述本次提交的 message,由用户自己完成,这部分内容绝对不能省略,并要好好描述,是用来记录你的提交细节,是给我们人看的。

例如:

git commit 命令执行成功后会告诉我们,1个文件被改动(就是我们新添加的FirstFile⽂件),插入了两行内容(FirstFile 有两行内容)。
我们还可以多次 add 不同的文件,而只 commit ⼀次便可以提交所有文件,是因为需要提交的文件是通通被 add 到暂存区中,然后⼀次性 commit 暂存区的所有修改。如

截至目前为止,我们已经更够将代码直接提交至本地仓库了。我们可以使用 git log 命令,来查看
下历史提交记录:

该命令显示从最近到最远的提交日志,并且可以看到我们 commit 时的日志消息。
如果嫌输出信息太多,看得眼花缭乱的,可以试试加上 --pretty=oneline 参数:

需要说明的是,我们看到的⼀⼤串类似 23807c5...56eed6 的是每次提交的 commit id (版本
号),Git 的 commit id 不是1,2,3……递增的数字,⽽是⼀个 SHA1 计算出来的⼀个非常大的数字,⽤十六进制表示。

3.5 Git文件目录

[root@iZ0jl7jamelmq7pl8qut26Z gitcode]# tree .git/
.git/
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── fsmonitor-watchman.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-merge-commit.sample
│   ├── prepare-commit-msg.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── push-to-checkout.sample
│   └── update.sample
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
│       └── heads
│           └── master
├── objects
│   ├── 54
│   │   └── 990fb04a5f51d9209095edc784aa8b546fd753
│   ├── 76
│   │   └── 18edfd30e673463bf8d35e8e5059609678a9aa
│   ├── 87
│   │   └── 9bc3d4d27694d78e531cb35a008a11cfeed3c2
│   ├── e6
│   │   └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│   ├── ea
│   │   └── eeb89160446a3b6ff525a6fd7b2231326139c6
│   ├── f6
│   │   └── 98d3f274aa44d867c89912c82eeae58f52e8d9
│   ├── info
│   └── pack
└── refs├── heads│   └── master└── tags
  1. index 就是我们的暂存区,add 后的内容都是添加到这⾥的。
  2. HEAD 就是我们的默认指向 master 分支的指针

而我们master所指向的其实就是最新一次提交的commit id。

objects 为 Git 的对象库,里面包含了创建的各种版本库对象及内容。当执执行 git add  命令
时,暂存区的⽬录树被更新,同时⼯作区修改(或新增)的⽂件内容被写⼊到对象库中的⼀个新的对象中,就位于".git/objects"目录下。让我们来看看这些对象有何用处:

查找 object 时要将 commit id 分成2部分,其前2位是⽂件夹名称,后38位是⽂件名称。
找到这个文件之后,⼀般不能直接看到里面是什么,该类⽂件是经过 sha (安全哈希算法)加密过的⽂件,好在我们可以使⽤ git cat-file  命令来查看版本库对象的内容:

其中我们查看tree,发现就是我们提交的所有git记录。

 总结⼀下,在本地的 git 仓库中,有⼏个文件或者目录很特殊

  • index:暂存区, git add 后会更新该内容。
  • HEAD: 默认指向 master 分⽀的⼀个指针。
  • refs/heads/master: ⽂件⾥保存当前  master 分⽀的最新 commit id 。
  • objects: 包含了创建的各种版本库对象及内容,可以简单理解为放了 git 维护的所有修改

需要注意的是,git add 只是将数据添加到缓存区中,而不是添加到版本库中。只有commit才是添加到版本库中。

Git 比其他版本控制系统设计得优秀,因为 Git 跟踪并管理的是修改,而非⽂件。
什么是修改?比如你新增了一行,这就是⼀个修改,删除了一行,也是⼀个修改,更改了某些字符,也是⼀个修改,删了⼀些⼜加了⼀些,也是⼀个修改,甚⾄创建⼀个新⽂件,也算⼀个修改,

这里我们 对 1.txt 进行修改,作者这里使用的是finalshell,可以直接对其进行修改,我们对文件新增内容 ttt:

我们可以用 git status 命令用于查看你上次提交之后是否对文件进行再次修改,但是这往往不够,我们只知道改动的文件是什么,不知道改动的内容是什么,

所以 我们可以用命令 git diff [文件名] 来显示 工作区和暂存区文件的差异

 当然 也可以用git diff head -- [file] 命令来查看工作区和版本库文件的区别。

3.6 版本回退

Git 能够管理⽂件的历史版本,这也是版本控制器重要的能力。如果有⼀天你发现
之前前的⼯作做的出现了很⼤的问题,需要在某个特定的历史版本重新开始,这个时候,就需要版本回退的功能了。
执行 git reset  命令⽤于回退版本,可以指定退回某⼀次提交的版本。要解释⼀下“回退”本质是
要将版本库中的内容进⾏回退,⼯作区或暂存区是否回退由命令参数决定:

git reset  命令语法格式为: git reset [ --soft | --mixed | --hard ] [HEAD]

  • --soft 参数对于工作区和暂存区的内容都是不变,只是版本库回退到指定版本。
  • --mixed 为默认选项,使用时可以不用带该参数,该参数将暂存区和版本库的内容退回为指定提交版本。
  • --hard 参数将暂存区和工作区以及版本库都回退到指定版本,切记工作区有未提交的代码时不要使用这个命令,因为工作区会回滚,你没有提交的代码就再也找不回了,所以使用该参数前一定要慎重。

HEAD 说明:

  • 可直接写成 commit id,表示指定退回的版本
  • HEAD 表示当前版本 
  • HEAD^ 上⼀个版本 
  • HEAD^^ 上上⼀个版本 
  • 以此类推

示例:

这里我们就通过 git log --pretty=oneline 的方法来获取每次提交的日志,由于这里显示的commit id是从最新到最老的,所以我们这里拿最老的commit id,回退到最初的状态:

当然了,如果想反悔了呢?那么我们就继续从当前终端上获取刚刚显示的 最新的commit id,即可进行回滚:

当然了,有时候可能终端上找不到刚刚那个commit id 了,比如各种意外情况,进行了 clear 清屏操作,或者是 掉电之类的,

git 也会提供对应的解决方案,使用 git reflog 方法可以查看本地提交的所有git记录。

值得说的是,Git 的版本回退速度非常快,因为Git在内部有个指向当前分支(此处是master)的HEAD 指针, refs/heads/master 文件⾥保存当前 master 分⽀的最新 commit id 。当我们
在回退版本的时候,Git 仅仅是给 refs/heads/master  中存储⼀个特定的 version,可以简单理解
成如下示意图:

3.7 撤销修改

3.7.1 对于工作区的代码,还没有进行add操作

可能有人会说,使用 git diff xxx 命令,来看看区别在哪,但是如果你书写了很多代码,这时候就不太好撤销了,因为人工可能有出错的可能的,Git为我们提供了更好的方式:

git checkout -- [file] 

该命令让工作区的文件回到最近一次 add 或 commit 时的状态。需要注意的是,git checkout -- [file] 该命令中的 -- 很重要,切记不能忽略,一旦忽略,该命令就变为其他意思了。

示例如下:

使用 该命令后,1.txt 文件中的内容全部都回退到改动之前的版本了。

3.7.2 已经 add,但没有 commit

直接使用之前学过的 git reset操作:

 3.7.3 已经add,并且也 commit了

不要担心,我们可以 git reset --hard HEAD^ 回退到上⼀个版本!不过,这是有条件的,就是
你还没有把⾃⼰的本地版本库推送到远程。还记得Git是分布式版本控制系统吗?我们后⾯会讲到远程版本库,⼀旦你推送到远程版本库,那就没办法了。

分析:之前版本1.txt 是有 ttt和 222的,现在变回ttt了。 

3.8 删除文件

在git中,删除也是一个修改操作,比如 我们要删除这个2.txt该如何删除呢?

第一种方式需要3步,先在工作区 利用 rm 命令删除文件,然后将其状态add进暂存区,最后commit。

对于第⼀种情况,很明显是没有删完,我们只删除了⼯作区的⽂件。这时就需要使用 git rm  将文件从暂存区和工作区中删除,并且 commit:

可以看出,git rm 这个命令,相比于第一种情况,省了add的过程。

四、Git分支管理

4.1 理解分支

在版本回退里,你已经知道,每次提交,Git都把它们串成⼀条时间线,这条时间线就可以理解为是⼀个分支。截至到目前,只有⼀条时间线,在Git⾥,这个分⽀叫主分⽀,即 master 分支。再来理解⼀下HEAD,HEAD 严格来说不是指向提交,⽽是指向 master,master才是指向提交的,所以,HEAD 指向的就是当前分支。

每次提交,master 分支都会向前移动⼀步,这样,随着你不断提交,master分⽀的线也越来越长,⽽HEAD只要⼀直指向master分支即可指向当前分支。
通过查看当前的版本库,我们也能清晰的理出思路:

4.2 创建分支(图的dev分支即为代码的test-branch分支)

Git支持我们查看或创建其他分支,在这里我们来创建第一个自己的分支,对应的命令为:

当我们创建新的分支后,Git新建了一个指针叫 dev,* 表示当前HEAD指向的分支是master分支。另外,可以通过目录结构发现,新的 dev 分支。

发现目前 dev 和 master 指向同一个修改。并且HEAD目前是指向master的:

用一张图总结:

4.3 切换分支

那如何切换到dev分支下进行开发呢?使用 git checkout 命令即可:

如图所示,为切换后的效果,HEAD指向当前分支: 

现在我们在dev分支下,进行修改文件,并进行commit操作,观察master分支下是否能感应到?

我们使用finalshell,在1.txt上进行添加内容,但是切换到master分支后查看文件发现并没有添加。

而刚刚我们在test-branch上修改的是存在的:

当切换到master分支的时候,图中的HEAD指针就会指向master,当然就看不到修改了。

这是就需要我们进行手动的合并分支操作。 

4.4 合并分支

为了在 master 主分⽀上能看到新的提交,就需要将 dev 分⽀合并到 master 分支,示例如下:

git merge 命令⽤于合并指定分支到当前分支。合并后,master 就能看到 test-branch 分支提交的内容了。此时的状态如图如下所示:

Fast-forward 代表“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度⾮常快。
当然,也不是每次合并都能 Fast-forward,我们后面会讲其他⽅式的合并。

4.5 删除分支

合并完成后,test-branch 分支对于我们来说已经没用了,那么test-branch就可以被删除掉,注意如果当前正处于某分支下,就不能删除当前分支,如:

而可以在其他分支下删除当前分⽀,如


此时的状态如图如下所示:

4.6 合并冲突

在实际分⽀合并的时候,并不是想合并就能合并成功的,有时候可能会遇到代码冲突的问题。
为了演示这问题,创建⼀个新的分支 dev1 ,并切换至目标分⽀,我们可以使⽤  

git checkout -b dev1

一步完成创建并切换的动作,示例如下:

在dev1分支下修改1.txt文件,并进行commit提交:

此时在master分支上,我们再次对1.txt文件进行修改,并且进行commit操作:

 这个时候,dev1和master分支上都有了新的提交,如下所示:

 这时候git合并冲突的时候就会出现如下的问题:

 发现 ReadMe 文件有冲突后,可以直接查看文件内容,要说的是Git 会⽤ <<<<<<<,=======,>>>>>>>来标记出不同分⽀的冲突内容,如下所示:

此时我们需要手动调整冲突代码,并需要再次提交修正后的结果。(注意:再次提交非常重要,切勿忘记)。

 此时冲突就解决了,这时候git的状态变为如下所示:

使用带参数的git log 也可以看到分支的合并情况: 

4.7 分支管理策略

通常合并分⽀时,如果可能,Git 会采⽤ Fast forward 模式。还记得如果我们采用 Fast
forward 模式之后,形成的合并结果是什么呢?回顾⼀下

如下所示: 

在这种 Fast forward 模式下,查看分支历史时,会丢掉分支信息,看不出来最新提交到底是 merge 进来的还是正常提交的。
虽然在合并冲突部分,我们可以看到解决冲突问题的状态,这存在一些弊端(不方便排查是谁干的):

Git 支持我们强制禁⽤ Fast forward 模式,那么就会在 merge 时生成⼀个新的 commit ,这样,
从分支历史上就可以看出分支信息。
下面我们实战⼀下 --no-ff 方式的 git merge 。首先,创建新的分支 dev2 ,并切换至新的分
⽀:

请注意 --no-ff 参数,表⽰禁⽤ Fast forward 模式。禁用 Fast forward 模式后合并会创建
⼀个新的 commit ,所以加上 -m 参数,把描述写进去。
合并后,查看分支历史:

 可以看到,不使⽤ Fast forward 模式,merge后就像这样:

所以在合并分支时,加上 --no-ff 参数就可以⽤普通模式合并,合并后的历史有分⽀,能看出来曾
经做过合并,⽽ fast forward 合并就看不出来曾经做过合并:

4.8 分支策略 

在实际开发中,我们应该按照几个基本原则进行分⽀管理:
⾸先,master分支应该是非常稳定的,也就是仅⽤来发布新版本,平时不能在上面干活;
那在哪干活呢?⼲活都在dev分支上,也就是说,dev分⽀是不稳定的,到某个时候,⽐如1.0版本发布时,再把dev分⽀合并到master上,在master分支发布1.0版本;
你和你的小伙伴们每个⼈都在dev分支上干活,每个⼈都有自己的分支,时不时地往dev分支上合并就可以了。
所以,团队合作的分支看起来就像这样:

4.8.1 master遇到bug并且分支正在开发该怎么处理?

假如我们现在正在 dev2 分支上进行开发,开发到一半,突然发现master分支上面有bug,需要解决。在git中,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。

可现在 dev2 代码在工作区中开发了一半,还无法提交,怎么办呢?(需要注意的是,在dev2分支未进行commit操作的时候,dev2和master上所看到的内容都是一样的)

Git 提供了 git stash 命令,可以将当前的⼯作区信息进⾏储藏,被储藏的内容可以在将来某个时
间恢复出来:

存储dev2 工作区内容后,由于我们要基于master分支修复bug,所以需要切回master分支,再新建一个临时的分支来修复bug,示例如下:

修复完成后,切换到master分支,并完成合并,最后删除fix-bug分支:

至此,bug的修复工作已经做完了,我们还要继续回到dev2分支上进行开发:

工作区是干净的,刚刚的写的代码去哪了? 我们使用git stash list 命令查看:

⼯作现场还在,Git 把 stash内容存在某个地⽅了,但是需要恢复⼀下,如何恢复现场呢?我们可以使 ⽤ git stash pop 命令,恢复的同时会把 stash 也删了,示例如下:

再次查看的时候,我们已经发现已经没有现场可以恢复了:

另外,恢复现场也可以采用 git stash apply 恢复,但是恢复后,stash内容并不删除,你需要
⽤ git stash drop 来删除;

当然,你可以多次stash,恢复的时候,先⽤ git stash list 查看,然后恢复指定的stash,⽤命令
git stash apply stash@{0} ,这部分就不细讲了。

恢复完代码之后我们便可以继续完成开发,开发完成后便可以进行提交,例如:

但我们注意到了,修复 bug 的内容,并没有在 dev2 上显示。此时的状态图为:
 

Master 分支 目前 最新的提交,是要领先于新建 dev2 时基于的 master 分⽀的提交的,所以我们
在 dev2 中当然看不见修复 bug 的相关代码。

我们的最终目的的是要让 master 合并 dev2 分支的,那么正常情况下我们切回 master 分⽀直接合
并即可,但这样其实是有⼀定⻛险的。
是因为在合并分支时可能会有冲突,⽽代码冲突需要我们手动解决(在 master 上解决)。我们无法保证对于冲突问题可以正确地⼀次性解决掉,因为在实际的项⽬中,代码冲突不只一两行那么简单,有可能几十上百行,甚至更多,解决的过程中难免⼿误出错,导致错误的代码被合并到 master 上。此时的状态为:



解决这个问题的⼀个好的建议就是:最好在自己的分⽀上合并下 master ,再让 master 去合并
dev ,这样做的目的是有冲突可以在本地分支解决并进行测试,而不影响 master 。

第一步:dev合并master分支,用于解决合并冲突。

第二步:合并冲突已解决,master合并dev。 

代码如下:

dev2上合并master,并进行解决冲突:

切回master分支,进行合并dev2分支:

4.8.2 删除临时分支

软件开发中,总有⽆穷⽆尽的新的功能要不断添加进来。
添加⼀个新功能时,你肯定不希望因为⼀些实验性质的代码,把主分⽀搞乱了,所以,每添加⼀个新功能,最好新建⼀个分支,我们可以将其称之为 feature 分支,在上面开发,完成后,合并,最
后,删除该  feature  分支。
可是,如果我们今天正在某个  feature 分支上开发了⼀半,被产品经理突然叫停,说是要停止新功
能的开发。虽然白干了,但是这个 feature  分支还是必须就地销毁,留着无用了。这时使⽤传统
的 git branch -d 命令删除分⽀的⽅法是不行的。演示如下:

由于这里的newdev分支上的内容已经是commit状态了,所以无法通过 -d 进行 删除,

只能通过 -D 进行删除。

五、总结

分支在实际中有什么⽤呢?假设你准备开发⼀个新功能,但是需要两周才能完成,第⼀周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别⼈不能⼲活了。如果等代码全
部写完再⼀次提交,⼜存在丢失每天进度的巨大⻛险。
现在有了分⽀,就不⽤怕了。你创建了⼀个属于你⾃⼰的分⽀,别⼈看不到,还继续在原来的分⽀上正常⼯作,⽽你在⾃⼰的分⽀上⼲活,想提交就提交,直到开发完毕后,再⼀次性合并到原来的分支上,这样,既安全,⼜不影响别人⼯作。
并且 Git ⽆论创建、切换和删除分⽀,Git在1秒钟之内就能完成!⽆论你的版本库是1个⽂件还是1万个⽂件。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/811047.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习51单片机必备:从电子基础到编程技巧全解析

学习51单片机需要掌握一系列的基础知识和技能&#xff0c;以下是一些主要的学习内容&#xff1a; 电子基础知识 了解基本的电子元件和电路原理是学习单片机的基础。这有助于理解单片机如何与外围设备交互以及如何设计电路。 数字逻辑 理解数字逻辑和布尔代数&#xff0c;对于编…

Redis性能管理和集群的三种模式(二)

一、Redis集群模式 1.1 redis的定义 redis 集群 是一个提供高性能、高可用、数据分片、故障转移特性的分布式数据解决方案 1.2 redis的功能 数据分片&#xff1a;redis cluster 实现了数据自动分片&#xff0c;每个节点都会保存一份数据故障转移&#xff1a;若个某个节点发生故…

探索柔性负荷在综合能源系统中的优化调度策略

柔性负荷&#xff0c;指的是那些可以根据系统需求和市场信号调整其使用模式的负荷。它们包括可平移负荷、可转移负荷和可削减负荷。这些负荷的灵活性为IES&#xff08; Integrated Energy System, 综合能源系统&#xff09;提供了额外的调节能力&#xff0c;有助于平衡供需、提…

MyBatis实例更新

MyBatis具体 准备工作 预编译SQL 新增 更新 查询 //查询员工Select("select * from emp where id #{id}")public Emp getById(Integer id);//方案一:给字段起别名&#xff0c;让别名与实体类属性一致Select("select id,username,password,name,gender,image,j…

DataX案例,MongoDB数据导入HDFS与MySQL

【尚硅谷】Alibaba开源数据同步工具DataX技术教程_哔哩哔哩_bilibili 目录 1、MongoDB 1.1、MongoDB介绍 1.2、MongoDB基本概念解析 1.3、MongoDB中的数据存储结构 1.4、MongoDB启动服务 1.5、MongoDB小案例 2、DataX导入导出案例 2.1、读取MongoDB的数据导入到HDFS 2…

Failed to load dll

Unity运行时提示 dll 加载失败 Plugins: Failed to load ‘Assets/Plugins/xxx.dll’ because one or more of its dependencies could not be loaded. 使用 Dependency Walker 查看这个 dll 引用&#xff0c;一推引用丢失 最后确认是 C 组件缺失 打开 Visual Studio Install…

Java基础入门--第十一章--JDBC(Java Database Connection)Java数据库连接

JDBC 11.1 什么是JDBC11.1.1 JDBC概述11.1.2 JDBC驱动程序 11.2 JDBC的常用API11.3 JDBC编程11.3.1 JDBC 编程步骤11.3.2 实现第一个JDBC程序 我的MySQL的root密码: root 11.1 什么是JDBC 11.1.1 JDBC概述 JDBC的全称是Java数据库连接&#xff08;Java Database Connectivit…

光威神策PRO PCIe 5.0 SSD发布,国产固态硬盘进入10G俱乐部

全球半导体供应链的紧张局势和闪存资源的短缺让许多行业都面临着不小的压力 &#xff0c; 连带的也让消费者难以获取物美价廉的闪存产品 。但是&#xff0c;总有一些企业能够逆流而上&#xff0c; 像是 光威科技这家国产存储品牌&#xff0c; 最近就给国内消费者 带来了一个惊喜…

【JAVA基础篇教学】第六篇:Java异常处理

博主打算从0-1讲解下java基础教学&#xff0c;今天教学第五篇&#xff1a; Java异常处理。 异常处理是Java编程中重要的一部分&#xff0c;它允许开发人员在程序运行时检测和处理各种错误情况&#xff0c;以保证程序的稳定性和可靠性。在Java中&#xff0c;异常被表示为对象&am…

【Kafka】Zookeeper集群 + Kafka集群

Zookeeper 概述 Zookeeper是一个开源的分布式的&#xff0c;为分布式框架提供协调服务的Apache项目。 Zookeeper 工作机制★★★ Zookeeper从设计模式角度来理解&#xff1a; 1&#xff09;是一个基于观察者模式设计的分布式服务管理框架&#xff1b; 它负责存储和管理大家都关…

AI大模型创新交汇点:当AI遇见艺术

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

代码随想录算法训练营三刷 day48 |动态规划之 198打家劫舍 213打家劫舍II 337打家劫舍III

三刷day48 198.打家劫舍1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组 213.打家劫舍II情况一&#xff1a;考虑不包含首尾元素情况二&#xff1a;考虑包含首元素&#xff0c;不包含尾元素情况三&…

LinkedList部分底层源码分析

JDK版本为1.8.0_271&#xff0c;以插入和删除元素为例&#xff0c;LinkedList部分源码如下&#xff1a; //属性&#xff0c;底层结构为双向链表 transient Node<E> first; //记录第一个结点的位置 transient Node<E> last; //记录最后一个结点的尾元素 transient …

域控软件安全隔离关键技术剖析:MCU域 VS SOC域

安全隔离的需求 功能安全开发中&#xff0c;软件阶段由软件V模型左边的软件安全需求SSR开始。SSR是从技术安全需求TSR中提取出软件的功能安全需求&#xff0c;大多数情况下具有不同的ASIL等级。 图1 功能安全软件开发V模型 随后&#xff0c;软件安全需求会被分配到软件架构中的…

AcWing-滑动窗口

单调队列模板题&#xff1a; 所需知识&#xff1a;单调队列 利用双端队列来实现单调队列&#xff1b; 双端队列与普通队列的不同处&#xff1a;双端队列删除元素时既可以删除队头又可以删掉队尾&#xff0c;其可以较好的维护单调队列的单调性&#xff1b; 双端队列的定义及…

蓝桥杯-数组切分

问题描述 已知一个长度为 N 的数组: A1,A2,A3,...AN 恰好是1~ N的一个排列。现 在要求你将 4 数组切分成若干个 (最少一个,最多 N 个)连续的子数组,并且 每个子数组中包含的整数恰好可以组成一段连续的自然数。 例如对于 4 1,3,2,4,一共有 5 种切分方法: 1324:每个单独的数显然…

卫星影像联合无人机实现农业保险全生命周期监管监测

随着科技的进步&#xff0c;农业保险监管系统的发展日新月异。特别是近年来&#xff0c;随着卫星技术与无人机技术的结合&#xff0c;为农业保险监管系统带来了前所未有的革新。本文将深入探讨如何利用卫星与无人机方案构建高效的农业保险监管系统&#xff0c;并结合实例进行说…

Dart 中 JS 互操作的历史

由于在 Dart 3.3 中达到了令人兴奋的 JavaScript 互操作里程碑&#xff0c;Wasm 的支持刚刚登陆当前的 Flutter 测试版。为了庆祝这一里程碑&#xff0c;我们回顾了 Dart 和 JavaScript 互操作性长达十年的历程。 从 Dart 诞生之初&#xff0c;互操作性就是一个核心重点。2011…

golangci-lint 报错

File is not gci-ed with --skip-generated -s standard,default (gci) golangci-lint 报错上面的错解决办法&#xff1a; 1. 文件换行需要换成"LF" 而不是"CRLF" ---->>> 我用的goland IDE&#xff0c;随便在这个文件删除一个空行&#xff…

20240412,引用,函数高级

老子什么时候能找到一个很爱我还和我一样喜欢看日出日落的对象 一&#xff0c;引用 给变量起别名&#xff0c;数据类型 & 别名原名&#xff1b;引用一定要初始化&#xff0c;初始化之后不能更改 #include <iostream> using namespace std; int main() {int a 10;i…