三棵树
工作区域,也就是我们平时写代码的文件夹
暂存区域,临时存放我们的改动,也称为Index
Git仓库(本地仓库),存放版本数据的地方,HEAD指针指向最新提交的记录
这边没有提到远程仓库,是因为Git的大部分操作都是在这三棵树之间来回转换,只要把这三棵树搞明白,推送或更新远程仓库是很简单的,文章后面也会讲到
Git的工作流程
- 在工作目录中添加,修改文件
- 将需要进行版本管理的文件放入暂存区域
- 将暂存区域的文件提交到Git仓库
Git命令介绍
我们这里先讲命令行的方式,因为命令行的方式会了,图形化界面的自然也会了
- 在电脑上新建一个文件夹my-project进入文件夹,执行
git init
命令,会生成 .git 文件夹,该文件夹用来追踪文件的变化,默认为隐藏状态 - 在文件下新建一个文本文件,project.txt,并输入内容,执行
git status
命令查看文件状态,会显示project.txt还未被git追踪 -
git add project.txt
将文件从工作目录加入到暂存区,文件从第1棵树到了第2棵树,git add project1.txt project2.txt
可以添加多个文件到暂存区,git add .
可以将所有变化的文件提交到暂存区 -
git commit -m '第一次提交'
将文件提交到本地仓库,文件从第2棵树到了第3棵树
下面我们演示修改文件的操作
- 修改project.txt文件内容
-
git status
查看文件状态 -
git add project.txt
添加文件到暂存区 -
git commit -m '增加作者信息'
提交文件到本地仓库
回到过去
撤销工作目录文件的修改,假如我们现在对project.txt做了修改,然后需要恢复成原来的样子,我们可以使用
git checkout project.txt
命令撤销修改,此命令会拉取暂存区文件到工作目录,也就是第2棵树的文件覆盖了第1棵树撤销
add
操作,有时候我们只需要添加2个文件到暂存区,这时候不小心添加了3个文件,这时候我们需要取消第3个文件,我们可以使用git reset HEAD project.txt
此命令会拉取本地仓库文件到暂存区,也就是第3棵树文件覆盖第2棵树-
git reset HEAD project.txt
不仅仅是撤销add
操作,假如我们修改了project.txt文件,然后添加到了暂存区,这时候需要还原project.txt文件,这时候使用git checkout project.txt
命令已经无效,因为暂存区文件和本地文件已经一致了,我们可以连续使用这两个命令git reset HEAD project.txt
git checkout project.txt
来完成最核心的还是要明白命令的原理,原理明白了,就能实现各种不同的效果
-
使用
git log
可以查看提交历史记录,每一次提交都有一个 id ,是根据文件生成的哈希值,我们可以通过这个哈希值,从本地仓库拉取指定版本的文件到暂存区,git reset hash project.txt
可以不用整串的哈希,前七位即可仔细看下图,会发现一个怪现象,我们有2次提交记录,我们把第1次提交的project.txt从第3棵树拉取到第2棵树,然后使用
git status
查看文件状态,会发现有2个modified。这是因为暂存区的project.txt是第一次提交的内容,不包括作者信息,但是工作空间和本地仓库都有作者信息,所以本地文件与暂存区不一致,暂存区与本地仓库文件不一致
-
git reset HEAD~
将本地仓库快照回滚到上一次,HEAD表示当前指针,~表示指向上一个版本,git reset HEAD~~
表示指向上上个版本,git reset HEAD~2
也可以这样写 ,git reset hash
也可以指定哈希值进行回滚git reset --mixed HEAD~
其中--mixed为默认值,表示影响2棵树,也就是本地仓库和暂存区。git reset --hard HEAD~
会影响3棵树,git reset --soft HEAD~
会影响1棵树,既本地仓库下图演示了
git reset --hard hash
命令,我们回滚到了第一次提交,并且影响了3棵树,接下来我们又执行了git reset hash
,将项目回滚到第二次提交,然后使用git status
发现本地文件有修改,这是因为本地文件没有作者信息,第二次回滚只影响了2棵树,git checkout project.txt
即可恢复最开始的样子
修改最后一次条件、删除文件和重命名
git commit --amend -m 'modify some'
修改最后一次commit信息
git rm project.txt
删除工作空间和暂存区文件
git rm -f project.txt
当工作空间和暂存区不一致时,暴力删除
git rm --cached project.txt
删除暂存区文件
git mv project.txt project-new.txt
重命名文件,若直接手动改,git会认为删除了文件,添加了新文件
分支
假如我们在masterf分支把任务开发完毕,我们可以创建分支v1.0,v1.0分支担任修改bug作用,这时候master分支可以开发v1.1的任务。这样的好处是修改完bug,我们可以把v1.0分支部署到生产环境,而不会存在还未开发完的v1.1部署到生产环境,v1.1开发完成后,我们只需要把v1.0改的bug合并到master分支,这时候我们可以创建分支v1.1,如此反复,这种开发模式也称为集中式
上面说的是master担任开发任务,分支担任发版部署任务。我们也可master担任发版部署任务,分支担任开发任务,这种开发模式也称为分散式
这两种分支都有各自优缺点,集中式合并代码比较方便,因为只是合并了bug,但是不适于多个部门独立开发。分散式可以做到多个分支开发独立的功能,但是合并代码的代价就比较大,下面我们以集中式为例。
-
git branch v1.0
创建v1.0分支,git checkout v1.0
切换到v1.0分支,git checkout -b v1.0
是对上面两个命令的合并 。这时候我们发现作者信息不对,修改了project.txt,然后提交到本地仓库
- 合并分支,我们切换到master分支,准备开发v1.1内容,修改project.txt,增加头和尾,并提交。
git log --oneline --graph --all
查看项目详细提交记录,--oneline一行显示,--graph 图形化界面显示,--all显示所有提交信息。git merge v1.0
将v1.0分支合并到当前分支。
- 解决冲突,我们打开project.txt会发现有冲突,其中以 '=======' 为分界线
- 删除分支
git branch -d 分支名
删除分支,git branch -D 分支名
暴力删除。删除分支不会影响已提交的记录,因为在git里面分支通过HEAD指针实现的
远程仓库
-
在Github上新建一个项目my-project,然后使用
git remote add origin https://github.com/xxx/my-project.git
与远程仓库进行关联,最后使用git push -u origin master
将项目推送到远程仓库若远程仓库不是空的,这时候本地仓库和远程仓库是独立的,
git pull origin master --allow-unrelated-histories
需要将远程仓库与本地仓库进行合并 -
git pull <远程主机名> <远程分支名>:<本地分支名>
更新代码,本地分支可以省略,省略后默认为当前本地分支,远程分支也可以省略,第4条会讲到当工作空间修改了project.txt时,但是还没有commit,这时候其他人提交project.txt到了远程仓库,若project.txt存在冲突,
git pull origin master
会失败。git stash
命令会将本地修改暂时隐藏,这时候我们更新代码,更新完成后,git stash pop
将之前隐藏的释放出来,最后解决冲突即可上面说的是没有commit,假如我们已经commit,我们这时候可以直接更新代码,解决冲突即可
新建远程分支,
git push origin v1.0:v1.0
此命令会将本地v1.0分支推送到远程v1.0分支本地分支和远程分支进行追踪,
git branch --set-upstream-to=origin/master master
此命令将远程master分支与本地master分支进行关联, 在使用git pull origin
或git push origin
可以省略远程分支名,假如当前项目只与一个远程仓库进行了关联,主机名origin也可以省略我们也可以使用
git clone url
把项目检出,检出后不需要将本地仓库与远程仓库进行关联,也不需要设置分支追踪,使用相对于上面来说比较简单git branch
查看本地分支
git branch -r
查看远程分支
git branch -a
查看所有分支
git push origin -d 分支名
删除远程分支
git remote remove origin
解除与远程仓库的关联
git checkout -b myRelease origin/Release
检出远程的Release分支,在本地起名为myRelease分支,并切换到本地的myRelase分支
其它
git update-index --assume-unchanged application-dev.yml
忽略已跟踪的文件的改动
git update-index --no-assume-unchanged application-dev.yml
恢复已跟踪的文件的改动
git config --global user.name "your name"
设置全局用户名
git config --global user.email "your email"
设置全局邮箱
git config --global credential.helper "store"
保存密码
git config --list
查看全局设置