学习资料:Git GitHub GitLab使用教程
git:版本控制系统,一种命令,一种工具。
gitlib:用于实现git功能的开发库。
github:基于git实现的在线代码仓库,一个网站界面,向互联网开放。
gitlab:基于git实现的在线代码仓库,用于搭建自己的类似github一样的系统,一般用在企业等内部网络搭建git私服。
1 git的文件变化周期
工作目录下面的所有文件都不外乎这两种状态:
- 已跟踪(tracked)。指本来就被纳入版本控制管理的文件,在上次快照中有它们的记录。工作一段时间后,它们的状态可能是未更新(unmodified),已修改(modified)或者已放入暂存区(staged)
- 未跟踪(untracked)。
2 git基本命令
#配置
% git config --global user.name "xxx" #配置或修改用户名,方便项目追踪
% git config --global user.email "xxx@xxx.com" #配置邮箱
% git config --list #查看配置列表
% git config user.name #查看用户名
#help
% git help //查看一些命令说明
% git help 命令 //查看该命令详细说明
#常用命令
% git init <file> //在这个文件夹下创建git项目
% git status //查看git状态 branch commits..空文件夹不会被获取到,但是空文件可以
% git add <file> //将file加入git
% git add . //把该目录下所有没被track的文件全部加入git
3 commit
提交,当前的项目备份的版本是否生成取决于是否做了commit。
% git commit //得到一个hash值的档案号
% git commit -m "xxx"//用于提交跟踪过的文件
% git commit -am "xxx"//用于提交暂存区的文件,只能提交已经跟踪过且修改了的文件。
-m和-am的区别:
1 % git add .
2 % git commit -m "描述"
3 % git commit -am "描述" (第三步等于第一步和第二步)
- 如果有文件没被track,则不能commit。
- 某文件发生改变后,需要重新add,才能commit;或直接使用-am commit。
4 追踪
4.1 log追踪
% git log
% git log -p -2 //查看最近两次提交版本的差异
% git log --oneline //每个版本只显示一行,hash值和描述
% git log --graph //查看版本线图
% git log --graph -2//查看最近两个版本线图
% git log --graph --all //查看所有分支的版本线图
% git log --pretty //更详细得显示
% git log --pretty=oneline //一行显示完整hash值和描述
% git log --pretty=format:"%h - %an , %ar : %s" //hash值、作者、时间、描述
% git log --author="XXX" //显示所有作者是XXX显示的版本
4.2 文件追踪
#追踪文件修改前后的区别
% git diff <file> #显示已写入暂存区和已经被修改但尚未写入暂存区文件对区别。也就是确认没问题了,再add。
% git diff --cached <file> #显示暂存区和上一次提交的差异
% git diff --staged <file> #显示暂存区和上一次提交的差异
% git diff <first-branch>...<second-branch> #显示两次提交之间的差异
% git diff HEAD #查看已缓存的与未缓存的所有改动
% git diff --stat #显示摘要而非整个 diff
总结:
- 文件修改后,git diff 查看区别。
- 确认没问题,git add .。
- 由于此时还未commit,可以用git diff --cached/staged查看区别。
- 确认没问题,git commit -m。
- 由于此时已提交,使用git diff [first-branch]…[second-branch]查看两次提交之间的差异。
5 文件忽略
% touch .gitignore #创建一个忽略的文件
% /node_modules #这句话写入.gitignore中,忽略node_modules文件夹下所有文件
% *.log #这句话写入.gitignore中,忽略.log结尾的文件
% *.zip #这句话写入.gitignore中,忽略.zip结尾的文件
#已暂存的文件无法被忽略
% git -rm -r --cached stuff/ #把tracked的文件变为untracked,再忽略
% git -rm -r --cached . #把缓存里面所有内容都提出来
6 还原&版本回退
% git checkout -- <file> #恢复到修改前的状态,file需要是tracked
% git reset HEAD <file> #撤销当前文件的追踪/拉取最近一次提交到版本库的文件到暂存区,该操作不影响工作区
% git reset --hard HEAD^ #回退到上一个版本,hard表示强行
% git reset --hard HEAD^^ #回退到上上个版本
% git reset --hard HEAD <hash号> #回退到指定hash的版本
% git checkout <hash> -- <file> #回到旧版本,后面需要再提交
% git checkout <hash> -- . #所有文件
% git reflog #查看指针指向的日志
- 修改后,可以使用git checkout还原。
- add后,使用git reset HEAD还原到上次缓存区的状态。
- commit后:
- 不保存目前的版本:使用git reset – hard HEAD回到上次commit的状态。版本回退后,后面的版本都没有了。
- 保存目前的版本:git checkout – ,并再提交。
版本回退:v1 -> v2 -> v3 ,回退删掉,v1 -> v2
回到某个版本:v1 -> v2 -> v3,回到v2,v1 -> v2 -> v3 -> v4 (=v2)
7 分支
分支是什么?
- 可理解为移动硬盘。
- 同一个版本,复制到另一个分支后,hash值一样。
- 在分支B下做改变,不影响分支A。
% git branch #罗列当前拥有的分支
% git branch <name> #创建分支
% git checkout <branch name> #切换分支
% git checkout -b <branch name> #建立和切换同时进行
% git branch <name> -d #删除分支,在别的分支下运行;如果没有合并,则需要使用强制删除。
% git branch <name> -D #强制删除分支
% git branch <name> <hash> #恢复被删除的分支
% git push origin --delete <远端branch name> #本地删除远端分支
不同分支下的log不同。
在分支下修改后,如果需要返回master,需要提交后再返回,否则会影响master。
% git merge <branch name> #合并分支,在分支A上合并分支B
#解决冲突
% git status #查看冲突原因
#sol1:放弃合并
% git merge --abort #忽略本次合并
#sol2:手动选择正确内容,再提交
% git commit
% git branch --merged #显示已经合并了的分支
% git branch --no-merged #显示未合并的分支
% git branch --merged |egrep -v"(^*|master|develop)"|xargs git branch -d #一次性删掉所有不想要/已经合并了的分支,括号里的是不想删的分支,xargs是转换
% git branch --no-merged |egrep -v"(^*|master|)"|xargs git branch -D #未合并的分支用D强行删除
快转机制(fast forward):快转实际就是当前master的将来时。
% git merge <branchname> --no-ff #不执行快转
% git merge --no-ff --no-commit <branch name> #不执行快转,不提交,只是修改,只是工作区发生了变化。适用于合并后,需要测试的场景。
% git merge --squash <branch name> #压缩并合并该分支
% git merge --no-ff -squash <branch name> #此命令矛盾不可用,因为no-ff要展示各个版本,而squash要压缩各版本到一个。
% git reset -hard ORIG_HEAD #回退到没有合并前
8 github
创建repository,不选择初始化
…create a new repository on the command line
% echo "# test2" >> README.md
% git init
% git add README.md
% git commit -m "first commit"
% git branch -M main
% git remote add origin https://github.com/Juyz18/test2.git #连接远端仓库地址,origin映射后面的地址
% git push -u origin main #把本地的推到远端仓库去
% git push --set-upstream origin master #远端生成master分支,-u就是--set-upstream的缩写,两句话效果相同。
…or push an existing repository from the command line
% git remote add origin https://github.com/Juyz18/test2.git
% git branch -M main
% git push -u origin main
主仓库作为服务器
Repository name:username.github.io
获取远端项目
% git clone <远端仓库地址>
% git clone --no-checkout <远端仓库地址> <new name>
% git clone --bare <远端仓库地址> #裸体,不显示代码,只显示仓库信息(.git文件)
% git pull # pull = fetch + merge
% git fetch #从远端到本地,git push 从本地到远端
% git merge
% git remote -v #查看远端版本
% git push origin --delete <branch name> #删除远端分支
% git remove set-url origin <远端仓库地址> #仓库迁移
9 SSH
SSH是一种安全协议,连接客户端和服务端
ssh git@github.com
ssh-keygen
~/.ssh/id_rsa #private key 私钥
~/.ssh/id_rsa.pub #public key 公钥
将公钥存入服务器中的SSH key中