git branch、fork、fetch、merge、rebase 和 clone 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3329943/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 08:49:00  来源:igfitidea点击:

What are the differences between git branch, fork, fetch, merge, rebase and clone?

gitbranchclonegit-clonegitx

提问by Hymaniekazil

I want to understand the difference between a branch, a fork and a clone in Git?

我想了解 Git 中分支、分叉和克隆之间的区别?

Similarly, what does it mean when I do a git fetchas opposed to a git pull?

同样,当我做 agit fetch而不是 a时,这意味着什么git pull

Also, what does rebasemean in comparison to merge?

另外,rebase与 相比是什么意思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?

GitHub 是如何出现的?

采纳答案by siride

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.

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

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:

分支是存储库中的东西。从概念上讲,它代表了一条发展线索。您通常有一个 master 分支,但您也可能有一个分支,您正在其中处理某些功能 xyz,以及另一个修复错误 abc 的分支。当您签出一个分支时,您所做的任何提交都将保留在该分支上,并且不会与其他分支共享,直到您将它们与相关分支合并或将它们重新绑定到相关分支上。当然,当涉及到分支时,Git 似乎有点奇怪,直到您查看分支实现方式的底层模型。我不会自己解释它(我已经说了太多,我想),我将链接到 Git 网站上关于 Git 如何建模分支和提交的“计算机科学”解释:

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

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.

分叉实际上并不是 Git 概念,它更像是一种/社会理念。也就是说,如果有些人对项目的进展方式不满意,他们可以获取源代码并独立于原始开发人员自行处理。那将被视为分叉。Git 使分叉变得容易,因为每个人都已经拥有自己的源代码“主”副本,因此就像切断与原始项目开发人员的联系一样简单,并且不需要像使用 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 answerbelow mine for more information.

编辑:由于我不知道 GitHub 等网站使用的“fork”的现代定义,请查看评论以及Michael Durrant在我下面的回答以获取更多信息。

回答by Michael Durrant

Git

吉特

This answer includes GitHub as many folks have asked about that too.

这个答案包括 GitHub,因为很多人也问过这个问题。

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(本地)有一个目录 ( .git),您将文件提交到该目录,这是您的“本地存储库”。这与像 SVN 这样的系统不同,在这种系统中您可以立即添加并提交到远程存储库。

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 存储通过保存整个文件而更改的文件的每个版本。它在这方面也与 SVN 不同,因为您可以转到任何单个版本,而无需通过增量更改“重新创建”它。

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.

Git 根本不“锁定”文件,因此避免了编辑的“独占锁定”功能(想到 pvcs 等旧系统),因此所有文件始终可以被编辑,即使在离线时也是如此。在拉取或提取/推送到远程存储库(例如 GitHub)期间,它实际上在将文件更改(在同一文件中!)合并在一起方面做得非常出色。唯一需要手动更改(实际上是编辑文件)的情况是两个更改涉及同一行代码。



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.

分支允许您保留主代码(“主”分支),制作副本(新分支),然后在该新分支中工作。如果工作需要一段时间或 master 在分支创建后获得了大量更新,则应该对 master 分支进行合并或重新定位(通常首选以获得更好的历史记录和更容易解决冲突)。完成后,将分支中所做的更改合并回主存储库。许多组织为每项工作都使用分支,无论是功能、错误还是杂项。其他组织仅将分支用于版本升级等重大更改。

Fork: With a branch you control and manage the branch, whereas with a fork someone else controls accepting the code back in.

Fork:使用分支,您可以控制和管理分支,而使用 fork,其他人控制接受重新输入的代码。

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.

从广义上讲,有两种主要的方法来做分支。第一个是将大部分更改保留在 master 分支上,仅将分支用于更大和更长时间运行的事情,例如版本更改,其中您希望有两个分支可用于不同的需求。第二种是基本上为每个功能请求、错误修复或杂项创建一个分支,然后手动决定何时将这些分支实际合并到主主分支中。虽然这听起来很乏味,但这是一种常见的方法,也是我目前使用和推荐的方法,因为这可以使 master 分支保持清洁,并且它是我们将其提升到生产环境的 master,因此我们只想要完整的、经过测试的代码,通过 rebase 和分支的合并。

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.

