本文章属于git入门篇,针对刚开始接触git的同学,帮助大家了解git并理清使用思路,当然有git使用经验的也不妨一看,说不定会有意外收获呢
本篇假设你已经安装好git,并配置好了username、email信息。
一、git简介
Git是一款开源的先进的分布式VCS,SVN是集中式VCS,由Linux之父Linus用C语言写的。git本质上是一个内容寻址的文件系统。起初git是为方便开发Linux而设计开发的,目的性和专业性很强,所以你会发现git和Linux那一套很像。后来经过多次演化,才变得相对易用一些。
ps:如果你使用过SVN的话更好,你可以对比着SVN来看下,git与SVN有哪些差异?本文章最后也会说一下作者的看法。
二、为什么需要git?
1)文件版本的控制
版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。在git中每次commit就是一个版本,他里面记录了此时所有文件修改后的最新快照。一个软件可能由许多分支组成,每个分支可能由许多commit组成,每个commit可能由许多修改后的文件快照组成。假如说一个文件在10次commit中被修改了2次,那他就有3个版本,被修改了9次,那他就有10个版本,我们也可以单独对单个文件进行回滚。
2)多人协作(一个人搞不了,那就好多人一起搞,git可以在多人之间同步更新)
3)安全、方便(分支)、速度快
git命令帮助文档:
和linux的man、--help等帮助命令一样,git也提供了帮助命令,如下
git 命令 -help #查看命令的选项
git 命令 --help #命令的详细文档
git help 命令 #命令的详细文档
不明白的命令可以看文档查一查。
二、git的使用流程
这张图描述了git的常用命令和基本工作流程,大家先感受下:
这里面git clone的作用描述的有点问题,知道答案的同学欢迎评论区,showtime~~~
ok,下面就以tom、jerry两个人协作为例,梳理一下git的基本使用流程。这里使用先初始化本地仓库,在推送到远程仓库的方式进行说明:
一、用git对项目进行初始化
1、初始化本地仓库
1.0 .gitignore 文件
有一些文件不想让git跟踪,此时可以将这些文件添加到.gitignore 文件中,git将忽略跟踪这些文件。.gitignore文件通常和.git文件夹在一个目录。在初始化项目之前 添加.gitignore文件是个好习惯。
1.1 初始化本地仓库
假设 tom 已经将项目框架搭建好了,进入项目根目录下,右键Git Bash Here,进入git命令行窗口,输入 git init 用来初始化一个本地仓库。
1.2 项目添加到Git的本地仓库
方式一:git命令方式
1)git add . #将当前文件夹下的所有untracked files 添加到暂存区
2)git commit -m '' 说明文字" #将暂存区的文件提交的本地仓库
方式二:开发工具idea的方式
( 用idea打开该项目,然后你会看到所有的文件都发红了,因为还没有纳入git的版本控制中。)
对着项目根目录右键, git->add ,然后发现所有的文件变绿了。再对着项目根目录右键, git->commit Directory ,在弹出的框中输入本次提交的信息,点击commit,就成功将项目初始化得到本地仓库中了。
2、建立远程仓库
再码云上或gitHub上创建一个仓库,复制项目的https或ssh地址。
3、将本地仓库中的项目推送到远程仓库
3.1、添加本地仓库的远程仓库 (地址会自动保存到.git文件夹下的config文件中)
git remote add origin 远程仓库的地址 #origin是自定义的远程仓库地址的别名,方便直接通过别名操作
3.2、推送项目到远程仓库中
git push -u origin master -f # -f 表示强制推送
推送时注意:
最好建立远程仓库时不要添加.gitignore和Reademe文件,.gitignore使用本地的,Readme文件也在本地编辑好或者等项目传上去后再根据提示添加就好了。
注意:远程仓库的地址,若使用ssh协议需要先配置公钥私钥。
配置公钥私钥步骤:windows系统下
1、进入到当前用户目录,打开 git bash 。#用户目录如: C:\Users\admin,Linux下可用 cd ~ 命令直接进入
2、执行 ssh-keygen -t rsa -C "你的邮箱地址" ,然后一路enter即可。
3、之后默认会生成一个.ssh目录,里面有俩文件 id_rsa 文件保存私钥,id_rsa.pub文件保存公钥。
然后将公钥复制到码云/github的 设置-》ssh公钥里面即可(注意是个人中心里面的ssh公钥,不是仓库里面的)。
之后再git remote ,,,
4、jerry将项目clone下来协同开发
jerry进入某个文件夹下,通过Git Bash 窗口执行 git clone 远程仓库地址 将远程仓库克隆到本地,默认会创建同名的文件夹。
git clone repositoryUrl 文件夹名 #clone到指定的文件夹中,没有就创建
git clone -b 分支名 #只克隆指定分支的代码到本地
git clone 默认的远程仓库别名是origin,默认的分支名称是master
5、创建分支
创建完仓库后默认有个master主分支,我们可以创建一个dev分支,用于新的分支进行开发,保持了master分支的稳定性。
方式一、对于码云/github,我们可以在页面上直接创建分支,然后将dev分支clone下来。
方式二、本地创建dev分支,然后推送到远程仓库即可。
步骤:
git branch dev #创建dev分支
git checkout dev #切换到dev分支
git merge master #将master的代码合并到当前分支
git push -r origin dev #将本地当前分支的代码推送到远程dev分支
注意:使用多个分支开发的模式,就要时刻清楚自己当前处于哪个分支中。
5.1 队友拉取分支
假设此时,队友已经用git clone将远程仓库克隆了下来。
git fetch #更新本地仓库中的远程分支列表
# 之后如果想切换到某个远程分支时,执行下面的命令即可。
git checkout -b 分支名 远程仓库/分支名 #创建并切换到某个分支,并让该分支的代码追踪某个远程分支的代码
6、撤销操作
对于这里的命令不理解的没关系,等看完git使用小手册(二)或许就能理解了。
1)撤销工作区文件的变动:
用该文件上一个版本覆盖当前版本
就近原则,如果暂存区存在文件暂存,就用暂存区的内容覆盖;如果没有暂存,就用本地库的内容覆盖。
git checkout -- fileName
git restore fileName
2)撤销文件暂存
修改后的暂存->上次检出时的快照:
git reset HEAD fileName #用当前分支HEAD提交上的该文件重置暂存区中的该文件
git restore --staged <fileName>
注意:以上撤销操作都是不可逆的,将导致文件内容丢失。在git中凡是已提交的文件都是可以找到的,但未提交的文件git就找不到了。
3)修改上一次commit
使用git commit的 --amend选项,可以直接修改上一次的提交,比如提交日志,如果本次暂存区有内容,也会合并到上一次的提交中。
git commit --amend -m "这是修改后的提交日志"
4)撤销提交:
撤销提交只能用版本穿梭。
5).gitignore文件忘记忽略某些文件了,想把已经提交的文件在远程删除掉
https://blog.csdn.net/wqkeep/article/details/119063171
7、文件内容产生冲突的原因
git区分差异的最小单位是“行”,所以当两个人对同一个文件的同一行内容改动时,在合并代码时就产生了冲突。
git不知道要使用哪个人的代码,所以将产生差异的地方完全保留了下来,等待用户手动解决冲突。而像IDEA等工具在拉取代码时会提供GUI界面,以方便用户解决冲突。
三、让别人帮忙写代码
如果我们的项目进行过程中遇到了困难,想让不是本团队的人帮忙该BUG或写代码时,可以利用远程仓库的fork和 pull request 功能让别人提交代码。
具体做法是:
若你想对某个开源项目贡献你的代码,你可以先fork一份一样的到你的个人仓库中,然后你再用git clone命令,从你的仓库中克隆下来该项目,修改完后,再git push 提交修改后的代码到你的个人仓库中,再通过你的个人仓库向原仓库发送pull request请求(请求对方拉取你的代码),该项目的管理员看到你的拉取请求后,选择同意或者拒绝,若同意的话,该管理员就会merge(合并)代码,将你的代码合并到原项目中。
更改远程仓库地址:
1、git remote rm origin #先删除之前的远程仓库地址引用
2、git remote add origin 新的远程仓库的地址 #再添加新的远程仓库地址
四、用git进行版本穿梭
4.1、查看历史提交信息
git log #查看当前分支的提交日志, -n 能查看指定个数的日志。
git log --oneline #查看精简的提交日志
git reflog #查看所有的版本改动信息(包括版本穿梭、分支操作)
翻页操作:
空格向下翻页
b 向上翻页
q 退出
4.2、穿梭到某一版本
git reset 用于在git中进行版本的穿梭,他本质上是在本地仓库中移动HEAD指针指向某次提交,同时根据参数决定是否重置暂存区和工作区。
例如:git reset --hard commit #将本地库的head指针指向某次commit,同时重置暂存区和工作区,与指定commit一致
git reset后再提交,就是接着穿梭后的版本继续提交了。之前提交的版本还保留着,可以通过reflog查看。
4.2.1、reset 命令的三个参数对比
--hard 参数
作用:1、本地库穿梭到某一版本、2、重置暂存区、3、重置工作区。
--mixed 参数(默认的)
作用:1、本地库穿梭到某一版本、2、重置暂存区、3、工作区不变。
--soft 参数
作用:1、本地库穿梭到某一版本、2、暂存区不变、3、工作区不变。
4.2.2、相对引用:
通过哈希值(commit的哈希值)穿梭还要先查询,不方便,git提供了相对引用解决了这个问题:
1)^符号
git reset --hard HEAD^ #一个^表示后退一步,n 个表示后退 n 步
2)~符号
git reset --hard HEAD~n #表示后退 n 步
五、分支操作
1、查看分支
1)git branch #查看所有本地分支
2)git branch -r #查看所有远程分支
3)git branch -a #查看所有本地和远程分支
4)git branch -vv #查看所有本地分支和远程分支提交的差异
2、创建分支
1)git branch 分支名 #创建分支
2)git checkout -b 分支名 #创建分支同时切换到该分支
3、切换分支
1)git checkout 分支名 #切换分支,用目标分支的最新一次提交树 重置暂存区和工作区。
注意:1、当工作区或暂存区有未提交的代码时,该操作会使代码丢失。git为了防止代码丢失会阻止你切换分支,你需要commit或stash后才能切换分支。
3.1、stash:储藏
git允许先将本次工作区和暂存区的内容储藏起来,就好像没发生过什么事一样,此时就可以切换分支了。
git采用一个储藏栈来保存每次的储藏内容,你可以选择在任何分支上应用(apply)这些储藏内容。应用就类似内容合并,所以可能会产生合并冲突,需要手动处理一下。
git stash apply #在当前分支上应用这些储藏。
git stash apply --index #在当前分支上应用这些储藏,同时保持当时储藏时,工作区和暂存区的状态。
git stash list #显示仓库中所有的储藏。
git stash drop stash@{num} #从储藏栈中删除指定储藏。
4、删除分支
1)git branch -d 分支名 #删除本地仓库的某个分支。
2)git branch -dr 分支名 #删除远程仓库的某个分支。
5、合并分支
1)git merge 分支名
#站在当前分支上,将别的分支的代码合并过来。可能会产生新的提交(三方合并),也可能不会。
2)git rebase 分支名
#变基,即改变基节点,效果是将当前分支上的提交“复制一份”,然后放到指定分支的最新提交之后,开始开发。这样与基分支还是两个分支并行开发。好处是提交线由两条变成一条,使得整体的提交记录线更清晰。
3)git cherry-pick commit1、commit2...
#摘樱桃。我可以从其他分支的提交记录中摘取几次提交,变成当前分支的新提交。
六、给版本打个标签
和其他VCS一样,git也允许给某次提交打上标签(tag),以示重要。通常用来作为重要版本的标记(v1.0.0)、或阶段性发布节点标记等。因为git的commit是保留最新软件版本的快照,所以一个tag就相当于一个软件某个版本的备份或着存档。就和SVN的tags文件夹下的存档一样,只不过git简化了存档的过程。
git中标签分为两种类型,轻量级标签(lightweight)和注释标签(annotated)。
lightweight寓意临时标签、不重要的标签,没有多余的标签信息。
annotated寓意重要点的标签,包含一些标签信息(如标记人、标记时间),常用来作为重要版本标记标签。
打标签意味着VCS需要提供查看、创建、删除、重命名标签的基本功能才行。
1、查看标签
git tag #查看该仓库的所有标签,标签是不区分分支的
git tag -l 'v1.0.*' #支持通配符查找标签
git show 标签名 #查看指定标签版本的详细信息
2、创建标签
默认是给当前分支的最新一次提交打标签。标签名不允许重复。
git tag 标签名 #创建一个lightWeight标签
git tag -a 标签名 -m "注释标签的信息" #创建一个annotated标签
git tag -a 标签名 commit #给之前的commit打标签,只需要在最后加上该commit的哈希值即可
2.1 共享标签
git push 命名不会将标签推送到远程仓库的,你需要手动推送该标签。
git push origin tagName #提交指定的标签到远程仓库
git push origin --tags #提交所有的标签到远程仓库,已推送的就不再推送了
3、删除标签
git tag -d tagName #删除本地指定的标签
git push origin :refs/tags/[tagName] #将本地的标签与远程仓库的标签同步,相当于删除了远程的标签
4、检出标签
如果你想穿梭到某个tag的版本,用git reset即可。如果你想穿梭到某个tag的版本,并想在此基础上创建个分支继续开发,可以先git reset,再git branch,再git checkout,git提供了检出标签指令简化了这一过程。
git checkout -b 新分支名 之前的标签名 #在原来某个标签的基础上,创建一个分支并切换到该分支。
七、最后
好了,本文到此基本就结束了。
简单回顾一下,本文对git中基本操作操作、分支、版本穿梭、撤销操作、打标签等内容做了梳理,理解并应用以上内容能解决日常开发中至少80%的问题。如果对git的核心概念、.git文件夹内容、基本运行原理感兴趣,可以继续看这篇文章 git使用小手册(二)
如果觉的还不错或者对你有帮助的话,那就动一下手指点个赞呗!