Git&GitHub-进阶教程
1. 远程仓库-GitHub
Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。怎么分布呢?最早,肯定只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都是一样的,并没有主次之分。
实际情况往往是这样,找一台电脑充当服务器的角色,每天24小时开机,其他每个人都从这个“服务器”仓库克隆一份到自己的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交。
1.1 本地电脑如何关联GitHub?
由于你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以,需要一点设置:
- 创建SSH Key
$ ssh-keygen -t rsa -C "haochen273@gmail.com"
一路回车就可以了
如果一切顺利的话,可以在用户主目录(C:\Users\haoch.ssh)里找到.ssh
目录,里面有id_rsa
和id_rsa.pub
两个文件,这两个就是SSH Key
的秘钥对,id_rsa
是私钥,不能泄露出去,id_rsa.pub
是公钥,可以放心地告诉任何人。
- 设置GitHub的SSH Key
在GitHub主页找到Account Seetings
, SSH Key
页面:将id_rsa.pub
的内容粘贴到里面即可Add
GitHub为什么要用SSH Key呢?
因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。
当然,GitHub允许你添加多个Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送了。
1.2. 创建并操控远程库GitHub
在GitHub中创建一个远程库名为learngit
:
(1) 把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库。:本地->远程
- 关联
在本地库运行命令:
$ git remote add origin git@github.com:haochen95/learngit.git
添加后,远程库的名字就是origin
,这是Git默认的叫法,也可以改成别的,但是origin
这个名字一看就知道是远程库。
- 推送
使用命令git push -u origin master -f
$ git push -u origin master -f
Enumerating objects: 23, done.
Counting objects: 100% (23/23), done.
Delta compression using up to 8 threads
Compressing objects: 100% (17/17), done.
Writing objects: 100% (23/23), 1.82 KiB | 465.00 KiB/s, done.
Total 23 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), done.
To github.com:haochen95/learngit.git
+ cc71eae...1f108b4 master -> master (forced update)
Branch 'master' set up to track remote branch 'master' from 'origin'.
把本地库的内容推送到远程,用git push
命令,实际上是把当前分支master
推送到远程。
由于远程库是空的,我们第一次推送master
分支时,加上了-u参数,Git不但会把本地的master
分支内容推送的远程新的maste
r分支,还会把本地的master
分支和远程的master
分支关联起来,在以后的推送或者拉取时就可以简化命令。
成功后的页面
- 以后的每次提交只写一个命令
$ git push origin master
把本地master
分支的最新修改推送至GitHub
,现在,你就拥有了真正的分布式版本库!
(2) 从GitHub克隆库到本地: 远程->本地
现在我们另外创建一个空文件夹: D:\git_clone
克隆的代码是: $ git clone git@github.com:haochen/learngit.git
$ git clone git@github.com:haochen95/learngit.git
Cloning into 'learngit'...
remote: Enumerating objects: 23, done.
remote: Counting objects: 100% (23/23), done.
remote: Compressing objects: 100% (12/12), done.
Receiving objects: 100% (23/23), done.
Resolving deltas: 100% (5/5), done.
remote: Total 23 (delta 5), reused 23 (delta 5), pack-reused 0
你看,本地的库里面就有了跟GitHub一样的内容
2. Git分支管理(重要)
创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
2.1. 创建和合并分支
在版本回退
里,你已经知道,每次提交,Git
都把它们串成一条时间线,这条时间线就是一个分支。截止到目前,只有一条时间线,在Git
里,这个分支叫主分支,即master
分支。HEAD
严格来说不是指向提交,而是指向master
,master
才是指向提交的,所以,HEA
D指向的就是当前分支
一开始的时候,master
分支是一条线,Git
用master
指向最新的提交,再用HEAD
指向master
,就能确定当前分支,以及当前分支的提交点:
每次提交,master
分支都会向前移动一步,这样,随着你不断提交,master
分支的线也越来越长:
1)增加分支的原理
我们创建新的分支,例如dev
时,Git
新建了一个指针叫dev
,指向master
相同的提交,再把HEAD
指向de
v,就表示当前分支在
dev`上
增加分支的原理: 增加一个指针,更改HEAD
的指向
2)增加分支后的提交变化
现在开始,对工作区的修改和提交就是针对dev
分支了,比如新提交一次后,dev
指针往前移动一步,而master
指针不变:
3) 分支合并
就是直接把master
指向dev
的当前提交,就完成了合并
合并分支的原理: 改改指针(dev->master)
4)分支删除
删除dev
分支就是把dev
指针给删掉,删掉后,我们就剩下了一条master
分支
代码测试
1. 创建分支
$ git checkout -b dev
Switched to a new branch 'dev'
git checkout
命令加上-b
参数表示创建并切换
2. 查看分支
$ git branch
* dev
master
3. 在分支上提交
增加一个文件命名为love.txt
并且提交
$ git add love.txt
$ git commit -m "love"
[dev b3045f0] love
1 file changed, 1 insertion(+)
create mode 100644 love.txt
4. 从dev分支切换回master分支
$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
再次查看文件夹发现没有love.txt文件
,因为那个提交是在dev
分支上,而master
分支此刻的提交点并没有变
5. master和dev分支合并
$ git merge dev
Updating 1f108b4..b3045f0
Fast-forward
love.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 love.txt
6. 删除dev分支
$ git branch -d dev
Deleted branch dev (was b3045f0).
7. 再次查看branch信息
$ git branch
* master
2.2. 解决合并冲突
问题: 在分支上提交一个修改,转到master后又提交一个修改,两个修改都在同一个位置,请问如何合并?
现在,master
分支和feature1
分支各自都分别有新的提交,变成了这样:
这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突,我们试试看
$ git merge feature1
Auto-merging love.txt
CONFLICT (content): Merge conflict in love.txt
Automatic merge failed; fix conflicts and then commit the result.
需要手动解决冲突
通过git status
查看状态
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: love.txt
no changes added to commit (use "git add" and/or "git commit -a")
我们可以直接查看love.txt
的内容:
<<<<<<< HEAD
I love you
=======
I come from china
>>>>>>> feature1
我们重新修改为
I come from china
然后再提交
$ git commit -m "loving"
[master e6c7c5f] loving
现在,master分支和feature1分支变成了下图所示:
我们可以通过命令$ git log --graph --pretty=oneline --abbrev-commit
查看分支情况
$ git log --graph --pretty=oneline --abbrev-commit
* e6c7c5f (HEAD -> master) loving
|\
| * 445380a (feature1) from china
* | 62b6881 love you
|/
* b3045f0 love
* 1f108b4 (origin/master) remove text.txt
* f2863ca new text
* aa4f64e git tracks
* 45700b2 how it works
* 5103166 delete software
* 9fbb435 github infor
* 4fb84da add new line
* f7f8050 write to readme
2.3. 分支管理策略
master
分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;- 干活都在
dev
分支上,也就是说,dev
分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev
分支合并到master
上,在master
分支发布1.0版本 - 你和你的小伙伴们每个人都在
dev
分支上干活,每个人都有自己的分支,时不时地往dev
分支上合并就可以了。 - 使用
git merge --no-ff -m "merge with no-ff" dev
合并会留下历史信息,建议这样用
2.4. Bug分支
假设,你正正在完成love.txt
的编辑工作,但是这个文件需要2天才能完成,但是现在老板给你说readme.txt
有一个错误(I love USA)你需要更改这个bug, 那怎么办? 你想创建一个分支issue-101
来修复它,但是,等等,当前正在feature1
上进行的工作还没有提交:
$ git status
On branch feature1
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: love.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
1) git stash
这个功能是把当前工作现场“储藏”起来,等以后恢复现场后继续工作:
$ git stash
Saved working directory and index state WIP on feature1: f1f394f modifyed
现在,用git status
查看工作区,就是干净的(除非有没有被Git管理的文件),因此可以放心地创建分支来修复bug。
2) 创建issue分支解决bug
在master上创建分支
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 4 commits.
(use "git push" to publish your local commits)
$ git checkout -b issue
Switched to a new branch 'issue'
然后修改readme.txt
的删除I love China,在提交
$ git commit -m "fix issue101"
[issue bdc0b2e] fix issue101
1 file changed, 1 deletion(-)
然后转到master合并分支
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 4 commits.
(use "git push" to publish your local commits)
$ git merge --no-ff -m "merged bug fix 101" issue
Merge made by the 'recursive' strategy.
readme.txt | 1 -
1 file changed, 1 deletion(-)
哈哈,Bug解决啦,是时候回到feature1
分支继续工作啦
$ git checkout feature1
Switched to branch 'feature1'
$ git status
On branch feature1
nothing to commit, working tree clean
工作区是干净的,刚才的工作现场存到哪去了?用git stash list
命令看看
$ git stash list
stash@{0}: WIP on feature1: f1f394f modifyed
工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法
1)恢复办法1:git stash apply
用git stash apply
恢复,但是恢复后,stash
内容并不删除,你需要用git stash dro
p来删除;
2)恢复方法2: git stash pop
git stash pop
,恢复的同时把stash内容也删了
2.5. Feature分支
添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature
分支,在上面开发,完成后,合并,最后,删除该feature
分支。
Git&GitHub-进阶教程的更多相关文章
- git github 使用教程
参考文章:文章地址: http://wuyuans.com/2012/05/github-simple-tutorial/ github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般 ...
- Git & Github 使用教程【1】入门篇
Github教程 1-1 版本管理工具简介 主要作用:备份文件.记录历史.回到过去.多端共享.独挡一面.团队协作 2-1 版本管理工具发展历史 3-1 Git下载和安装[略] 3-2 linux下安装 ...
- Idea+Git+GitHub图文教程,一篇教程帮你搞定
导语 该文章主要记录如何在GitHub上创建远程仓库.如何创建本地仓库并把代码提交到GitHub.如何创建分支以及分支合并到主干的操作. 一.在GitHub上创建远程仓库 (前提:已经注册过githu ...
- Git和Github简单教程
原文链接:Git和Github简单教程 网络上关于Git和GitHub的教程不少,但是这些教程有的命令太少不够用,有的命令太多,使得初期学习的时候需要额外花不少时间在一些当前用不到的命令上. 这篇文章 ...
- Git-it:一个学习Git和Github的教程(软件)
Git-it https://github.com/jlord/git-it 2016-08-01 在FreeCodeCamp的引导下了解到的Git-it.OSC有收录. Git-it是一个指导使用G ...
- Git和Github简单教程(收藏)
原文链接:Git和Github简单教程 目录: 零.Git是什么 一.Git的主要功能:版本控制 二.概览 三.Git for Windows软件安装 四.本地Git的使用 五.Github与Git的 ...
- Git服务搭建及github使用教程
.pos { position: fixed; top: 35%; left: 90% } .pos a { border: 2px solid white; background: #99CCFF; ...
- git和github使用教程
看官请移步git和github简单教程, 本文是上述链接的截图,担心哪天作者不小心删除了,备一份在自己这里,仅为自己看着方便.侵权请告知
- GitHub 新手教程 五,Git GUI 新手教程(2),Clone Existing Repository 克隆代码库
1,注意: 网上大部分教程都是从“Create New Repository”讲起,这其实给我们新手埋了很大的一个坑.按照类似的教程,仅做到一半,各种错误窗口就会弹出来了,像什么:“非同一代码库”.“ ...
- GitHub 新手教程 四,Git GUI 新手教程(1),OpenSSH Public Key
1,从开始菜单 启动 Git GUI,或者运行: D:\soft\Git\cmd\git-gui.exe(D:\soft\Git 为您的 GitHub 安装文件夹) 2,获取 SSH 密钥: 3,点击 ...
随机推荐
- Python系列:五、异常处理-技术流ken
至今为止还没有进一步的谈论过错误信息,不过在你已经试验过的那些例子中,可能已经遇到过一些.Python 中(至少)有两种错误:语法错误和异常( syntax errors 和 exceptions ) ...
- iOS -数据持久化方式-以真实项目讲解
前面已经讲解了SQLite,FMDB以及CoreData的基本操作和代码讲解(CoreData也在不断学习中,上篇博客也会不断更新中).本篇我们将讲述在实际开发中,所使用的iOS数据持久化的方式以及怎 ...
- C#单元测试如何查看输出的调试信息?
在Visual Studio 2012的单元测试中使用: Console.WriteLine()输出的信息在“输出”面板都找不到??? 查了不少资料,才得知在单元测试中打印的信息不显示在“输出”版 ...
- sql存储过程,根据多个条件查询,返回一个dataTable或者DataSet
不废话,先直接代码 首先sql部分(我在这里加了一个@zx作为判断,一般不需要这个参数): ALTER Proc [dbo].[Proc_Boss_Show] ),--开始条数 ),--结束条数 @S ...
- 第一册:lesson thirty one。
原文:Where is Sally? A:Where is .. B? B:She is in the garden,A. A:What's she doing? B:She is sitting u ...
- 注册asp.net 4.0版本到IIS服务器中
在IIS服务器的运维的过程中,有时候部署asp.net网站发现未安装.net framework对应版本信息,此时就需要重新将.net framework对应的版本注册到IIS中,此处以重新注册.ne ...
- [android] 自定义广播事件
上一节的短信拦截在4.0以上系统中无效,可以使用这种办法实现,定义一个activity,清单文件中指定主题为透明,在onCreate()方法里面直接调用finsh()方法,关掉,这样可以就可以实现了 ...
- [android] xml文件的序列化
生成xml文件,模拟备份短信,创建短信的业务bean,创建一个domain的包放业务bean,这个业务bean里面,定义成员属性,生成get set方法,生成有参和无参的构造方法. 生成随机数,实例化 ...
- mysql的coalesce使用技巧
今天无意间发现mysql的coalesce, coalesce()解释:返回参数中的第一个非空表达式(从左向右依次类推): 使用示例:a,b,c三个变量. ,); // Return 2 select ...
- Spring-继承JdbcDaoSupport类后简化配置文件内容
正常情况下,我们在实现类中想要晕用模板类需要在配置文件中注入连接池,再将连接池注入给模板类,然后在实现类中得到. <!-- 配置C3P0连接池 --> <bean id = &quo ...