![49ed9a308e4ff64be127400c1f77e8c1.png](https://i-blog.csdnimg.cn/blog_migrate/f6d09ae9c511a7c7e05b08e129082ae8.jpeg)
下面带来git的入门教程:
一、牛刀小试
安装好git之后,开始初始化一个git项目:
- 创建一个项目目录,可手动创建,也可以使用终端命令:
mkdir git //创建目录
cd git //进入目录
git init //初始化git项目
- 在项目里生成一个文件,可随意
比如新增一个 test.txt 文本文件,来进行相关操作
test.txt:
this is my first git project
git常用操作
- 这样创建好一个文件之后,我们将它添加到仓库中:
$ git add test.txt
git add命令是将修改的部分添加到一个暂存区。
- 接下来需要将修改提交到仓库(git初始化完成后,生成了 .git 的版本库,并自动创建一个master分支,commit 就是往master分支上提交修改):
$ git commit -m "first commit"
git commit 命令是一次性提交所有暂存区的修改,-m 表示此次提交的说明,强烈建议每次提交都进行填写,以确保自己或者团队合作时可以知晓提交的具体情况。
另:
$ git status //用于查看当前仓库的状态,有哪些修改;
$ git diff //具体查看上次修改的内容
版本控制
$ git log //用于查看提交日志,终端里按键盘q键退出查看状态
$ git log --pretty=oneline --abbrev-commit //查看简洁版
日志返回的很多条一串字符串(sha1),则是各个日志的版本号commit_id,因为git是分布式版本控制系统,多人协作时每个人的版本都是不一样的,以此来区分防止冲突。
下面我们继续提交一次新修改:
test.txt:
this is my first git project, now commit again.
接着:
$ git add //直接add 添加全部文件
$ git commit -m "第二次提交"
- 版本回退 git reset
当需要回退版本时,git的版本控制的强大就体现出来了
一些知识点:
git只需知道当前是什么版本,在git中,当前版本用 HEAD (指向某个版本库的指针索引)表示,上一版本 HEAD^ ,上上一版本 HEAD^^ ...
$ git reset --hard HEAD^
这样就将版本返回到上一版本了,还可以继续执行以上命令继续回退版本。
但是此时执行 git log 之后,发现回退之前的版本已经没了,难道无法撤销了?
当然不是,此时只要能够找到你想要执行的版本号就可以返回。但是在log日志里找不到,执行
$ git reflog //该命令记录你每一次的操作命令历史,以回到未来的某个版本
命令 就可以了,根据你的操作,找到当前版本操作的commit_id ,比如:2ed45,执行:
$ git reset --hard 2ed45
就可以回退版本到你想要的地方了。
- 撤销修改 git checkout --
当我们改动某个文件之后,想撤回到原版本,只要执行:
$ git checkout -- <file> // -- 必需,否则就变成了 ”切换到另一个分支“
就可以了。
注意:
- 当文件修改后没有添加到暂存区,则撤销到和原版本库一致;
- 当文件被添加到暂存区,且做了修改之后,则撤销到暂存区时的状态。
总之,撤销是让这个文件回到最近一次git commit
或git add
时的状态。
当文件修改被添加到暂存区了怎么撤销?别怕,你可以的。
执行:
$ git reset HEAD <file>
git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD
时,表示最新的版本。然后我们再执行
$ git checkout -- <file>
就可以销掉已经放入暂存区的修改了~
- 重新提交 git commit --amend -m 'xxx'
有时本次的提交提示对上次提交的内容进行小修改或者你commit的说明需要修改,你可能会直接在本地修改一下,重新提交一次。此次操作会重新生成一个git版本。如果你只是像替换掉上一次的版本,或者只是修改上一次提交的说明内容,你就可以在下次提交时执行操作:
$ git commit --amend
此次的提交,就是替换了上一次的提交版本了。
具体的用法,可看一下我这篇文章专门介绍用法:
玉藻前:git commit --amend 用法详解zhuanlan.zhihu.com![acff7496570bd15b53891ab3b37ebd02.png](https://i-blog.csdnimg.cn/blog_migrate/dfee8a4298ca41ec0f1e1d0454d7e5b1.jpeg)
- 删除文件 git rm
当你想删除某个文件时,此时你是手动删除了工作区某个文件,接着要删除版本库的该文件,执行:
$ git rm/add <file> //手动删除后,rm和add效果是一样的
接着再提交 git commit就可以了。
当你手动误删一个文件时,还记得撤销操作吗~可以执行撤销操作:
$ git checkout -- <file>
这样就还原了。
二、远程仓库
上面介绍了关于git本地仓库的操作,目前版本只是存在了本地库,如果想要在远程仓库保存,以便团队都可以去操作该仓库,就必须要使用到远程仓库了,接下来我们将利用github进行,请各位准备好自己的github(以下是默认你会使用GitHub,如果还不清楚,去学习一下关于GitHub的知识)。
由于你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以,需要一点设置:
- 第一步:创建SSH Key。
在你电脑的用户主目录(user/)下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa
和id_rsa.pub
这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:
$ ssh-keygen -t rsa -C "youremail@example.com"
你需要把邮件地址换成你自己的邮件地址,然后一路回车,默认即可,一般无需设置密码。创建完成的话,可以在用户主目录里找到.ssh
目录,里面有id_rsa
和id_rsa.pub
两个文件,这两个就是SSH Key的秘钥对,id_rsa
是私钥,需保密,id_rsa.pub
是公钥。
- 第二步:将本地库与GitHub远程库关联
登录到github之后,点击头像->Settings->SSH and GPG keys,点击Add New SSH按钮,
![c9e7c9594e9cb44574564bf7b3aa1730.png](https://i-blog.csdnimg.cn/blog_migrate/8e2834d9c29af87ed0b61a93efdf3105.jpeg)
出现上面的界面,title可根据个人爱好填写,Key就是把你.ssh目录里id_rsa.pub的内容粘帖进去,点击Add,保存成功。
接着,在GitHub上创建一个Git仓库,点击头像左边的加号,选择New repository,填写你要创建的仓库的名称,然后保存后就来到了你的仓库内,
![4fc01fdc37249ae95097e557e7e585d8.png](https://i-blog.csdnimg.cn/blog_migrate/bdfb3961bef73b5bbc8ae16f65c46e48.jpeg)
我们需要把我们本地已经存在的库进行关联,所以根据提示的 push existing的方法,分别在终端输入那两行命令:
$ git remote add origin git@github.com:yourName/yourRepName.git //origin是你自定义的远程库名称,以后推送都是推到这个名称上
$ git push -u origin master
返回Counting objects: n, done. 等其他信息,关联成功!
把本地库的内容推送到远程,用git push
命令,实际上是把当前分支master
推送到远程。
由于远程库是空的,我们第一次推送master
分支时,加上了-u
参数,Git不但会把本地的master
分支内容推送的远程新的master
分支,还会把本地的master
分支和远程的master
分支关联起来,在以后的推送或者拉取时就可以简化命令:
$ git push origin master
去看一下github仓库是不是和本地一样~
- 从远程库克隆
$ git clone git@github.com:xxx/xxx.git //后面的xxx是你需要克隆的github仓库地址
三、分支管理
又是我们编写程序时,为了提交某一天的工作量,但是代码有没有写完,这样上传到分支上会有问题,别人更新时就会报错。为了避免这种错误,就需要进行分支管理,你的部分代码上传到你自己的分支上,在完成所有代码,再将你的分支合并到主分支上。下面开始分支~
- 创建分支dev
$ git checkout -b dev
git checkout 加上 -b 表示该命令切换并创建 dev分支,相当于下面两步:
$ git branch dev //创建分支dev
$ git checkout dev //切换到dev分支
这种就创建好了dev分支。
$ git branch //查看所有分支,当前分支前面会有 * 标识
此时当前分支就是 dev了,现在修改一下文件内容,添加再提交(方法你应该会了)到dev分支上。提交成功后,现在我们再切换到master主分支上:
$ git checkout master
可以发现,之前的修改不见了~因为它是提交到了dev分支上,回到主分支上以后就没有了~
- 合并分支
现在我们将dev分支与master分支进行合并:
$ git merge dev //git merge命令用于合并指定分支到当前分支
合并完成之后,你可以删除dev分支:
$ git branch -d dev //删除一个没有合并的分支,需要使用 -D 强制删除
上面的合并模式使用的是:Fast-forward,快速合并,这样合并后删除分支会丢掉分支信息,我们一般的开发方式是:主分支master用来发布正式环境,dev分支用来开发,团队提交代码也都是在dev分支上进行提交,所以分支的信息就很重要,记录着开发时的主要工作内容。
使用--no-ff 强制禁用Fast-forward模式,Git就会在合并时生成一个新的commit,这样,从分支历史上就可以看出分支信息。执行:
$ git merge --no-ff -m "some message" dev
这样合并之后,就可以看到开发的历史了。
- 删除分支
删除本地分支:
$ git branch -d xxx
删除远程分支:
$ git push --delete origin xxx
- 合并冲突
冲突出现的情况:你在主分支修改某个文件的代码,提交;然后在其他分支上的同一文件进行相同代码的其他修改,提交。这样同一时间线上有两份相同文件却有不同修改,当执行 合并操作时,会提示该文件有冲突(CONFLICT),此时你只有手动修改一下合并冲突的地方,重新提交一下,就好了。
- BUG分支
有时我们正在dev分支编写项目时,测试提出了bug-001需要立马修改,但是我们现在手里的代码还没写完,肯定不能在目前代码里修改再提交上去。目前很好地解决方案是:当前的版本先暂存起来,在原版本上修改bug,进行提交,而不会牵扯到你手里正在编写的未完成的代码。Git当然能够为你解决这个问题!
首先解决代码暂存:
$ git stash
暂存之后,切换到你要修改的版本分支,比如要在主干上修改,先切换到主干:
$ git checkout master
$ git checkout -b issue-001 //新建分支issue-001 去修改bug
修改完bug后,添加并提交,然后切换到主干版本,合并bug分支之后删除bug分支(方法你会的!),这样就很快的修改完bug,接下来就可以继续你手里的工作了:
$ git checkout dev
$ git stash pop //恢复暂存的代码,同时删除stash的内容
看看是不是你之前正在写的代码呢~!
- 多人协作开发
当多个人协作开发时,就会涉及到代码的拉取、推送等操作,冲突也是在所难免。
下面我们先进行一些多人协作的流程演示:
- 项目开始时,先从远程克隆一个项目
$ git clone git@github.com:xxx/xxx.git
此时,你克隆到本地只有master分支,我们需要在目前项目的dev分支上进行开发,所有我们需要切换到远程dev分支并在本地创建dev分支:
$ git checkout -b dev origin/dev
这样我们就可以在本地dev分支上进行开发了。
2. 修改项目完成后,就需要push到远程dev分支:
$ git push origin dev
如果没有问题的话,这样就提交成功了。但有个同事也修改了这个文件,比你早推送了,此时你再推送的时候,远程库告诉你有其他相同的提交,让你 git pull 拉取目前的更新并再次push。
$ git pull //从远程拉取代码
注:如果 git pull 报错:There is no tracking information for the current branch,则说明本地分支和远程分支的链接关系没有创建,根据它给你的提示:
$ git branch --set-upstream-to=origin/dev dev
再次拉取一下,假如出现错误:fatal: refusing to merge unrelated histories,原因是在网页新建项目后,本地项目和托管项目是完全两个不通的项目,此时需要执行:
$ git pull --allow-unrelated-histories
注:有时会让你填写一下信息,接着在下面输入 :wq 即可。
执行完毕后,在执行git pull 就可以把远程项目拉取下来,如果有冲突,先解决掉冲突,然后本地提交完成后,再推到远程仓库。
3. 解除关联
git remote remove origin
四、标签管理
有时我们想要回到某个版本时,需要找到那一串提交的commit id,很是麻烦,这时候需要给提交的某个版本加个标签(标签是打在你没提提交的commit上的),比如发布版:v1.0,v1.1,通过标签去查找版本,就比较方便了。
- 创建标签
$ git tag tagName
上面的命令便创建好了一个标签,默认是最新的一个版本,查看所有标签:
$ git tag
如果想在之前的某个版本上打标签的话,就需要知道它的commit id 了,执行:
$ git log --pretty=oneline --abbrev-commit
找到你想要打标签的commit,并执行:
$ git tag tagName commitId
还可以给标签加上说明:
$ git tag -a tagName -m "message"
注意:标签总是和某个commit挂钩。如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签。
- 操作标签
你添加的标签只会保存在本地,你可以在本地操作它。你也可以把标签推到远程
- 删除本地标签
git tag -d tagName
如果要删除远程标签,先执行本地删除后,在执行:
$ git push origin :refs/tags/tagName
2. 推送标签到远程
$ git push origin tagName
推送全部标签:
$ git push origin --tags
3. 修改打标签的某个版本
标签只是对某次的提交起了一个别名,类似指针,所以不要以为通过标签就能直接拉取代码。这个过程是相对繁琐的,请多多熟悉才行,已tag v.1.0为例:
(1)查看标签详情,找出改标签的commitId.
$ git show v1.0 //返回 23b8a3
(2)版本回退
$ git reset --hard 23b8a3 //会退到当前版本
这时你的主干分支上就是v1.0时候的代码了。注意!!!!不要在这个分支上直接修改,这个时候你需要新建个hotfixed分支(bug分支,具体可查看我的git flow那篇文章有介绍各个分支:Einzbern:git flow),将代码合并过去,然后在bug分支上进行修改。
(3)切换分支
$ git checkout -b hotfixed // 接下来就在这个分支上进行修改了
(4)主干分支会退到原版本
拉取到bug分支之后,一定记得先把主分支还原。一定(坚定脸.png)。方法上面第一节就有写到(回到未来版本,git reflog).
$ git checkout master //先回到主分支
$ git reflog 查看最新的一次提交的commitId
$ git reset --hard xxx //根据最新的commitId回退
(5)回到bug分支开始编写
$ git checkout hotfixed
// 修改完成后
$ git tag v1.1 //修改提交完成后,记得再打个标签 表明此次提交
(6)合并修改到主干
$ git checkout master
$ git merge hotfixed //合并
$ git branch -d hotfixed //删除bug分支
$ git push origin v1.1 //手动将标签推动到远程(你也可以不删用来修改以后的bug,但是还是即用即删吧,不怕麻烦)
(7)强制更新远程分支
遇到该操作时,可能是下面的原因:
某个同事误操作把修改的feature分支推到了远程master上,这是你要回滚远程分支的话,使用git reset退回版本后,你知退回了本地分支,远程是推不上去的,它会告诉你先pull才行。
这是你就需要本地reset之后,在使用以下命令,来强制提交本地分支,以更新远程分支:
git push -f origin xxx
五、使用码云gitee
使用国内的git托管,会比github快很多,操作方法和之前关联github类似。
有一些区别的就是:
创建好一个仓库之后,会默认创建一个Readme.md文件,你要是把代码推送的话,会提示你先git pull ,当你拉取之后,会告诉你:fatal: refusing to merge unrelated histories,拒绝合并未关联的历史
原因:在网页新建项目后,本地项目和托管项目是完全两个不通的项目
执行下面语句:
$ git pull --allow-unrelated-histories