目录

Git | Git 操作整理-远端操作

https://img.dawnguo.cn/Git/2_mind.png

1. 远端仓库

git 中远端的定义较为广泛,任何其他位置,只要不是当前仓库,都可以算作远端。同一台机器上,只要不是当前仓库的位置也可以算作远端。另外,我们常见的 github、gitlab 也是远端仓库。那么本地仓库和远端仓库之间的传输协议有以下那么几种:

常用协议 语法格式 说明
本地协议(1) /path/to/repo.git 哑协议
本地协议(2) file:///path/to/repo.git 智能协议
http/https 协议 http://git-server.com:port/to/repo.git https://git-server.com:port/to/repo.git 平时接触的都是智能协议
ssh 协议 user@git-server.com:path/to/repo.git 工作中最常用的智能协议
  • 本地协议是指同一台机器上,通过文件路径能访问到的
  • http/https 方式需要账号密码
  • ssh 协议是需要公私秘钥的
  • 哑协议传输进度不可见,智能传输协议可见,另外智能协议比哑协议传输速度快

2. 远端操作

2.1. git remote 与远端仓库建立连接

1
2
3
4
git remote add <远端名> <远端仓库地址>  # 这边远端名的意思是远端仓库的别名,push、pull 都将用到远端名
git remote -v 					    # 查看远端仓库连接情况
git remote set-url <远端名> 你新的远程仓库地址	# 修改远端仓库地址
git remote rm <远端名>				  # 删除远端仓库

在使用 git remote 命令之后,会多出一个远端分支。

2.2. git clone 将远端仓库 clone 下来

1
2
git clone <远端仓库地址>	# 把远端仓库 clone 下来
git clone --bare  <远端仓库地址> # bare 是指不带工作目录,也就相当于只 clone .git 目录

从远端上 clone 一个仓库的时候,那么 clone 下来的仓库已经和远端建立了连接,不需要再使用 git remote 命令

2.3. git push 将本地分支推到远端

1
2
3
4
5
git push <远端名> <本地分支名> 
git push -u <远端名> <本地分支名> # -u 表示将本地分支的内容推到远端分支,并且将本地分支和远端分支关联起来
git push -u origin master	# 表示把本地 master 分支的内容推到远端分支 origin/master,并且将本地分支 master 和远端分支 origin/master 关联起来

git push	# 这条命令也可以使用,默认是将当前本地分支推到相关联的远端分支

git push 的意思是本地比较新,要把本地 push 到远端,对远端进行更新,其实也就是更新 origin/master 的指向。所以 git push origin master, 其实就相当于把 origin/master 的指针移到 master 的位置,这样子 origin/master 就被更新了,然后将远端分支拷贝到远端,这样就相当于远端被更新了,但是在执行 push 的时候得要求远端仓库的 origin/master 是本地更新之后的 origin/master 的 fast-forward,也就相当于远端仓库的 origin/master 得在本地更新之后的 origin/master 的前面,其实也就是在一条线上。简单来说 git push 就是先将改变 origin/master ,然后将其复制到远端。(Hint:经过测试,本地仓库处于 master 分支,那么执行 git push origin temp 命令,操作的两个分支其实是 origin/temp 和 temp 分支)

在push的时候有时候会遇到 None fast-forward 问题,None fast-forward 是指:同分支情况下或者说两个相互绑定的远端分支和本地分支的情况下(通常origin/mastermaster 属于同分支),远端分支不是本地分支的父亲上的,也就是远端分支跟本地分支不在同一个分支上也就是远端分支所指的 commit 不在本地分支最新的 commit 的前面。

2.4. git fetch 将远端分支 fetch 到本地

1
2
git fetch <远端名> <本地分支名>
git fetch origin master # 将远端分支 origin/master fetch 到本地

2.5. git pull 这个命令是 git fetchgit merge 的整合

1
2
git pull <远端名> <本地分支名>	# 将远端分支 fetch 到本地,并且将远端分支和本地所处分支进行合并
git pull --rebase # 以 rebase 方式进行合并,也就是将本地分支 rebase 到远端分支

git pull 的意思是远端比较新,要把本地分支进行更新。那么 git pull origin master,是相当于先把远端的 origin/master fetch 到本地,然后让 master 移到 origin/master 的位置(这是本地所在分支为 master,并且是 fast-forward 的情况)。假如 master 和 origin/master 不是 fast-forward(但是本地所在分支是 master),那么 master 和 origin/master 会进行 merge。那么假如本地当前分支不是 master,而是 temp,并且 temp 分支跟 origin/master 也不是 fast-forward,那么 temp 分支会和 origin/master 分支进行 merge。所以简单来说 git pull 就是先把远端分支 fetch 下来,然后将本地分支更新为远端分支所指的地方,这跟 git push 正好是反操作。

多人开发的情况下,一定要先 git fetch 或者 git pull。

2.6. 远端操作总结—个人理解

刚开始的时候对 git 的远端概念不太懂,怎么一会儿远端分支 origin/master、一会儿本地分支 master的,为啥 push 了之后,远端仓库内容就被更新了呢,pull 之后本地仓库就被更新了呢。在接触之后,其实从 git 是分布式的角度可以理解一波,git 分布式也就意味着一份仓库的内容,同时在远端和本地都有备份。如下图所示

https://img.dawnguo.cn/Git/2_12.jpg

那么远端分支和本地分支都是这个仓库的分支,比如 origin/master 和 master 都是仓库的分支。只是本地仓库操作的分支是都是本地分支,而远端仓库只在远端分支上进行操作,远端仓库显示的内容是远端分支的内容。那么 push、pull 等操作其实就可以简单的当做对本地仓库分支的操作,比如 push 操作就是把本地仓库中的远端分支指向本地分支,然后把远端分支的情况同步到远端。pull 操作就是把远端仓库的远端分支同步下来,然后对将本地分支指向远端分支。

3. git 与 github 简单同步

上文提到了 github 也可以算是一个远端仓库,那么本地仓库与远端仓库之间通信的方式有四种。显然,假如把 github 当成远端仓库,本地协议不能用了,只能用 http/https 协议或者 SSH 协议。假如需要想用 SSH 协议的话,需要配置公私钥,但是这个步骤在这里省略,下面是已经配好公私钥的。

3.1. Github 上创建仓库

https://img.dawnguo.cn/Git/2_3.png

依次将所需填写的内容填写完成,之后点击 “Create repository” 即可创建相应的仓库,其中关于填写选项有以下几点说明:

  • Description:如果希望别人很容易搜到你的 repository 的话,那么需要在这块写具体一点

  • Public:repository 可以让所有看到,但是仅有只读权限。

  • Private:repository 并不是对外开放的,需要授权。

  • README:搜索 repository 的时候,会到 README 里面搜索关键字的。

  • Add .gitignore:有很多 .gitignore 的模板供你选择,可以根据仓库会使用的语言选择一个,也可不选。

  • Add a license:选择开源协议

创建完成之后,如下图所示:

https://img.dawnguo.cn/Git/2_4.png

3.2. 本地仓库同步到 Github 上

现在要将本地的这个仓库同步到 Github 上

  • 首先与远端仓库进行关联
1
2
3
git remote add test git@github.com:******/*****.git
# test 是远端连接的名字,test 就表示后面那个仓库的地址,git 默认的是 origin,也可以改为别的;
# git@...  这是上面新建仓库的地址,这是 SSH 协议的格式,也可以选择 https 方式的
  • 之后使用 git push 命令把本地库的内容推送到远程
1
git push -u test master

由于远程库是空的,我们第一次推送时,加上了 -u 参数,Git不但会把本地的 master 分支内容推送到远程新的 master 分支,还会把本地的 master 分支和远程的 master 分支关联起来。此后,每次本地提交后,就可以使用命令 git push origin master 推送最新修改。上述提交完成之后,Github 上面的内容就和本地的一样了。

3.3. 本地仓库与远程仓库进行整合

上面所述的是在 Github 创建的是一个空仓库,假如Github上创建的仓库已经存在了东西,如下所示,仓库中已经还有了 LICENSE 文件,那么在 push 之前需要先 pull 或者 fetch && merge。

https://img.dawnguo.cn/Git/2_5.png

  • 先使用 git remote 命令与远端仓库建立连接
1
git remote add git_learning git@github.com:******/******/.git 
  • 之后先把远端的东西 fetch 下来
1
git fetch git_learning master

假如不把远端的仓库中的东西 fetch 下来的话,而是直接 push 的话会报 fast-forward 错误。

https://img.dawnguo.cn/Git/2_6.png

  • 使用 git merge 将两颗不相关的分支进行整合
1
2
3
git merge --allow-unrelated-histories git_learning/master
# allow-unrelated-histories 表示允许两颗不相关的分支进行整合,这边不相关可以指没有父子关系
# git_learning/master  表示要 merge 的两个分支
  • 最后再 git push
1
git push git_learning master

其他方法

  • 其实针第二步开始可以使用 git pull 命令,因为 git pull 命令就包含了 fetch 和 merge 两个命令。

  • 当然,我们可以不用 merge 的方式进行合并,还可以使用 rebase 的方式进行合并,使用 git rebase orgin/master (假设本地仓库 HEAD 指向 master),那么就相当于把本地 master 中的 commit 以线性的方式依次合并到 origin/master 中。

  • 甚至可以在 git pull 的时候直接使用 git pull --rebase