git分支,fork,取,merge,rebase和clone,有什么区别?

有人能帮我理解Git中的分支,分支和克隆之间的区别吗?

同样,当我做一个git fetch而不是一个git pull时,这意味着什么?

另外,与merge相比, rebase是什么意思?

我怎样才能把自己的承诺压缩在一起?

他们如何使用,他们为什么使用,他们代表什么?

GitHub怎么样?

克隆只是一个存储库的副本。 从表面上看,其结果等同于svn checkout ,您可以从其他仓库下载源代码。 像Subversion这样的集中式VCS和像Git这样的DVCS之间的区别在于,在Git中,当你克隆的时候,你实际上正在复制整个源代码库,包括所有的历史和分支。 现在,您的计算机上已经有了一个新的存储库,并且您提交的任何提交进入该存储库。 没有人会看到任何改变,直到你将这些提交推送到另一个存储库(或原始存储库),或者直到有人从存储库中提取提交(如果可公开访问)。

分支是存储库内的东西。 从概念上讲,它代表了一个发展的线索。 你通常有一个主分支,但是你也可能有一个分支,你正在做一些特性xyz,另外一个来修复bug abc。 当你签出一个分支时,你所做的任何提交都将停留在该分支上,并且不会与其他分支共享,除非你将它们合并或者重新绑定到分支上。 当然,就分支而言,Git似乎有点奇怪,直到您看到分支如何实现的基本模型。 我不是自己解释它(我已经说了太多,methinks),我将链接到Git模型分支和提交的“计算机科学”解释,从Git网站:

http://eagain.net/articles/git-for-computer-scientists/

叉子实际上不是一个Git的概念,它更像是一个政治/社会的概念。 也就是说,如果有些人不满意项目进行的方式,他们可以将原始代码与原始开发人员分开独立工作。 这将被视为一个分叉。 Git使得分叉变得容易,因为每个人都有自己的“主”副本的源代码,所以就像切断与原始项目开发人员的联系一样简单,并且不需要从共享库中导出历史logging,就像你可能不得不使用SVN 。

编辑:因为我没有意识到像GitHub这样的站点所使用的“叉”的现代定义,请看看评论和迈克尔·杜兰特的答案在我的下面了解更多信息。

混帐

我的回答包括github,许多人也问过这个问题。

本地存储库

git(本地)有一个目录(.git),你提交你的文件,这是你的“本地存储库”。 这与svn这样的系统不同,你可以立即添加和提交到远程仓库。

git存储通过保存整个文件而改变的文件的每个版本。 这与svn在这方面也不同,因为你可以去任何单独的版本,而不需要通过增量变化来“重新创build”它。

git根本不会“locking”文件,从而避免了编辑的“独占locking”function(像pvcs这样的老系统),所以所有的文件都可以被编辑,即使在脱机时也是如此。 它实际上在合并文件更改(在同一个文件中!)的过程中一起做了一个了不起的工作,在拉或提取/推送到远程存储库,如github。 唯一需要手动更改(实际上是编辑文件)的时间是两个更改涉及相同的代码行。


分行

分支允许您保留主代码(“主”分支),复制(新分支),然后在新分支中工作。 完成后,将分支中所做的更改合并回主存储库。 许多组织对每件作品都使用分支,无论是function,错误还是杂项项目。 其他组织仅使用分支进行版本升级等重大更改。 有了一个分支,你可以控制和pipe理这个分支,而用一个别人控制接受代码。
一般来说,有两种主要的方法来做分支。 首先是在主分支上保留大部分更改,只使用分支来执行更大和更长的运行,例如版本更改,您希望有两个分支可用于不同的需求。 第二个是你基本上为每个function请求,错误修复或杂事build立一个分支,然后手动决定何时将这些分支实际合并到主分支中。 虽然这听起来很乏味,但这是一个常用的方法,也是我目前使用和推荐的方法,因为这样可以保持主分支更清洁,而且它是我们促进生产的主人,所以我们只需要完成,testing的代码,合并分支机构。

