简单地说,一个remote repository是一个非本地的repo。它可以是在你公司网络上的另外一个git repo,也可以是在internet上,甚至在你本地文件系统中的一个repo,关键点是它和你的my-git-repo project是不同的。

我们已经知道branch在单个的repo中是如何组织你的工作流的,但是要知道branch本身在Git的跨repo分享commit也有重要作为。Remote branches和我们一直本地使用的local branch没有太多区别,他们仅仅代表着存在于另外一个repo中的一个branch而已。

这意味着我们可以利用我们branch的merging/rebasing技能很方便扩展到合作开发上去。下面我们假装在我们的样例web项目开发中有多个开发人员一起工作,他们是如何利用Git来协作的。

我们假设Mary,作为我们的graphic designer,她需要加入我们的web项目开发中。

Clone the Repository(MARY)

首先,mary需要一个她自己的repo以便可以开始工作。Git支持分布式的工作流,但是为了简便我们直接在本地文件系统中模拟不同repo协作。

cd /path/to/my-git-repo
cd ..
git clone my-git-repo marys-repo
cd marys-repo

上面的命令将在本地不同目录clone了一个my-git-repo项目repo,命名为marys-repo。

Configure The Repository (Mary)

首先,mary需要配置她clone的repo以便我们知道谁对项目做了贡献。

git config user.name "Mary"
git config user.email mary.example@rypress.com

注意由于我们没用--global选项,上面的user.name,email都只对这个repo有效,保存在.git的config文件中。

Start Mary’s Day (Mary)

今天,Mary开始开发她的bio page,她首先要在我们repo的clone repo中(对她来说,就是一个local repo)创建一个独立的分支以便隔离工作。

git checkout -b bio-page

Mary可以方便地在她的repo中创建和check out branches。她的repo是一个完全和我们的repo隔离的环境,她可以不用考虑任何在我们原始my-git-repo中的开发活动,任意地做她想做的开发工作。

就如branches是working directory的一种抽象,the staged snapshot, a commit history, a repository是一个branch的抽象。

Create Mary’s Bio Page ,commit,merge(Mary)

在marys-repo中,更改about/mary.html,随后commit该change到bio-page branch上,merge该branch到master上,以便准备分享mary自己的工作

git commit -a -m "Add bio page for Mary"
git log -n
git checkout master
git merge bio-page

现在我们项目repo和mary的repo是这样的:

注意:两个repo都有常见的,本地branches,两个repo之间还没有任何交互动作,所以我们没有看到remote branches.在切换到my-git-repo之前我们看看mary的remote connections:

View Remote Repositories (Mary)

git remote -v

Mary可以使用git remote命令列出她有哪些和其他repo之间的connections。明显地,她有一个被命名为origin的remote.注意,当你clone一个repo时,git自动增加一个指向original repo的remote,git预设你希望将来对这个cloned repo做协同。

Return to Your Repository (You)

注意这时你的repo中mary的bio page依然为空的。注意这个repo和mary repo是完全隔离的,这一点很重要。当她修改她的bio page时,我们可以在my-git-repo中做任何事情。我们甚至可以在我们的repo中修改她的bio page,而这将来在pull她的变动时就可能产生conflict.

Add Mary as a Remote (You)

在我们可以使用mary的bio page之前,我们需要访问她的repo.我们通过查看我们repo中的remote: git remote,你会发现我们还没有任何remote(注意我们没有做过任何clone,所以就不会有origin这个remote),我们需要手工创建mary这个remote.

git remote add mary ../marys-repo
git remote -v

现在我们就可以使用mary来引用Mary的repo了(位置在../marys-repo) git remote add命令用于bookmark另外一个git repo以方便访问,我们两个repo之间的关联如下图:

既然我们的remote repository已经建立好了,我们下面将花时间探讨remote branches.

Fetch Mary’s Branches (You)

正如前面提过,我们可以使用remote branches来访问来自另外一个repo的snapshots。我们先看看我们当前的remote branches,使用:git branch -r命令,同样地,我们没有任何remote branch,为了获得这些remote branch list,我们需要fetch the branches from Mary's repository:

