当你不仅仅是在本地单人工作时,就需要使用git remote、push、pull等命令来实现多人协作。
当你使用clone命令从某个网络地址下载得到一个本地的git仓库: git clone <url>
或者 git remote add <shortname> <url>
git pull <shortname>
网络仓库的结构和你的本地仓库结构分别如下图所示:
然后当你在本地做了一些修改,同时服务器上的内容经过别人的一些修改(并提交)后,两者的结构就会发生变化:
这时你如果用 git fetch origin
或者偷懒一点,可以省略origin,它是默认参数: git fetch
来下载得到指定的remote上所有本地没有的commits,以及branches的位置,结构图变成下图所示:
这里origin是clone后自动生成的一个remote,它就指代的是clone的地址(上图中的 [email protected]:project.git)。
origin/master表示origin上面的master分支的位置(可以理解为一个指针)
fetch下载的数据放在.git文件夹里,所以此时的工作目录不会有任何变化。你也无法通过git branch看到下载到的origin的各分支。不过你可以通过 git ls-remote origin
来查看origin上的各分支,然后使用 git checkout origin/<branch_name>
来切换到刚刚fetch到的某个remote分支
现在假设此时你又得知在另外的网址也建立了一个该库,你也想获得它,可以使用 git remote add <shortname> <url>
来新加一个remote,其中<shortname>
是你自己为它随意命名的,这里假设取名为teamone。
然后用 git fetch teamone
来下载该仓库的各个分支。
完成后结构图如下,左上是原服务器仓库,右上是新加的服务器仓库:
git push
git push <remote> <branch>
如: git push origin master
它的意思是用本地的master分支去更新origin服务器上的master分支。你也可以指定不同名称的<local_branch>
与<remote_branch>
: git push <remote> <local_branch>:<remote_branch>
之前的git push origin master
等价于git push origin master:master
git pull
git pull
缺省情况下等于git pull origin
就等于先git fetch origin
然后git merge <tracked_branch>
git fetch origin
从origin下载得到所有本地没有的commits,以及所有origin上branches的位置信息。 git merge <tracked_branch>
的意思是将当前branch 跟踪(track)的remote branch合并到当前branch,如果当前branch没有track的对象,必须显式指定出来: git pull <remote> <branch>
它就相当于
git fetch
git merge /
Tracking Branches
上一节提到了跟踪(track),那么如何让本地的branch track相应的服务器分支呢。
一般如果你clone了一个工程,那么你的本地master分支默认已经track了origin/master。如果我们要新增一个track关系,分三种情况:
1. 本地有分支服务器没有分支
git push -u或--set-upstream <remote> HEAD或<branch_name>
如:git push -u origin test
上文中提到过,它等价于 git push -u origin test:test
,也就是用本地的test分支去更新origin/test分支,同时让本地的test分支track origin/test(-u的效果)
2. 本地没有服务器有
git checkout -b <local_branch> <remote>/<remote_branch>
如:git checkout -b test origin/test
-b的意思是新建一个local_branch(不能和本地已有的重名),如果同时附上remote branch,就可以让它track该remote branch。这里<remote_branch>
和<local_branch>
不需要同名。
还有另一种写法: git checkout --track <remote>/<remote_branch>
相当于 git checkout -b <remote_branch> <remote>/<remote_branch>
还有另一种更简单的写法: git checkout <remote_branch>
相当于 git checkout -b <remote_branch> <remote>/<remote_branch>
该写法生效需满足:
1.本地不存在名为<remote_branch>
的分支(不然就直接checkout过去了)
2.只有一个remote拥有<remote_branch>
3. 本地有服务器也有
git branch <local_branch> -u或--set-upstream-to <remote>/<remote_branch>
如:git branch experiment -u origin/test
或:git branch -u origin/test
让<local_branch>
track <remote>/<remote_branch>
如果省略<local_branch>
参数将使用当前所在的branch。
之后merge的时候将自动将<remote>/<branch>
合并到当前branch
可以使用 git branch -vv
来查看本地branches的跟踪情况:
图中[ ]内就是track的对象,后面还会写出local branch与remote branch比较的结果。如ahead 3, behind 1就表示local branch有3个commits是remote branch所没有的,而remote branch有1个commit是local branch所有没有的,也就是存在着分叉。
建立了track关系后进行pull、merge就可以不用指定参数了。
删除remote branches
git push <remote> --delete <remote_branch>
或git push <remote> :<remote_branch>
不会影响到本地的branches删除remotes
git remote rm <remote>
其他git remote的常用命令:
-v
并显示总体概要信息show <remote_name>
显示某一remote的详细信息,如:git remote show origin
rename <old_name> <new_name>