Git - What is “Refspec”

匆匆过客 提交于 2019-12-03 18:26:32

问题


I've been following this guide on configuring GitLab continuous integration with Jenkins.

As part of the process, it is necessary to set the respec as follows

+refs/heads/*:refs/remotes/origin/* +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*

Why this is necessary is not explained in the post, so I began looking online for an explanation and looked at the official documentation as well as some related stack overflow questions like this one.

In spite of this, I'm still confused -

What exactly is refspec?

And why is the above refspec necessary - what does it do?


回答1:


A refspec tells git how to map references from a remote to the local repo.

The value you listed was +refs/heads/*:refs/remotes/origin/* +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*; so let's break that down.

You have two patterns with a space between them; this just means you're giving multiple rules. (The pro git book refers to this as two refspecs; which is probably technically more correct. However, you just about always have the ability to list multiple refspecs if you need to, so in day to day life it likely makes little difference.)

The first pattern, then, is +refs/heads/*:refs/remotes/origin/* which has three parts:

  1. The + means to apply the rule without failure even if doing so would move a target ref in a non-fast-forward manner. I'll come back to that.
  2. The part before the : (but after the + if there is one) is the "source" pattern. That's refs/heads/*, meaning this rule applies to any remote reference under refs/heads (meaning, branches).
  3. The part after the : is the "destination" pattern. That's refs/remotes/origin/*.

So if the origin has a branch master, represented as refs/heads/master, this will create a remote branch reference origin/master represented as refs/remotes/origin/master. And so on for any branch name (*).

So back to that +... suppose the origin has

A --- B <--(master)

You fetch and, applying that refspec you get

A --- B <--(origin/master)

(If you applied typical tracking rules and did a pull you also have master pointed at B.)

A --- B <--(origin/master)(master)

Now some things happen on the remote. Someone maybe did a reset that erased B, then committed C, then forced a push. So the remote says

A --- C <--(master)

When you fetch, you get

A --- B
 \
  C

and git must decide whether to allow the move of origin/master from B to C. By default it wouldn't allow this because it's not a fast-forward (it would tell you it rejected the pull for that ref), but because the rule starts with + it will accept it.

A --- B <--(master)
 \
  C <--(origin/master)

(A pull will in this case result in a merge commit.)

The second pattern is similar, but for merge-requests refs (which I assume is related to your server's implementation of PR's; I'm not familiar with it).

More about refspecs: https://git-scm.com/book/en/v2/Git-Internals-The-Refspec



来源:https://stackoverflow.com/questions/44333437/git-what-is-refspec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!