很多时候,Git和Ruby on Rails看起来就像魔法……比如在Ruby on Rails 3教程的第一章中,它谈到了Git:

git remote add origin git@github.com:peter/first_app.git
git push origin master

它只是说“它只是工作”,而没有过多地讨论它们是什么,并开始讨论分支。在网上搜索发现,git remote add是添加一个“短名称”,比如origin,也可以是任何名称,就像URL的别名一样。

origin是远程存储库所指向的通常路径(在http://git-scm.com/book/en/Git-Basics-Working-with-Remotes“添加远程存储库”下)。

为什么URL不是git://git@github.com/peter/first_app.git,而是另一种语法,什么语法?为什么一定要以。git结尾?我试着在结束时不使用.git,它也能工作。如果不是。git,还能是什么?git@github.com中的git似乎是git服务器上的一个用户帐户?

此外,为什么使用git push origin master需要如此冗长?默认不能是原点和master吗?我发现第一次,是需要origin master,但经过一个小的编辑和提交,然后git push是它所需要的(不需要origin master)。有了解情况的人能告诉我们一些细节吗?

有时候感觉就像有很多没有解释的魔法……有时使用它的人太自信了,当被问到为什么时,他们解释不清,只回答说“就是这样”。有时非常实际和务实。实际一点也不错,但可能不实际到不知道发生了什么。


Git就像Unix。它对用户很友好,但它对朋友很挑剔。它就像一个外壳管道一样强大和用户友好。

话虽如此,一旦您理解了它的范例和概念,它就具有我从Unix命令行工具中所期望的相同的禅宗般的清晰度。您应该考虑抽出一些时间来阅读在线上可用的许多优秀Git教程。Pro Git的书是一个很好的开始。

回答你的第一个问题。

What is git remote add ...? As you probably know, Git is a distributed version control system. Most operations are done locally. To communicate with the outside world, Git uses what are called "remotes". These are repositories other than the one on your local disk which you can push your changes into (so that other people can see them) or pull from (so that you can get others changes). The command git remote add origin git@github.com:peter/first_app.git creates a new remote called origin located at git@github.com:peter/first_app.git. Once you do this, in your push commands, you can push to origin instead of typing out the whole URL. What is git push origin master? This is a command that says "push the commits in the local branch named master to the remote named origin". Once this is executed, all the stuff that you last synchronised with origin will be sent to the remote repository and other people will be able to see them there.

Now about transports (i.e., what git://) means. Remote repository URLs can be of many types (file://, https://, etc.). Git simply relies on the authentication mechanism provided by the transport to take care of permissions and stuff. This means that for file:// URLs, it will be Unix file permissions, etc. The git:// scheme is asking Git to use its own internal transport protocol, which is optimised for sending Git changesets around. As for the exact URL, it's the way it is because of the way GitHub has set up its Git server.

现在是冗长。您键入的命令是通用命令。可以这样告诉Git:“master分支是远程bar上foo分支的本地镜像”。在Git中,这意味着master跟踪bar/foo。当您第一次克隆时,您将获得一个名为master的分支和一个名为origin的远程分支(您从哪里克隆的),并使用本地主集跟踪起源上的主集。

设置好后,你只需输入git push,它就会完成。如果你需要的话,可以使用更长的命令(例如,git push可以推送到官方的公共存储库,git push review master可以用于推送到你的团队用来审查代码的单独远程)。你可以使用git branch命令的——set-upstream选项将你的分支设置为跟踪分支。

我觉得Git(不像我使用过的大多数其他应用程序)更容易由内而外地理解。一旦您理解了如何在存储库中存储和维护数据,命令及其功能就变得非常清晰。我同意你的观点,在许多Git用户中有一些精英主义,但我也发现,对于Unix用户来说,曾经有过这样的经历,学习系统是值得的。好运!

The .git at the end of the repository name is just a convention. Typically, on Git servers, repositories are kept in directories named project.git. The Git client and protocol honours this convention by testing for project.git when only project is specified. git://git@github.com/peter/first_app.git is not a valid Git URL. Git repositories can be identified and accessed via various URL schemes specified here. git@github.com:peter/first_app.git is the ssh URL mentioned on that page. Git is flexible. It allows you to track your local branch against almost any branch of any repository. While master (your local default branch) tracking origin/master (the remote default branch) is a popular situation, it is not universal. Many a times you may not want to do that. This is why the first git push is so verbose. It tells Git what to do with the local master branch when you do a git pull or a git push. The default for git push and git pull is to work with the current branch's remote. This is a better default than origin master. The way git push determines this is explained here.

Git是相当优雅和易于理解的,但是有一个学习曲线。

更新:请注意,目前接受的答案延续了对git push行为的常见误解,尽管有评论指出了这一点,但尚未得到纠正。

您对远程的总结是正确的——就像存储库URL的昵称一样。

为什么URL不是git://git@github.com/peter/first_app.git,而是另一种语法,什么语法?为什么一定要以。git结尾?我试着在结束时不使用.git,它也能工作。如果不是。git,还能是什么?初学者的git似乎是git服务器上的一个用户帐户?

The two URLs that you've mentioned indicate that two different transport protocols should be used. The one beginning with git:// is for the Git protocol, which is usually only used for read-only access to repositories. The other one, git@github.com:peter/first_app.git, is one of the different ways of specifying access to a repository over SSH - this is the "scp-style syntax" described in the documentation. That the username in the scp-style syntax is git is because of the way that GitHub deals with identifying users - essentially that username is ignored, and the user is identified based on the SSH key-pair that they used to authenticate.

至于git push origin master的冗长,您已经注意到在第一次推送之后,您可以再执行git push。这是因为一系列难以记住但通常有用的默认值:)

如果未指定远程,则使用为当前分支配置的远程(在您的示例中为remote.master.url)。如果没有设置,则使用origin。 如果没有指定“refspec”(例如master, master:my-experiment等),则Git默认推送与远程分支具有相同名称的每个本地分支。如果在您的存储库和远程存储库之间只有一个名为master的公共分支,那么这就相当于将您的master推到远程master。

就我个人而言,因为我倾向于有许多主题分支(通常是几个远程),我总是使用这种形式:

git push origin master

... 避免不小心推到其他树枝。


回复你对另一个答案的评论,在我看来,你似乎在以自上而下的方式非常有效地学习Git——你已经发现默认值是有效的,你的问题是问为什么;)更重要的是,Git在本质上可以像SVN一样简单地使用,但了解一些远程和分支意味着您可以更灵活地使用它,这确实可以更好地改变您的工作方式。

