菜鸡的git记录-2

前文学完了本地操作,现在就来学习一下远程操作.jpg

题外话:有问题可以git --help,会有一些基本的指令帮助以及解释
推荐的git学习网址

远程仓库

现在一般通过github来实现git的远程操作

配置SSH key

配置SSH Key的原因是确认这个东西是由你自己本人进行的推送

如果忘了自己有没有配置过ssh,可以在C:\Users\asus(反正是用户目录)看有没有.ssh的目录
如果没有,通过以下指令创建SSH Key

1
$ ssh-keygen -t rsa -C "email@example.com"

因为也不是啥高级机密,一路enter就好

之后就可以看见.ssh的目录,里面有id_rsaid_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。

在github上配置SSH Key

登陆GitHub,打开“Account settings”,“SSH Keys”页面:

然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容

点“Add Key”,你就应该看到已经添加的Key

添加远程库

首先在github新建一个仓库
本地仓库与远程仓库关联

1
$ git remote add origin <the ssh or https>

将本地库的所有内容推送到远程库上

1
$ git push -u origin master

顺便一提,如果一不小心把远程仓库的地址与本地仓库的地址绑定错了,可以用以下指令取消

1
$ git remote rm origin

其实git push是将当前的master分支推送,加上-u参数不仅仅会推送至新的master分支,还会将这两个分支进行合并。
在此之后,可以通过以下指令直接推送修改

1
$ git push origin master

从远程库克隆

假若从零开始,最好的方式是通过从远程库克隆到本地。
在你准备存放该仓库的路径使用git bash

1
$ git clone <the ssh or https>

之后可以通过ls指令显示当前目录下的文件

github中通常会给出https以及ssh两种地址,ssh支持的git协议运行速度最快

分支管理

主要用于在合作开发之中将自己未完成的代码先保存在另一个分支上,主分支仍旧在正常工作,开发完毕后再合并到主分支上,不会造成损失

创建和合并分支

在起始,默认为master分支,即主分支。而之前提及的HEAD也不是指向提交,而是指向master。

原理解释

一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点

分支

而同时随着这样的操作,master这个线也越来越长。
而现在,假如说我们新建了一个dev分支,那么Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上

分支

而这个时候只是增加了一个dev指针和更改了HEAD的指向,工作区的文件是没有任何的变化。
但是需要注意的是,现在对于工作区的修改与提交都是针对dev分支的,比如新提交一次后,dev指针往前移动一步,而master指针不变

分支

假如在dev上的工作完成了,就可以把dev合并到master上。合并最简单的方法,就是直接把master指向dev的当前提交

分支

合并完分支后,还可以删除dev分支。
删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支,就完成了分支的合并以及修改

分支

实际操作说明

创建一个dev分支

1
$ git branch dev

切换到dev分支

1
$ git checkout dev

表示创建并切换到该分支

1
$ git checkout -b dev

之后可以通过一下指令查看当前分支

1
2
3
4
$ git branch

dev
* master

其中*部分表示选择的当前分支
同时细心的你也会发现在每次使用命令之时,后面的括号提示也会有改变

在dev分支时修改并提交了之后在切换回master分支,这个时候就可以合并啦
将dev分支上面的内容合并到master分支

1
2
3
4
5
6
$ git merge dev

Updating 671ee66..cc2baf3
Fast-forward
readme.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

这个时候可能有人关注到了Fast-forward,这个是指快速合并模式。它存在的意义在之后就可以知道了

之后进行dev分支的删除

1
2
3
$ git branch -d dev

Deleted branch dev (was cc2baf3).

当然,在合并的路上并不是一帆风顺的啊

解决分支冲突

在某些时刻,在你自己进行了分支的编写并准备推送到master分支
但是并没有想到的是,有人也在master分支提交了修改内容

这个时候就相当于两个分支都有新的提交

冲突

在commit之后准备合并之后就会显示冲突

1
2
3
4
5
$ git merge feature1

Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.

然后可以重新进入原来修改的文件内,git会用<<<<<<<< ========= >>>>>>>>>来标识不同的分支以及其中的内容

修改之后再一次进行提交,就发现冲突内解决了,此时状态可以用下图展现

冲突

在之后也可以通过以下指令来观看分支合并图

1
$ git log --graph

分支管理策略

通常来说合并分支都是使用的Fast-forward,但是在这种情况之下合并之后就会删除掉原来的分支信息
当然,是有办法存留分支信息的,但是这个时候就会被强制commit一次以保留信息

1
$ git merge --no-ff -m "description"

在这里有-m指令也正是因为拥有commit的指令
那么接下来的这个图可以形象地表示非Fast-forward模式下的分支合并

分支

而现在可以通过这个分支来充分地体现一个团队合作的流程

分支

Bug分支

在某些时刻转而向其他的地方进行修复,这个时候我们不得不又创建另外一个分支,但是当前分支上面的内容还没有完善,我们可以通过以下指令来存储当前的状态

1
$ git stash

然后就可以新建其他的分支来进行bug的修复。
当然,这个指令可以使用多次
修复完了自然是要将原来的样子给恢复过来,可用以下指令查看当前的存储状态

1
$ git stash list

里面就会列出存储的状态,如果要恢复的话就有两种方式

1
2
3
4
5
6
$ git stash apply
$ git stash drop



$ git stash pop

前者调用一个指令之后,会恢复,但是stash内的内容不作删除,需要用接下来的这个指令进行删除
后者就是恢复该情形的时候顺便删除了stash的内容

如果要从多个stash状态中恢复指定的一个,可调用如下指令

1
$ git stash apply stash@{0}

注意,后面这个给出的名字可以从git stash list中获得

Feature分支

在实际操作之中,如果想开发一个新功能,还是新建立一个feature分支,防止该实验的代码影响master分支内的内容。
如果因为一些不可抗原因要强行删除该分支,调用以下命令

1
$ git branch -D <name>

来进行强制性的删除

多人协作

当自己从远程库clone到本地的时候,git自动的将本地的master分支和远程的master分支对应起来,默认名称也设置为origin
查看远程库的信息可以用git remote,也可以用git remote -v显示更详细的信息,之中显示了fetch和push(抓取与推送)的地址

推送分支

推送本地指定分支到远程对应的分支上

1
$ git push origin <name>

在这里顺便一提需要推送的分支

  • master主分支,需要远程同步
  • dev开发分支,也需要远程同步
  • bug分支一般只用于本地修复bug,没有推到远程的意义
  • feature分支是否推到远程,取决于开发的模式,是个人开发还是合作开发

另外,如果不推送到远程,别人是看不见你自己的本地分支的

抓取分支

当你的小伙伴已经已经在远程做出了最新提交,恰好跟你即将要提交的东西有冲突,这个时候就要将远程的东西抓取下来,冲突修改了之后再进行推送。

首先要建立本地的分支与远程分支的连接

1
$ git branch --set-upstream-to=orighin/<name> name

后面的名字是远程库对应的分支,后面的name是指对应的本地分支名
之后再使用以下指令进行远程分支的拿取

1
$ git pull

这个时候就需要解决之前的冲突了,方法跟之前解决冲突的方式完全一样
再提交+push就可以完成操作了

Rebase

不详细介绍了..就是适合强迫症让git log --graph的出现的分支图变成一个直线
具体用法

1
$ git rebase

原理的话,就是将我们本地提交的额时间挪动了位置,将本地提交移到了远程关联之后(maybe?)
不过缺点是本地分支也已经被修改过了

标签管理

发布一个版本的适合,还可以在版本库里面打一个标签,就可以确定这个版本,实际上就是指向某个commit的指针
类似于commit中的记录,但是这个tag更适合于对于一个历史版本的寻找

创建标签

首先切换到需要打标签的分支
之后使用命令

1
$ git tag <description>

来创建tag
之后可以用以下指令来查看当前的所有标签

1
$ git tag

不过还要注意的一点就是这个标签并不是按照时间顺序标出来的,而是按字母排序的,如果想要看见该标签下的具体内容,键入指令

1
$ git show <tagname>

在这里需要注意的是,标签是打在最新的commit上面的,如果需要打以前commit的tag,需要在历史记录里面找到commit id,之后键入命令

1
$ git tag <description> <commit id>

还可以通过-a以及-m来创建带说明的标签,例如

1
$ git tag -a <tagname> -m "description" <commit id>

如果这个commit同时出现在多个分支内,在对应的分支都能够看见这个标签

标签操作

删除标签

1
$ git tag -d <tagname>

这个标签创建的时候一般都是存储在本地的,不会推送到远程。
如果需要推送到远程仓库的话,使用命令

1
2
3
$ git push origin <tagname>

$ git push origin --tags

前者是推送指定标签名到远程,后者是一次性推送没有被推送到远程的本地标签

如果删除远程tag,操作如下

1
2
$ git tag -d <tagname>
$ git push origin :refs/tags/<tagname>