git相关概念
Repository
一个仓库(Repository)可以理解为管理一个项目的文件夹,只不过里面有一些配置文件,这些配置文件用于对项目进行版本控制。
git和github的关系
github是项目的托管平台,只支持git作为唯一的版本库格式进行托管。
要注意git和github并不是密不可分,可以理解为git是一个软件,用于管理项目仓库;
而github是在git的基础上建立的。
github只能使用git,但是git可以应用于其他支持git的项目托管平台,比如gitee。
git bash与cmd
git bash封装了cmd,并在此基础上加了bash环境的环境变量。
但是在封装的过程中,windows可能对调用自己cmd命令行控件的第三方应用设了限制,因此git bash在绝大多数情况下可以像普通cmd一样使用。
git clone与下载zip的区别
下载zip会默认下载master主版本工程文件,下载后的文件夹为name-master,而git clone不会有。
使用git clone下载时会现在本地初始化git项目文件,这也是比直接下载zip文件多出的一个.git文件夹。
就是通过这个多出的.git文件夹可以修改源码后重新往github提交,而直接下载zip的工程文件没办法提交了。
所以如果直接使用从github上下载的东西而不push上去的话,两种方法都可以。
git的三个工作区域
工作目录、暂存区、本地仓库、远程的git仓库
工作区(workspace) :平时存放代码的地方
暂存区(index/stage) :临时存放改动,事实上只是一个文件。
本地仓库(repository) :最终确定的文件保存到仓库,成为一个新的版本,并且对他人可见。
远程仓库(remote) :代码托管的远程服务器
git基本操作
git的配置文件
查看系统配置git config --system --list
查看用户配置git config --global --list
查看本仓库配置git config --local --list
系统配置文件所在位置[安装位置]/etc/gitconfig
用户配置文件所在位置C:/Users/[xxx]/.gitconfig
向仓库中添加更新
添加文件到暂存区git add .
提交暂存区内容到本地仓库git commit -m "[提交描述]"
配置用户名邮箱
配置用户名git config --global user.name "[用户名]"
配置邮箱git config --global user.email "[邮箱]"
注意这里的用户名和邮箱只是起到一个区分身份的作用,可以随便填写。
配置免密登录
本地生成rsa密钥对ssh-keygen -t rsa -C "[邮箱]"
-C是comment的缩写
-C表示提供一个注释,用于识别这个密钥。因为邮箱地址具有唯一性所以一般用来识别密钥
查看生成的公钥cat ~/.ssh/id_rsa.pub,在github添加SSH公钥
测试是否添加成功git remote -v,如果没报错,说明添加成功。
刚配置好时没有内容,可以手动添加默认的或者自定义的远程链接的别名,也可以等第一次push到github的时候git将仓库链接自动添加到origin别名里。
添加远程关联
git remote add 关联名 https://仓库链接查看远程关联信息
git remote -v删除远程关联
git remote rm 关联名push到github
git push 关联名 当前本地分支名
拉取仓库修改并提交
在github上创建一个仓库之后,就可以用git clone url将这个仓库完整的拉取下来。
然后进入此项目目录中进行修改,修改完后要同步到github上,就要进行下面的操作。
先将本地的修改同步到暂存区git add .
然后将暂存区的更新同步到本地仓库git commit -m "注释描述"
最后将本地仓库push到github上,git push或者git push 关联名 本地当前分支名:要推送到远程的分支名(可以是新的)
git add时报错
warning: LF will be replaced by CRLF in解决办法windows中的换行符为 CRLF, 而在linux下的换行符为LF,git为了解决跨平台开发的换行问题,提供了
自动换行转换,这个功能是默认处于”自动模式“即开启状态的。这样在git add的时候即便没有修改内容,由于转换换行的原因,git也会认为你修改过内容,所以会提示warning。不需要关注
版本回退
查看版本历史记录git reflog,更详细的信息用git log
可以使用git reset --hard commitId来切换项目的版本。注意--hard的作用是同时作用于工作区和暂存区。
reset回退方式可以将代码库中的某个版本回退到之前的某个版本,会更改本地分支的历史记录,不建议使用。
revert命令可以创建一个新的提交,撤销特定提交引入的更改,但保留提交历史。
git revert commitId即reset是回到某个commtId,revert是撤销某个commitId
git切换版本的原理,底层其实是移动HEAD指针。
可以看本地的
.git目录下的HEAD文件,可以看到里面指针指向refs/heads/master,说明当前是在master分支上。然后查看指针指向的文件,里面保存的就是当前的commitId。
同分支commitId切换
HEAD是一个指针,通常情况下,它指向当前所在分支,而分支又指向一个commit提交。
HEAD并不总指向一个分支,某些时候仅指向某个commit提交(git checkout commitId的时候),这就形成detached HEAD。切换到 detached HEAD 状态时,会有一个警告
也就是说切换到某个commit后,只能查看代码历史,不能对代码进行修改、提交等操作。
解决方法是在切换的时候直接创建一个新的分支,git switch -c [新分支名],可以想象一个分支图来理解
git的分支
查看分支git branch -v, git branch -a
创建分支git branch 分支名
切换分支git checkout 分支名
合并分支git merge 分支名,注意如果要将一个分支合并到主分支上,需要先checkout到主分支上,再进行merge。
切换分支本质上也是修改的HEAD指针。
fetch和pull区别
git fetch是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中。git fetch用户从远程仓库获取最新的更改,但是不会合并到自己的当前工作分支
git pull则是将远程主机的最新内容拉下来后直接合并,即:git pull = git fetch + git merge,这样可能会产生冲突,需要手动解决。因此最好只使用git fetch而不使用git pull
fork\clone\fetch\push\pr全流程
pull request是对于开源项目来说,自己没有权限直接操作远程仓库。可以fork一个项目,然后更改,通过pull request的方式提交给仓库所有者。
几点说明:
1.
git clone时会把整个仓库clone下来,也就是说仓库有多少分支就都会clone下来,然后可以用git chekcout <分支名>来切换到想要操作的分支上。2.修改的是哪个分支(也就是说当前是在哪个分支),fetch的时候就要fetch哪个分支。
3.在PR的时候一定要看清楚要把当前分支PR到原repo的哪个分支上去,千万别a分支PR到b分支上去。
1.使用gitee,账号azsxdc0账号下创建myrepo仓库
2.chen账号fork这个仓库,并clone下来
3.chen账号修改user.name和user.email
git config --local user.name "xx"
git config --local user.email "xx@qq.com"
4.chen账号修改readme.md内容如下
1.hello~1
然后还需要git add ., git commit -m "..."来做一个节点
5.这时再从azsxdc0账号下重新clone一份,修改user.name和user.email
6.azsxdc0账号修改readme.md内容如下
2.hello~2
7.azsxdc0账号commit并push到主分支(这里用来模拟chen账号开发完之后想要push时,原仓库azdxdc0账号的源码已经更新了的情况)
8.chen账号这个时候需要fetch一下azdxdc0账号的新源码,操作如下
9.先添加remote
git remote add upstream https://gitee.com/azsxdc0/myrepo.git
10.把azsxdc0账号新源码fetch下来
git fetch upstream master
语法:git fetch <remote添加的原仓库名> <master分支>
这个时候会将azsxdc0账号master新版本下载下来
11.将remotes/upstream/master合并到本地master分支,因为两个readme.md文件内容不一样,因此报错conflict
注意这里的一个做法是不切换到远程master分支,而是以本地master分支为基础,让远程master来合并到本地master分支
12.使用git status查看冲突信息,发现readme.md都修改了
13.这个时候再去看readme.md,可以看到冲突
14.适当修改后,再次
git add .
git commit -m "fix conflict"
git merge remotes/upstream/master
git push
15.chen账号上gitee页面上提交pull request
16.azsxdc0账号上审核一下pull request就可以了
17.chen账号接下来的开发就正常进行,还是在提交之前先fetch一下
git fetch用法
用法1和用法2的区别就是在fetch之后的checkout不同,用法1是切换到远程分支,用法2是切换到本地分支,推荐使用用法2切换到本地分支
git fetch用法1(不推荐)
应用场景为多个人一个项目,
在clone一个项目后,进行一定的修改,比如加了一个文件,然后git commit,主要切换分支之前一定要git commit,否则当前工作为丢失。
要跟其他项目合并,先执行git fetch,执行git checkout -b 本地分支-dev origin/远程分支拉取远程分支
注意这里的操作是以远程分支为基础新创建一个本地的分支
这时就将远程的这个分支拉下来,然后执行merge,将刚才修改的内容merge到本地分支-dev中,git merge main
git log可以查看到相应的日志
将合并后的分支推送到远程原有分支git push origin 本地分支-dev:远程分支
具体fetch的原理图参考
https://blog.csdn.net/qq_42780289/article/details/98049574
git fetch用法2(推荐)
应用场景为一个人一个项目,在两台电脑上操作,相当于坚果云的备份
本地创建两个文件夹用于模拟两个电脑,gitee上创建项目test2,
在1文件夹中clone下来,新建a.txt,然后commit和push
在2文件夹下,clone下来test2项目,新建b.txt,然后commit和push,git push origin master:v1.0此时push到v1.0分支
回到1文件夹下,git fetch,git checkout v1.0,注意这里是切换到本地的v1.0分支而不是git checkout origin/v1.0
继续在1文件夹下,新建c.txt,然后commit,push到v2.0分支git push origin v1.0:v2.0
再回到2文件夹下,git fetch,git checkout v2.0,新建d.txt,然后commit,git push origin v2.0:v3.0
checkout时遇到的问题
对于新创建的文件(没有commit),不论是
git checkout 分支还是git reset等都不会影响,只能通过
git checkout .; git clean -df清除
如果当前分支已经修改一些内容,现在要checkout到其他分支,那么会有以下几种操作
-
1.直接把当前修改(没有commit)清除了不要了,强制恢复到上一个commit
-
git checkout . //放弃本地修改,新增和删除的仍然没有恢复 git clean -df //从工作目录中移除没有track的文件 git log, git reset --hard <commit_id> git checkout <分支名> - 另外需要注意,如果git reset到前两个版本(中间跳过一个版本)时,前一个版本增加的文件不会被删除,而是会以untracked的状态留下来,这时如果不想要前一个版本留下来的文件,就又回到了清除当前修改的操作,需要执行
git checkout, git clean -df, ...操作
-
-
2.这个版本还要
-
2.1(推荐)先把当前修改commit一下,
git add ., git commit -m "", git checkout <分支名> -
2.2或者,暂存修改
git stash 暂存修改 git stash list 显示所有stash数据 git stash apply 恢复最近一次的暂存修改 git stash apply stash@{1} 恢复索引号对应的暂存 git stash drop stash@{1} 删除索引号对应的暂存 git stash pop 将最近一次暂存pop出来并删除
-
PR注意事项
pull requests时注意要选择合并后不删除原分支,或者删除原分支后在本地立刻git push一下,要不然自己仓库的分支就没了
Issue事务
Issue用于跟踪待办事项、bug、功能需求等。
Issue在项目中可以承担用户反馈的作用,用户可以在这个地方提出bug反馈与优化建议,也可以为开发者服务,用于记录待完成的任务。
一般来说,可以包含以下类型:
- 软件的bug
- 功能优化建议
- 待完成的任务
milestone里程碑
里程碑是一个项目计划管理工具,用于集中管理 Issue 和 Pull Request 进度。每个里程碑milestone中可以选择issue中优先级高的问题和新功能
里程碑的操作也在issue中
一个里程碑可以包含多个issue
Issue相关操作
当然除了下面commit提交时更新Issue,还可以直接在web页面上点击对应图标进行修改
Gitee 新的方案已经不采用 issue 的 id 标识 issue,而是使用 ident
比如编号为I99H9V的issue_ident的issue_url为https://gitee.com/chenfight/test1/issues/I99H9V
一个 commit message 可同时关联多个任务,不同 issue_ident 之间请用空格隔开
通过commit关联事务
关键字:link, linked, linking, relate, related, relating
形式:commit message中输入link #issue_ident或者 link issue_url
通过commit关闭事务
关键字:close, closes, closing, closed, fixed, fix, resolved
形式:commit message中输入close #issue_ident或 close issue_url
通过commit评论事务
关键字:comment, reply
形式:commit message中输入comment #issue_ident或comment issue_url
管理多个证书
参考连接https://blog.csdn.net/qq_35658349/article/details/103334343
git commit
commit message语法参考https://blog.csdn.net/xtho62/article/details/108196796
具体操作
在项目根目录创建.gitmessage文件
# head: <type>(<scope>): <subject>
# - type: ✨ feat, 🐞 fix, 📃 docs, 🌈 style, 🦄 refactor, 🎈 perf, 🧪 test, 🔧 build, 🐎 ci, 🐳 chore, ↩ revert
# - scope: can be empty (eg. if the change is a global or difficult to assign to a single component)
# - subject: start with verb (such as 'change'), 50-character line
#
# body: 72-character wrapped. This should answer:
# * Why was this change necessary?
# * How does it address the problem?
# * Are there any side effects?
#
# footer:
# - Include a link to the ticket, if any.
# - BREAKING CHANGE
#
通过 git config 命令指定 commit.template 的路径
git config commit.template .gitmessage
然后在提交的的时候不加-m
git commit
这时就会出现模板文件,按照上面的规则编写commit,此时还可以在footer位置加fix等操作把issue关掉
最后git push即可