git 的分布式设计, 使得每个开发者的 local 都有 remote repo 的一份 copy , 我们在这份 copy 上提交, 创建新 branch, 最终, 我们会把我们在 local 的改动, 同步到远程的 repo; 当别人更新了远程 repo, 我们还要从远程 repo 同步这些改动到自己的 local. 这一系列的操作, 我们可以统称为git的同步, 同步发生在 local repo 和 remote repo 之间, 这篇文章就详细说说同步的事情.

remote URL and shortcuts

要想跟 remote repo,我们自然要知道 repo 的地址,git repo 的地址是一个 URL,这个 URL,可能是一个文件系统路径,可能是一个 http 协议的地址,可能是一个 ssh 协议的地址,git 所有跟远程 repo 交互的命令,都需要提供这个 URL,但是这些 URL 往往都比较长,且难以记忆,给他们起一个名字( 也可以叫 shortcut ),通过这个 shortcut 来跟远程 repo 交互是一个可以想到的比较好的方式,实际上 git 也是这么做的,我们在 git clone 的时候,输入这个URL,git默认就为我们创建了这么一个shortcut,叫origin,这个 shortcut 与 URL 对,组成了一个remote connection,我们可以使用git remote来查看 local repo 目前有哪些 remote shortcut,使用git remote -v来查看shortcut详细对应的URL。

除了 git 默认给我们创建的 shortcut,我们实际上可以用git remote创建新的 remote shortcut,这个命令其实可以管理 remote connection,增删改查样样拿手。

local repo 与 remote repo 同步

有了 remote shortcut,我们跟 remote repo 打交道就变得简单多了,在说同步之前, 还得说说 branch. 如果我们有了 remote connection, 那么我们在本地, 其实就有了 remote 的所有 branch, 可以通过git branch -a看到 remotes/开头的 branch, 使用 git clone 之后, 因为会默认创建origin这个 remote shortchut, 所以你会看到有remotes/origin/master这种 branch. git 的同步,首先是将我们本地的 remote branch 更新, 然后再去 upload 或者是将 remote branch 的更新 merge 到 local branch.

同步有 download 和 upload 两个动作.

  • download

    download 有两个命令, git fetchgit pull, git pull其实是git fetchgit merge的组合, 它更新 local 的 remote branch 的代码, 并将改动 merge 到我们当前的 branch 上; 而git fetch则仅仅是将 remote 的改动更新到 local 的 remote branch, 它比git pull更加安全.

  • upload

    git push来将我们 local branch 的改动提交到 remote. 当然它首先是将 local branch 的改动更新到 local remote branch, 然后再去将改动上传给 remote. 无论是 download 还是 upload, 我们自然都要指定 remote 的地址是什么, 因为我们创建了 remote shortcut, 所以我们可以直接使用诸如origin来操作, 下面是常用的一些操作:

#download
git fetch —all # download所有的remotes
git fetch origin # download origin 这个remote的所有branch

git pull —rebase # 建议使用rebase的方式来merge远程的代码到我们的local branch
git pull origin master # 将origin这个remote的master分支更新, 并merge到我们当前的branch, 这个其实是`git pull`这个命令的默认动作.

#upload
git push origin master #将我们本地的改动更新到origin这个remote的master分支. origin是push命令的默认remote

#remote的管理
git remote add other_repo <other_repo_url> # 添加一个新的remote, 叫other_repo, 我们可以在后续的git fetch other_repo, git push other_repo master里来跟othe_repo这个remote来同步代码. 
git remote add -f other_repo <other_repo_url> # 添加新的remote, 并直接将这个remote的repo fetch到本地.
git remote rename other_repo feature_repo
git remote rm feature_reop

git remote show origin # 查看某个remote shortcut详细信息, 比如本地的哪个branch跟踪的是remote的哪个branch