前天搞了个面试,发现好多都是会使用,但是要我说,难得说出来,现在对基础进行巩固总结。其实我感觉要求背出来一样的没必要吧,ide基本上可视化了会用就行吧。
文章目录
介绍
git是一个分布式开源的版本控制系统。
可以对开发的各种版本进行管理,也可以人多协同开发。
git可以帮助保存文件的所有修改记录,并使用版本号进行区分,可以随时浏览历史记录和各个版本的代码区别。起到恢复和保护的作用
创建git仓库后,会在根文件夹内生成一个.git的隐藏文件夹,里面存放的就是git仓库的信息。
git的状态
工作区:
就是电脑看见的目录
除了隐藏的.git
暂存区:
一般存放在.git 目录下的 index 文件中,所以我们把暂存区有时也叫作索引。
版本库
.git文件夹就是整个的版本库,包括index
也就是进行版本管理了,
使用/安装/配置
windows安装:git官网下载
linux安装:
sudo apt install git-all
设置用户
这个对git没有太多影响,只是说明性的,但是必须要有,用于区分提交者
$ git config --global user.name "用户名"
$ git config --global user.email 邮箱
检查配置信息
git config --list
操作
从使用的流程进行说起:
初始化
首先的就是创建git仓库
git init
初始化本地仓库,会生成一个.git文件夹。
后面还可以跟着一个参数就是目录的地址
git clone <git地址> [<本地目录>]
可以克隆一个git仓库,如可以从代码托管平台github/gitee上来进行。
地址在github上的项目中点击code就可以查看了。
建议在github上使用ssh,https因为墙的原因,速度很慢,而且成功率低。
跟踪文件(暂存区)
就是说如果让这个文件给git来管理。将文件添加进暂存区
git add <name>
删除暂存区文件
git rm <name># 保留在目录但是不被跟踪
git rm --cache <name>
如果修改之后,则还需要通过add来对文件进行修改,这个add命令差不多相当于在暂存里面save or update吧
git add <file-name>
跟踪当前文件夹所有
git add .
提交(版本库)
文件在add会使得文件在暂存区中,而提交则会生成一次版本。
git commit -m "本次版本的消息"
-a 暂存+提交
提交的时候很多时候会出现,像下面这样的东西
这样表明在代码检查的时候代码出现了错误,或者说代码出现了警告。不让提交
括号里面其实也说出了解决方式
那就是添加 --no-verify跳过检查
补丁操作/撤销
如果你提交完后,发现少了或者提交信息写错了那么可以加上 − − a m e n d --amend −−amend 参数。
如我如果提交之后发现有文件没有在暂存区可以这样操作
git commit -m "123"
git add .
git commit --amend
这样这次的提交记录会覆盖上一次的
撤销提交
git reset head~ --soft
撤销上一次的,不过不能撤销第一次(也就是必须要有提交)
查看文件状态
git status# 缩短状态命令的输出
git status -s /--short
status下面都有各个的状态和需要的操作
查询详细
git diff
查看差异详细
历史记录
git log
历史提交
-p
按补丁格式显示每个提交引入的差异。--stat
显示每次提交的文件修改统计信息。--shortstat只显示 --stat 中最后的行数修改添加移除统计。--name-only
仅在提交信息后显示已修改的文件清单。--name-status
显示新增、修改、删除的文件清单。--abbrev-commit
仅显示 SHA-1 校验和所有 40 个字符中的前几个字符。--relative-date
使用较短的相对时间而不是完整格式显示日期(比如“2 weeks ago”)。--graph
在日志旁以 ASCII 图形显示分支与合并历史。--pretty
使用其他格式显示历史提交信息。可用的选项包括 oneline、short、full、fuller 和 format(用来定义自己的格式)。
--oneline
--pretty=oneline --abbrev-commit 合用的简写。-<n>
仅显示最近的 n 条提交。--since, --after
仅显示指定时间之后的提交。--until, --before
仅显示指定时间之前的提交。--author
仅显示作者匹配指定字符串的提交。--committer
仅显示提交者匹配指定字符串的提交。--grep
仅显示提交说明中包含指定字符串的提交。-S
仅显示添加或删除内容匹配指定字符串的提交。
也可以通过添加pretty参数来美化
git log --pretty=onelinegit log --pretty=format:"自定义格式"
%H 提交的完整哈希值
%h 提交的简写哈希值
%T 树的完整哈希值
%t 树的简写哈希值
%P 父提交的完整哈希值
%p 父提交的简写哈希值
%an 作者名字
%ae 作者的电子邮件地址
%ad 作者修订日期(可以用 --date=选项 来定制格式)
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者的名字
%ce 提交者的电子邮件地址
%cd 提交日期
%cr 提交日期(距今多长时间)
%s 提交说明
以可视化来大于
git log --graph
在用上分支后才有明显区别,区别在于最左边的。
远程仓库
链接远程
git remote
查看当前远程仓库名称
-v 将列出所有的远程仓库
git remote <二级命令>
add 远程仓库名字 远程链接url
添加
rename 原来名字 修改后名字
修改名字
show <remote>
查看某个远程仓库
推送
将本地代码推送到远程仓库
git push 本地分支 远程分支
--tags 推送标签这样每次都需要输入本地和远程名字
我们可以加上一个-u参数,然后后面的推送就不需要输入了如:
第一次推送:git push -u 本地分支 远程分支
第二次推送:git push
github禁止用户名密码认证,可以用ssh或者令牌来认证
ssh设置
- 进入.ssh目录
- 输入命令ssh_keygen来生成密钥
-t 选择生成算法
-b 密钥大小
-C 评论 - 输入密钥名字
- 输入密码
- 在github设置界面添加ssh
获取数据
git fetch <name>
这个命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。
标签管理
列出所有标签
git tag
按照通配符列出标签需要 -l 或 --list 选项
创建标签
git tag -a 标签名 -m "消息"
删除标签
git tag -d 标签名
查看某个标签所指向的文件版本
git checkout
分支管理
分支也就相当于我们在改代码的时候,被删除原有的不用的代码,而是拷贝文件在新文件上修改,老文件看情况实用。
分支也就是差不多一个文件相当于一个分支了。
优势:
每个人单独开发一个不同功能的时候,从主分支上分离一个,开发完功能后合并到主分支。不影响其他人的开发。
但是如果2个分支对同一个功能/代码进行修改,则需要手动差异然后才能合并。
查看分支
查看所有
git branch --list查看当前可以通过下面命令看到
git status
git log
创建分支
git branch 分支名字
切换分支
git checkout namegit checkout -b name
如果name不存在则新建一个name分支并切换
合并分支
git merge name
将name分支合并到现在的分支
如果合并的时候有相同位置的修改,则需要手动修改保留那一部分。在来合并。
拉取数据
git fetch teamone
抓取本地没有的数据时git pull
将本地仓库和远程仓库(本地的)更新到远程的最新版本
存藏
如果开发到一半想切换其他的是不可以的,要么直接提交在切换,也可以实用这个存藏功能
git stash
存藏当前所修改的东西git stash apply <stash@{数字}>
恢复刚才存藏的内容git stash list
查看存藏git stash pop
恢复最近一次存藏,恢复后直接删掉git stash drop <stash@{}>
删除
变基操作
就相当于你本来在a分支上创建的b分支,变基c就相当于在c分支上把b分支操作进行一次。
git rebase name
其他
忽视文件
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件的模式。
特别是像密钥密码什么的,忽视掉这个配置文件也是一种不错的选择。
支持匹配符,写在里面的都是忽视掉的文件
如
#忽视所有的以yml后缀的文件
*.yml#忽略所有以 .o 或 .a 结尾的文件
*.[ao]# 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO# 忽略任何目录下名为 build 的文件夹
build/# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf