查看远程储存
如果你想要查看你已经配置的远程仓库服务器,可以运行git remote
命令。
- 它会列出你指定的每一个远程服务器的简写。
- 如果你已经克隆了自己的仓库,那么至少应该能看到 origin ——这是 Git 给你克隆的仓库服务器的默认名字(
git clone
会自行添添加远程仓库):
$ git clone https://github.com/schacon/ticgit
Cloning into 'ticgit'...
remote: Reusing existing pack: 1857, done.
remote: Total 1857 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1857/1857), 374.35 KiB | 268.00 KiB/s, done.
Resolving deltas: 100% (772/772), done.
Checking connectivity... done.
$ cd ticgit
$ git remote
origin
- 你也可以指定选项 -v,会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL。
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
- 如果你的远程仓库不止一个,该命令会将它们全部列出。 例如,与几个协作者合作的,拥有多个远程仓库的仓库看起来像下面这样:
$ cd grit
$ git remote -v
bakkdoor https://github.com/bakkdoor/grit (fetch)
bakkdoor https://github.com/bakkdoor/grit (push)
cho45 https://github.com/cho45/grit (fetch)
cho45 https://github.com/cho45/grit (push)
defunkt https://github.com/defunkt/grit (fetch)
defunkt https://github.com/defunkt/grit (push)
koke git://github.com/koke/grit.git (fetch)
koke git://github.com/koke/grit.git (push)
origin git@github.com:mojombo/grit.git (fetch)
origin git@github.com:mojombo/grit.git (push)
添加远程仓库
两种方法:
-
git clone
会自行添添加远程仓库(执行克隆后,远程数据库的全部内容都会被下载) -
手动 运行
git remote add <shortname> <url>
添加一个新的远程 Git 仓库,同时指定一个方便使用的简写:
$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
pb https://github.com/paulboone/ticgit (fetch)
pb https://github.com/paulboone/ticgit (push)
现在你可以在命令行中使用字符串 pb 来代替整个 URL。 例如,如果你想拉取 Paul 的仓库中有但你没有的信息,可以运行 git fetch pb:
$ git fetch pb
remote: Counting objects: 43, done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 43 (delta 10), reused 31 (delta 5)
Unpacking objects: 100% (43/43), done.
From https://github.com/paulboone/ticgit
* [new branch] master -> pb/master
* [new branch] ticgit -> pb/ticgit
拉取远程仓库到本地
git fetch
$ git fetch <remote>
git fetch是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中。
- 如果你使用 clone 命令克隆了一个仓库,命令会自动将其添加为远程仓库并默认以 “origin” 为简写。 所以,git fetch origin 会抓取克隆(或上一次抓取)后新推送的所有工作。
- 必须注意 git fetch 命令只会将数据下载到你的本地仓库——它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作。
如左图:远程仓库中有两个本地仓库中没有的提交,执行git fetch
,效果如右图:
- 从远程仓库下载本地仓库中缺失的提交记录
- 更新远程分支指针(比如o/main)
- git fetch 并不会改变本地仓库的状态。它不会更新你的 main 分支,也不会修改你磁盘上的文件(仅仅将远程仓库中的数据下载下来了,但是没有修改本地文件,相当于下载)
我们可以通过git fetch
获取远程数据之后,然后合并到本地分支。
从上面我们直到,git fetch
已经将远程分支中的数据下载到本地了,因此,可以像合并本地分支一样来合并远程分支,即:- git cherry-pick o/main
- git rebase o/main
- git merge o/main
等等
实际上,由于先抓取更新再合并到本地分支这个流程很常用,因此 Git 提供了一个专门的命令来完成这两个操作:git pull
git pull
作用演示
git pull 相当于 git fetch; git merge o/main
- 先用 fetch 下载了 C3,
- 然后通过 git merge o/main 合并了这一提交记录。
现在我们的 main 分支包含了远程仓库中的更新
提交细节
情况一:
- 如果本地仓库分支没有任何的更改
这时只执行fast-forward
合并:
- 如果本地仓库有新的更新,那么需要合并双方的修改
执行pull就可以进行合并。这时,如果没有冲突的修改,就会自动创建合并分支。
如果有冲突就需要新解决冲突,在手动提交
git fakeTeamwork
fakeTeamwork
默认操作就是在远程仓库的 main 分支上做一次提交。
git push:将本地仓库推送到远程仓库上
我们可以通过git pull
下载他人的分享,同样的,我们可以通过git push
将自己的代码分享出去:
- 为了将本地数据库的修改记录共享到远程数据库,必须上传本地数据库中存储的修改记录。为此,需要在Git执行推送(Push)操作
- git push 负责将你的变更上传到指定的远程仓库,并在远程仓库上合并你的新提交记录。
- 一旦 git push 完成, 你的朋友们就可以从这个远程仓库下载你分享的成果了
假设你周一克隆了一个仓库,然后开始研发某个新功能。到周五时,你新功能开发测试完毕,可以发布了。但是 —— 天啊!你的同事这周写了一堆代码,还改了许多你的功能中使用的 API,这些变动会导致你新开发的功能变得不可用。但是他们已经将那些提交推送到远程仓库了,因此你的工作就变成了基于项目旧版的代码,与远程仓库最新的代码不匹配了。
这种情况下, git push 就不知道该如何操作了。如果你执行 git push,Git 应该让远程仓库回到星期一那天的状态吗?还是直接在新代码的基础上添加你的代码,亦或由于你的提交已经过时而直接忽略你的提交?
因为这情况(历史偏离)有许多的不确定性,Git 是不会允许你 push 变更的。也就是说在执行pull之后,进行下一次push之前,如果其他人进行了推送内容到远程数据库的话,那么你的push将被拒绝。
实际上它会强制你先合并远程最新的代码,然后才能分享你的工作。(这是因为,如果不进行合并就试图覆盖已有的变更记录的话,其他人push的变更(图中的提交C)就会丢失)
有许多方法做到这一点呢,不过最直接的方法就是通过 rebase 调整你的工作。咱们继续,看看怎么 rebase!
- 先用
git fetch;
更新本地仓库中的远程分支 - 然后用
git rebase
将我们的工作移动到最新的提交记录下 - 最后用
git push
推送到远程仓库
我们也可以使用merge
在远程仓库变更了以后更新我们的工作- 尽管
git merge
不会移动你的工作(它会创建新的合并提交),但是它会告诉git你已经合并了远程仓库的所有变更。 - 这是因为远程分支现在是你的本地分支的祖先,也就是说你的提交已经包含了远程分支的所有变化
- 尽管
但是要敲那么多命令,有没有更简单一点的?
当然 —— 前面已经介绍过 git pull 就是 fetch 和 merge 的简写,类似的 git pull --rebase 就是 fetch 和 rebase 的简写!
git pull --rebase; git push
git pull; git push