git fetch mary
git branch -r
将会输出:
mary/bio-page
mary/master

remote branch总是以<remote-name>/<branch-name>的形式列出,这样永远不会和local branches混淆。上面列出的remote branch反映了Mary的repo在执行fetch命令时的状态。但是注意如果Mary继续在她的repo中开发,那么我们fetch过来的状态并不会自动体现后面Mary的改动!这也就是说我们的remote branches本身并没有直接和Mary的repo链接起来,这意味着我们如果需要最新的Mary的update,必须再次执行fetch命令。

上面的途中显示了我们的repo的状态,我们已经可以访问Mary的snapshots(以方框指示)和她的branches,虽然我们没有一个实时的connection到Mary的repo。

Check Out a Remote Branch

我们可以在自己的repo中执行 git checkout mary/master来checkout一个remote branch以便检查review Mary's changes.

这个动作将会使我们的工作环境进入detached HEAD state,就像我们本地开发时checkout一个历史commit时的状态一样。这本身并不奇怪,因为我们的remote branches是Mary的branch的一个copy. checking out一个remote branch将会把我们的HEAD脱离local branch的tip,以下图来示例

红色方框为HEAD指向remote branch(mary的commit),local master则指向前一个commit。

如果我们不在local branch时,我们不能继续开发commit(我们可以检查代码)。为了能在mary/master上开发??,我们需要将该branch merge到我们的local master或者再创建另外一个分支。

Find Mary’s Changes

我们可以使用本地repo操作一样的log-filtering语法来查看Mary's changes.

git log master..mary/master --stat

这将不会有任何输出,因为自从Mary clone了repo后,我们并未做改变,换句话说,我们的历史还没有发散,我们只是落后一个commit。

Merge Mary’s Changes

我们来apprvoe Mary的变更并且集成到我们的master branch上去。

git checkout master
git merge mary/master

虽然mary/master是一个remote branch,这仍然会产生一个fast-forward merge,因为从我们的local master到mary/master的tip之间是linear path。在merge之后,Mary remote branch上的snapshots称为我们local master branch的一部分,比较merge前后的情况示意如下:

注意,虽然我们可以访问到她的bio-page分支,但是我们仅仅和Mary的master branch做了交互。

Push a Dummy Branch

为了对我们的git fetch命令做一个补充,我们看看pushing命令。Fetching和pushing几乎是相反的,fetching imports branches,而pushing exports branches to another repo.比如:

git branch dummy
git push mary dummy

上面的命令创建一个dummy branch,随后发送到Mary的repo中,我们切换到Mary的repo看看我们干过什么:

cd ../marys-repo
git branch

你会发现一个新的dummy branch在她的local branch listing.我说过git fetch和git push几乎是相反的是因为pushing创建一个local branch,而fetching却imports commits into remote branches!!

现在我们站在Mary的角度上来看,当她在她自己的repo中开发时却突然发现莫名其妙多了一个dummy branch在她的local branch list中,这是不是很唐突混乱?明显的,push branch到其他人的repo中将会造成workflow混乱。因此,作为一个general rule,你永远不要push你的本地变更到别的开发人员的repo中!!但是,我们到底应该如何使用push呢?

在下面的文章中,我将描述push操作对于维护public repo是非常有必要的!

Push a New Tag

git push的一个重要特性是git push不会自动push和一个branch关联的tags。我们做下面的实验:

git tag -a v2.0 -m "An even stabler version of the website"

git push mary master
git push mary v2.0

通过上面的命令,你将可以在Mary的repo中看到一个v2.0 tag。注意:非常容易你可能虽然创建了一个tag,却忘记push!如果你的项目缺少一两个tag,那么很大的可能是你忘记push到remote repo了!

有一点需要谨记: remotes are for people, branches are for topic! 不要为了你的每一个开发人员创建一个独立的分支,而应该给他们独立的repo并且使用git remote add来引用。Branches总是用来做项目开发的,不是用来管理用户的。