将分支“引入”到 master 的标准方法是执行merge. 分支也可以“重新定位”以“清理”历史记录。它不会影响当前状态,并且是为了提供“更干净”的历史记录。

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).

基本上,这个想法是你从某个点(通常来自主人)分支。自从你分支以来,'master' 本身就从那个分支点向前移动了。如果您在一个分支中所做的所有更改都与 master 的当前状态及其所有最新更改进行对比,它将“更清晰”(更容易解决问题,历史将更容易理解)。所以,过程是:保存更改;获取“新”主控,然后针对该主控再次重新应用(这是变基部分)更改。请注意,rebase 与合并一样,可能会导致您必须手动解决(即编辑和修复)的冲突。

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.

需要注意的一条准则:
仅当分支在本地并且您尚未将其推送到远程时才重新设置基准
这主要是因为 rebase 可以改变其他人看到的历史,其中可能包括他们自己的提交。

Tracking branches

跟踪分支

These are the branches that are named origin/branch_name(as opposed to just branch_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 you git pusha branch called building_groups, your branch goes first to origin/building_groupsand then that goes to the remote repository. Similarly, if you do a git fetch building_groups, the file that is retrieved is placed in your origin/building_groupsbranch. You can then choose to merge this branch into your local copy. Our practice is to always do a git fetchand a manual merge rather than just a git pull(which does both of the above in one step).

这些是命名的分支origin/branch_name(而不是仅仅branch_name)。当您向/从远程存储库推送和拉取代码时,这实际上是发生这种情况的机制。例如,当您git push有一个名为building_groups的分支时,您的分支将首先origin/building_groups转到远程存储库,然后再转到远程存储库。同样,如果您执行 a git fetch building_groups,则检索到的文件将放置在您的origin/building_groups分支中。然后您可以选择将此分支合并到您的本地副本中。我们的做法是始终进行 agit fetch和手动合并,而不仅仅是 a git pull(在一个步骤中完成上述两项操作)。

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 fetchwhich will get all new and changed branches into the locally repository using the tracking branches (e.g., origin/). Once fetched, one can git branch --remoteto list the tracking branches and git checkout [branch]to actually switch to any given one.

获取新分支:在克隆的初始点,您将拥有所有分支。但是,如果其他开发人员添加分支并将它们推送到远程,则需要有一种方法来“了解”这些分支及其名称,以便能够在本地将它们拉下来。这是通过 a 完成的git fetch,它将使用跟踪分支(例如,origin/)将所有新的和更改的分支放入本地存储库。一旦fetchED,人们可以git branch --remote列出跟踪分行和git checkout [branch]实际切换到任何给定的一个。

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 masterbranch. This is done by git checkout masterto switch to the masterbranch, then git merge your_branch. The merge will bring all the different files and even different changes to the same filestogether. This means that it will actually change the code inside files to merge all the changes.

合并是合并来自不同分支或来自同一分支的不同版本的代码更改的过程(例如,当本地分支和远程分支不同步时)。如果在一个分支中开发了工作,并且工作完成、准备就绪并经过测试,则可以将其合并到master分支中。这是通过git checkout master切换到master分支来完成的,然后git merge your_branch。合并会将所有不同的文件甚至对相同文件的不同更改放在一起。这意味着它实际上会更改文件内的代码以合并所有更改。

When doing the checkoutof masterit's also recommended to do a git pull origin masterto 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 that git pull. If that is the case (master changed) you are advised to git checkout your_branchand then rebaseit 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.

在执行此操作checkoutmaster,还建议执行 agit pull origin master将最新版本的远程主服务器合并到您的本地主服务器中。如果远程主服务器发生更改,即,moved forward您将看到反映该更改期间的信息git pull。如果是这样的话(主变),建议您git checkout your_branch,然后rebase它来掌握,这样的更改实际得到的“新”高手“的顶部重播”。然后,您将继续更新 master,如下一段所示。

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_branchwill 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 <<<<<<<<.

如果没有冲突,那么 master 将添加新的更改。如果有冲突,这意味着相同的文件在类似的代码行周围有更改,无法自动合并。在这种情况下,git merge new_branch将报告存在需要解决的冲突。您可以通过编辑文件(其中包含两个更改)、选择您想要的更改、从字面上删除您不想要的更改行然后保存文件来“解决”它们。更改标有分隔符,例如========<<<<<<<<

Once you have resolved any conflicts you will once again git addand git committhose changes to continue the merge (you'll get feedback from git during this process to guide you).

一旦您解决了任何冲突,您将再次git addgit commit这些更改继续合并(在此过程中您将获得来自 git 的反馈以指导您)。

When the process doesn't work well you will find that git merge --abortis very handy to reset things.

当这个过程不能很好地工作时,你会发现git merge --abort重置东西非常方便。

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 once (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:

在考虑是否这样做时,评估的关键因素是多次提交是否针对同一个文件或多个文件(在这种情况下最好压缩提交)。这是通过交互式变基工具完成的。这个工具可以让你压缩提交、删除提交、改写消息等。 例如,git rebase -i HEAD~10注意:那是 a ~,而不是 a-)提出以下内容:

interactive rebasing in Git

Git 中的交互式变基

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.

在 Git 存储库中有两种主要的协作方法。第一个,上面详述的,是直接通过人们从/向拉和推的分支。这些协作者将他们的 SSH 密钥注册到远程存储库。这将让他们直接推送到该存储库。缺点是您必须维护用户列表。另一种方法 - 分叉 - 允许任何人“分叉”存储库,基本上是在他们自己的 Git 存储库帐户中制作本地副本。然后他们可以进行更改,并在完成后发送“拉取请求”(实际上更像是来自他们的“推送”和对实际存储库维护者的“拉取”请求)以使代码被接受。

This second method, using forks, does notrequire someone to maintain a list of users for the repository.

第二种方法,使用叉子,并没有需要专人维护用户存储库的列表。



GitHub

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 .gitdirectory structure that lives on a remote server.

GitHub(远程存储库)是一个远程源,如果您拥有(或添加到)这样的存储库,您通常会将这些提交的更改推送和拉取到其中,因此本地和远程实际上是截然不同的。另一种理解远程存储库的方式是,它是一种.git位于远程服务器上的目录结构。

When you 'fork' - in the GitHub web browser GUI you can click on this button Image of fork button- you create a copy ('clone') of the code in yourGitHub 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:

当您“分叉”时 - 在 GitHub 网络浏览器 GUI 中,您可以单击此按钮叉形按钮的图像- 您会在您的GitHub 帐户中创建代码的副本(“克隆”)。第一次这样做可能会有点微妙,因此请务必查看代码库列在谁的存储库下 - 原始所有者或“分叉自”和您,例如,像这样:

Image of name of forked repository

分叉存储库名称的图像

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: Image of pull request button) 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 cloneand paste. This will set you up locally and you can also push and pull to the (shared) GitHub location.

对于一起处理代码的团队来说,更常见的是“克隆”存储库(单击存储库主屏幕上的“复制”图标)。然后,在本地键入git clone并粘贴。这将在本地设置您,您还可以推拉到(共享)GitHub 位置。

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 clonecommand 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 (DistributedVersion 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.

如 GitHub 上的部分所述,克隆是存储库的副本。当您拥有远程存储库时,您可以git clone针对其 URL发出命令,然后您最终会获得该存储库的本地副本或克隆。这个克隆拥有一切,文件,主分支,其他分支,所有现有的提交,整个shebang。您对这个克隆进行添加和提交,然后远程存储库本身就是您将这些提交推送到的地方。正是这种本地/远程概念使 Git(以及与其类似的系统,例如 Mercurial)成为 DVCS(分布式版本控制系统),而不是更传统的 CVS(代码版本控制系统),例如 SVN、PVCS、CVS 等。您直接提交到远程存储库。

Visualization

可视化

Visualization of the core concepts can be seen at
http://marklodato.github.com/visual-git-guide/index-en.htmland
http://ndpsoftware.com/git-cheatsheet.html#loc=index

核心概念的可视化可以在
http://marklodato.github.com/visual-git-guide/index-en.htmlhttp://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(gitxfor 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.

如果您想直观地显示更改的工作方式,您无法通过我称之为“地铁地图”(特别是伦敦地铁)的 GUI击败可视化工具gitggitx适用于 macOS),非常适合显示谁做了什么,事物如何变化、分歧和合并等。

You can also use it to add, commit and manage your changes!

您还可以使用它来添加、提交和管理您的更改!

Image of gitg/gitx interface

gitg/gitx 界面图片

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:

尽管 gitg/gitx 相当少,但 GUI 工具的数量还在不断增加。许多 Mac 用户使用兄弟的 gitx 分支,对于 Linux,一个很好的选择是 smart-git,它具有直观但功能强大的界面:

Image of smart-git GUI

smart-git GUI 的图像

Note that even with a GUI tool, you will probably do a lot of commands at the command line.

请注意,即使使用 GUI 工具,您也可能会在命令行执行大量命令。

For this, I have the following aliases in my ~/.bash_aliasesfile (which is called from my ~/.bashrcfile for each terminal session):

为此,我的~/.bash_aliases文件中有以下别名(从我的~/.bashrc文件中为每个终端会话调用):

# git
alias g='git status'
alias gcob='git checkout -b '
alias gcom='git checkout master'
alias gd='git diff'
alias gf='git fetch'
alias gfrm='git fetch; git reset --hard origin/master'
alias gg='git grep '
alias gits='alias | grep "^alias g.*git.*$"'
alias gl='git log'
alias gl1='git log --oneline'
alias glf='git log --name-status'
alias glp='git log -p'
alias gpull='git pull '
alias gpush='git push '

AND I have the following "git aliases" in my ~/.gitconfigfile - why have these ?
So that branch completion (with the TAB key) works !

而且我的~/.gitconfig文件中有以下“git别名” ——为什么会有这些?
这样分支完成(使用 TAB 键)就可以了!

So these are:

所以这些是:

[alias]
  co = checkout
  cob = checkout -b

Example usage: git co [branch]<- tab completion for branches will work.

示例用法:git co [branch]<- 分支的选项卡完成将起作用。

GUI Learning Tool

图形用户界面学习工具

You may find https://learngitbranching.js.org/useful in learning some of the base concepts. Screen shot: enter image description here
Video: https://youtu.be/23JqqcLPss0

您可能会发现https://learngitbranching.js.org/在学习一些基本概念时很有用。屏幕截图: 视频:https: //youtu.be/23JqqcLPss0enter image description here

Finally, 7 key lifesavers!

最后,7个关键的救命稻草!

  1. You make changes, add and commit them (but don't push) and then oh! you realize you are in master!

    git reset [filename(s)]
    git checkout -b [name_for_a_new_branch]
    git add [file(s)]
    git commit -m "A useful message"
    
    Voila!  You've moved that 'master' commit to its own branch !
    
  2. 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:

    git reset --hard origin/master  # You will need to be comfortable doing this!
    
  3. You start making changes locally, you edit half a dozen files and then, oh crap, you're still in the master (or another) branch:

    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
    
  4. 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:

    git checkout your/directories/filename
    

    This actually resets the file (like many Git commands it is not well named for what it is doing here).

  5. You make some changes locally, you want to make sure you don't lose them while you do a git resetor rebase: 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.

  6. You are rebasing but things gets messed up:

    git rebase --abort # To abandon interactive rebase and merge issues
    
  7. Add your Git branch to your PS1prompt (see https://unix.stackexchange.com/a/127800/10043), e.g.

    Image of prompt

    The branch is selenium_rspec_conversion.

  1. 您进行更改,添加并提交它们(但不要推送)然后哦!你意识到你是大师!

    git reset [filename(s)]
    git checkout -b [name_for_a_new_branch]
    git add [file(s)]
    git commit -m "A useful message"
    
    Voila!  You've moved that 'master' commit to its own branch !
    
  2. 您在本地分支工作时弄乱了一些文件,只想回到上次执行以下操作时的状态git pull

    git reset --hard origin/master  # You will need to be comfortable doing this!
    
  3. 您开始在本地进行更改,编辑六个文件,然后,糟糕,您仍然在 master(或另一个)分支中:

    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
    
  4. 您弄乱了当前分支中的一个特定文件,并希望基本上“重置”该文件(丢失更改)到上次从远程存储库中提取它时的状态:

    git checkout your/directories/filename
    

    这实际上会重置文件(就像许多 Git 命令一样,它在这里所做的事情并没有很好地命名)。

  5. 你做出一些改变局部,你要确保,而你做你不会失去他们git resetrebase:我常常使整个项目的手动副本(cp -r ../my_project ~/)时,我不知道如果我可能搞砸了Git中或丢失重要变化。

  6. 你正在变基,但事情变得一团糟:

    git rebase --abort # To abandon interactive rebase and merge issues
    
  7. 将您的 Git 分支添加到您的PS1提示中(请参阅https://unix.stackexchange.com/a/127800/10043),例如

    Image of prompt

    分支是selenium_rspec_conversion

回答by Contango

Here is Oliver Steele's image of how it all fits together:

这是奥利弗斯蒂尔关于如何组合在一起的图像:

enter image description here

enter image description here

回答by Timothy L.J. Stewart

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).

请看这张图。(最初来自http://www.dataschool.io/content/images/2014/Mar/github1.png)。

.-------------------------.     1. Fork     .-------------------------.
| Your GitHub repo        | <-------------- | Joe's GitHub repo       |
| github.com/you/coolgame |                 | github.com/joe/coolgame |
| ----------------------- | 7. Pull Request | ----------------------- |
| master -> c224ff7       | --------------> | master -> c224ff7 (c)   |
| anidea -> 884faa1 (a)   |                 | anidea -> 884faa1 (b)   |
'-------------------------'                 '-------------------------'
    |                 ^
    | 2. Clone        |
    |                 |
    |                 |
    |                 |
    |                 |
    |                 | 6. Push (anidea => origin/anidea)
    v                 |
.-------------------------.
| Your computer           |  3. Create branch 'anidea'
| $HOME/coolgame          |
| ----------------------- |  4. Update a file
| master -> c224ff7       |
| anidea -> 884faa1       |  5. Commit (to 'anidea')
'-------------------------'

(a) - after you have pushed it
(b) - after Joe has accepted it
(c) - eventually Joe might merge 'anidea' (make 'master -> 884faa1')

Fork

叉子

  • A copy to your remote repo (cloud) that links it to Joe's
  • A copy you can then clone to your local repo and F*%$-up
  • When you are done you can push back to your remote
  • You can then ask Joe if he wants to use it in his project by clicking pull-request
  • 将其链接到 Joe 的远程存储库(云)的副本
  • 然后你可以克隆到本地仓库和 F*%$-up 的副本
  • 完成后,您可以推回遥控器
  • 然后,您可以通过单击 pull-request 询问 Joe 是否想在他的项目中使用它

Clone

克隆

  • a copy to your local repo (harddrive)
  • 复制到您的本地存储库(硬盘驱动器)

回答by Alois Mahdal

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:

很好地意识到,从技术上讲,克隆回购和分叉回购是一回事。做:

git clone $some_other_repo

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 involve forkingcloning the repo at some point.

Git,作为一个 VCS,实际上就是克隆分叉。除了使用远程用户界面(例如 cgit)“只是浏览”之外,与 git repo 几乎没有什么关系,不涉及在某些时候分叉克隆 repo。

However,

然而,

  • when someone says I forked repo X, they mean that they have created a clone of the repo somewhere else with intention to exposeit 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 as opposed 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.

  • 当有人说我分叉了 repo X 时,他们的意思是他们在其他地方创建了一个 repo 的克隆,意图公开给其他人,例如展示一些实验,或应用不同的访问控制机制(例如,允许人们没有Github 访问但与公司内部帐户协作)。

    事实是:repo 很可能是用其他命令创建的,而不是 git clone,它很可能托管在服务器上的某个地方,而不是某人的笔记本电脑上,并且很可能格式略有不同(它是一个“裸仓库”,即没有工作树)都只是技术细节。

    事实上,它很可能包含不同的分支、标签或提交集,这很可能是他们首先这样做的原因。

    (当您单击“fork”时,Github 所做的只是添加糖进行克隆:它为您克隆 repo,将其放在您的帐户下,记录“fork from”某处,添加名为“upstream”的远程,最重要的是,播放漂亮的动画。)

  • 当有人说我克隆了 repo X 时,他们的意思是他们已经在他们的笔记本电脑或台式机上本地创建了一个 repo 的克隆,目的是研究它、玩它、贡献它,或者从其中的源代码构建一些东西。

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.

Git 的美妙之处在于它使这一切完美地结合在一起:所有这些存储库共享提交链的公共部分,因此可以安全地(参见下面的注释)在所有这些存储库之间来回合并更改,因为您认为合适。



Note:"safely" as long as you don't rewrite the common part of the chain, and as long as the changes are not conflicting.

注意:“安全”只要您不重写链的公共部分,并且只要更改不冲突。