git@vger.kernel.org mailing list mirror (one of many)
 help / Atom feed
From: Stefan Beller <sbeller@google.com>
To: git@vger.kernel.org
Cc: Stefan Beller <sbeller@google.com>
Subject: [PATCH] RFC: A new type of symbolic refs
Date: Mon, 10 Jul 2017 18:06:39 -0700
Message-ID: <20170711010639.31398-1-sbeller@google.com> (raw)

A symbolic ref can currently only point at (another symbolic) ref.
However are use cases for symbolic refs to point at other things
representing a commit-ish, such as gitlink entries in other
repositories.  In this use case we can use such a symbolic link
to strengthen the relationship between a submodule and a superproject.
Examples:

1) It makes it easier to explain when we recurse into submodules and
   to which sha1 the submodule is updated.

   Currently a submodule (or any repo) is either on a branch (i.e.
   HEAD is a symbolic ref) or is in 'detached HEAD' state (HEAD is
   a direct ref).
   For submodules it is wrong to be on its own branch if it wants to be
   controlled by the superproject as being on its own branch signals that
   the submodule is independent and can move the HEAD freely.
   Being in 'detached HEAD' state is the alternative to that and was
   chosen when git-submodule was implemented, but it is equally wrong;
   the lesser of two evils.

   Semantically the correct way to state a submodule is part of the
   superproject is by pointing its HEAD to the superproject.

   We do have "reset/checkout --recurse-submodules" now, but it is
   hard to explain what actually happens there (Which submodules are
   updated? All of them! -- But I want a subset only!)

   With this new mode of symbolic refs, any submodule that tracks the
   superproject, would 'automatically follow' the superproject as the
   submodules HEAD moves when the superproject changes.

2) "git -C submodule commit" would behave the same as it would on branch
   nowadays: It would make the commit in the submodule and then change
   the target of the symbolic ref which would be the index of the
   superproject! That implies that you do not need to 'git add' the
   submodule to the superproject, but have it done automatically.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 cache.h              |  2 ++
 refs/files-backend.c | 10 ++++++++++
 submodule.c          | 40 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 52 insertions(+)

diff --git a/cache.h b/cache.h
index 71fe092644..4f79d23202 100644
--- a/cache.h
+++ b/cache.h
@@ -2029,4 +2029,6 @@ void sleep_millisec(int millisec);
  */
 void safe_create_dir(const char *dir, int share);
 
+extern int read_external_symref(struct strbuf *from, struct strbuf *out);
+
 #endif /* CACHE_H */
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 0404f2c233..f56f7b87ce 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -713,6 +713,16 @@ static int files_read_raw_ref(struct ref_store *ref_store,
 		goto out;
 	}
 
+	if (starts_with(buf, "repo:")) {
+		if (read_external_symref(&sb_contents, referent)) {
+			*type |= REF_ISBROKEN;
+			ret = -1;
+			goto out;
+		}
+		*type |= REF_ISSYMREF;
+		ret = 0;
+	}
+
 	/*
 	 * Please note that FETCH_HEAD has additional
 	 * data after the sha.
diff --git a/submodule.c b/submodule.c
index da2b484879..7297f90485 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2037,3 +2037,43 @@ int submodule_to_gitdir(struct strbuf *buf, const char *submodule)
 cleanup:
 	return ret;
 }
+
+int read_external_symref(struct strbuf *from, struct strbuf *out)
+{
+	struct child_process cp = CHILD_PROCESS_INIT;
+	const char *repo, *gitlink;
+	int hint, code;
+	struct strbuf **split = strbuf_split(from, 0);
+	struct strbuf cmd_out = STRBUF_INIT;
+
+	if (!split[0] || !split[1])
+		return -1;
+
+	repo = split[0]->buf + 5; /* skip 'repo:' */
+	gitlink = split[1]->buf;
+
+	argv_array_pushl(&cp.args,
+			"ignored-first-arg",
+			"-C", repo,
+			"ls-tree", "-z", "HEAD", "--", gitlink, NULL);
+
+	/*
+	 * 17 accounts for '160000 commit ',
+	 * the \t before path and trailing \0.
+	 */
+	hint = 17 + GIT_SHA1_HEXSZ + split[1]->len;
+	code = capture_command(&cp, &cmd_out, hint);
+
+	strbuf_release(split[0]);
+	strbuf_release(split[1]);
+
+	if (!code) {
+		strbuf_reset(out);
+		strbuf_add(out, cmd_out.buf + strlen("160000 commit "),
+			   GIT_SHA1_HEXSZ);
+	} else
+		return -1;
+
+	return 0;
+}
+
-- 
2.13.2.695.g117ddefdb4


             reply index

Thread overview: 7+ messages in thread (expand / mbox.gz / Atom feed / [top])
2017-07-11  1:06 Stefan Beller [this message]
2017-07-16 13:04 ` Philip Oakley
2017-07-16 14:20   ` Philip Oakley
2017-07-17 19:21   ` Stefan Beller
2017-07-17 21:48 ` Junio C Hamano
2017-07-17 23:22   ` Stefan Beller
2017-07-18 19:03     ` Junio C Hamano

Reply instructions:

You may reply publically 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

  List information: http://vger.kernel.org/majordomo-info.html

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

  git send-email \
    --in-reply-to=20170711010639.31398-1-sbeller@google.com \
    --to=sbeller@google.com \
    --cc=git@vger.kernel.org \
    /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

git@vger.kernel.org mailing list mirror (one of many)

Archives are clonable:
	git clone --mirror https://public-inbox.org/git
	git clone --mirror http://ou63pmih66umazou.onion/git
	git clone --mirror http://czquwvybam4bgbro.onion/git
	git clone --mirror http://hjrcffqmbrq6wope.onion/git

Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.version-control.git
	nntp://ou63pmih66umazou.onion/inbox.comp.version-control.git
	nntp://czquwvybam4bgbro.onion/inbox.comp.version-control.git
	nntp://hjrcffqmbrq6wope.onion/inbox.comp.version-control.git
	nntp://news.gmane.org/gmane.comp.version-control.git

 note: .onion URLs require Tor: https://www.torproject.org/
       or Tor2web: https://www.tor2web.org/

AGPL code for this site: git clone https://public-inbox.org/ public-inbox