• [工具] Git版本管理(二)(分支)


    一、分支

    1.git中如何保存版本

    在我们以往使用文件来进行版本控制的时候,都是将上一个版本复制一份,然后在其基础上进行修改。

    但在git中,git只保存当前版本和上一个版本之间的差异,这样可以节省存储空间, 在生成版本的时候速度也会更快。

    2.Master主线

    如下图所示:

    当只有一条主线Master时,新版本都是在上一个版本的基础上进行修改的,例如Version2在Version1的100个文件基础上,新增了20个文件,并修改了其中10个文件。

    也就是说Version2只需要保存新增的20个文件,以及修改的10个文件的修改信息,当我们需要Version2的时候,git再去Version1中拿未修改的90个文件。

    同理,Version3、Version4也是如此。

    3.分支概念

    当我们需要已某个版本作为基准,同时开发多个新功能,则可能在该基准版本处产生分支,如下图所示:

    处理线上系统的紧急BUG:

    例如,Version3是已上线的版本, 我们在Version3的基础上开发新功能:

    Version3突然出现紧急BUG,需要修复,怎么办?我们可以在Version3的基础上新开一个分支,专门用作BUG修复,修复完后合并到主分支:

     而负责新功能开发的分支,可以继续研发新功能,不受影响。等到新功能开发测试完毕后,也可以合并到主分支Master中去。

    4.创建分支(开发新功能)

    1)查询分支信息

    git branch

    可以看到,我们目前只有一个master主分支。

    2)创建新的分支(开发商城功能)

    git branch dev_shop

    使用命令创建了一个分支,叫做dev_shop。用于开发新功能,商城。

    "*"号代表我们所处的分支。

    3)切换分支

    使用命令:

    git checkout dev_shop

    可以看到,我们已经切换到了dev_shop分支,我们在这个新分支下编写代码,是不会影响到其他分支的。

    通过git log查看一下版本信息:

     可以看到,我们所处的版本是"修改约饭-->约",但是分支处于dev_shop。而在这个版本处存在两个分支:master和dev_shop。相当于下图所示:

    如果我们在dev_shop分支上再生成一个版本,则会变成如下:

    在分支中添加了商城功能后,使用git log查看版本信息:

    5.创建分支(修改BUG)

     1)切换回master分支

    git checkout master

    2)创建新分支(修改BUG)

    git branch bug

    查看分支:

    git branch

    3)切换到BUG分支

    git checkout bug

    修改代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Index</title>
    </head>
    <body>
        <ul>
            <li>欧美</li>
            <li>日韩</li>
            <li>港台澳</li>
            <li>直播</li>
            <li></li>
        </ul>
    </body>
    </html>

    将"港台"修改为"港台澳"。并提交生成新的版本。

    此时查看git log:

     此时的分支结构为:

    6.合并分支

    将bug分支合并到master分支中。

    1)切换回master分支

    git checkout master

    2)合并bug分支

    git merge bug

    查看当前的版本信息:

     当前的分支结构:

    7.删除分支

    当Master分支将bug分支合并之后,bug分支就没用了,可以使用命令删除bug分支:

    git branch -d bug

    删除后,查看当前分支信息:

    可以看到bug分支已经被删除。

    8.继续开发dev_shop

    1)从Master切换到dev_shop

    git checkout dev_shop

    2)继续开发dev_shop,并提交

    9.将dev_shop合并到Master中

    1)切换回Master分支

    git checkout master

    2)合并dev_shop分支

    git merge dev_shop

    当合并的时候,如果没有冲突(例如都是添加代码),则可以自动合并。

    自动合并后会生成一个新的版本:

    如果产生了冲突(例如修改了同一行代码),则自动合并失败。

    当产生冲突的之后,git会将两个文件所修改的地方全部放在文件中,然后由我们人工进行处理:

     我们人工修改为最终版本后,再次进行git add 、 git commit操作,重新提交即可。手工生成的版本信息,由我们自己指定。

    二、分支总结

    1.查看分支

    git branch

    2.创建分支

    git branch 分支名

    3.切换分支

    git checkout 分支名

    4.合并分支

    git merge 分支名

    注意,假设分支2要合并到分支1中,则需要切换到分支1中执行"git merge 分支2"。

    三、简单工作流

    git中默认有一个master分支,但是不建议我们直接在master分支上去做开发,master分支主要用于保存正式版本(稳定版本)。

    我们开发新的功能,都应该去一个单独的分支上去做开发。例如叫dev的分支。如图所示:

    从图中可以看到,我们的开发都在dev分支上做,而master分支的版本都是稳定版本。

    类似于QQ的稳定版和beta版,稳定版在master分支中,beta测试版在dev分支中。

    以上就是最基本的工作流。

    四、github

    github和git其实没有本质的联系,github只是一个类似于云盘的代码仓库。除了github,还有CSDN、码云等平台也提供类似的功能。

    要使用github,需要以下几个步骤:

    1)注册一个github账号

    2)创建一个仓库

    3)将本地代码推送到github仓库

    1.注册github账号

    (略)

    2.创建仓库

    Repository name尽量与项目名一致,方便查找。

    Description用于描述项目。

    Public表示开源(代码公开),Private表示只有自己能看到。

    Initialice this repository with a README,自动创建一个README文件。

    Add .gitignore表示创建一个不被git管理的文件夹

    Add a license表示我们代码的许可证。

    3.推送代码到仓库

     在我们的项目文件夹中打开git bash窗口,执行命令:

    git remote add origin https://github.com/leokale/dbhot.git

    origin就是我们要推送的目的仓库的别名。

    然后再执行push命令:

    git push -u origin master

    推送master分支到仓库。

    此时会弹出一个用户名密码窗口,用于github验证:

    输入账号密码通过验证后,可以看到推送成功:

    此时,我们可以在github中看到仓库里存放着master分支的相关文件:

    推送dev_shop分支的代码到仓库:

    git push -u origin dev_shop

    第二次推送,就无需验证github账号密码了。

    此时,在github仓库中,可以看到多出了一个dev_shop分支。

    4.从仓库拉代码

    例如我们在另一台PC上,进入一个根目录(用于存放dbhot项目文件夹)。

    在该目录打开git bash:

    获取仓库的地址:

     使用命令拉取代码:

    git clone https://github.com/leokale/dbhot.git

    可以看到该目录下出现dbhot文件夹:

    进入目录使用git bash即可:

    5.github总结

    1)给远程仓库起别名

    git remote add xxxx 远程仓库地址

    2)向远程推送代码

    git push -u xxxx 分支名

    3)克隆全程仓库代码

    git clone 远程仓库地址

    当克隆代码之后,实际上帮我们执行了git remote add origin 远程仓库地址。所以我们以后推送的时候,可以使用origin就可以了。

    五、局部代码推送与拉取

    例如目前的版本结构如下图所示:

    当我们要继续在dev_shop分支上去做开发时,发现dev_shop分支的代码不是最新的,因为master分支合并了bug分支和dev_shop分支。所有当前master分支才是最新的。

    所以,我们在开发代码之前,首先在本地将master分支合并到dev_shop分支中,让dev_shop分支变为最新代码:

    git checkout dev_shop
    git merge master

    合并后,dev_shop分支中的代码已经变为最新版,也就是和master分支一样,版本为"Merge branch 'dev_shop' "。

    1.推送部分代码(在PC-A上的操作)

    在dev_shop分支中开发新代码(例如新增一个a1.py文件):

    touch a1.py

    保存一个版本:

    git add a1.py
    git commit -m "在PC-A添加了一个新文件a1.py"

    推送到仓库:

    git push origin dev_shop

    此时在仓库的dev_shop分支中可以看到:

    2.拉取部分代码(在PC-B上的操作)

    首先,切换到dev_shop分支:

    git checkout dev_shop

    然后,拉取在PC-A上提交的部分代码(a1.py文件):

    git pull origin dev_shop

    在a1.py中添加内容:

    # a1.py文件
    
    print("HELLO WORLD")

    将新的代码推送给仓库:

    git add a1.py
    git commit -m "在PC-B中修改了a1.py"
    git push origin dev_shop

    3.pull命令分解

    在git中,git pull命令实际上可以拆分为以下两个命令:

    git fetch origin dev_shop
    git merge origin/def_shop

    git fetch的意思是将dev_shop分支从远程仓库(github)拉回本地版本库。由于拉回版本库,可能和本地的dev_shop不一致,所以名字为origin/dev_shop

    git merge origin/dev_shop的意思是将原来仓库拉下来的dev_shop(origin/dev_shop)合并到工作区。

    当然,merge的时候origin/dev_shop分支和本地的dev_shop可能存在冲突(例如PC-A上开发的代码忘了推送,然后在PC-B上又开发了其他代码并推送到了仓库,再在PC-A上fetch下来,就会不一样),需要我们手工解决冲突。

    六、查看版本分支结构

    1.graph参数

    使用git log查看版本结构的时候,可以加上--graph参数:

     

    2.简化模式

    git log --graph --pretty=format:"%h %s"

    %h:hash值(短)

    %H:hash值(长)

    %s:备注信息

    %an:作者

    %ae:作者email

    %ad:提交时间

    其他格式化字符参考:

    git log --help

    七、变基(rebase)

    变基:git  rebase。

    有以下三种使用场景。

    1.合并多个提交记录

    当我们反复在不同的地方开发代码时,可能会经常commit,然后push,这样会生成很多提交记录(版本)。这对于我们自己可能是由意义的,但是对于其他协同开发者是没有意义的。

    例如,在某个项目中,我们一共有4条提交记录:

    假设,我们想将v2~v4合并成一个提交:

    git rebase -i af57743e74ce9f36a8f142e87cd10599b6a36fc4

    后面的ID就是v2这个提交的ID。他会将v2~当前提交这三条提交合并成一个提交。

    另一种方式:

    git rebase -i HEAD~3

    HEAD~3是从当前提交往前数3个提交,合并成一个。

    执行上述任意一个命令后,会进入以下画面:

    我们关注最前面的三行(pick *****),将v3和v4的"pick"修改为"s":

    表示将v3和v4合并到v2中,:wq保存,进入另外一个画面:

    修改合并后的commit的描述信息:

    :wq保存:

    执行git log查看提交记录:

    我们可以看到,合并后的commit的时间和v2的时间一致。

    2.补充

    在执行git rebase HEAD~3命令以后,进入的第一个画面:

    我们关注的最前面三行,是分别对三个版本的处理方式:

    1)pick:表示使用commit,如果3个版本都是pick,则不发生任何改变,还是v2 v3 v4。

    2)reword:同pick,使用commit,但是可以修改备注信息。保存后,会进入修改备注的页面。按r指定的版本,一个一个修改备注。

    3)squash:标记为s的版本,会向前合并,例如v4标记为s,则会合并到v3中,以此类推。

    4)fixup:和squash很像,但不会进入修改备注的界面,也就是说丢弃标记f的版本的备注信息,并合并到前一个版本中。

    5)drop:删除指定的版本。

    注意:在使用rebase合并版本时,最好不要是已经push到仓库的版本,最好是合并好后再push到仓库中。

    2.将分支的版本合并进master(变成master一条线)

    例如,我们目前master有2个版本,分别为m1和m2。

    在m1处,创建了分支dev,并且提交了版本d1。

    此时的结构如下:

    我们如果使用git merge命令,则会将其变为:

    但是我们想将其变得更简洁,例如下图:

    使用命令:

    git checkout dev  # 切换到dev分支
    git rebase master  # 将dev作为base,相当于将master合并进dev
    git checkout master  # 切换回master
    git merge dev  # 将dev合并到master

    执行上述命令后,master和dev分支的版本都是m1<----m2<----d1。如果不需要dev分支,则将其删除即可:git branch -d dev

    3.合并不产生分叉

    在《第五节:局部代码推送与拉取》中,我们在PC-A和PC-B上分别开发了代码,PC-A提交在本地版本库,但没有推送到远程仓库。而PC-B的推送到了远程仓库。

    当我们在PC-A上pull仓库的代码时,git会帮我们自动进行合并,但可能产生冲突,然后由我们手动解决冲突。

    我们知道pull命令可以拆分为:

    git fetch origin dev
    git merge origin/dev
    
    

    但是,在这种情况下,一定会产生分叉,因为fetch回来的分支叫做 origin/dev,而本地的叫做dev。

    此时,可以使用rebase来代替merge:

    git fetch origin dev
    git rebase origin/dev

    4.rebase时解决冲突

    当我们在master和dev分支中都对同一个文件的同一行进行了修改,并都提交到了版本库。我们使用rebase将他们合并成一条分支时,会报冲突错误:

    此时,我们可以按照报错提示,去m3.py中查看冲突:

    解决冲突:

    然后执行命令,继续rebase:

    git add m3.py  # 处理完冲突后,要使用add加入暂存区或使用rm命令删除
    git rebase --continue  # 然后继续执行rebase操作

    666

  • 相关阅读:
    Comet OJ
    Comet OJ
    Comet OJ
    Comet OJ
    Codeforces Round #562 (Div. 2)
    P1202 USACO1.1 黑色星期五
    P1201 USACO1.1 贪婪的送礼者
    【线段树】HDU1166:敌兵布阵
    标准C++中的string类的用法总结(转)
    【递归】分形
  • 原文地址:https://www.cnblogs.com/leokale-zz/p/12115554.html
Copyright © 2020-2023  润新知