Git 完全手册:从入门到团队协作实战(2)

发布于:2025-07-20 ⋅ 阅读:(13) ⋅ 点赞:(0)

         Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路!

我的博客:<但凡.

我的专栏:《编程之路》《数据结构与算法之美》《C++修炼之路》《Linux修炼:终端之内 洞悉真理》

感谢你打开这篇博客!希望这篇博客能为你带来帮助,也欢迎一起交流探讨,共同成长。

        这一期我们主要来说一下git中版本回退和分支的概念。

目录

1、版本回退

        1.1、版本回退的操作

        1.2、版本回退的理解 

2、撤销修改

3、分支

        3.1、分支基础操作

        3.2、分支深入理解

         3.2.1、合并冲突

        3.2.2、合并模式

          3.2.3、bug分支

        3.2.4、删除临时分支


1、版本回退

        1.1、版本回退的操作

        如果我们想恢复到上一次提交,我们该怎么做呢?

        现在,我准备了一个readme文件,并且在文件中分三次提交了test1,test2,test3:

        我们使用以下命令回退到上一个版本:

git reset --hard HEAD~1

        但是,没有那么简单,我们有三点细节需要说明:

        第一,我们以上的命令是把工作区,暂存区,版本库全部回到了上一个版本,但是,在实践中我们可能只向让其中一个或两个回退,那么这个回退的范围是根据选项来区分的,其中--mixed是默认选项。

         那么我们怎么控制回退的版本呢?我们HEAD后面跟的数字就是回退的版本数,没错,我们可以一次性回退两个版本。

        我们恢复到最开始的样子,再次回退,但是不回退工作区,只回退暂存区和版本库:

        接着使用命令查看工作区和暂存区的内容区别:

git diff

        我们可以使用命令查看当前的本地仓库内容,或者叫查看最后一次提交:

git show HEAD

        我们再使用以下命令,打印版本库和暂存区的区别

git diff --cached HEAD

         第二,我们以上的更改都是对本地仓库进行的修改,如果我们想远端更新,就得在强制推送覆盖远端内容,使用以下命令:

git push --force origin <branch-name>

         但是,这样很明显是不安全的,在多协作场景下强制推送会导致其他开发者的进度丢失。我们可以使用以下命令代替:

git revert HEAD

        我们就不实验了,以后我们会详细讲。 

        第三,如果我们版本更新了一百次,但是我们要回到第一次更新,怎么办呢?

        我们可以使用命令,打印出历史上每次更新的commit id

git log --pretty=oneline

        接着执行以下命令,回退到指定版本:

git reset [选项] commit id

        现在我们回退到test1提交。

        然后我后悔了,这时候怎么办呢?我们可以执行以下命令,查看我们想要回到的那个版本的commit id:

git reflog

        接着复制commit id,和刚才一样的操作,回到指定版本。 

        1.2、版本回退的理解 

         git是如何实现以上版本版本回退的操作的呢?

        我们可以发现,git的版本回退实际上速度是很快的。因为git内部有个指向当前分支的HEAD指针,在refs/heads/master文件中保存着master分支最新的commit id,当我们版本回退时,仅仅是更改一下指针的指向:

2、撤销修改

        有时候,我们想撤销一些区域的修改,比如说我们想让工作区的新增内容撤销,而不改变暂存区和工作区。那么这种情况在版本回退中是没有对应的指令的,此时我们该怎么办呢?

        我们分别讨论以下三种情况:

        情况一:

        这种情况下我们可以选择手动修改,不过更好的方式是使用以下指令:

git checkout -- 文件名

        情况二:

        这种情况我们可以直接使用git reset --hard。因为我们可以拿到上一次提交的commit id,然后恢复版本,这样的话实际上版本库是不进行更改的,而工作区和暂存区回退到上一个版本了。从整体来看,就是我们使用git reset回退到了当前版本。

        或者我们使用git reset  --mixed, 此时就和情况一一样了,然后我们再按照情况一的方法更改。

         情况三:

        这种情况我们直接使用git reset --hard HEAD~1就好了。在这里还是要强调一下,我们这些修改都是针对本地仓库来说的,对于远程仓库的操作我们以后再说。

3、分支

        3.1、分支基础操作

        Git 分支是开发中用于隔离不同工作流的独立线路。每个分支代表一个独立的提交历史,便于并行开发、实验性功能实现或问题修复,而不会影响主分支。

        Git的分支功能是一个非常强大的功能,分支功能的出现,就允许了一个团队中的不同成员,同时进行项目不同部分的开发,并在开发完成之后,合并到主分支中。大家可以想一下,有了分支功能,我们的总体效率会大大的提高。

        现在我们就先来简单介绍一下如何创建分支和和并分支。

         首先我们使用以下命令查看当前的分支

git branch

        我们使用以下命令创建分支

