1.安装与创建
安装命令:sudo apt-get install git
2.创建版本库
新建一个目录 gitTest,在 gitTest 目录下创建一个版本库,命令如下
初始化命令:git init
,可以看到在 gitTest 目录下创建了一个 .git
隐藏目录,这就是版本库目录。
3.版本创建与回退
3.1.使用
在 gitTest 目录下创建一个文件 code.cc
使用:git add code.cc
和 git commit -m "版本1"
,可以创建一个版本:
3.2.回退
想要回退到某个版本,可以使用:git reset --hard HEAD^
其中 HEAD
表示当前最新版本,HEAD^
表示当前版本的前一个版本,HEAD^^
表示当前版本的前前个版本,也可以使用HEAD~1
表示当前版本的前一个版本,HEAD~100
表示当前版本的前 100 版本。
假如现在又想回到版本2,可以使用命令:git reset --hard 版本号
:
但如果上面的终端已经关了,不知道 version_1 的版本号,怎么回退版本,git reflog
命令可以查看操作记录。
前面的序列号就是版本号,再使用命令进行版本回退。
4.工作区和暂存区
电脑中的目录,比如我们的 gitTest,就是一个工作区。
工作区有一个隐藏目录 .git
,这个不是工作区,而是 git 的版本库。
git 的版本库里存了很多东西,其中最重要的就是称为 stage(或者叫index)的 暂存区,还有 git 为我们自动创建的第一个分支 master,以及指向 master 的一个指针叫 HEAD。
第一步是用 git add
把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用 git commit
提交更改,实际上就是把暂存区的所有内容提交到当前分支。
需要提交的文件修改通通放到暂存区(可以多次 git add
),然后,一次性提交暂存区的所有修改(一次 git commit
)。
4.1 修改
git 管理的文件的修改,它只会提交暂存区的修改来创建版本。
场景1:直接丢弃工作区的修改时,用命令 git checkout -- file
。
场景2:不但修改了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file
,就回到了场景1,第二步按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,版本回退。
4.2 对比文件不同
要对比工作区中 code.txt 和 HEAD 版本中 code.cc 的不同。使用如下命令:git diff HEAD -- code.cc
在要对比 HEAD 和 HEAD^ 版本中code.cc的不同,使用如下命令:git diff HEAD HEAD^ -- code.cc
- 代表前面文件的内容,+ 代表后面文件的内容
4.3 删除文件
把目录中的code2.cc删除:
这个时候,git 知道删除了文件,因此,工作区和版本库就不一致了,git status 命令会立刻提示哪些文件被删除了。
现在有两个选择,一是确实要从版本库中删除该文件,那就用命令 git rm
删掉,并且 git commit
【git rm
功能在这里和 git add
一样的】
另一种情况是删错了,可以直接使用 git checkout – code2.cc
,这样文件 code2.cc 又回来了。
分支管理
git 把之前每次提交的版本串成一条时间线,这条时间线就是一个分支。
在 git 里,只有一条时间线这个分支叫主分支,即 master 分支。HEAD 严格来说不是指向提交,而是指向 master,master 才是指向提交的,所以,HEAD 指向的就是当前分支。
一开始的时候,master 分支是一条线,git 用 master 指向最新的提交,再用 HEAD 指向 master,就能确定当前分支,以及当前分支的提交点:
每次提交,master 分支都会向前移动一步,这样,随着不断提交,master 分支的线也越来越长。
当我们创建新的分支,例如 dev 时,git 新建了一个指针叫 dev,指向 master 相同的提交,再把 HEAD 指向 dev,就表示当前分支在 dev:
上:
git 创建一个分支很快,因为除了增加一个 dev 指针,改变 HEAD 的指向,工作区的文件都没有任何变化。
不过,从现在开始,对工作区的修改和提交就是针对 dev 分支了,比如新提交一次后,dev 指针往前移动一步,而 master 指针不变:
假如在 dev 上的工作完成了,就可以把 dev 合并到 master 上。git 怎么合并呢?最简单的方法,就是直接把 master 指向 dev 的当前提交,就完成了合并:
git 合并分支也很快,就改改指针,工作区内容也不变。
合并完分支后,甚至可以删除 dev 分支。删除 dev 分支就是把 dev 指针给删掉,删掉后,就剩下了一条 master 分支:
注意到上面的 Fast-forward 信息,Git 告诉我们,这次合并是“快进模式”,也就是直接把 master 指向 dev 的当前提交,所以合并速度非常快。
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
5.1 冲突解决
在 master 分支和 dev 分支各自都分别有新的提交时,变成了这样:
这种情况下,git 无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突。
必须手动解决冲突后再提交。
git 用<<<<<<<,=======,>>>>>>>
标记出不同分支的内容,修改后保存。
用带参数的git log也可以看到分支的合并情况:git log --graph --pretty=oneline
,最后工作完成,可以删除dev分支。
5.2 分支管理策略
通常,合并分支时,如果可能,git会用fast forward模式,但是有些快速合并不能成而且合并时没有冲突,这个时候会合并之后并做一次新的提交。但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用 fast forward 模式,git 就会在 merge 时生成一个新的 commit,这样,从分支历史上就可以看出分支信息。
准备合并dev分支,请注意–no-ff参数,表示禁用Fast forward:git merge --no-ff -m "mege" dev
5.3 BUG 分支
每个 bug 都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
当接到一个修复一个代号 001 的 bug 的任务时,很自然地,想创建一个分支 bug-001 来修复它,但是,等等,当前正在 dev 上进行的工作还没有提交:
修复 bug 时,我们会通过创建新的 bug 分支进行修复,然后合并,最后删除;
当手头工作没有完成时,先把工作现场 git stash
一下,然后去修复bug,修复后,再git stash pop
,恢复工作现场。
内容来源:Git(linux)