使分支“掌握”的标准方法是掌握merge 。 分支机构也可以用来“清理”历史。 这并不影响目前的状况,而是为了提供一个“更清洁”的历史。 基本上这个想法是,你从某个点(通常是从主)分支。 既然你分支'主'本身已经向前移动。 所以,如果你在一个分支中所做的所有改变都与最新的主人一起进行改变,那么它就会更清洁。 所以这个过程是:保存更改; 得到“新”主人,然后再次重新应用这些变化。 请注意,重新分配与合并一样,可能会导致冲突,您必须手动parsing(编辑)。

一个“指导方针”要注意的是: 如果分支机构是本地的,那么只有重新分配,并且你还没有把它推到远程呢! 这主要是因为重新贷款可以改变其他人看到的可能包括他们自己的承诺的历史。

跟踪分支

这些是名为origin / branch_name(而不是branch_name)的分支。 当你向远程仓库推送代码时,这实际上是发生这种情况的机制。 例如,当你git push一个名为“building_groups”的分支时,你的分支首先到达origin / building_groups,然后到达远程仓库(实际上这是一个过度简化,但现在已经足够了)。 同样,如果你做一个git fetch building_groups ,那么检索到的文件被放置在你的origin / building_groups分支中。 然后,您可以select将此分支合并到本地副本中。 我们的做法是总是做一个git fetch和一个手动合并,而不仅仅是一个git pull(上面的两个步骤)。

Fetch新的分支。

获取新分支:在克隆的起始点,您将拥有所有分支。 但是,如果其他开发人员添加分支并将其推送到远程,则需要有一种“知道”这些分支及其名称的方法,以便能够在本地将其撤销。 这是通过git fetch ,它将使用跟踪分支(例如origin /)将所有新的和已更改的分支获取到本地存储库中。 一旦fetch编辑,可以git branch --remote列出跟踪分支和git checkout [branch]实际切换到任何给定的。

合并

合并是将来自不同分支的代码更改或来自同一分支的不同版本的代码更改(例如,当本地分支和远程不同步时)进行组合的过程。 如果在分支机构开展了工作,并且工作已经完成,准备好并经过testing,则可以将其合并到master分支机构中。 这是由git checkout master切换到master分支,然后git merge your_branch 。 合并将带来所有不同的文件, 甚至不同的更改到相同的文件在一起。 这意味着它实际上会改变文件中的代码来合并所有的改变。 在完成mastercheckout出时,也build议使用git pull origin master来获取合并到本地主服务器上的最新版本的远程主服务器。 如果远程主服务器发生了变化,即moved forward ,您将看到反映在该git pull过程中的信息。 如果是这种情况(主人更改),build议您git checkout your_branch ,然后重新git checkout your_branch到主,以便您的更改实际上“重播”在“新”主人之上。 然后你会继续让主人更新如下一段所示。

