git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Duy Nguyen <pclouds@gmail.com>
To: Jeremy Bicha <jbicha@ubuntu.com>
Cc: git@vger.kernel.org
Subject: Re: feature request: git-config: Add conditional include for gitbranch
Date: Fri, 9 Mar 2018 08:40:43 +0700	[thread overview]
Message-ID: <20180309014043.GA9506@duynguyen.dek-tpc.internal> (raw)
In-Reply-To: <CAAajCMbFEF+1i8+MOpOfdMgChi0FfdA1CoCjKLjjKMT2m-58KQ@mail.gmail.com>

On Thu, Mar 08, 2018 at 07:23:00PM -0500, Jeremy Bicha wrote:
> Use Case
> ======
> Jeremy is a developer for Debian and Ubuntu. The same repository is
> used for both Debian and Ubuntu packaging but with different branches.
> For commits to the debian/master branch, Jeremy wants to use his
> @debian.org email address. For commits to the ubuntu/master branch,
> Jeremy wants to use his @ubuntu.com email.
> 
> Proposal
> =======
> The includeIf feature of git-config could be extended to offer a
> gitbranch conditional include in addition to the gitdir conditional
> include it already offers.

Interesting. It looks quite simple to do this. My prototype looks like
this.

-- 8< --
Subject: [PATCH] config: support conditional include by matching ref pattern

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/config.txt  | 12 ++++++++++++
 config.c                  | 30 ++++++++++++++++++++++++++++++
 t/t1305-config-include.sh | 26 ++++++++++++++++++++++++++
 3 files changed, 68 insertions(+)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index ce9102cea8..4e8fb6d99c 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -143,6 +143,18 @@ refer to linkgit:gitignore[5] for details. For convenience:
 	This is the same as `gitdir` except that matching is done
 	case-insensitively (e.g. on case-insensitive file sytems)
 
+`ref`::
+	The data that follows the keyword `ref:` is used as a glob
+	pattern that matches against the current branch. `*` in the
+	pattern does not match `/` and `**` matches multiple levels,
+	the same as .gitignore syntax. The branch is a full reference
+	(i.e. with `refs/heads/` prefix). If HEAD is detached, the
+	pattern will be matched against the value "HEAD".
+
+`ref/i`::
+	This is the same as `ref` except that matching is done
+	case-insensitively
+
 A few more notes on matching via `gitdir` and `gitdir/i`:
 
  * Symlinks in `$GIT_DIR` are not resolved before matching.
diff --git a/config.c b/config.c
index b0c20e6cb8..72ff2da667 100644
--- a/config.c
+++ b/config.c
@@ -16,6 +16,7 @@
 #include "string-list.h"
 #include "utf8.h"
 #include "dir.h"
+#include "refs.h"
 
 struct config_source {
 	struct config_source *prev;
@@ -202,6 +203,31 @@ static int prepare_include_condition_pattern(struct strbuf *pat)
 	return prefix;
 }
 
+static int include_by_ref(const struct config_options *opts,
+			  const char *cond, size_t cond_len, int icase)
+{
+	struct strbuf pattern = STRBUF_INIT;
+	char *branch;
+	unsigned flags = WM_PATHNAME;
+	int ret;
+
+	if (!opts->git_dir)
+		return 0;
+
+	branch = resolve_refdup("HEAD", 0, NULL, NULL);
+	if (!branch)
+		return 0;
+
+	if (icase)
+		flags |= WM_CASEFOLD;
+	strbuf_add(&pattern,  cond, cond_len);
+	ret = !wildmatch(pattern.buf, branch, flags);
+
+	free(branch);
+	strbuf_release(&pattern);
+	return ret;
+}
+
 static int include_by_gitdir(const struct config_options *opts,
 			     const char *cond, size_t cond_len, int icase)
 {
@@ -268,6 +294,10 @@ static int include_condition_is_true(const struct config_options *opts,
 		return include_by_gitdir(opts, cond, cond_len, 0);
 	else if (skip_prefix_mem(cond, cond_len, "gitdir/i:", &cond, &cond_len))
 		return include_by_gitdir(opts, cond, cond_len, 1);
+	else if (skip_prefix_mem(cond, cond_len, "ref:", &cond, &cond_len))
+		return include_by_ref(opts, cond, cond_len, 0);
+	else if (skip_prefix_mem(cond, cond_len, "ref/i:", &cond, &cond_len))
+		return include_by_ref(opts, cond, cond_len, 1);
 
 	/* unknown conditionals are always false */
 	return 0;
diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh
index d9d2f545a4..27ecfc74b7 100755
--- a/t/t1305-config-include.sh
+++ b/t/t1305-config-include.sh
@@ -296,6 +296,32 @@ test_expect_success SYMLINKS 'conditional include, gitdir matching symlink, icas
 	)
 '
 
+test_expect_success 'conditional include by refs' '
+	git init inc-by-ref &&
+	(
+		check() {
+			echo "ref: $1" >.git/HEAD &&
+			echo "[includeIf \"ref:$2\"]path=bar8" >.git/config &&
+			git config test.var >actual &&
+			test_cmp expect actual
+		}
+		cd inc-by-ref &&
+		echo "[test]var=matched" >.git/bar8 &&
+		echo matched >expect &&
+
+		check refs/heads/foo refs/heads/foo &&
+		check refs/heads/foo "refs/heads/*" &&
+		check refs/heads/foo "refs/heads/f*" &&
+		check refs/heads/deep/in/foo "refs/heads/**/foo" &&
+
+		test_commit one &&
+		git checkout --detach &&
+		echo "[includeIf \"ref:HEAD\"]path=bar8" >.git/config &&
+		git config test.var >actual &&
+		test_cmp expect actual
+	)
+'
+
 test_expect_success 'include cycles are detected' '
 	cat >.gitconfig <<-\EOF &&
 	[test]value = gitconfig
-- 
2.16.2.903.gd04caf5039

-- 8< --

      reply	other threads:[~2018-03-09  1:40 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-09  0:23 feature request: git-config: Add conditional include for gitbranch Jeremy Bicha
2018-03-09  1:40 ` Duy Nguyen [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180309014043.GA9506@duynguyen.dek-tpc.internal \
    --to=pclouds@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=jbicha@ubuntu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).