Git 分布式版本控制系统
一、为什么要学习git?
1.可以帮我们进行版本的管理,随时可以回退到之前的版本,并且可以清晰的知道哪次修改了那些信息。
2.同事之间可以远程协作,共同去修改一个文件。
二、git命令
git init : 新建一个仓库
git add xxx.txt 将我们修改的文件添加到暂存区
git status 查看当前仓库的状态
git log 查看我们的提交日志(16位的commit id避免在分布式场景下发生冲突)。
git reset --hard HEAD^(当前分支) 回退到之前的某个版本
反悔了:git reset --hard commit id 回退到未来的某个分支
通过git reflog 来查看历史命令,可以来查找commit id
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C8t6kQt4-1664610210888)(C:\Users\Yu_zhiqiang\AppData\Roaming\Typora\typora-user-images\image-20220929205643290.png)]
git commit 只能用来将暂存区修改的文件提交。
如果我们错误的修改(修改、删除)了文件
,还没有添加到暂存区可以使用:git checkout – myfile.txt,
如果提交到了暂存区,可以使用 git reset HEAD myfile.txt;
三、关联远程仓库(gitee)
1.以后本地仓库---->远程仓库
git remote add origin git@server-name:path/repo-name.git //默认名字为origin 将已有的本地的仓库和远程仓库连接
2.远程仓库----->本地仓库
git clone ~~~~
四、分支管理
SVN同样有分支管理,但是由于速度过慢,用的人很少。 git的创建分支、合并分支就是修改指针的指向,所以很快。
git checkout -b dev //Switch to a new branch “dev”
相当于:
git branch dev // new a branch
git checkout dev // switch to branch ‘dev’
我们一般开发一个功能,会新建一个自己的分支进行开发(可以随时进行提交,避免丢失),开发完成以后将我们的dev分支合并到主分支master(就是将master指针指向dev分支的当前节点),之后我们就可以将我们的分支删除掉。
git checkout -b dev
git checkout master
git merge dev //merge dev to current branch
git branch -d dev //delete own branch
由于前面我们使用git checkout – myfile 去撤销对一个文件的修改,和切换分支类似,我们可以使用git switch -c dev创建并切换到该分支
分支冲突:
git switch -c nb(new branch 简称:nb) 创建并切换nb分支
修改myfile.txt,切换回master分支继续对myfile.txt修改,然后合并nb分支到主分支:git merge nb 会出现冲突。
此时再打开myfile.txt文件,会出现冲突的标志。
默认的git merge合并分支采用的时Fast forward模式,但这种情况,删除分支会丢掉分支信息
如果采用–no-ff模式,merge时会生成一个新的commit分支
区别:–no-ff可以看出会生成一个commit点做合并。
fix the bug
如果我们在一个分支dev开发一个功能期间,突然需要先修复一个bug,我们可以通过git stash将当前分支工作区所做的修改存起来,之后可以通过git stash pop 恢复。然后新建一个分支issue-a来fix bug,修复好以后我们merge到master分支之后删除掉这个分支。但是由于dev是在fix bug之前分出来的,dev分支也有这个bug,我们可以通过git cherry-pick commit 将修复以后的issue-a分支复制到当前分支。
删除未合并的分支
直接git branch -d feature不行, 可以使用git branch -D feature 强制删除
并不是所有的分支都要push的远程库:
- master分支是主分支,要时刻与远程仓库master同步(
master并不是一定要和dev分支同步,dev开发完成一个功能以后次啊会合并到master分支上
) - dev分支是开发分支,团队所有成员都需要在上面工作,也需要与远程dev同步
远程协作
你的伙伴想将远程库拉下来,默认只有master分支,想在dev分支上开发需要
git checkout -b dev origin/dev
远程协作遇到的问题:
- 首先,可以试图用
git push origin <branch-name>
推送自己的修改;- 如果推送失败,则因为远程分支比你的本地更新,需要先用
git pull
试图合并;
- 如果git pull提示no tracking information
git branch --set-upstream-to <branch-name> origin/<branch-name>
建立本地分支和远程分支的关联- 如果合并有冲突,则解决冲突,并在本地提交;
- 没有冲突或者解决掉冲突后,再用
git push origin <branch-name>
推送就能成功!
为什么需要git branch --set-upstream-to <branch-name> origin/<branch-name>
建立本地分支和远程分支的关联?
如果没有建立连接:我们每次push或者pull都需要git push origin dev、git pull origin dev,建立连接以后,我们就可以直接git push 、git pull
正常的分支开发流程:
并不是每次dev开发完后都需要合并到master上然后push远程,这样两个分支的意义就不大了。每次在dev分支开发完以后push到远程库dev分支上,当某个大的功能稳定了,会有人把dev分支合并到master分支的。
git rebase
git rebase 将本地未push的提交历史整理成一条直线,使我们在查看历史提交变化是更容易,但是本地的分叉提交会被修改。
原理是将一个分支的修改移到另一个分支。
最近在做项目时发现自己的Git知识比较薄弱,所以系统的学习了一下
持续更新…
项目中.gitignore的作用
并不是所有的文件都需要保存到版本库中,例如‘target’目录下的文件。可以通过在此文件中以一定规则去忽略某些文件。
Git忽略规则优先级:
从命令行中读取可用的忽略规则
当前目录定义的规则
父级目录定义的规则,依次递推
$GIT_DIR/info/exclude 文件中定义的规则
core.excludesfile中定义的全局规则
12345
Git忽略规则匹配语法:
- ** 匹配多级目录,可在开始,中间,结束
- ? 通用匹配单个字符
- ‘*’ 通用匹配零个或多个字符
- [] 通用匹配单个字符列表
常见匹配示例:
bin/: 忽略当前路径下的bin文件夹,该文件夹下的所有内容都会被忽略,不忽略 bin 文件
/bin: 忽略根目录下的bin文件
/*.c: 忽略 cat.c,不忽略 build/cat.c
debug/*.obj: 忽略 debug/io.obj,不忽略 debug/common/io.obj 和 tools/debug/io.obj
a/**/b: 忽略a/b, a/x/b, a/x/y/b等
!/bin/run.sh:不忽略
bin 目录下的 run.sh 文件
*.log: 忽略所有 .log 文件
config.php: 忽略当前路径的 config.php 文件
如果添加一个文件到Git,但发现添加不了,原因是这个文件被.gitignore忽略了:
git add -f App.class 使用-f选项强制添加到git
git check -ignore -v App.class 找出哪个规则写错了