git branch 分支名

        我们的HEAD默认是指向master的,HEAD被指向的分支就是当前工作的分支。

        我们可以通过以下指令查看当前的HEAD指向哪个分支

cat .git/HEAD

        当然,直接branch也可以看当前在那个分支,分支前带星号的就是当前分支:

         我们可以通过以下命令切换分支:

git checkout dev

        现在,我们在dev分支上进行一些修改代码,提交的操作,我们来理解一下这个过程

        master和dev这两个分支始终指向自己这个分支上最新的一次提交。如果我们在dev分支提交东西,那么dev分支创建出一个新的提交节点,并且指向他。 

        接下来我们合并两个分支:

git merge 分支名

        需要注意的是我们不能在当前分支下合并自己。我们得先切换到master分支然后git merge dev。当然了我们其实也可以把master合并到dev上。

        我们来看一下合并之后的状态图:

        接下来我们介绍一下如何删除分支:

git branch -d 分支名

        我们不能删除当前的分支。 

        3.2、分支深入理解

         3.2.1、合并冲突

        当我们合并的两个分支内容发生冲突时,就会出现合并冲突的情况,比如,两个分支分别在同一个文件中添了一行不同的代码,此时如果进行合并操作,git就闹不清我们到底该保留哪一行代码了。

        我们首先创建一个这样的情景,在dev分支中,我们为readme文件添加一行“dev test”字符串,在master分支中添加一行"master test"。接着我们尝试把dev合并到master上:

        我们尝试合并操作,他会提示合并失败,接着我们打开readme文件:

        git已经给我们显式出了冲突内容,我们需要手动删除,保留需要更改的部分。接下来我们使用git add .和git commit就可以了。

         我们可以通过以下命令,查看我们合并过程的图示:

git log --graph --abbrev-commit

        3.2.2、合并模式

         其实merge的模式是可以选择的。默认我们使用的都是ff(fast forward),这种模式的合并我们看不出来是merge出来的还是commit出来的。所以我们一般使用no-ff模式:

git merge --no-ff dev

Fast-Forward (FF) 模式
        当目标分支(如 main)的最新提交是当前分支(如 feature)的直接祖先时,Git 默认会采用 FF 模式合并。这种合并不会创建新的合并提交,而是简单地将 main 分支的指针移动到 feature 分支的最新提交上。历史记录保持线性,没有分叉。

A --- B --- C (main)
       \
        D --- E (feature)

执行 git merge feature 后(FF 模式):

A --- B --- C --- D --- E (main)

No-Fast-Forward (--no-ff) 模式
        通过 git merge --no-ff 强制禁用 FF 模式,即使满足 FF 条件,Git 也会创建一个新的合并提交。这会保留分支的拓扑结构,明确显示分支的合并点,便于追踪历史。

A --- B --- C (main)
       \
        D --- E (feature)

执行 git merge --no-ff feature 后:

A --- B --- C --------- F (main)
       \              /
        D --- E ------

        为了我们的提交记录更清晰,我们推荐使用no-ff模式。


          3.2.3、bug分支

        在开发的过程中,我们经常利用临时分支来修复bug。比如现在我们的master分支上就出现了一个bug,我们会新建一个分支,在这个分支上修复bug,最后再合并。

        那么假设我们已经有了一个分支,并且正在这个分支上写代码,这时突然发现master上有bug,我们想用这个分支去修复bug,可是这个分支的开发内容刚进行了一半,我们也无法提交了,这时候该怎么办呢?

        在git中,我们可以使用git stash命令,对当前工作区信息进行存储,被存储的内容以后可以恢复出来。说白了,就是暂时保存一下当前分支的代码:

git stash

         我们可以通过命令查看工作区:

git status

         接着我们就可以安心的切回到master分支,然后新建修改bug的临时分支。

        当我们修复完分支之后,可以切换回刚才的分支,我们刚才的代码可以用以下命令查看:

git stash list

        我们可以通过以下命令恢复现场

git stash pop

        我们可以使用以下命令来恢复现场

git stash apply #恢复现场但不删除stash内容
git stash drop  #删除stash内容

        接着我们完成dev分支的任务,合并到master上。 

        此时的状态图应该是这样的:

        但是我们不建议这样修复bug!因为在最终dev合并到master上是可能会有冲突。我们手动解决冲突的话无法保证对于冲突问题一次性解决掉,因为在实际的项目中,代码冲突不只一两行那么简单。

        我们建议的是在合并时首先把master合并到dev上,在dev分支测试没问题之后再合并到master上:

        3.2.4、删除临时分支

         如果我们的分支已经完成了合并,那我们可以使用之前的删除分支命令,可是如果这个分支还没有完成合并,我们想要删除他,就需要以下命令:

git branch -D 分支

        好了,今天的内容就分享到这,我们下期再见! 


网站公告

今日签到

点亮在社区的每一天
去签到