Git学习笔记(二)

来源:互联网 发布:多普达软件下载 编辑:程序博客网 时间:2024/05/29 06:51

十.分支管理

分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努力学习SVN。如果两个平行宇宙互不干扰,那对现在的你也没啥影响。不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了Git又学会了SVN.

分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。

1.创建一个分支

在前面版本回退的内容知道,在Git里有一条主分支叫master,head指向的master,而master指向的是提交。所以head指向的是当前的分支。

每次提交,master都会往前推进一步,此时head也会随其推进,指向当前发分支。


当我们创建一个新的分支dev时,git新建了一个指针叫dev,head指向了dev,表明当前分支是dev。所以在git上新建分支只是新建了一个指针和改变了head指向。

假设我们在dev分支上的工作已经全部完成,要将其与主分支master合并,此时只需要将master指向dev的当前提交就好了。之后可以选择是否删除分支dev。

(1)创建分支dev

$ git branch dev

切换分支dev

$ git checkout dev
也可以创建和切换同时进行:

$ git checkout -b dev
-b表示创建和切换。

(2)查看分支情况

$ git branch

如图,我们有新建的分支dev和主分支master,星号表示的是当前分支为master。

(3)在分支上修改内容

切换到dev分支上在工作区改变readme.txt的内容,然后add和commit提交。表示该分支的工作已经完成并提交。

之后切换到master上,查看readme.txt内容,会发现刚才所做的修改并没有出现。是因为刚才的修改实在dev分支下进行的。而此时master的提交点还是dev创建之前最新的提交点。

(4)合并分支

之后把dev上的修改合并到master上。

$ git merge dev
之后在查看readme.txt就发现和dev的最新提交一样勒。

(5)删除分支

$ git branch -d dev
2.合并分支出现的冲突

在dev分支下修改readme.txt文件,然后add和commit提交。然后转到master分支上修改readme.txt文件,add和commit提交。

(转到master分支上会自动提示Your branch is ahead of 'origin/master' by 1 commit. 表示当前master分支比远程的master分支要超前1个提交)

现在dev和master分支都各自进行了提交,变成了下图所示。(dev=feature1)


在这种情况下进行合并会出现下面的冲突:

提示readme.txt出现了合并冲突。打开readme.txt文件可以看到:


<<<<<<< ========= >>>>>>>>都是华丽的分割线。

当前head的指向(master)的内容 new new hehehe与dev分支的内容i am in branch dev now lalala出现了冲突。

此时需要手动修改内容,如下图:


然后在add &  commit提交。

此时分支情况如下:

也可以用git log查看分支的合并情况: 

$ git log --graph --pretty=oneline --abbrev-commit

最左边的直线是master分支,旁边是分支。可以看到在dev上的提交(new 160913)与master上的提交(new_master 160913)合并修改之后的提交是160913。

3.分支管理策略

通常在进行分支合并的时候,git会自动用fast forward模式,在这种模式下,删除分支后会丢点此分支的信息,不利于日后代码的分析。

不使用这种模式的话,git在merge的时候会自行生成新的commit,用来记录分支上的信息,用来避免丢失信息。

禁用fast forward的命令:

$ git merge --no-ff -m "merge with no-ff" dev


–-no-ff,其作用是:要求git merge即使在fast forward条件下也要产生一个新的merge commit。此处,要求采用–no-ff的方式进行分支合并,其目的在于,希望保持原有“develop branches”整个提交链的完整性。合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。

介绍fast forward和no fast forward模式的文章。

4.git stash用法

假设在分支dev上的工作进行到一半,不能提交,此时又需要去处理另一件与之无关的问题。所以需要把当前的工作状态(工作现场)存起来,等解决掉其他事之后再恢复继续工作。比如修复一个bug。

将当前工作分支的状态(现场)储存:

$ git stash
好啦~去干其他的事情吧~

完事之后,要回到之前所保存的工作状态。

查看所保存的工作状态列表:

$ git stash list
查到之后,需要恢复其中的状态,有两种方式:

$ git stash apply

用此命令恢复后,stash的内容并不删除,还需要用git stash drop来删除;

$ git stash pop
恢复的同时把stash内容也删了。

可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令:

$ git stash apply stash@{0}

5.强行删除没哟被合并的分支

新建了一个分支feature-vulcan,此分支功能快完成的时候突然不需要了,而又没有合并到主分支上,要强行删除的时候:

$ git branch -d feature-vulcan

6.查看远程库

当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。要查看远程库的信息,用:

$ git remote
显示更详细的信息:

$ git remote -v
7.推送分支

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

$ git push origin dev
8.抓取分支

当我们从远程库github上克隆一个仓库,默认情况下,只能看到Master主分支,而A需要从dev的分支上开发,此时必须创建远程origin的dev分支到本地,于是A用\命令创建本地dev分支:

$ git checkout -b dev origin/dev
当A完成对dev的开发,将origin/dev分支推送提交至远程库后,我也对同样的文件进行了修改并尝试推送,然而推送失败,因为A的最新提交和我试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送:

$ git pull
git pull也失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接:

$ git branch --set-upstream dev origin/dev

再pull:

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

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

首先,可以试图用git push origin branch's name推送自己的修改;

如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;

如果合并有冲突,则解决冲突,并在本地提交;

没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功!

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

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

Git中从远程的分支获取最新的版本到本地有这样2个命令:

git fetch:相当于是从远程获取最新版本到本地,不会自动merge  

git pull  :相当于是从远程获取最新版本并merge到本地 

十一.标签管理

我们知道之前每次commit的时候都会生成一个版本号,而这个版本号乱七八糟不好记,所以用标签来代替,比如v1.9 v2.0之类的。

1.创建标签

切换到需要创建标签的分支上,然后:

$ git tag v1.0
创建标签默认的是创建在此分支上最新的commit版本上。比如v1.0代指此分支最新的commit版本。

2.创建任意时间的标签

有时候,如果忘了打标签,比如,现在已经是周五了,但应该在周一打的标签没有打,怎么办? 方法是找到历史提交的commit id,然后打上就可以了:

$ git log --pretty=oneline --abbrev-commit
先找到commit的历史记录,然后对其中需要打标签的ID:比如6224937

$ git tag v0.9 6224937

3.创建带有说明的标签

$ git tag -a v0.1 -m "version 0.1 released" 3628164
用-a指定标签名,-m指定说明文字。  对ID位3628164的commit创建标签v0.1,并说明是version 0.1 released。

4.查看所有标签

$ git tag

5.查看标签信息

标签不是按时间顺序列出,而是按字母排序的。可以用git show <tagname>查看标签信息:

$ git show v0.9

6.删除本地标签

因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。

$ git tag -d v0.1
7.推送本地标签至远程库

如果要推送某个标签到远程,使用命令:

$ git push origin v1.0
或者,一次性推送全部尚未推送到远程的本地标签:

$ git push origin --tags
8.删除远程标签

先从本地删除:

$ git tag -d v0.9
然后,从远程删除。删除命令也是push,但是格式如下:

$ git push origin :refs/tags/v0.9







0 0
原创粉丝点击