git分支、fork、fetch、merge、rebase和clone之间有什么区别?
我想了解 Git 中分支、分叉和克隆之间的区别?
同样,当我执行 git fetch
而不是 git pull
时,这意味着什么?
另外,与 merge
相比,rebase
意味着什么?
我怎样才能将个人的承诺压缩在一起?
它们如何使用、为什么使用以及它们代表什么?
GitHub 如何发挥作用?
I want to understand the difference between a branch, a fork and a clone in Git?
Similarly, what does it mean when I do a git fetch
as opposed to a git pull
?
Also, what does rebase
mean in comparison to merge
?
How can I squash individual commits themselves together?
How are they used, why are they used and what do they represent?
How does GitHub figure in?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Git
这个答案包括 GitHub,因为很多人也问过这个问题。
本地存储库
Git(本地)有一个目录 (
.git
),您可以将文件提交到该目录,这是你的“本地存储库”。这与 SVN 等系统不同,在 SVN 中您可以立即添加并提交到远程存储库。Git 通过保存整个文件来存储更改的文件的每个版本。在这方面它也与 SVN 不同,因为您可以转到任何单独的版本,而无需通过增量更改“重新创建”它。
Git 根本不会“锁定”文件,从而避免了编辑时的“独占锁定”功能(例如 pvcs 之类的旧系统),因此所有文件始终可以编辑,即使在离线状态下也是如此。实际上,它在拉取或获取/推送到远程存储库(例如 GitHub)期间将文件更改(在同一文件内!)合并在一起方面做得非常出色。唯一需要手动更改(实际编辑文件)的情况是两个更改涉及相同的代码行。
分支
分支允许您保留主代码(“主”分支),制作副本(新分支),然后在该新分支中工作。如果工作需要一段时间或者 master 自分支创建以来获得了大量更新,那么应该针对 master 分支进行合并或变基(通常是为了更好的历史记录和更容易解决冲突而首选)。完成后,您可以将分支中所做的更改合并回主存储库。许多组织对每项工作都使用分支,无论它是功能、错误还是杂务项目。其他组织仅使用分支进行重大更改,例如版本升级。
分叉:使用分支,您可以控制和管理分支,而使用分叉,其他人可以控制接受代码返回。
一般来说,有两种主要的方法来执行分支。第一个是将大部分更改保留在主分支上,仅将分支用于更大且运行时间更长的事情,例如版本更改,您希望有两个分支可用于不同的需求。第二种方法是,您基本上为每个功能请求、错误修复或杂务创建一个分支,然后手动决定何时实际将这些分支合并到主主分支中。虽然这听起来很乏味,但这是一种常见的方法,也是我目前使用和推荐的方法,因为这可以使主分支保持干净,并且它是我们升级到生产的主分支,所以我们只需要通过变基和测试完成的、经过测试的代码分支的合并。
将分支引入 master 的标准方法是进行合并。分支也可以“重新定位”以“清理”历史记录。它不会影响当前状态,而是为了提供“更干净”的历史记录。
基本上,这个想法是你从某个点(通常是从master)分支。自从你分支以来,“master”本身就从那个分支点向前移动了。如果您在分支中所做的所有更改都与 master 的当前状态及其所有最新更改相对应,那么它将变得“更干净”(更容易解决问题,历史记录也更容易理解)。所以,过程是:保存更改;获取“新”主控,然后再次应用(这是变基部分)更改。请注意,变基就像合并一样,可能会导致您必须手动解决(即编辑和修复)的冲突。
需要注意的一项准则:
仅当分支是本地且您尚未将其推送到远程时才进行变基!
这主要是因为变基可以改变其他人看到的历史记录,其中可能包括他们自己的提交。
跟踪分支
这些是名为
origin/branch_name
的分支(而不是仅branch_name
)。当您将代码推送到远程存储库或从远程存储库拉取代码时,这实际上就是发生这种情况的机制。例如,当您git Push
一个名为building_groups
的分支时,您的分支首先进入origin/building_groups
,然后进入远程存储库。同样,如果您执行git fetchbuilding_groups
,检索到的文件将放置在您的origin/building_groups
分支中。然后,您可以选择将此分支合并到本地副本中。我们的做法是始终执行 git fetch 和手动合并,而不仅仅是 git pull (一步完成上述两项操作)。获取新分支。
获取新分支:在克隆的初始点,您将拥有所有分支。但是,如果其他开发人员添加分支并将它们推送到远程,则需要有一种方法来“了解”这些分支及其名称,以便能够在本地将它们拉下来。这是通过 git fetch 完成的,它将使用跟踪分支(例如,origin/)将所有新的和更改的分支获取到本地存储库中。一旦
fetch
ed,人们可以gitbranch --remote
列出跟踪分支,并git checkout [branch]
实际切换到任何给定的分支。合并
合并是合并来自不同分支或同一分支的不同版本的代码更改的过程(例如,当本地分支和远程分支不同步时)。如果一个人在一个分支中开发了工作,并且该工作已经完成、准备就绪并经过测试,那么它可以合并到
master
分支中。这是通过git checkout master
切换到master
分支,然后git merge your_branch
来完成的。合并会将所有不同的文件以及甚至同一文件的不同更改合并在一起。这意味着它实际上会更改文件内的代码以合并所有更改。在执行
master
的checkout
时,还建议执行git pull origin master
将远程 master 的最新版本合并到您的本地大师。如果远程主服务器发生变化,即向前移动
,您将在git pull
期间看到反映这一情况的信息。如果是这种情况(master 已更改),建议您git checkout your_branch
,然后将其rebase
为 master,以便您的更改实际上在 '新的主人。然后,您将继续使 master 保持最新状态,如下一段所示。如果不存在冲突,那么 master 将添加新的更改。如果存在冲突,则意味着相同的文件在相似的代码行周围有更改,因此无法自动合并。在这种情况下,
git merge new_branch
将报告存在需要解决的冲突。您可以通过编辑文件(其中将包含两个更改),选择所需的更改,逐字删除不需要的更改行,然后保存文件来“解决”它们。更改用分隔符标记,例如========
和<<<<<<<<<<<<
。解决所有冲突后,您将再次
git add
和git commit
这些更改以继续合并(在此过程中您将获得 git 的反馈来指导您) 。当该过程无法正常工作时,您会发现 git merge --abort 可以非常方便地重置内容。
交互式变基和压缩/重新排序/删除提交
如果您已经完成了许多小步骤的工作,例如,您每天将代码作为“正在进行的工作”提交,您可能希望将这些许多小提交“压缩”为一个很少有较大的提交。当您想与同事一起进行代码审查时,这尤其有用。您不想重播您采取的所有“步骤”(通过提交),您只想说这是我在一次提交中对这项工作所做的所有更改的最终效果(差异)。
在考虑是否这样做时要评估的关键因素是多次提交是否针对同一文件或多个文件(在这种情况下最好压缩提交)。这是通过交互式变基工具完成的。该工具可让您压缩提交、删除提交、改写消息等。例如,
git rebase -i HEAD~10
(注意:这是~
,而不是a-
) 会显示以下内容:但要小心并“小心”地使用这个工具。一次执行一个压缩/删除/重新排序,退出并保存该提交,然后重新输入该工具。如果提交不连续,您可以对它们重新排序(然后根据需要进行压缩)。实际上,您也可以在这里删除提交,但是当您这样做时,您确实需要确定自己在做什么!
分叉
Git 存储库中有两种主要的协作方法。第一个,如上所述,是直接通过人们拉动和推入的分支。这些协作者的 SSH 密钥已在远程存储库中注册。这将使他们直接推送到该存储库。缺点是您必须维护用户列表。
另一种方法 - 分叉 - 允许任何人“分叉”存储库,基本上是在自己的 Git 存储库帐户中制作本地副本。然后,他们可以进行更改,并在完成后发送“拉取请求”(实际上,这更多的是来自他们的“推”和对实际存储库维护者的“拉”请求)以使代码被接受。
第二种方法使用分叉,不需要某人维护存储库的用户列表。
GitHub
GitHub(远程存储库)是一个远程源,如果您拥有(或添加到)这样的存储库,您通常会推送和拉取这些已提交的更改,因此本地和远程实际上是截然不同的。考虑远程存储库的另一种方式是,它是位于远程服务器上的
.git
目录结构。当您“分叉”时 - 在 GitHub Web 浏览器 GUI 中,您可以单击此按钮 - 您创建一个复制(“克隆”)您的 GitHub 帐户中的代码。第一次执行此操作时可能会有点微妙,因此请务必查看代码库列在谁的存储库下 - 原始所有者或“分叉自”以及您,例如,如下所示:
一旦您拥有本地副本,您就可以根据需要进行更改(通过将它们拉取并推送到本地计算机) 。完成后,您向原始存储库所有者/管理员提交“拉取请求”(听起来很花哨,但实际上您只需单击此: ),然后他们将其“拉”进去。
对于一起处理代码的团队来说,更常见的是“克隆”存储库(单击存储库主屏幕上的“复制”图标)。然后,在本地输入 git clone 并粘贴。这将在本地进行设置,您还可以推送和拉取到(共享)GitHub 位置。
克隆
正如 GitHub 上的部分所示,克隆是存储库的副本。当您拥有远程存储库时,您可以针对其 URL 发出 git clone 命令,然后您最终会得到该存储库的本地副本或克隆。这个克隆拥有一切,文件、主分支、其他分支、所有现有的提交、整个 shebang。您可以针对此克隆进行添加和提交,然后将这些提交推送到远程存储库本身。正是这种本地/远程概念使 Git(以及类似的系统,例如 Mercurial)成为 DVCS(分布式版本控制系统),而不是更传统的 CVS(代码版本控制系统),例如 SVN, PVCS、CVS 等,您可以在其中直接提交到远程存储库。
可视化
核心概念的可视化可以参见
http://marklodato.github.com/visual-git-guide/index -en.html 和
http://ndpsoftware.com/git-cheatsheet.html#loc=index
如果您想要直观地显示更改的效果,那么您无法击败可视化工具
gitg
(适用于 macOS 的gitx
),它的 GUI 被我称为“地铁”地图”(尤其是伦敦地铁),非常适合显示谁做了什么、事物如何变化、分歧和合并等。您还可以使用它来添加、提交和管理您的更改!
尽管 gitg/gitx 相当小,但 GUI 工具的数量仍在不断增加。许多 Mac 用户使用 Brotherbard 的 gitx 分支,而对于 Linux,smart-git 是一个不错的选择,它具有直观而强大的界面:
请注意,即使使用 GUI 工具,您也可能会做很多事情命令行中的命令。
为此,我的
~/.bash_aliases
文件中有以下别名(从每个终端会话的~/.bashrc
文件中调用):并且我有在我的
~/.gitconfig
文件中遵循“git aliases” - 为什么有这些?这样分支完成(使用 TAB 键)就可以工作了!
这些是:
用法示例:
git co [branch]
<- 分支的制表符补全功能将起作用。GUI 学习工具
您可能会发现 https://learngitbranching.js.org/ 对于学习一些基本概念很有用。屏幕截图:
视频:https://youtu.be/23JqqcLPss0
最后,7 个关键救星!
您进行更改、添加并提交它们(但不要推送),然后哦!你意识到你已经掌握了!
您在本地分支工作时弄乱了一些文件,只想返回到上次执行
git pull
时的状态:您开始在本地进行更改,您编辑了半个文件十几个文件,然后,哦,糟糕,你仍然在主(或另一个)分支中:
你搞乱了当前分支中的一个特定文件,并且想要基本上“重置” ' 该文件(丢失更改)为您上次从远程存储库中提取它时的样子:
这实际上会重置文件(像许多 Git 命令一样,它的名称并没有很好地说明它在这里所做的事情)。
您在本地进行了一些更改,您希望确保在执行
git重置
或rebase
时不会丢失它们:我经常手动复制当我不确定我是否会在 Git 中搞砸或丢失重要更改时,整个项目(cp -r ../my_project ~/
)。你正在变基,但事情变得一团糟:
将 Git 分支添加到
PS1
提示符中(请参阅 https://unix.stackexchange.com/a/127800/10043),例如分支是
selenium_rspec_conversion
。Git
This answer includes GitHub as many folks have asked about that too.
Local repositories
Git (locally) has a directory (
.git
) which you commit your files to and this is your 'local repository'. This is different from systems like SVN where you add and commit to the remote repository immediately.Git stores each version of a file that changes by saving the entire file. It is also different from SVN in this respect as you could go to any individual version without 'recreating' it through delta changes.
Git doesn't 'lock' files at all and thus avoids the 'exclusive lock' functionality for an edit (older systems like pvcs come to mind), so all files can always be edited, even when off-line. It actually does an amazing job of merging file changes (within the same file!) together during pulls or fetches/pushes to a remote repository such as GitHub. The only time you need to do manual changes (actually editing a file) is if two changes involve the same line(s) of code.
Branches
Branches allow you to preserve the main code (the 'master' branch), make a copy (a new branch) and then work within that new branch. If the work takes a while or master gets a lot of updates since the branch was made then merging or rebasing (often preferred for better history and easier to resolve conflicts) against the master branch should be done. When you've finished, you merge the changes made in the branch back in to the master repository. Many organizations use branches for each piece of work whether it is a feature, bug or chore item. Other organizations only use branches for major changes such as version upgrades.
Fork: With a branch you control and manage the branch, whereas with a fork someone else controls accepting the code back in.
Broadly speaking, there are two main approaches to doing branches. The first is to keep most changes on the master branch, only using branches for larger and longer-running things like version changes where you want to have two branches available for different needs. The second is whereby you basically make a branch for every feature request, bug fix or chore and then manually decide when to actually merge those branches into the main master branch. Though this sounds tedious, this is a common approach and is the one that I currently use and recommend because this keeps the master branch cleaner and it's the master that we promote to production, so we only want completed, tested code, via the rebasing and merging of branches.
The standard way to bring a branch 'in' to master is to do a
merge
. Branches can also be "rebased" to 'clean up' history. It doesn't affect the current state and is done to give a 'cleaner' history.Basically, the idea is that you branched from a certain point (usually from master). Since you branched, 'master' itself has since moved forward from that branching point. It will be 'cleaner' (easier to resolve issues and the history will be easier to understand) if all the changes you have done in a branch are played against the current state of master with all of its latest changes. So, the process is: save the changes; get the 'new' master, and then reapply (this is the rebase part) the changes again against that. Be aware that rebase, just like merge, can result in conflicts that you have to manually resolve (i.e. edit and fix).
One guideline to note:
Only rebase if the branch is local and you haven't pushed it to remote yet!
This is mainly because rebasing can alter the history that other people see which may include their own commits.
Tracking branches
These are the branches that are named
origin/branch_name
(as opposed to justbranch_name
). When you are pushing and pulling the code to/from remote repositories this is actually the mechanism through which that happens. For example, when yougit push
a branch calledbuilding_groups
, your branch goes first toorigin/building_groups
and then that goes to the remote repository. Similarly, if you do agit fetch building_groups
, the file that is retrieved is placed in yourorigin/building_groups
branch. You can then choose to merge this branch into your local copy. Our practice is to always do agit fetch
and a manual merge rather than just agit pull
(which does both of the above in one step).Fetching new branches.
Getting new branches: At the initial point of a clone you will have all the branches. However, if other developers add branches and push them to the remote there needs to be a way to 'know' about those branches and their names in order to be able to pull them down locally. This is done via a
git fetch
which will get all new and changed branches into the locally repository using the tracking branches (e.g.,origin/
). Oncefetch
ed, one cangit branch --remote
to list the tracking branches andgit checkout [branch]
to actually switch to any given one.Merging
Merging is the process of combining code changes from different branches, or from different versions of the same branch (for example when a local branch and remote are out of sync). If one has developed work in a branch and the work is complete, ready and tested, then it can be merged into the
master
branch. This is done bygit checkout master
to switch to themaster
branch, thengit merge your_branch
. The merge will bring all the different files and even different changes to the same files together. This means that it will actually change the code inside files to merge all the changes.When doing the
checkout
ofmaster
it's also recommended to do agit pull origin master
to get the very latest version of the remote master merged into your local master. If the remote master changed, i.e.,moved forward
, you will see information that reflects that during thatgit pull
. If that is the case (master changed) you are advised togit checkout your_branch
and thenrebase
it to master so that your changes actually get 'replayed' on top of the 'new' master. Then you would continue with getting master up-to-date as shown in the next paragraph.If there are no conflicts, then master will have the new changes added in. If there are conflicts, this means that the same files have changes around similar lines of code that it cannot automatically merge. In this case
git merge new_branch
will report that there's conflict(s) to resolve. You 'resolve' them by editing the files (which will have both changes in them), selecting the changes you want, literally deleting the lines of the changes you don't want and then saving the file. The changes are marked with separators such as========
and<<<<<<<<
.Once you have resolved any conflicts you will once again
git add
andgit commit
those changes to continue the merge (you'll get feedback from git during this process to guide you).When the process doesn't work well you will find that
git merge --abort
is very handy to reset things.Interactive rebasing and squashing / reordering / removing commits
If you have done work in a lot of small steps, e.g., you commit code as 'work-in-progress' every day, you may want to 'squash' those many small commits into a few larger commits. This can be particularly useful when you want to do code reviews with colleagues. You don't want to replay all the 'steps' you took (via commits), you want to just say here is the end effect (diff) of all of my changes for this work in one commit.
The key factor to evaluate when considering whether to do this is whether the multiple commits are against the same file or files more than one (better to squash commits in that case). This is done with the interactive rebasing tool. This tool lets you squash commits, delete commits, reword messages, etc. For example,
git rebase -i HEAD~10
(note: that's a~
, not a-
) brings up the following:Be careful though and use this tool 'gingerly'. Do one squash/delete/reorder at a time, exit and save that commit, then reenter the tool. If commits are not contiguous you can reorder them (and then squash as needed). You can actually delete commits here too, but you really need to be sure of what you are doing when you do that!
Forks
There are two main approaches to collaboration in Git repositories. The first, detailed above, is directly via branches that people pull and push from/to. These collaborators have their SSH keys registered with the remote repository. This will let them push directly to that repository. The downside is that you have to maintain the list of users.
The other approach - forking - allows anybody to 'fork' the repository, basically making a local copy in their own Git repository account. They can then make changes and when finished send a 'pull request' (really it's more of a 'push' from them and a 'pull' request for the actual repository maintainer) to get the code accepted.
This second method, using forks, does not require someone to maintain a list of users for the repository.
GitHub
GitHub (a remote repository) is a remote source that you normally push and pull those committed changes to if you have (or are added to) such a repository, so local and remote are actually quite distinct. Another way to think of a remote repository is that it is a
.git
directory structure that lives on a remote server.When you 'fork' - in the GitHub web browser GUI you can click on this button - you create a copy ('clone') of the code in your GitHub account. It can be a little subtle first time you do it, so keep making sure you look at whose repository a code base is listed under - either the original owner or 'forked from' and you, e.g., like this:
Once you have the local copy, you can make changes as you wish (by pulling and pushing them to a local machine). When you are done then you submit a 'pull request' to the original repository owner/admin (sounds fancy but actually you just click on this: ) and they 'pull' it in.
More common for a team working on code together is to 'clone' the repository (click on the 'copy' icon on the repository's main screen). Then, locally type
git clone
and paste. This will set you up locally and you can also push and pull to the (shared) GitHub location.Clones
As indicated in the section on GitHub, a clone is a copy of a repository. When you have a remote repository you issue the
git clone
command against its URL and you then end up with a local copy, or clone, of the repository. This clone has everything, the files, the master branch, the other branches, all the existing commits, the whole shebang. It is this clone that you do your adds and commits against and then the remote repository itself is what you push those commits to. It's this local/remote concept that makes Git (and systems similar to it such as Mercurial) a DVCS (Distributed Version Control System) as opposed to the more traditional CVSs (Code Versioning Systems) such as SVN, PVCS, CVS, etc. where you commit directly to the remote repository.Visualization
Visualization of the core concepts can be seen at
http://marklodato.github.com/visual-git-guide/index-en.html and
http://ndpsoftware.com/git-cheatsheet.html#loc=index
If you want a visual display of how the changes are working, you can't beat the visual tool
gitg
(gitx
for macOS) with a GUI that I call 'the subway map' (esp. London Underground), great for showing who did what, how things changes, diverged and merged, etc.You can also use it to add, commit and manage your changes!
Although gitg/gitx is fairly minimal, the number of GUI tools continues to expand. Many Mac users use brotherbard's fork of gitx and for Linux, a great option is smart-git with an intuitive yet powerful interface:
Note that even with a GUI tool, you will probably do a lot of commands at the command line.
For this, I have the following aliases in my
~/.bash_aliases
file (which is called from my~/.bashrc
file for each terminal session):AND I have the following "git aliases" in my
~/.gitconfig
file - why have these ?So that branch completion (with the TAB key) works !
So these are:
Example usage:
git co [branch]
<- tab completion for branches will work.GUI Learning Tool
You may find https://learngitbranching.js.org/ useful in learning some of the base concepts. Screen shot:
Video: https://youtu.be/23JqqcLPss0
Finally, 7 key lifesavers!
You make changes, add and commit them (but don't push) and then oh! you realize you are in master!
You mess up some files while working in a local branch and simply want to go back to what you had the last time you did a
git pull
:You start making changes locally, you edit half a dozen files and then, oh crap, you're still in the master (or another) branch:
You mess up one particular file in your current branch and want to basically 'reset' that file (lose changes) to how it was the the last time you pulled it from the remote repository:
This actually resets the file (like many Git commands it is not well named for what it is doing here).
You make some changes locally, you want to make sure you don't lose them while you do a
git reset
orrebase
: I often make a manual copy of the entire project (cp -r ../my_project ~/
) when I am not sure if I might mess up in Git or lose important changes.You are rebasing but things gets messed up:
Add your Git branch to your
PS1
prompt (see https://unix.stackexchange.com/a/127800/10043), e.g.The branch is
selenium_rspec_conversion
.克隆只是存储库的副本。从表面上看,它的结果相当于 svn checkout,您可以在其中从其他存储库下载源代码。像 Subversion 这样的集中式 VCS 和像 Git 这样的 DVCS 之间的区别在于,在 Git 中,当您克隆时,您实际上是在复制整个源存储库,包括所有历史记录和分支。现在,您的计算机上有一个新的存储库,您所做的任何提交都会进入该存储库。除非您将这些提交推送到另一个存储库(或原始存储库),或者直到有人从您的存储库中提取提交(如果可以公开访问),否则没有人会看到任何更改。
分支是存储库中的东西。从概念上讲,它代表了开发的线程。您通常有一个 master 分支,但也可能有一个分支用于处理某些功能 xyz,另一个分支用于修复 bug abc。当您签出一个分支时,您所做的任何提交都将保留在该分支上,并且不会与其他分支共享,直到您将它们合并或重新设置到相关分支上。当然,在您查看分支实现方式的底层模型之前,Git 在涉及分支时似乎有点奇怪。我不会自己解释(我想我已经说得太多了),而是链接到 Git 如何建模分支和提交的“计算机科学”解释,取自 Git 网站:
http://eagain.net/articles/git-for-computer-scientists/
分叉不是Git 概念实际上,它更多的是一个政治/社会想法。也就是说,如果有些人对项目的进展方式不满意,他们可以获取源代码并独立于原始开发人员进行处理。那将被视为一个叉子。 Git 使分叉变得容易,因为每个人都已经拥有自己的源代码“主”副本,因此就像切断与原始项目开发人员的联系一样简单,并且不需要像使用 SVN 那样从共享存储库导出历史记录。
编辑:由于我不知道 GitHub 等网站使用的“fork”的现代定义,请查看评论以及
A clone is simply a copy of a repository. On the surface, its result is equivalent to
svn checkout
, where you download source code from some other repository. The difference between centralized VCS like Subversion and DVCSs like Git is that in Git, when you clone, you are actually copying the entire source repository, including all the history and branches. You now have a new repository on your machine and any commits you make go into that repository. Nobody will see any changes until you push those commits to another repository (or the original one) or until someone pulls commits from your repository, if it is publicly accessible.A branch is something that is within a repository. Conceptually, it represents a thread of development. You usually have a master branch, but you may also have a branch where you are working on some feature xyz, and another one to fix bug abc. When you have checked out a branch, any commits you make will stay on that branch and not be shared with other branches until you merge them with or rebase them onto the branch in question. Of course, Git seems a little weird when it comes to branches until you look at the underlying model of how branches are implemented. Rather than explain it myself (I've already said too much, methinks), I'll link to the "computer science" explanation of how Git models branches and commits, taken from the Git website:
http://eagain.net/articles/git-for-computer-scientists/
A fork isn't a Git concept really, it's more a political/social idea. That is, if some people aren't happy with the way a project is going, they can take the source code and work on it themselves separate from the original developers. That would be considered a fork. Git makes forking easy because everyone already has their own "master" copy of the source code, so it's as simple as cutting ties with the original project developers and doesn't require exporting history from a shared repository like you might have to do with SVN.
EDIT: since I was not aware of the modern definition of "fork" as used by sites such as GitHub, please take a look at the comments and also Michael Durrant's answer below mine for more information.
这是 Oliver Steele 的图像,展示了它们如何组合在一起:
Here is Oliver Steele's image of how it all fits together:
叉子与叉子的对比克隆 - 两个词都表示复制
请参阅此图表。 < sup>(最初来自 http://www.dataschool.io/content/ images/2014/Mar/github1.png).
Fork
您可以通过单击拉取请求克隆
Fork Vs. Clone - two words that both mean copy
Please see this diagram. (Originally from http://www.dataschool.io/content/images/2014/Mar/github1.png).
Fork
Clone
只是为了向其他人添加一个专门针对分叉的注释。
很高兴认识到从技术上讲,克隆存储库和分叉存储库是同一件事。做:
你可以拍拍自己的背——你刚刚分叉了一些其他的仓库。
Git 作为一个 VCS,实际上就是关于
克隆分叉。除了使用远程 UI(例如 cgit)“只是浏览”之外,与 git 存储库没有什么关系,不涉及在某些时候forking克隆存储库。然而,
当有人说我分叉了 repo X 时,他们的意思是他们已经创建了
其他地方的存储库克隆,旨在将其公开
其他,例如展示一些实验,或应用不同的
访问控制机制(例如允许没有 Github 访问权限但
与公司内部帐户进行协作)。
事实:该存储库很可能是使用其他命令创建的
git clone
,它很可能托管在服务器上的某个位置与某人的笔记本电脑相反,并且很可能略有不同
格式(它是一个“裸存储库”,即没有工作树)都只是
技术细节。
事实上,它很可能包含不同的分支集,
标签或提交很可能是他们第一次这样做的原因
地点。
(当你点击“fork”时,Github 所做的只是克隆并添加了
Sugar:它为您克隆存储库,将其放在您的帐户下,记录
从某处“分叉”,添加名为“上游”的远程,并且大多数
重要的是,播放漂亮的动画。)
当有人说我克隆了存储库 X 时,他们的意思是他们已经创建了
有意在笔记本电脑或台式机上本地克隆存储库
研究它、使用它、为它做出贡献或从源代码构建一些东西
代码。
Git 的美妙之处在于它使这一切完美地结合在一起:所有这些存储库共享
block提交链的公共部分,因此可以安全地(参见下面的注释)在所有这些存储库之间来回合并更改您认为合适的回购协议。注意:“安全”,只要您不重写链的公共部分,并且只要更改不冲突。
Just to add to others, a note specific to forking.
It's good to realize that technically, cloning the repo and forking the repo are the same thing. Do:
and you can tap yourself on the back---you have just forked some other repo.
Git, as a VCS, is in fact all about
cloningforking. Apart from "just browsing" using remote UI such as cgit, there is very little to do with git repo that does not involveforkingcloning the repo at some point.However,
when someone says I forked repo X, they mean that they have created
a clone of the repo somewhere else with intention to expose it to
others, for example to show some experiments, or to apply different
access control mechanism (eg. to allow people without Github access but
with company internal account to collaborate).
Facts that: the repo is most probably created with other command than
git clone
, that it's most probably hosted somewhere on a server asopposed to somebody's laptop, and most probably has slightly different
format (it's a "bare repo", ie. without working tree) are all just
technical details.
The fact that it will most probably contain different set of branches,
tags or commits is most probably the reason why they did it in the first
place.
(What Github does when you click "fork", is just cloning with added
sugar: it clones the repo for you, puts it under your account, records
the "forked from" somewhere, adds remote named "upstream", and most
importantly, plays the nice animation.)
When someone says I cloned repo X, they mean that they have created
a clone of the repo locally on their laptop or desktop with intention
study it, play with it, contribute to it, or build something from source
code in it.
The beauty of Git is that it makes this all perfectly fit together: all these repos share the common part of
blockcommit chain so it's possible to safely (see note below) merge changes back and forth between all these repos as you see fit.Note: "safely" as long as you don't rewrite the common part of the chain, and as long as the changes are not conflicting.