版本控制工具
1. 安全高效的合并他人代码
2. 对项目的版本进行控制 (版本的多元开发 回退 撤销 )
版本控制工具分类
git (分布式版本控制工具)
可以在开发者本地形成‘自己’的版本, 如果形成‘合并’版本也必须访问中央仓库(github/gitlab/码云 网络访问)
svn (集中式版本控制工具)
不能在开发者本地 形成版本控制 ,所有的版本访问都需要访问中央仓库(远程服务器 网络访问)
git优势:
1.本地形成版本
2.版本说明重写(git可以 svn不可以)
3.git中的一切’合法‘操作,都是可以后悔(撤销操作)
4.强大的分支(branch)系统
5.git 全量备份 svn 增量备份
linux 常用命令
cd -- change directory 切换目录
ls -- list 显示目录下文件和文件夹
ls -l <==> ll 以长格式展示文件和文件夹
ls -a 查看所有文件(隐藏文件)
mkdir -- make directory 创建文件夹
touch -- 创建文件
pwd -- print work directory 打印当前所在的位置
echo -- 输出
echo '' >> 文件 (追加写入)
echo '' > 文件 (覆盖写入)
cat -- 查看文件的内容
vi 文件
默认模式(不可以直接编辑文件 )
按i 进入编辑模式
按esc 退出编辑模式 才能保存
使用:w wirte
q quit
! 强制
:wq! 强制保存并退出
:q! 不保存强制退出
ctrl + a 定向光标到开始位置
ctrl + e 定向光标到结束位置
ctrl + c 放弃当前这行命令
rm -rf 目录
r 递归 目录必须加r
f force 强制
cp -- copy 拷贝文件和目录
cp 原文件 目标文件
cp -r 原目录 目标目录
mv 源文件名 目标文件名 移动或者是重命名
//git 基本操作
git 三个区 和 文件状态
三个区 : 工作区(开发区域) 暂存区 对象区(版本)
文件状态:
已管理(已追踪)
未追踪
已暂存
已提交
已修改
git 仓库初始化和移除仓库
mkdir test
cd test
git init
/*
Initialized empty Git repository in C:/Users/xuanqiyan/Desktop/test/.git/
*/
rm -rf ./.git
三个区域中的文件状态
git init (初始化git仓库)
touch a.txt
git status (查看git仓库文件状态)
/*
On branch master
No commits yet // 还没有任何提交
Untracked files:
(use "git add <file>..." to include in what will be committed)// 将文件加入到暂存区
a.txt
nothing added to commit but untracked files present (use "git add" to track)
*/
git add a.txt
git status
/*
On branch master
No commits yet // 还没有任何提交
Changes to be committed: //commit 提交
(use "git rm --cached <file>..." to unstage) //将文件从暂存区拉回到工作区
new file: a.txt
*/‘
步骤1 : 执行拉回工作区
git rm --cache a.txt (没有版本的情况下)
git restore --staged a.txt (暂存区的文件拉回到工作区 已经有历史版本的情况下)
步骤2 : 执行提交 --》 形成版本
git commit -m "版本提交说明"
/*
[master (root-commit) c8dff02] 第一次版本形成
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 a.txt
*/
#### 日志查看
git log 查看版本
git log -n 查看最近几次版本日志
git log --pretty=oneline 一行显示日志信息
git log --pretty=format:"%h - %an ,%ar : %s" 自定义日志风格
/*
%h - %an ,%ar : %s"
3ddf10c - xuanqiyan ,6 minutes ago : 修改a.txt
*/
git blame 文件名 查看包含该文件的所有版本
#### git 仓库的邮箱和姓名设置
git config
/*
--system 1 (本计算机了解) use system config file
--global 2 (本用户 常用) use global config file
--local 3 (本仓库 了解) use repository config file
*/
同时配置邮箱和姓名 优先级:3》2》1
//local级别设计name和email
git config --local user.name 'XUANQIYAN'
git config --local user.email '123456@qq.com'
git config -- unset user.name
git config -- unset user.email
检出实验
modified : a.txt --》 检出 --》 移除modified 还原到未修改的状态
delete : a.txt --》 检出 --》 移除delete 还原文件
检出就是移除文件的前面的操作动作,而且这个检出必须针对工作区的文件
实验一:对已提交的文件(commit)执行修改操作
git init
touch a.txt
git add .
git commit --> 版本
------
echo '2222' >> a.txt
/*
修改已提交的文件 那么这个文件将被拉回到工作区
查看状态 modified: a.txt
*/
执行检出
git restore a.txt
git status
/*
On branch master
nothing to commit, working tree clean
证明工作区的被修改的a.txt文件被还原到对象区了
*/
cat a.txt
/*
发现修改的内容不在了
*/
实验二:对已提交的(commit)文件执行删除 (操作系统的删除 rm命令)
touch b.txt
git add .
git commit -m ''
-----
rm b.txt (操作系统的删除 rm命令)
/*
删除已提交的文件 那么这个文件将被拉回到工作区
查看状态 delete: a.txt
*/
git status
/*
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: b.txt
*/
git restore b.txt
git status
ll 查看文件 b.txt 又被还原了
实验三:对已提交的(commit)文件执行删除 (git rm命令)
git rm b.txt
git status
/*
On branch master
Changes to be committed: 可以提交
(use "git restore --staged <file>..." to unstage) 将暂存区的b.txt文件拉回到工作区
deleted: b.txt
*/
方式1:提交删除
git commit -m '删除b.txt'
方式2:撤销删除
git restore --staged b.txt (拉回工作区)<==> git reset HEAD b.txt
git restore b.txt 检出 <==> git checkout -- b.txt
ll 发现b.txt 文件又还原了
#### git忽略
.gitignore 忽略某些文件或者是目录不被git所管理
/*
node_modules 第三方插件
/dist 项目上线压缩构建项目
# local env files 本地的环境变量
.env.local
.env.*.local
# Log files 错误日志文件
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files 本地配置的编辑器 后台脚本配置
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*/
// 实验:自定义.gitignore 文件 (linux中.开头的文件或者是目录都是隐藏的)
新建仓库 test1
touch .gitignore
a.* 已a开头的所有文件
*.js 所有js文件
*.txt
!c.txt 除了c.txt 忽略其他
自动忽略空目录
/demo 忽略demo目录
abc/*/*.txt 忽略 abc/a/*.txt abc/c/*.txt
abc/**/*.txt 忽略 abc/a/a/b/*.txt
//git 分支操作
分支概念:
1.由多个commit按照时间顺序形成的工作记录线就是分支(branch)
2.每一个commit就是提交的版本
3.分支的建立必须要有一个commit作为基础(起始点)
注意:
1.HEAD(当前所在) 指向分支名
2.分支名指向最新的commit
分支操作:
创建分支
git branch 分支名
切换分支
git checkout 分支名
创建并切换分支
git checkout -b 分支名
查看所有分支
git branch
-v 查看分支指向的版本
删除分支
git branch -d 分支名
git branch -D 分支名(强制删除)
合并分支
git merge 分支名
/*
合并方式有两种
1. fast-forward(默认的 )
2. --no-ff
*/
## 不能删除分支实验
1.不能再当前分支删除该分支
2.如果分支有’未合并‘的内容不能删除
场景:
两个分支 dev分支有新的commit(未合并) master 分支落后
git checkout master
git branch -d dev
/*
error: The branch 'dev' is not fully merged(合并).
If you are sure you want to delete it, run 'git branch -D dev'.
*/
选择一:(强制删除)
git branch -D dev
/*
但是未合并的版本一直是保留的 ,只不过这个版本不能再读取
*/
选择二:合并在删除
git merge dev
/*
Updating 6d0208e..b94867c
Fast-forward 向前合并
a.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 a.txt
*/
git branch -d dev
注意细节:
1.如果在 dev 分支进行了写操作(删除 修改 添加 ),这个写操作只局限在工作区和暂存区,
master 分支是可以看到写操作的,如果dev写操作执行了commit(形成版本分支指针前进指向最新的commit)
master 分支是不可以看到写操作的
2.如果在 dev 分支进行了写操作(删除 修改 添加 ),这个写操作只局限在工作区和暂存区,
master 分支是可以看到写操作的,所以dev分支可以删除
3.分支之间共享工作区和暂存区
## 合并实现fast-forward
场景:
dev分支存在为合并的commit, master 落后
git checkout master
git megre dev
/*
Updating 4d20921..75baab0
Fast-forward
*/
注意:
1.分支合并本质上是分支指针的移动,合并后会保留中间的commit
2.两个分支指向同一个commit 点
3.会丢失分支信息
补充命令:图形化查看日志
git log --graph
git log --graph --pretty=oneline --abrev-commit
## 合并实现--no-ff
场景:dev分支存在为合并的commit, master 落后
git checkout master
git merge --no-ff dev
注意:
1.no-ff 合并完两个分支指向不同的commit 点 ,主动合并的在前,被合并的在后
2.no-ff 合并不会丢失分支信息
3.被合并的还要执行一次ff合并,让两个分支指向同一个commit
## 合并分支时的冲突和解决冲突
场景 :
dev 和master 分支都向前提交形成一个版本,而且两个版本对同一个文件的同一行有不同的实现,
master 分支合并dev 分支
产生的原因: 没有时间(先后)关系的版本合并可能就会产生冲突
实现:
git checkout master
git merge dev --> 产生冲突
/*
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
Automatic merge failed; fix conflicts and then commit the result.
*/
解决冲突:
master 主动合并的分支
git checkout master
vi a.txt 冲突文件
git add . // 目的不是说加入到暂存区 而告知git 冲突已经解决
git commit -m '解决了a.txt 文件的冲突'
dev 被合并分支
git checkout dev
git merge master
## 合并分支时不会产生冲突
场景 :
dev 和master 分支都向前提交形成一个版本,而且两个版本对同一个文件的不同行有不同的实现
或者是不同文件的同一行有不同的实现,在合并的时候都不会产生冲突
touch a.txt b.txt c.txt
git add .
git commit -m 'init'
git checkout dev
echo 'bbb' >> b.txt
git add .
git commit -m 'dev b.txt文件的修改'
git checkout master
echo 'aaaa' >> a.txt
git add .
git commit -m 'master a.txt文件的修改'
git checkout master
//执行合并
git merge dev
//打开 vi ,编辑合并的版本说明
//保存退出后有合并的新的版本产生(包含两个版本中的合并以后的结果)
//git 版本回退和前进
### 版本后退
git reset --hard HEAD^ 后退到上个版本
git reset --hard HEAD^^ 后退到上上个版本
git reset --hard HEAD~n 后退到上n个版本
### 版本前进和后退
git reflog (配合良好的日志习惯 -m 注释不能瞎写)
git reset --hard sha1 (根据日志获得的版本号)
## 远程仓库
git config --list 查看所以信息
git config --global -l 查看远程仓库
git remote add origin 远程仓库地址 本地仓库与远程仓库建立连接
git push origin master -u 提交到远程仓库
git remote rm origin 删除远程仓库地址
git clone 远程仓库地址 克隆下载到本地
git clone -b dev 远程仓库地址 文件夹名 指定分支克隆
git remote -v 查看远程仓库地址
ssh-keygen -t rsa -C "邮箱"
cat id_rsa_pub