你对一学期课程的评论让我想起了Scott Chacon在播客采访中所说的——学生们被教授计算机科学和软件工程的各种基本工具,但很少有版本控制。像Git和Mercurial这样的分布式版本控制系统现在是如此的重要,如此的灵活,以至于有必要教授关于它们的课程来给人们一个良好的基础。

我的观点是,使用git,这种学习曲线是绝对值得的——使用大量的主题分支,轻松地合并它们,在不同的存储库之间推拉它们,一旦你对系统有信心,这是非常有用的。不幸的是:

Git的主要文档对于新手来说很难解析。(尽管我认为,如果你谷歌几乎所有的Git问题,有帮助的教程材料(或Stack Overflow的答案:))现在。) Git中有一些奇怪的行为现在很难改变,因为许多脚本可能依赖于它们,但这让人们感到困惑。

Git远程添加原点:

它将你的源代码集中到其他项目中。它是基于Linux开发的, 完全开源,并使您的代码对其他git用户有用。我们称之为参考。

它使用GitHub的远程URL将代码推入Git存储库。

看一下添加远程存储库的语法。

git remote add origin <url_of_remote repository>

例子:

git remote add origin git@github.com:peter/first_app.git

让我们来分析一下这个命令:

git远程,用于管理托管git存储库的中央服务器。

也许你正在使用GitHub作为你的中央存储库。我将给你一个例子,并解释git远程添加origin命令

假设我使用GitHub和Bitbucket作为Git存储库的中央服务器,并在这两个网站上为我的第一个应用程序项目创建了存储库。

现在,如果我想将更改推送到这两个Git服务器上,那么我需要告诉Git如何到达这些中央存储库。所以我要把这些加起来,

对于GitHub

git remote add gh_origin https://github.com/user/first-app-git.git

对于Bitbucket

git remote add bb_origin https://user@bitbucket.org/user/first-app-git.git

我已经使用了两个变量(到目前为止,我很容易称它们为变量)gh_origin (gh GitHub)和bb_origin (bb Bitbucket)只是为了解释你,我们可以调用任何我们想要的起源。

现在,在做了一些更改之后,我将不得不发送(推送)所有这些更改到中央存储库,以便其他用户可以看到这些更改。所以我调用

推送到GitHub

git push gh_origin master

推送到Bitbucket

git push bb_origin master

Gh_origin持有https://github.com/user/first-app-git.git的值,bb_origin持有https://user@bitbucket.org/user/first-app-git.git的值

这两个变量让我的生活更简单

因为每当我需要发送我的代码更改时,我需要使用这个词,而不是记住或键入相同的URL。

大多数情况下,除了origin,你不会看到任何东西,因为大多数情况下你只会处理一个中央存储库,比如GitHub或Bitbucket。

这是这个问题的答案(导出Heroku应用程序到一个新的GitHub回购),它已被标记为这一个的副本,并重定向到这里。

我想把我的存储库从Heroku镜像到GitHub个人,这样它就能显示所有的提交,等等,这也是我在Heroku中做的。使用GitHub文档中的命令行导入Git存储库非常有用。