当前位置:   article > 正文

git切换分支_Git学习笔记和整理心得

git 切分支

寒假在昆明呆了3天,因为闲着没事做,所以把Git教程看了看。鉴于之前学习python不懂得整理,导致后来选择性遗忘没。所以就抽出一天时间来,整理一下Git的一些常用命令和自我理解的通俗性语言。

Git的定义

Git是一种分布式版本控制系统,顾名思义,就是每个人的计算机都是一个完整的版本库,它允许多人进行协作,是因为它强大的分支管理(后面会提及),而不是像集中式那样,只有一台中央服务器,其他计算机需要进行开发时,必须向中央服务器申请。一旦中央服务器出现了宕机,项目进度就只能被迫停止。总而言之,Git方便代码管理,为协作编程和进行版本控制提供了极大便利。

安装Git

Git可以在Windows上跑,也可以在Linux上跑,当然其他操作系统也可以。本次我安装在Windows上。首先去Git官网下载、默认安装。成功之后,在开始菜单找到Git Bash,OK安装成功

bc3b1a5e98eca1a0b1af72907b359e88.png

一、二、Git的使用及其操作

我所理解的Git的使用是在服务器(也就是自己的计算机上),可以建立多个仓库,每个仓库对应一个项目,仓库=U盘嘛。别人可以clone你的仓库,修改你的代码,你也可以在对代码进行版本控制(比如发布v1.0、v2.0)和游戏版本一样。

1.1建立仓库

所以首先我们先创建一个文件夹:

  1. mkdir <仓库名>
  2. cd <仓库名>
  3. pwd //密码

然后将它变成Git可以来管理的仓库

git init

OK,Git就把仓库建好了。

1.2 提交文件到仓库

在该文件夹下编写一个.txt文件

vi readme.txt

然后通过git add,将文件从工作区添加到仓库中的缓存区(stage)中,

git add readm.txt

再通过git commit,将文件从缓冲区中提交到仓库中

git commit -m "我写了一个readme,厉害不"   //-m是本次提交说明

补充一点,最好“”里面的

文字用英文代替,中文很容易乱码,我在这纯属以后方便记忆。

总结一下:(我就直接用廖雪峰老师的话来代替了)

初始化一个Git仓库,使用 git init命令。
添加文件到Git仓库,分两步:
使用命令 git add <file>,注意,可反复多次使用,添加多个文件;
使用命令 git commit -m <message>,完成。

2.1 版本回退

假设我们对readme.txt 做了多次修改,要是我们想还原到某一次修改的地方,我们应该怎么找到那一次修改呢?用git log

git log

然后在git log 里找到你对应版本的地址,16进制的,通常你输入前面几个,Git就会自动找到该版本。但我墙裂建议用

git log --pretty=online    //超级清爽有木有

334a0be07000e9e25eb85577b37111da.png
黄色部分即代表版本地址

现在,我们要回退到比如&simple版本

git reset --hard a065af

现在再查看readm.txt 的内容

cat readme.txt

就回发现已经到那一个版本了。

还有一种办法,因为在Git中HEAD指针始终是指向最后一次commit的,要是只想回去上一次,可以这样操作:

git reset --hard HEAD^ //回退到上一个版本

ok,继续借用老师的总结:

HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令 git reset --hard commit_id
穿梭前,用 git log可以查看提交历史,以便确定要回退到哪个版本。
要重返未来,用 git reflog查看命令历史,以便确定要回到未来的哪个版本。

2.2撤销修改

git checkout -- file可以丢弃工作区的修改:

git checkout -- readme.txt

命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:

一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

总之,就是让这个文件回到最近一次git commitgit add时的状态。

但是会有这么一种情况:你修改了文件,而且还将它add到了缓存区了,但还没有提交。这时候,可以把缓存区的修改撤销掉,重新放回工作区:这需要2步

1、

git reset HEAD readme.txt

2、

这时候,再丢弃工作区的修改:

git checkout -- readme.txt
OK,又到了小结时间:
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令 git checkout -- file
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令 git reset HEAD <file>,就回到了场景1,第二步按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。

2.3删除文件

在本地的文件,可以直接用rm命令删除:

rm test.txt

这时候,Git知道你删除了哪些文件(通过git status 可看出),此时,工作区和版本库就不一致了。如果你要从版本库中删除该文件,这样做:

  1. git rm test.txt
  2. git commit -m "remove test.txt"

