这篇文章写一下 git
的操作,git 的安装与配置可以看之前的文章 git安装配置。
创建版本库
先创建一个文件夹并进入:
1 | mkdir git_test_1210 |
在这个目录下创建一个版本库:
1 | git init |
版本创建与回退
使用
- 在当前目录下创建一个文件
code.txt
,写入:this is the first line
使用如下两条命令可以创建一个版本:
1
2git add .\code.txt
git commit -m "版本1"使用如下命令可以查看版本记录
1
git log
继续编辑
code.txt
,在里面增加一行this is the second line
再使用如下命令创建一个版本并查看版本记录:
现在若想回到某一个版本,可以使用如下命令:
1
git reset --hard HEAD^
其中 HEAD 表示当前最新版本,HEAD^表示当前版本的前一个版 本,HEAD^^表示当前版本的前前个版本,也可以使用 HEAD
1 表示当前版本的 前一个版本,HEAD100 表示当前版本的前 100 版本。现在若觉得想回到版本 1,可以使用如下命令:
现在就回到了第一个版本
假设我们现在又想回到版本2,怎么办?
可以使用下面命令:
1
git reset --hard 版本号
版本号就是
git log
commit后面那一串字符串,例如:这个时候版本就回到版本2了,可以
cat code.txt
查看下面内容:我们上面回退那个版本2的版本号是我们在当前黑色终端中复制的,但是如果我们当前终端关闭了怎么办?
我们还按照上面将版本回退到版本1,把终端关闭,然后在查看
git log
:我们还可以通过
git reflog
命令可以查看我们的操作记录:1
git reflog
我们可以看到版本2(8cccee7)的版本号,可以通过这个版本号进行回退:
1
git reset --hard 8cccee7
工作区和暂存区
工作区(Working Directory)
电脑中的目录,比如我们的 git_test_1210
就是一个工作区
版本库(Repository)
工作区中有一个隐藏目录 .git
,这个不是工作区,而是git的版本库
git 的版本库里存了很多东西,其中最重要的就是称为 stage
(或者叫index)的暂存区,还有 git 为我们自动创建的第一个分支 master ,以及指向master的一个指针 HEAD。
因为我们创建git版本库时,git自动为我们创建唯一一个master分支,git commit
就是往 maste分支上提交更改。
简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性 提交暂存区的所有修改。
前面讲了我们把文件往 git 版本库里添加的时候,是分两步执行的:
第一步是用 git add
把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用 git commit
提交更改,实际上就是把暂存区的所有内容提交到当 前分支。
下面再目录下创建
code.txt
文件,然后编辑内容如下:然后再次编辑 code.txt 内容,在其中加入一行,编辑后内容如下:
使用如下命令查看当前工作树的状态:
1
git status
上面提示我们 code.txt 被修改,而 code2.txt 没有被跟踪。
我们使用如下命令把 code.txt 和 code2.txt 加入到暂存区,然后再 执行
git status
命令,结果如下:这样就把文件放到暂存区里面了。
然后,执行
git commit
就可以一次性把暂存区的所有修改提交到分支 创建一个版本。一旦提交后,之后如果我们没有对工作区做任何修改,那么工作区就是干净的。执行如下命令可以发现:
现在我们的版本库变成了这样:
管理修改
git 管理的文件的修改,它只会提交暂存区的修改来创建版本。
编辑 code.txt,并使用
git add
命令将其添加到暂存区中继续编辑 code.txt,并在其中添加一行。
git commit
创建一个版本,并使用git status
查看,发现第二次 修改 code.txt 内容之后,并没有将其添加的工作区,所以创建版本的 时候并没有被提交。
撤销修改
继续上面的操作,我们可以使用
git checkout -- <文件>
来丢弃工作区的改动。执行如下命令,发现工作区干净了,第二次改动的内容也没了。我们继续编辑 code.txt,并在其中添加如下内容,并将其添加的暂存区。
git 同样告诉我们,用命令
git reset HEAD file
可以把暂存区的修改撤销掉,重新放回工作区。现在若想丢弃 code.txt 的修改,执行如下命令即可。
小结
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时
1
git checkout -- file
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改
1
2
3
4先把暂存区的修改撤销
git reset HEAD file
和场景1一样
git checkout -- file场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交
1
2版本回退
git reset --hard HEAD^
对比文件的不同
对比工作区和某个版本中文件的不同
继续编辑文件 code.txt
现在要对比工作区 code.txt 和HEAD 版本中 code.txt 的不同,使用如下命令
使用如下命令丢弃工作区的改动。
对比两个版本间文件的不同
现在要对比 HEAD 和 HEAD^版本中 code.txt 的不同,使用如下命令:
删除文件
现在我们把目录下的 code2.txt 文件删除。
这个时候,git 知道删除了文件,因此,工作区和版本库就不一致了,
git status
命令会提示哪些文件被删除了。现在我们有两个选择,一是确实从版本库中删除该文件,那就用命令
git rm 删除文件
,并且git commit
。另外一种情况是删错了,可以直接使用
git checkout -- code2.txt
。这样code2.txt 文件就又回来了。
分支管理
创建和合并分支
git 把我们之前每次提交的版本串成一条时间线,这条时间线就是一个分支。截止到目前只有一条时间线,在 git 里,这个分支叫主分支,即 master 分支。HEAD 严格来说不是指向提交,而是指向 master ,master 才是指向提交的,所以,HEAD 指向的就是当前分支。
(1)一开始的时候,maste 分支就是一条线,git 用 master 指向最新的提交,再用 HEAD 指向 master,就能确定当前分支,以及当前分支的提交点:
每次提交,master 分支都会向前移动一步,这样,随着你不断提交, master 分支的线也越来越长。
(2)当我们创建新的分支,例如 dev 时,git 新建了一个指针叫 dev,指向 master 相同的提交,再把 HEAD 指向 dev,就表示当前分支在 dev 上:
git 创建一个分支很快,因为除了增加一个 dev 指针,改变 HEAD 的指 向,工作区的文件都没有任何变化。
(3)不过,从现在开始,对工作区的修改和提交就是针对 dev 分支了,比如新 提交一次后,dev 指针往前移动一步,而 master 指针不变:
(4)假如我们在 dev 上的工作完成了,就可以把 dev 合并到 master 上。git 怎么合并呢?最简单的方法,就是直接把 master 指向 dev 的当前提交,就完 成了合并:
git 合并分支也很快,就改改指针,工作区内容也不变。
(5)合并完分支后,甚至可以删除 dev 分支。删除 dev 分支就是把 dev 指针给删掉,删掉后,我们就剩下了一条 master 分支:
案例:
(1)执行如下命令可以查看当前几个分支并且看到在哪个分支下工作。
(2)下面创建一个分支 dev 并切换到其上进行工作。
(3)下面我们修改 code.txt 内容,在里面添加一行,并进行提交。
(4)dev 分支的工作完成,我们就可以切换成 master 分支:
查看 code.txt,发现添加的内容没有了。因为那个提交是在 dev 分支上,而 master 分支此刻的提交点并没有变:
(5))现在,我们把 dev 分支的工作成果合并到 master 分支上:
git merge 命令用于合并指定分支到当前分支。合并后,再查看 code.txt 的内容,就可以看到,和 dev 分支的最新提交是完全一样的。
注意到上面的 Fast-forward 信息,Git 告诉我们,这次合并是快进模 式,也就是直接把 master 指向 dev 的当前提交,所以合并速度非常快。
(6)合并完成后,就可以放心地删除 dev 分支了,删除后,查看 branch,就 只剩下 master 分支了。
小结
查看分支:git branch <name>
创建分支:git branch <name>
切换分支:git checkout <name>
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
分支冲突
合并分支往往也不是一帆风顺的。
再创建一个新分支 dev并切换到它。
1
git checkout -b dev
修改 code.txt 内容,并进行提交。
切换回 master 分支。
1
git checkout master
在 master 的 code.txt 添加一行内容并进行提交。
现在,master 分支和 dev 分支各自都分别有新的提交,变成了这样:
这种情况下,git 无法执行快速合并,只能试图把各自的修改合并起来,但 这种合并就可能会有冲突。
执行如下命令尝试将 dev 分支合并到 master 分支上来。
git 告诉我们,code.txt 文件存在冲突,必须手动解决冲突后再提交。
git status 也可以告诉我们冲突的文件:
查看 code.txt 的内容。
git 用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,我们修改 如下后保存:
再提交。
现在,master 分支和 dev 分支变成了下图所示:
用带参数的 git log 也可以看到分支的合并情况:
最后工作完成,可以删除 dev 分支。
1
git branch -d dev
分支管理策略
通常,合并分支时,如果可能,git 会用 fast forward 模式,但是有些快 速合并不能成而且合并时没有冲突,这个时候会合并之后并做一次新的提交。
但这种模式下,删除分支后,会丢掉分支信息。
创建切换到 dev 分支下。
1
git checkout -b dev
新建一个文件 code3.txt 编辑内容如下,并提交一个 commit。
切换回 master 分支,编辑 code.txt 并进行一个提交。
合并 dev 分支的内容到 master 分支。
出现如下提示,这是因为这次不能进行快速合并,所以 git 提示输入合并 说明信息,输入之后合并内容之后 git 会自动创建一次新的提交。
使用分支命令查看分支信息。
删除 dev 分支。
1
git branch -d dev
如果要强制禁用 fast forward 模式,git 就会在 merge 时生成一个新的 commit,这样,从分支历史上就可以看出分支信息。
创建并切换到dev分支
1
git checkout -b dev
修改 code.txt 内容,并提交一个 commit。
切换回 master 分支。
1
git checkout master
准备合并 dev 分支,加上
--no-ff
参数,表示禁用 Fast forward:因为本次合并要创建一个新的 commit,所以加上-m 参数,把 commit 描述写进去。
合并后,我们用
git log
看看分支历史: 可以看到,不使用 Fast forward 模式,merge 后就像这样:
Bug 分支
软件开发中,bug 就像家常便饭一样。有了 bug 就需要修复,在 git 中,由 于分支是如此的强大,所以,每个 bug 都可以通过一个新的临时分支来修复, 修复后,合并分支,然后将临时分支删除。
先随便在code.txt 文件中写点东西,模拟现在的工作代码,说明我们手头上正有工作。
当你接到一个修复一个代号 001 的 bug 的任务时,很自然地,你想创建一 个分支 bug-001 来修复它,但是,等等,当前正在 dev 上进行的工作还没有 提交:
并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需 1 天 时间。但是,必须在两个小时内修复该 bug,怎么办?
git 还提供了一个 stash 功能,可以把当前工作现场储藏起来,等以后 恢复现场后继续工作:
首先确定要在哪个分支上修复 bug,假定需要在 master 分支上修复,就 从 master 创建临时分支:
现在修复 bug,把 code3.txt 的第一行删掉,然后提交。
修复完成后,切换到 master 分支,并完成合并,最后删除 bug-001 分支。
现在 bug-001 修复完成,是时候接着继续干活了!
工作区是干净的,刚才的工作现场存到哪去了?用
git stash list
命 令看看:工作现场还在,git 把 stash 内容存在某个地方了,但是需要恢复一下。
小结
修复 bug 时,我们会通过创建新的 bug 分支进行修复,然后合并,最后删除;
当手头工作没有完成时,先把工作现场 git stash
一下,然后去修复 bug, 修复后,再 git stash pop
,恢复工作现场。
码云继续使用
克隆项目
前面我们都说过了,复制 SSH 那个链接,命令行 git clone
进行克隆项目到本地。
上传分支
项目克隆到本地之后,执行如下命令创建分支 smart。
创建一个 code.txt 并提交一个版本。
推送前码云上文件列表如下图。
分支信息如下。
推送分支,就是把该分支上的所有本地提交推送到远程库,推送时要指定本地分支,这样,git 就会把该分支推送到远程库对应的远程分支上。
1
2
3git push origin 分支名称
例:
git push origin smart再去码云网站上去看分支页面,内容如下。
将本地分支跟踪服务器分支
1 | git branch --set-upstream-to=origin/远程分支名称 本地分支名称 |
从远程分支上拉取代码
1 | git pull orgin 分支名称 |
使用上述命令会把远程分支 smart 上的代码下载并合并到本地所在分支。
工作使用 git
项目经理:
(1) 项目经理搭建项目的框架。
(2) 搭建完项目框架之后,项目经理把项目框架代码放到服务器。
普通员工:
(1) 在自己的电脑上,生成 ssh 公钥,然后把公钥给项目经理,项目经理把它添加的服务器上面。
(2) 项目经理会给每个组员的项目代码的地址,组员把代码下载到自己的电脑上。
(3) 创建本地的分支 dev,在 dev 分支中进行每天的开发。
(4) 每一个员工开发完自己的代码之后,都需要将代码发布远程的 dev 分支上。
Master:用户保存发布的项目代码。V1.0,V2.0
Dev:保存开发过程中的代码。