如果没有冲突,那么master将添加新的更改。如果存在冲突,这意味着相同的文件围绕类似的代码行进行更改,不能自动合并。 在这种情况下, git merge new_branch将报告有冲突(S)来解决。 您通过编辑文件(这两个文件中都有更改)来“解决”它们,select所需的更改,从字面上删除不需要的更改的行,然后保存该文件。 这些更改用分隔符(如========<<<<<<<<标记

一旦你解决了任何冲突,你将再次git addgit commit这些更改来继续合并(在这个过程中你会得到git的反馈来指导你)。 当这个过程无法正常工作时,你会发现git merge --abort可以很方便地重置事情。

交互重新绑定和压扁/重新sorting/删除提交

如果你已经做了很多小的工作,比如你每天都提交代码为“进行中的工作”,那么你可能想把这些许多小的提交“挤压”成几个更大的提交。 当您想与同事进行代码审查时,这可能特别有用。 你不想重播你所做的所有“步骤”(通过提交),你只想在这里说的是在一次提交中对这项工作所做的所有更改的最终效果(差异)。 在考虑是否这样做时,评估的关键因素是多次提交是否多次违反相同的文件或文件(在这种情况下最好压缩提交)。 这是通过交互式重新组装工具完成的。 这个工具可以让你压缩提交,删除提交,reword消息等。例如git rebase -i HEAD~10 请注意,这是一个~-一个-带出以下内容:
Git中的交互式重新装订 小心,小心使用这个工具。 一次压扁/删除/重新sorting,退出并保存该提交,然后重新input工具。 如果提交不是连续的,你可以重新sorting(然后根据需要压扁)。 实际上你也可以删除提交,但是你确实需要确定你在做什么。

福克斯

在git仓库中有两种主要的协作方法。 第一,详细的上面是直接通过分支,人们拉和推。 这些协作者将其ssh密钥注册到远程存储库。 这将让他们直接推送到该存储库。 缺点是你必须保持用户名单。 另一种方法 – 分叉 – 允许任何人“分叉”存储库,基本上在自己的git存储库帐户中创build本地副本。 然后,他们可以进行更改,完成后发送一个“拉取请求”(实际上它更像是一个“推送”,对于实际的存储库维护者是一个“拉”请求)来接受代码。
第二种使用分叉的方法不需要有人维护存储库的用户列表。


Github上

github(一个远程仓库)是一个远程源,你通常推送和提交这些提交的更改,如果你有(或添加到)这样一个仓库,所以本地和远程实际上是非常不同的。 另一种考虑远程仓库的方法是,它是一个驻留在远程服务器上的.git目录结构。

当你“分叉” – 在github网页浏览器gui中,你可以点击 在这里输入图像描述 – 您在github帐户中创build代码副本(“克隆”)。 首次执行操作可能会有些微妙,因此请确保您查看代码库所在的代码库 – 无论是原始所有者,还是您自己分配的代码库,例如 在这里输入图像描述
获得本地副本后,可以根据需要进行更改(通过将其推送到本地计算机)。 当你完成后,你提交一个“拉请求”的原始存储库所有者/pipe理员(听起来很花哨,但实际上你只是点击这个: – 在这里输入图像描述 ),他们“拉”进来。
团队共同工作的团队更常见的是“克隆”存储库(点击存储库主屏幕上的“复制”图标)。 然后,在本地inputgit clone [paste]这会在本地设置你,也可以推送到(共享的)github位置。

克隆

如github上的部分所示,克隆是存储库的副本。 当你有一个远程仓库时,你可以针对它的URL发出git clone命令,然后你得到一个本地副本,或者一个仓库克隆。 这个克隆有一切 ,文件,主分支,其他分支,所有现有的提交,整个shebang。 正是这个克隆,你做你的增加和提交,然后远程存储库本身就是你推这些提交。 正是这种本地/远程的概念,使git(和Mercurial类似的系统)成为DVCS( 分布式版本控制系统),而不是像SVN,PVCS,CVS等更传统的CVS(代码版本pipe理系统)你直接提交到远程仓库。

可视化

可以看到核心概念的可视化
http://marklodato.github.com/visual-git-guide/index-en.html和;
http://ndpsoftware.com/git-cheatsheet.html#loc=index

如果你想要一个视觉显示如何变化的工作,你不能击败可视化工具gitg(gitx for mac)与我称之为“地铁地图”(特别是伦敦地铁)的GUI,伟大的显示谁做的什么,事情如何变化,分化和合并等

您也可以使用它来添加,提交和pipe理您的更改!

gitg / gitx界面

虽然gitg / gitx是相当小的,但在过去的2 – 3年(2009-2012年),gui工具的数量不断扩大。 许多Mac用户使用brotherbard的gitx叉和Linux的一个很好的select是smart-git与一个直观而强大的界面:

聪明的git GUI

请注意,即使使用gui工具,也可能会在命令行执行大量命令。
为此,在我的〜/ .bash_aliases文件(从我的〜/ .bashrc文件为每个terminal会话调用:

 # git alias gst='git status' # Warning: gst conflicts with gnu-smalltalk (when used). alias gb='git branch' alias gco='git checkout' alias gcob='git checkout -b ' alias ga='git add ' alias gc='git commit' alias gg='git grep ' # A great very FAST search option, easier then `find` 

最后,六个关键的救生员:

1)你搞砸了你的本地分支,只想回到你上次做git pull的时候:

 git reset --hard origin/master # You will need to be comfortable doing this! 

2)你开始在本地进行更改,编辑六十个文件,然后,哦,废话,你仍然在主(或另一个)分支:

 git checkout -b new_branch_name # just create a new branch git add . # add the changes files git commit -m"your message" # and commit them 