现在,文件就从版本库中删除了。

但如果是误删了,可以从版本库中恢复最新的:

git checkout -- test.txt

PS:写总结可真累了,总算把第一部分写完了,明天抽空接着写最重要分支管理叭


昨天总结完了Git的一些“增删改查”,今天开始总结一下分支。

三、分支管理理解:

我所理解的分支是:假设一个项目是一条主线,它是由各个功能板块(函数?)构成的,假设没有分支的存在,那开放人员就只能像队列一样,等待前一个人处理完后,后一个人才能开始工作。但有了分支之后,每一个人就能够在自己的分支上开始工作,互不影响,最后大家再把各自的任务整合到一块,就可以形成一个完整的项目。

3.1、分支的创建和合并

在Git中,主分支默认为master,也可以理解为master是指向主分支的最后一次提交,HEAD指针指向master。

ecfc401e5a4237a96eb86bb94bd1e78a.png

当我们创建一个分支dev的时候,HEAD指针就会指向dev,此时对工作区的修改和提交都针对Dev,对dev进行一次commit,dev指针就会向前一步,而master指针始终不变。

d4f9601139c16b0583636a33c79e0a99.png

当我们将dev合并到master上时,直接将master指针指向dev当前的提交就OK啦。

216eca81b175a56d699581247e5cb0b4.png
合并就是改改指针的指向而已

合并结束后,我们可以将dev删掉,此时就只剩master了。

823c262658824d9a3e520c75ccd19138.png

图解结束后,我们直接上代码:

3.1.1、创建分支:

git checkout -b dev

其中,-b参数表示创建并切换。相当于

  1. git branch dev
  2. git checkout dev

事实上,我们注意到切换分支使用git checkout <branch>,而前面讲过的撤销修改则是git checkout -- <file>,同一个命令,有两种作用,确实有点令人迷惑。

实际上,切换分支这个动作,用switch更科学。因此,最新版本的Git提供了新的git switch命令来创建并切换分支:

git switch -c dev

直接切换到master分支,也可以用:

git switch master

可以用git branch 来查看分支:

b928a47a9a09627f459ccbfe33ce928c.png
git branch

当我们在dev完成工作后(指commit之后),可以将其合并

git merge dev

接着删除dev

git branch -d dev     //-d表示delete

现在做一个小回顾:

小结

Git鼓励大量使用分支:
查看分支: git branch
创建分支: git branch <name>
切换分支: git checkout <name>或者 git switch <name>
创建+切换分支: git checkout -b <name>或者 git switch -c <name>
合并某分支到当前分支: git merge <name>
删除分支: git branch -d <name>

3.2.1、解决冲突

本节得含义是:创建了一个feature1分支,修改其中得内容(比如readme.txt),假设修改内容是“1”,commit了之后。再切换回master分支,再将master分支上的同一内容(比如readme.txt)改为“2”,此时,feature1和master分支都有了新的提交,如图所示:

a4f1f9313c497b178ca26e83bb332e9f.png

这种情况下,因为feature1和master上的readme.txt不一样,将他们合并时,会产生冲突,此时就需要手动来解决冲突,然后再提交。同时,通过git status 也可以查看冲突的文件。

手动解决冲突的过程:将内容(readme.txt)改为我们所希望改的内容,再重新add+commit,就行,如图解:

7dd55906144e7a7cc0e9d29c64d9e04d.png
比原先的master更向前了一步
  1. 再删除feature1即可
git branch -d feature1
小结
当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
git log --graph命令可以看到分支合并图。

3.3.1 分支管理策略

上述说的分支合并是修改了master的指针,在Git中是Fast forward模式的,在删除分支后,会丢掉分支的信息。接下来说的是强制禁用Fast forward模式,Git会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

实践如下:

首先创建并切换dev分支

git switch -c dev

修改内容(readme.txt),并提交一个新的commit:

  1. git add readme.txt
  2. git commit -m "add merge"

现在,我们切换回master:

git switch master

用 --no-ff 来合并dev分支:

git merge --no-ff -m"merge with no-ff"dev          //no-ff  表示no-Fast forward

这时候,merge后的就像这样:

5c165277ce6aa24232d648b35daafccc.png

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

总结一下:

在实际开发中,我们应该按照几个基本原则进行分支管理:

首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;

那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;

你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

所以,团队合作的分支看起来就像这样:

da08298ef84efb7a89e16089df3a9c41.png

3.4.1 BUG 分支

假设现在来了一个bug,需要紧急修复,但你在dev上的工作没有完成,可以使用:

git stash //保存现场工作

然后在master上创建一个新的分支比如(test1)来修改BUG,等bug修复完成后,再合并,并且删除该分支(test1)。一切都结束之后,就可以继续进行自己先前保存的工作了

首先,先转向dev分支

git switch dev

接着,用git stash list 命令看看保存的工作现场去哪里了:

git  stash list

b95657756b917ec05bdba3a88d09d057.png

可以看出,我的dev在 11b7546这个位置。

恢复现场办法有两个,第一种方法是

git stash apply

恢复之后,但stash内容并没有删除,可以使用

git stash drop 

来删除。

第二种办法是直接使用:

git stash pop //恢复现场+删除stash里的内容

此时,用

git stash list

就看不到任何stash内容了。

刚才说的bug是在master上,照理来说我们现在工作的dev上也会存在同样的bug,那我们怎样用优雅又快速的方式来修复这同样的bug呢?

方法:只需把特定的提交merge到当前的分支即可。也就是说,我们把刚才对该bug的修改复制到dev分支上。注意:我们只想复制修改那个bug这个提交所做的修改,并不是把整个master分支merge过来。

Git提供了这么一个方法

git cherry-pick 4c805e2  //4c805e2是提交之前bug修改的commit的地址号

git cherry-pick,我们就不需要在dev分支上手动再把修bug的过程重复一遍。

小结一下:

修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
当手头工作没有完成时,先把工作现场 git stash一下,然后去修复bug,修复后,再 git stash pop,回到工作现场;
在master分支上修复的bug,想要合并到当前dev分支,可以用 git cherry-pick <commit>命令,把bug提交的修改“复制”到当前分支,避免重复劳动。

今天出去玩了,导致现在才写完,果然我的效率还是太低,也还有很多事情没做完。加油啊,明天争取搞完Git。就开始全身心搞编程啦,加油!老温!


3.4.1、Feature分支

新建了一个分支之后,处理完之后,要是并没有合并,用

git branch -d 分支名

这样,我们只能用-D来强行删除:

git branch -D 分支名

这一节只有这一个知识点。

3.4.2、多人协作

远程仓库的默认名称是origin。假设你想查看远程库的信息,可以用:

git remote

也可以用

git remote -v  //显示更详细的信息

推送分支:

推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:

git push origin 分支名

PS:并不是本地所有的分支都要远程推送的。

  • master分支是主分支,因此要时刻与远程同步;
  • dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
  • bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
  • feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

抓取分支:

//push 推送      pull 抓取

这一节需要两台电脑来协助,因为条件允许,我就大概描述一下这一节所要表达的意思。

假设你和你的另一个同事同时在同样的分支和同样的文件上操作,当他提前push到远程端,你push的文件就会和他产生冲突,解决冲突的办法很简单,就是通过git push把最新的提交从远程端抓(pull)下来。然后再本地合并,解决冲突,然后再push。

git pull

这时候会发现,git pull也失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置devorigin/dev的链接:(这里解释一下,这里是假设我和同事都是抓取dev来进行修改的)

git branch --set-upstream-to=origin/dev dev

再pull

git pull

这回git pull成功,但是合并有冲突,需要手动解决,解决的方法和分支管理中的解决冲突完全一样。解决后,提交,再push:

  1. git commit -m "fix env conflict" //先提交到本地版本库
  2. git push origin dev //再push到远程端

因此,多人协作的工作模式通常是这样:

  1. 首先,可以试图用git push origin <branch-name>推送自己的修改;
  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull抓取下来,试图合并;
  3. 如果合并有冲突,则解决冲突,并在本地提交;
  4. 没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!

如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>

这就是多人协作的工作模式,一旦熟悉了,就非常简单。

小结

查看远程库信息,使用 git remote -v
本地新建的分支如果不推送到远程,对其他人就是不可见的;
从本地推送分支,使用 git push origin branch-name,如果推送失败,先用 git pull抓取远程的新提交;
在本地创建和远程分支对应的分支,使用 git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
建立本地分支和远程分支的关联,使用 git branch --set-upstream branch-name origin/branch-name
从远程抓取分支,使用 git pull,如果有冲突,要先处理冲突。
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号