Git学习(二)

简介: Git学习(二)

一、版本管理


1.1 撤销修改


git commit --amend

这个命令会将暂存区中的文件提交。 如果自上次提交以来你还未做任何修改(例如,在上次提交后马上执行了此命令), 那么快照会保持不变,而你所修改的只是提交信息。

例如,你提交后发现忘记了暂存某些需要的修改,可以像下面这样操作:

$ git commit -m ‘initial commit’

$ git add forgotten_file

$ git commit --amend


最终你只会有一个提交——第二次提交将代替第一次提交的结果。


当你在修补最后的提交时,并不是通过用改进后的提交 原位替换 掉旧有提交的方式来修复的, 理解这一点非常重要。从效果上来说,就像是旧有的提交从未存在过一样,它并不会出现在仓库的历史中。

修补提交最明显的价值是可以稍微改进你最后的提交,而不会让“啊,忘了添加一个文件”或者 “小修补,修正笔误”这种提交信息弄乱你的仓库历史。


取消暂存

$ git reset HEAD readme.txt


撤销修改

$ git checkout – readme.txt


1.2 删除文件

rm test.txt


此时,工作区和版本库就不一致了

$ git rm test.txt

rm ‘test.txt’

$ git commit -m “remove test.txt”


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


小提示:先手动删除文件,然后使用git rm 和git add效果是一样的。

$ git checkout – test.txt


一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本


如果从来没提交到版本库,是没法还原


1.3 小结


场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file


场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD ,就回到了场景1,第二步按场景1操作


场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,可以用命令git reset --hard commit_id,不过前提是没有推送到远程库


二、分支管理


2.1 git 分支原理


假设现在有一个工作目录,里面包含了三个将要被暂存和提交的文件。

Git 仓库对象变化详解:

0a2653c851af460fa595bd959398a8f1.png

现在,Git 仓库中有五个对象:三个 blob 对象(保存着文件快照)、一个 树 对象 (记录着目录结构和 blob 对象索引)以及一个 提交 对象(包含着指向前述树对象的指针和所有提交信息)。


2d65d23f6d4748949b924e4057485923.png


做些修改后再次提交,那么这次产生的提交对象会包含一个指向上次提交对象(父对象)的指针。


2e9b90b2ca334476abebe75bafe6eeaa.png


Git 的分支,其实本质上仅仅是指向提交对象的可变指针。 Git 的默认分支名字是 master。 在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支。 master 分支会在每次提交时自动向前移动。

4cebaac233b3433da32a72337a77fc60.png


在 Git 里,每个仓库都会有一个主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。

一开始的时候,master分支是一条线,Git 用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:


6de278e6d6694ce5bb08e7e842b7e74b.png

每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长。


当我们创建新的分支,例如dev时,Git 新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:


7a399525ddec4b77923c464820b33738 (1).png

你看,Git 创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!


不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:

7a399525ddec4b77923c464820b33738 (1).png

假如我们在dev上的工作完成了,就可以把dev合并到master上。Git 怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

7a399525ddec4b77923c464820b33738.png


所以 Git 合并分支也很快!就改改指针,工作区内容也不变!

合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:


8ec4f2997fb246878c34ecd6d122b7c6.png


2.2 修改不同的分支


2.2.1 创建分支


首先,我们创建dev分支,然后切换到dev分支

$ git checkout -b dev

Switched to a new branch ‘dev’


git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:

$ git branch dev
$ git checkout dev
Switched to branch ‘dev’


0a2653c851af460fa595bd959398a8f1.png


2.2.1 查看当前分支

$ git branch


2d65d23f6d4748949b924e4057485923.png


可以在dev分支上正常提交,比如对readme.txt做个修改,提交:

$ git add readme.txt

$ git commit -m “branch test”


2e9b90b2ca334476abebe75bafe6eeaa.png


dev分支的工作完成,我们就可以切换回master分支

$ git checkout master


切换回master分支后,再查看一个readme.txt文件,刚才添加的内容不见了!因为那个提交是在dev分支上,而master分支此刻的提交点并没有变:


0a2653c851af460fa595bd959398a8f1.png2d65d23f6d4748949b924e4057485923.png


2.3 git 合并分支


2.3.1 合并分支


现在,我们把dev分支的工作成果合并到master分支上:

$ git merge dev


2e9b90b2ca334476abebe75bafe6eeaa.png


2.3.2 删除分支


合并完成后,就可以放心地删除dev分支了:

$ git branch -d dev


0a2653c851af460fa595bd959398a8f1.png


查看


2d65d23f6d4748949b924e4057485923.png


我们注意到切换分支使用git checkout ,而 Git 中撤销修改则是git checkout -- ,同一个命令,有两种作用,确实有点令人迷惑。

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

git switch


创建并切换到新的dev分支,可以使用:

$ git switch -c dev


直接切换到已有的master分支,可以使用:

$ git switch master


使用新的git switch命令,比git checkout要更容易理解。


2.4 git 合并策略


通常,合并分支时,如果可能,Git 会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。

如果要强制禁用Fast forward模式,Git 就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

下面我们看一看--no-ff方式的git merge:

$ git merge --no-ff -m “merge with no-ff” dev


因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。

合并后,我们用git log看看分支历史:

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

fc76cf7 (HEAD -> master) merge with no-ff

|\

| * f52c633 (dev) add merge

|/

cf810e4 conflict fixed

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


0a2653c851af460fa595bd959398a8f1.png


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

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

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

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

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

2d65d23f6d4748949b924e4057485923.png


2.5 实战(1): 准备新分支

$ git checkout -b dev


2.6 实战(2): 修改master分支

$ git checkout master


相关文章
|
19天前
|
Linux 开发工具 C语言
Linux的学习之路:7、yum与git
Linux的学习之路:7、yum与git
14 0
|
7月前
|
JSON 前端开发 JavaScript
前端AJAX入门到实战,学习前端框架前必会的(ajax+node.js+webpack+git)(一)
前端AJAX入门到实战,学习前端框架前必会的(ajax+node.js+webpack+git)(一)
526 0
|
10月前
|
Java 开发工具 数据库
|
3月前
|
安全 Shell 网络安全
Git学习---Git快速入门、Git基础使用、Git进阶使用、Git服务器使用(IDEA集成GitHub、Gitee、GitLab)、GitHub Desktop客户端
Git学习---Git快速入门、Git基础使用、Git进阶使用、Git服务器使用(IDEA集成GitHub、Gitee、GitLab)、GitHub Desktop客户端
136 0
|
4月前
|
缓存 数据可视化 开发工具
学习 Git,看这一篇就够了!(下)
学习 Git,看这一篇就够了!(下)
|
4月前
|
存储 Linux Shell
学习 Git,看这一篇就够了!(上)
学习 Git,看这一篇就够了!(上)
|
5月前
|
缓存 开发工具 数据安全/隐私保护
git-学习git,这一篇就足够了(初学者视角实战教程)
git-学习git,这一篇就足够了(初学者视角实战教程)
133 0
|
5月前
|
安全 开发工具 git
最近从 0 学习Git,详细分类总结了这份 Git 命令宝典(二)
最近从 0 学习Git,详细分类总结了这份 Git 命令宝典(二)
43 0
|
5月前
|
开发工具 git
最近从 0 学习Git,详细分类总结了这份 Git 命令宝典(一)
最近从 0 学习Git,详细分类总结了这份 Git 命令宝典
31 0
|
5月前
|
Java Linux 开发工具
阿里云git仓库学习
阿里云git仓库学习
99 1

相关实验场景

更多