git remotes的更多相关文章

  1. Git remotes/origin/pr/* 分支清理

    代码在gitHub上托管,每次git pull完后,用git branch -a都可以看到一堆remotes/origin/pr/*分支: 可以通过两种方式去除: 1,修改git的config文件找到 ...

  2. Git remotes/origin/pr/* 分支清理,代码回退等

    代码在gitHub上托管,每次git pull完后,用git branch -a都可以看到一堆remotes/origin/pr/*分支: 可以通过两种方式去除: 1,修改git的config文件找到 ...

  3. GIT(分布式版本控制系统)

    Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.[1] Git的读音为/gɪt/. Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常大的项目版本 ...

  4. git学习(这个我没有整理,是我不断在学习的过程中,自己总结的,对象是我,不过有问题的,我们可以相互交流)

    每次git提交,都会有一个parent指针,指向上一次的commit ,   如果合并,master就和hotfix河道一起,就直接删除hotfix就OK     此时,虽然操作一样,大底层实现不一样 ...

  5. git学习(持续踩坑中🤣)

    https://segmentfault.com/q/1010000002457936 常见指令: 一.创建版本库 $ mkdir learngit 创建文件夹 $ cd learngit 进入文件夹 ...

  6. svn转git

    在Git Bash 中输入 git-svn clone http://devsvnread.uuzuonline.net/GOT_PRIVATE/server/ --no-metadata -T tr ...

  7. svn转git合并代码

    在Git Bash 中输入 git-svn clone http://devsvnread.uuzuonline.net/GOT_PRIVATE/server/ --no-metadata -T tr ...

  8. Git管理分支

    管理分支:git branch 直至现在为止,我们的项目版本库一直都是只有一个分支 master.在 git 版本库中创建分支的成本几乎为零,所以,不必吝啬多创建几个分支.下面列举一些常见的分支策略, ...

  9. 第七章 : Git 介绍 (下)[Learn Android Studio 汉化教程]

    Learn Android Studio 汉化教程 Let’s reset even further to remove all traces of your work on the deprecat ...

随机推荐

  1. 首次发布App,In-App Purchase 无法submit for review 问题的解决方案

    原地址:http://blog.csdn.net/blucenong/article/details/7819195 一个IDP首次create app 然后首次create new IAP的时候,我 ...

  2. Sqli-labs less 31

    Less-31 Less-31与上述两个例子的方式是一样的,我们直接看到less-31的sql语句: 所以payload为: http://127.0.0.1:8080/sqli-labs/Less- ...

  3. js调试-定位到函数所在文件位置

    原文:http://www.cnblogs.com/52cik/p/js-console-show-source.html 在控制台输入要查找的函数名如votePost 然后回车: 函数源码粗显啦,并 ...

  4. POJ 2014

    #include <iostream> using namespace std; int main() { //freopen("acm.acm","r&qu ...

  5. NGINX轻松管理10万长连接 --- 基于2GB内存的CentOS 6.5 x86-64

    http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=190176&id=4234854 一 前言   当管理大量连接时,特别 ...

  6. oracle创建表空间,创建用户(转)

    //创建临时表空间 create temporary tablespace test_temp tempfile 'E:\oracle\product\10.2.0\oradata\testserve ...

  7. 初始JSON

    SON是一种传输数据的格式(以对象为样板,本质上就是对象,但用途有区别,对象就是本地用的,json是用来传输的 JSON的两种静态方法: 1.JSON.parse();  string --> ...

  8. Spark基础与Java Api介绍

    原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/3832405.html  一.Spark简介 1.什么是Spark 发源于AMPLab实验室的分布式内存计 ...

  9. iOS开发——技术精华Swift篇&Swift 2.0和Objective-C2.0混编之第三方框架的使用

    swift 语言是苹果公司在2014年的WWDC大会上发布的全新的编程语言.Swift语言继承了C语言以及Objective-C的特性,且克服了C语言的兼容性问题.Swift语言采用安全编程模式,且引 ...

  10. 浅析ODS与EDW关系(转载)

    浅析ODS与EDW 关系 刘智琼 (中国电信集团广州研究院广州510630) 摘要 本文重点介绍了企业运营数据仓储(ODS)和企业数据仓库(EDW )的概念,并对ODS与EDW 之间的关系,包括两者相 ...