我如何获得两个具有相同 url 的遥控器(一个带有 fetch 和一个推送)



我最近一直在尝试了解有关 git 的更多信息。我想知道遥控器是什么,我找到了答案,很简单,然后我跑了git remote -v,有两个具有相同的 url,但一个后跟(获取),另一个(拉)。所以

origin http://someurl_git/application (fetch)
origin http://someurl_git/application (push)

我只是想知道它是如何进入那种状态的?从我在另一个线程中读到的内容来看,有两个相同的 url 是不正常的。我想试着追溯一下,弄清楚它是如何变成这样的。以及这可能会导致什么问题。

然后我跑了:

git remote show origin

它列出了这个:

* remote origin 
Fetch: origin http://someurl_git/application
Push: origin http://someurl_git/application 
HEAD branch: master
Remote branches: 
BranchA tracked
develop tracked
BranchB tracked
Local branches configured for 'git pull': 
develop merges with remote develop
master  merges with remote master
Local refs configured for 'git push':
develop pushes to develop (local out of date)
master  pushes to master  (up to date)

我的问题是:

  1. 为什么上面有一个具有相同网址的获取和推送?

  2. ">
  3. 引用"和"分支"之间的相关性是什么? ref 是否仅表示我的推送将影响的远程分支?而本地上下文中的分支仅意味着..."拉动会影响当地分支机构" ?

  4. "(
  5. 本地过时)"和("最新")是什么意思?这是否意味着我的本地存储库中未反映在远程存储库中的任何更改?但是为什么它说"最新"的推动掌握?我认为它也会说同样的"远程/本地过时"。

我觉得我缺少一些术语,但如果没关系,我只是想避免任何问题,因为现在有更多的开发人员参与其中。

谢谢

1. 为什么上面有一个 Fetch 和一个 Push 具有相同的 url?

因为在某些设置中,可能需要从一个源拉取,但推送到另一个源。如果不是这种情况(默认情况下),则两者都具有相同的URL。这确实很正常。


2.a "refs"和"branches"之间有什么相关性?ref 是否仅表示我的推送将影响的远程分支?而本地上下文中的分支仅意味着..."拉动会影响当地分支机构" ?

引用是指向提交的指针。有两种类型的引用:分支和标签。

<小时 />

3."(本地过时)"和("最新")是什么意思?这是否意味着我的本地存储库中未反映在远程存储库中的任何更改?但是为什么它说"最新"的推动掌握?我认为它也会说同样的"远程/本地过时"。

"(本地过期)"表示远程分支具有本地分支仍然不知道的新提交,而"(最新)"表示两者都指向同一提交。

Romain Valeri的回答直接涵盖了你的三个问题,但听起来你需要更多的背景信息。

。我想知道遥控器是什么...

我想说它主要是URL的简称。 不过,这掩盖了很多细节。这是一个名字——多久取决于你;使其简短,以便于键入,并且应至少存储一个 URL。 不过,它可以很容易地存储两个URL:一个是"获取"URL,另一个是"推送"URL。 您可以使用git remote set-url或使用git config来设置这些。 每个远程的 URL 都存储在一个唯一的键下。 如果远程数据库命名为origin(通常第一个远程数据库是这样),则此键为:

remote.origin.url

,以及:

remote.origin.pushurl

作为推送网址。 如果未设置推送 URL(如果没有remote.origin.pushurl键),则推送 URL 将自动与抓取 URL相同

配置键位于.git/config$HOME/.gitconfig$HOME/.config/git或类似文件中(配置文件的确切位置取决于系统)。 当我们使用git config命令查询或设置它们时,它们具有这种点分隔形式,对于大多数其他用途,但在配置文件中,它们以修改后的 INI 文件格式存储。 Git 使用的修改格式如下所示:

[remote "origin"]
url = ssh://git@github.com/user/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*

例如。[remote "origin"]节标题下的这对条目定义了remote.origin.urlremote.origin.fetch

有关配置文件的更多信息

Git 中的某些键值对是单值的。 例如,user.nameuser.email设置以这种方式工作。 当你运行git commit进行新提交时,Git 会运行git config --get user.name的内部等效项来获取你的名字。

假设您的全局配置文件显示:

[user]
name = Fred Flintstone
email = fred@rockville.prehistory

但您的本地(Git 存储库中).git/config文件显示:

[user]
name = Barney Rubble

(没有user.email设置)。 运行的结果:

git config --get user.name

Barney Rubble,因为此处设置的本地设置将覆盖全局设置。 运行的结果:

git config --get user.email

fred@rockville.prehistory,因为没有本地设置,因此全局设置是唯一可用的设置。

其他键值对可以是多值的。 在这种情况下,每个设置都是可见的,但使用这些设置的 Git 程序必须运行内部等效项git config --get-all而不是 htangit config --get。 使用上述配置文件,运行:

git config --get-all user.name

会溢出两行:

Fred Flintstone
Barney Rubble

如果不查看每个单独的程序,就无法知道它是使用git config --get还是git config --get-all(或内部等效项)。 因此,如果您多次设置配置项目,您永远不会知道哪些命令可能使用所有设置,哪些命令将仅使用最后一个设置,除非它们在文档中告诉您。 有时你可以通过实验找到答案。 如果没有文档,您也无法判断现在或将来可能会使用哪些设置。 例如,您可以运行:

git config --global french.city paris

马上。Git 中目前没有任何内容使用此设置,因此您添加了:

[french]
city = paris

到您的全局 Git 配置不会影响今天的 Git 程序。 但是,如果某个 Git 程序明年开始使用该设置,那么您已经设置了它,因此它将在 2023 年执行该程序意味着它所做的任何操作。

这些设置是自由格式的事实使得引入拼写错误变得非常容易,并且永远不知道你已经这样做了。 请务必仔细检查设置!

git remote计划

git remote程序与许多 Git 命令一样,相当复杂。 它开始很简单,但随着时间的推移而增长。 它可以:

  • 显示、添加、重命名或删除某些遥控器;
  • 显示或设置遥控器的 URL;
  • 显示或设置遥控器的多值fetch行;
  • git fetch运行到单个遥控器或多个遥控器;
  • "修剪"遥控器(这与git fetch -p相似,但略有不同);
  • 设置或删除任何给定遥控器的"头";或
  • "显示"有关特定遥控器的信息。

这些操作中的大多数都不会调用有问题的远程,即它们不会通过网络联系另一组 Git 软件来查看其他一些 Git 存储库。 此规则的例外情况是:

  • update(fetch),它必须调用远程以查找可能存在的新提交或其他新对象;
  • prune,这有点像获取;
  • set-head--auto选项;和
  • show.

最后一个 -git remote show-可选地调用遥控器。 默认设置是,如果给定远程的名称,它应该这样做;-n标志可防止这种情况。

通过调用远程(git ls-remote也可以这样做;尝试一下;请注意,它可能会产生大量输出,您可能希望通过寻呼机通过管道传输它),git show命令可以找出远程存在哪些分支名称。 这有助于它弄清楚git fetchgit push会做什么,如果你现在运行git fetchgit push

当与-n一起使用时,git show命令实际上无法实现这一点。 这在一定程度上改变了输出,因为它(git remote show)知道它(git remote show)不知道如果使用该远程名称运行,它(git fetchgit push)会做什么。

原子数

但是,我认为没有-ngit remote show存在相当大的问题。 假设您克隆了一个高度活跃的存储库(例如 Git 或 Linux 内核的 Git 存储库)。 你很好奇git fetch origin可能会带来什么,如果你现在运行它,所以你运行:

git remote show origin

你的 Git 在 GitHub 或kernel.org或任何地方调用另一个 Git,与其他软件进行了相当长的对话,最终溢出了一些统计数据。 这需要几秒钟,然后你也会阅读这些相同的统计数据几秒钟——或者你可能在午休后回来阅读它们,或者其他什么。

然后你决定啊,我想要_____(在这里填写一些空白),所以你跑git fetch origin ______...你得到的东西与git show展示给你的东西非常不同,因为在你看你会得到什么和你实际跑git fetch得到东西之间的漫长延迟中,一切都变了

这并不意味着先看的行为一定是的。 例如,它适用于高度不活跃的存储库。 只是不能保证反映未来的现实。 如果你想知道会发生什么,你必须做这件事——不管它是什么——然后看看发生了什么。 在 Git 的情况下,这意味着运行git fetch.

这种事情是我不喜欢git pull的众多原因之一。 使用git pull,您运行git fetch然后不查看发生了什么,您假设您期望发生的事情确实发生了,然后运行第二个 Git 命令,git mergegit rebase。 第二个命令适用于发生的情况。 它不符合您的期望,除非您很幸运并得到了您所期望的。

如果您对要从中获取并<第二个命令>的存储库了解很多,那么这是合理的。 但是如果你知道的不多,而不是使用git show然后git pull,我个人更喜欢运行git fetch然后看看我得到了什么然后才运行第二个命令(或不运行)。 但这确实会因一个 Git 存储库而异(也基于我使用它以来的时间)。

这里的总体思想是原子性。 有些操作,如git fetchgit push,是"原子的":它们不能分解为子操作,至少不能从根本上改变事物。 其他操作,如git pull可以。 实际上,使用git remote showremote是试图低于 Git 实际提供的原子性级别。 所以我避免了这一点,只是运行git fetch,这是 Git 真正原子化的级别。 (另见 https://en.wikipedia.org/wiki/ACID)

最新更新