2

Meaning, having something like a per repo section [repo_url] that overrides global(not for a specific repo) options.

[core]
    filemode = false
    editor = notepad
[repo "example.com/repo1.git"]
    [core]
        filemode = true
        # editor = notepad
[repo "example.com/repo2.git"]
    [core]
        editor = vim
        # filemode = false

Is possible in git?

Note: I'm making a lot of clones(git clone) of repos which I would specify in such a global config

Hrisip
  • 900
  • 4
  • 13
  • I don't *think* there is a way to do this from your global configuration file, but each repository has its own configuration file (`.git/config`). You can edit that manually, or use the `--local` flag when running `git config`. – chepner May 24 '20 at 12:59
  • 1
    Group repositories in directories and use conditional includes. Examples: https://stackoverflow.com/a/49154229/7976758, https://stackoverflow.com/a/48018125/7976758 – phd May 24 '20 at 15:22
  • @phd, thank you. Didn't know about `includeIf`. That's a pretty random feature! – Hrisip May 24 '20 at 21:04

3 Answers3

4

With Git 2.36 (Q2 2022), you will have another option than relying on a local folder: the conditional inclusion mechanism of configuration files using "[includeIf <condition>]" learns to base its decision on the URL of the remote repository the repository interacts with.

See commit 399b198, commit ed69e11 (18 Jan 2022) by Jonathan Tan (jhowtan).
(Merged by Junio C Hamano -- gitster -- in commit 13ce8f9, 09 Feb 2022)

config: include file if remote URL matches a glob

Signed-off-by: Jonathan Tan
Acked-by: Elijah Newren

This is a feature that supports config file inclusion conditional on whether the repo has a remote with a URL that matches a glob.

Similar to my previous work on remote-suggested hooks, the main motivation is to allow remote repo administrators to provide recommended configs in a way that can be consumed more easily (e.g. through a package installable by a package manager - it could, for example, contain a file to be included conditionally and a post-install script that adds the include directive to the system-wide config file).

In order to do this, Git reruns the config parsing mechanism upon noticing the first URL-conditional include in order to find all remote URLs, and these remote URLs are then used to determine if that first and all subsequent includes are executed.
Remote URLs are not allowed to be configured in any URL-conditionally-included file.

config now includes in its man page:

hasconfig:remote.*.url:

The data that follows this keyword is taken to be a pattern with standard globbing wildcards and two additional ones, **/ and /**, that can match multiple components.
The first time this keyword is seen, the rest of the config files will be scanned for remote URLs (without applying any values).
If there exists at least one remote URL that matches this pattern, the include condition is met.

Files included by this option (directly or indirectly) are not allowed to contain remote URLs.

Note that unlike other includeIf conditions, resolving this condition relies on information that is not yet known at the point of reading the condition.

A typical use case is this option being present as a system-level or global-level config, and the remote URL being in a local-level config; hence the need to scan ahead when resolving this condition.

In order to avoid the chicken-and-egg problem in which potentially-included files can affect whether such files are potentially included, Git breaks the cycle by prohibiting these files from affecting the resolution of these conditions (thus, prohibiting them from declaring remote URLs).

As for the naming of this keyword, it is for forwards compatibility with a naming scheme that supports more variable-based include conditions, but currently Git only supports the exact keyword described above.

config now includes in its man page:

; include only if a remote with the given URL exists (note
; that such a URL may be provided later in a file or in a
; file read after this file is read, as seen in this example)
[includeIf "hasconfig:remote.*.url:https://example.com/**"]
path = foo.inc
[remote "origin"]
url = https://example.com/git
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 3
    For SSH connection you need to use ssh protocol: `git remote set-url origin ssh://git@gitlab.com/your/repo.git` and in your config file `[includeIf "hasconfig:remote.*.url:ssh://git@gitlab.com/**"]` – Kévin Berthommier May 18 '22 at 15:42
  • @KévinBerthommier Good point. That should work too. – VonC May 18 '22 at 16:28
  • 6
    @KévinBerthommier You can avoid having to edit the repo's origin by matching gitlab's default SSH URL format in your config file using `[includeIf "hasconfig:remote.*.url:git@gitlab.com:*/**"]` – nzkeith May 22 '22 at 18:41
1

Solution: includeIf (big thanks to @phd)

global config

[core]
  filemode = false
  editor = notepad
[includeIf "gitdir/i:repo1/"]
  path = path_to_repo1_git_config  
[includeIf "gitdir/i:repo2/"]
  path = path_to_repo2_git_config  

repo1_git_config

[core]
  filemode = true

repo2_git_config

[core]
  editor = vim

That way any repository to which repo1/repo2 is a parent(not immediate) directory will have respective config included. Note the slash at the end of each `includeIf (read docs).

Hrisip
  • 900
  • 4
  • 13
0

local and conditional configs will work for your title question, but there's no condition based on what's in a repo's remote urls. Considering local clones that idea immediately starts looking fragile and confusing.

It might make more sense to have a condition based on whether or not a particular commit exists in a repository, but there's no indication in your question what the motive is here. If you'll explain what situation you're in that prompts this question, it might get more helpful answers.

jthill
  • 55,082
  • 5
  • 77
  • 137
  • The apparent confusion between "repo" and (I had to guess) origin url makes the question far from clear, I chose to address the apparent desire for url-based configs in my answer, for which the answer is ~you can't do that, it would't be a good idea, but you can get close as comments have said~. Which is a pretty good paraphrase of the answer given. So I disagree. – jthill May 25 '20 at 01:36