3)你在你当前的分支中搞砸了一个特定的文件,并且想要基本上'重置'该文件(丢失改变)到最后一次从远程仓库中取出它的方式: git checkout your/directories/filename重置文件(就像许多git命令,它没有很好地命名它在这里做什么)。

4)你在本地进行一些更改,当你做一个git reset或rebase时,你要确保你不会丢失它们:当我经常做整个项目( cp -r ../my_project ~/ )的手动拷贝的时候我不确定我是否会陷入混乱或失去重要的变化。

5)你正在重塑,但事情变得混乱:

 git rebase --abort # To abandon interactive rebase and merge issues 

6)将你的git分支添加到你的PS1提示符( https://unix.stackexchange.com/a/127800/10043 ),例如 在这里输入图像描述
该分支是selenium_rspec_conversion

这是奥利弗·斯蒂尔(Oliver Steele)关于如何融合在一起的形象:

在这里输入图像描述

只是添加到其他人,特别是分叉的说明。

从技术上讲,克隆回购和回购回购是一回事,这是很好的。 做:

 git clone $some_other_repo 

你可以挖掘自己的后面—你刚刚分叉了一些其他的回购。

作为一个VCS,Git实际上是关于克隆分叉的。 除了使用远程用户界面(例如cgit)“浏览”之外,与git仓库无关,不涉及在某个时刻克隆仓库。

然而,

  • 当有人说我分叉回购X时 ,他们意味着他们已经在别处创build了回购的克隆,意图展示给其他人,例如展示一些实验,或者应用不同的访问控制机制(例如,允许没有人Github访问但与公司内部帐户协作)。

    事实是:回购最有可能是用git clone以外的其他命令创build的,它最有可能被托pipe在某个服务器的某个地方,而不是某个人的笔记本电脑,而且很可能有一些不同的格式(这是一个“裸回购”,即不工作树)都只是技术细节。

    事实上,它最有可能包含不同的分支,标签或提交集,这很可能是他们为什么这样做的原因。

    (当你点击“fork”时,Github所做的只不过是添加了糖的克隆:它克隆了你的回购,放在你的账户下,logging在某个地方的“分叉”,增加了远程命名的“上游”,最重要的是,播放漂亮的animation。)

  • 当有人说我克隆了repo X时 ,这意味着他们已经在笔记本电脑或桌面上本地创build了一个repo的克隆,目的是研究它,玩它,贡献它,或者从源代码中构build一些东西。

Git的美妙之处在于它使得这一切完美契合在一起:所有这些回购都共享提交链的共同部分,因此可以安全地(见下面的注释)在所有这些回购之间来回合并变更,如果您认为合适的话。


注意:只要不重写链的公共部分,只要这些更改没有冲突,就“安全”。

叉子VS. 克隆 – 两个词都意味着复制

请看这张图。 (最初来自http://www.dataschool.io/contenthttp://img.dovov.com2014/Mar/github1.png )。

叉子

  • 复制到您的远程回购(云),将其链接到乔的
  • 你可以克隆到你的本地仓库和F *%$ – up
  • 当你完成后,你可以推回到你的遥控器
  • 然后,您可以通过点击拉取请求来询问Joe是否想在他的项目中使用它

克隆

  • 复制到您当地的回购(硬盘)