git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/7] link.c, link.h: introduce fifth object type

From
Ramkumar Ramachandra <artagnon@gmail.com>
Date
Apr 4, 2013, 18:30 UTC
Message-ID
<1365100243-13676-2-git-send-email-artagnon@gmail.com>
In-Reply-To
<1365100243-13676-1-git-send-email-artagnon@gmail.com>

Submodules suffer from one major design flaw: they are represented as commit objects in the tree. There are several problems with this:

1. Since the object is actually part of the submodule's object
   store (you can't even cat-file the commit), the superproject knows
   very little about the submodule.  We currently work around this by
   having an ugly .gitmodules file in the toplevel directory mapping
   upstream URLs to submodule paths.
2. We are restricted to having a concrete SHA-1 to convey what the
   subproject's HEAD should point to.  As a result, it is impossible
   to have true floating submodules.
3. It is impossible to initialize a nested submodule without
   initializing the containing submodule first.  This is a consequence
   of our .gitmodules hack, and we should really fix it.
4. Always stat'ing all subproject worktrees can be problematic if
   there are very large subprojects; we should be able to turn it off
   for some submodules selectively.  A good future direction would be
   to add more submodule-specific properties, instead of assuming that
   all submodules are equal.  Stuffing more properties into
   .gitmodules is really not a solution.
5. Finally, the git-submodule shell script has lots of horrible warts
   (like cd-to-toplevel for any operation) that are non-trivial to
   fix, and introduces a very unnatural layer of abstraction.

There are various specialized tools like mr, repo, gitslave, and git-subtree, which offer different compositions solving some problems while introducing limitations of their own.

We propose to fix the problem for good. More specifically, introduce a new object type corresponding to mode 16000 (gitlink). This new object will convey all the required information about the individual submodules to the superproject. Rework git core to get rid of .gitmodules and git-submodule altogether.

This patch doesn't do anything by itself: although it is possible to create link objects using 'git hash-object -t link', parse_link_buffer() is unimplemented. In future patches, we intend to flesh out how core git will handle this object.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
 Makefile |  2 ++
 alloc.c  |  3 +++
 cache.h  |  3 ++-
 link.c   | 27 +++++++++++++++++++++++++++
 link.h   | 26 ++++++++++++++++++++++++++
 object.c |  9 +++++++++
 6 files changed, 69 insertions(+), 1 deletion(-)
 create mode 100644 link.c
 create mode 100644 link.h
diff --git a/Makefile b/Makefile
index 0f931a2..cd4b6f9 100644
--- a/Makefile
+++ b/Makefile
@@ -673,6 +673,7 @@ LIB_H += help.h
 LIB_H += http.h
 LIB_H += kwset.h
 LIB_H += levenshtein.h
+LIB_H += link.h
 LIB_H += list-objects.h
 LIB_H += ll-merge.h
 LIB_H += log-tree.h
@@ -801,6 +802,7 @@ LIB_OBJS += hex.o
 LIB_OBJS += ident.o
 LIB_OBJS += kwset.o
 LIB_OBJS += levenshtein.o
+LIB_OBJS += link.o
 LIB_OBJS += list-objects.o
 LIB_OBJS += ll-merge.o
 LIB_OBJS += lockfile.o
diff --git a/alloc.c b/alloc.c
index aeae55c..1445879 100644
--- a/alloc.c
+++ b/alloc.c
@@ -15,6 +15,7 @@
 #include "tree.h"
 #include "commit.h"
 #include "tag.h"
+#include "link.h"
 
 #define BLOCKING 1024
 
@@ -49,6 +50,7 @@ DEFINE_ALLOCATOR(blob, struct blob)
 DEFINE_ALLOCATOR(tree, struct tree)
 DEFINE_ALLOCATOR(commit, struct commit)
 DEFINE_ALLOCATOR(tag, struct tag)
+DEFINE_ALLOCATOR(link, struct link)
 DEFINE_ALLOCATOR(object, union any_object)
 
 static void report(const char *name, unsigned int count, size_t size)
@@ -66,4 +68,5 @@ void alloc_report(void)
 	REPORT(tree);
 	REPORT(commit);
 	REPORT(tag);
+	REPORT(link);
 }
diff --git a/cache.h b/cache.h
index ec2fd7a..ca0583f 100644
--- a/cache.h
+++ b/cache.h
@@ -317,7 +317,7 @@ enum object_type {
 	OBJ_TREE = 2,
 	OBJ_BLOB = 3,
 	OBJ_TAG = 4,
-	/* 5 for future expansion */
+	OBJ_LINK = 5,
 	OBJ_OFS_DELTA = 6,
 	OBJ_REF_DELTA = 7,
 	OBJ_ANY,
@@ -1241,6 +1241,7 @@ extern void *alloc_blob_node(void);
 extern void *alloc_tree_node(void);
 extern void *alloc_commit_node(void);
 extern void *alloc_tag_node(void);
+extern void *alloc_link_node(void);
 extern void *alloc_object_node(void);
 extern void alloc_report(void);
 
diff --git a/link.c b/link.c
new file mode 100644
index 0000000..bb20a51
--- /dev/null
+++ b/link.c
@@ -0,0 +1,27 @@
+#include "cache.h"
+#include "link.h"
+
+const char *link_type = "link";
+
+struct link *lookup_link(const unsigned char *sha1)
+{
+	struct object *obj = lookup_object(sha1);
+	if (!obj)
+		return create_object(sha1, OBJ_LINK, alloc_link_node());
+	if (!obj->type)
+		obj->type = OBJ_LINK;
+	if (obj->type != OBJ_LINK) {
+		error("Object %s is a %s, not a link",
+		      sha1_to_hex(sha1), typename(obj->type));
+		return NULL;
+	}
+	return (struct link *) obj;
+}
+
+int parse_link_buffer(struct link *item, void *buffer, unsigned long size)
+{
+	if (item->object.parsed)
+		return 0;
+	item->object.parsed = 1;
+	return 0;
+}
diff --git a/link.h b/link.h
new file mode 100644
index 0000000..64dd19d
--- /dev/null
+++ b/link.h
@@ -0,0 +1,26 @@
+#ifndef LINK_H
+#define LINK_H
+
+#include "object.h"
+
+extern const char *link_type;
+
+struct link {
+	struct object object;
+	const char *upstream_url;
+	const char *checkout_rev;
+	const char *ref_name;
+	unsigned int floating:1;
+	unsigned int statthrough:1;
+};
+
+struct link *lookup_link(const unsigned char *sha1);
+
+int parse_link_buffer(struct link *item, void *buffer, unsigned long size);
+
+/**
+ * Links do not contain references to other objects, but have
+ * structured data that needs parsing.
+ **/
+
+#endif /* LINK_H */
diff --git a/object.c b/object.c
index 20703f5..d3674ea 100644
--- a/object.c
+++ b/object.c
@@ -4,6 +4,7 @@
 #include "tree.h"
 #include "commit.h"
 #include "tag.h"
+#include "link.h"
 
 static struct object **obj_hash;
 static int nr_objs, obj_hash_size;
@@ -24,6 +25,7 @@ static const char *object_type_strings[] = {
 	"tree",		/* OBJ_TREE = 2 */
 	"blob",		/* OBJ_BLOB = 3 */
 	"tag",		/* OBJ_TAG = 4 */
+	"link",		/* OBJ_LINK = 5 */
 };
 
 const char *typename(unsigned int type)
@@ -175,6 +177,13 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
 			       return NULL;
 			obj = &tag->object;
 		}
+	} else if (type == OBJ_LINK) {
+		struct link *link = lookup_link(sha1);
+		if (link) {
+			if (parse_link_buffer(link, buffer, size))
+			       return NULL;
+			obj = &link->object;
+		}
 	} else {
 		warning("object %s has unknown type id %d", sha1_to_hex(sha1), type);
 		obj = NULL;
-- 
1.8.2.380.g0d4e79b
Previous: Ramkumar RamachandraNext: Ramkumar Ramachandra
Message 2 of 138 in “Rework git core for native submodules”
  1. 0/7 Rework git core for native submodulesRamkumar Ramachandra, Apr 4, 2013
  2. 1/7 link.c, link.h: introduce fifth object typeRamkumar Ramachandra, Apr 4, 2013
  3. 2/7 sha1_file, link: write link objects to the databaseRamkumar Ramachandra, Apr 4, 2013
  4. Ramkumar RamachandraApr 5, 2013
  5. Ramkumar RamachandraApr 5, 2013
  6. 3/7 teach ce_compare_gitlink() about OBJ_LINKRamkumar Ramachandra, Apr 4, 2013
  7. 4/7 builtin/log: teach show about OBJ_LINKRamkumar Ramachandra, Apr 4, 2013
  8. 5/7 edit-link: add new builtinRamkumar Ramachandra, Apr 4, 2013
  9. 6/7 clone: introduce clone.submodulegitdirRamkumar Ramachandra, Apr 4, 2013
  10. Ramkumar RamachandraApr 5, 2013
  11. 7/7 sha1_file: write ref_name to link objectRamkumar Ramachandra, Apr 4, 2013
  12. Ramkumar RamachandraApr 5, 2013
  13. Linus TorvaldsApr 4, 2013
  14. Ramkumar RamachandraApr 4, 2013
  15. Linus TorvaldsApr 4, 2013
  16. Junio C HamanoApr 4, 2013
  17. Ramkumar RamachandraApr 4, 2013
  18. Jens LehmannApr 4, 2013
  19. Ramkumar RamachandraApr 4, 2013
  20. Linus TorvaldsApr 4, 2013
  21. Ramkumar RamachandraApr 4, 2013
  22. Ramkumar RamachandraApr 4, 2013
  23. Ramkumar RamachandraApr 4, 2013
  24. Ramkumar RamachandraApr 4, 2013
  25. Jens LehmannApr 4, 2013
  26. Ramkumar RamachandraApr 4, 2013
  27. Junio C HamanoApr 4, 2013
  28. Ramkumar RamachandraApr 4, 2013
  29. Junio C HamanoApr 4, 2013
  30. Ramkumar RamachandraApr 4, 2013
  31. Junio C HamanoApr 4, 2013
  32. Ramkumar RamachandraApr 4, 2013
  33. Junio C HamanoApr 5, 2013
  34. Ramkumar RamachandraApr 5, 2013
  35. Ramkumar RamachandraApr 5, 2013
  36. Jonathan NiederApr 4, 2013
  37. Jonathan NiederApr 4, 2013
  38. Jonathan NiederApr 4, 2013
  39. Duy NguyenApr 8, 2013
  40. t3700 (add): add failing test for add with submodulesRamkumar Ramachandra, Apr 8, 2013
  41. Duy NguyenApr 8, 2013
  42. Junio C HamanoApr 8, 2013
  43. Jeff KingApr 8, 2013
  44. Junio C HamanoApr 8, 2013
  45. Jeff KingApr 8, 2013
  46. Ramkumar RamachandraApr 9, 2013
  47. 0/2 Fix git add with submodulesRamkumar Ramachandra, Apr 9, 2013
  48. 1/2 t3700 (add): add two tests for testing add with submodulesRamkumar Ramachandra, Apr 9, 2013
  49. 2/2 add: refuse to add paths beyond repository boundariesRamkumar Ramachandra, Apr 9, 2013
  50. Jeff KingApr 9, 2013
  51. Junio C HamanoApr 9, 2013
  52. Junio C HamanoApr 9, 2013
  53. Ramkumar RamachandraApr 9, 2013
  54. Junio C HamanoApr 9, 2013
  55. Ramkumar RamachandraApr 9, 2013
  56. Junio C HamanoApr 9, 2013
  57. Junio C HamanoApr 9, 2013
  58. Junio C HamanoApr 9, 2013
  59. Ramkumar RamachandraApr 10, 2013
  60. Junio C HamanoApr 10, 2013
  61. Junio C HamanoApr 9, 2013
  62. Ramkumar RamachandraApr 9, 2013
  63. Junio C HamanoApr 9, 2013
  64. Ramkumar RamachandraApr 10, 2013
  65. Jakub NarębskiApr 9, 2013
  66. Junio C HamanoApr 9, 2013
  67. Jakub NarębskiApr 9, 2013
  68. Junio C HamanoApr 9, 2013
  69. Jeff KingApr 9, 2013
  70. Jakub NarębskiApr 9, 2013
  71. Ramkumar RamachandraApr 9, 2013
  72. Jakub NarębskiApr 9, 2013
  73. Ramkumar RamachandraApr 6, 2013
  74. Junio C HamanoApr 7, 2013
  75. Ramkumar RamachandraApr 7, 2013
  76. Junio C HamanoApr 7, 2013
  77. Ramkumar RamachandraApr 7, 2013
  78. Ramkumar RamachandraApr 7, 2013
  79. John KeepingApr 7, 2013
  80. Ramkumar RamachandraApr 7, 2013
  81. John KeepingApr 7, 2013
  82. Ramkumar RamachandraApr 7, 2013
  83. John KeepingApr 7, 2013
  84. Ramkumar RamachandraApr 7, 2013
  85. John KeepingApr 7, 2013
  86. Jens LehmannApr 7, 2013
  87. Ramkumar RamachandraApr 7, 2013
  88. Jens LehmannApr 7, 2013
  89. Ramkumar RamachandraApr 7, 2013
  90. John KeepingApr 7, 2013
  91. Ramkumar RamachandraApr 7, 2013
  92. Ramkumar RamachandraApr 7, 2013
  93. Jonathan NiederApr 7, 2013
  94. Ramkumar RamachandraApr 7, 2013
  95. Jens LehmannApr 8, 2013
  96. Ramkumar RamachandraApr 8, 2013
  97. Jonathan NiederApr 8, 2013
  98. Ramkumar RamachandraApr 8, 2013
  99. Duy NguyenApr 8, 2013
  100. Ramkumar RamachandraApr 8, 2013
  101. Duy NguyenApr 8, 2013
  102. Ramkumar RamachandraApr 8, 2013
  103. Junio C HamanoApr 8, 2013
  104. Ramkumar RamachandraApr 8, 2013
  105. Junio C HamanoApr 8, 2013
  106. Ramkumar RamachandraApr 8, 2013
  107. Junio C HamanoApr 8, 2013
  108. Ramkumar RamachandraApr 8, 2013
  109. Junio C HamanoApr 8, 2013
  110. Ramkumar RamachandraApr 8, 2013
  111. Philip OakleyApr 10, 2013
  112. Ramkumar RamachandraApr 8, 2013
  113. Jakub NarębskiApr 9, 2013
  114. Ramkumar RamachandraApr 8, 2013
  115. Jonathan NiederApr 8, 2013
  116. Ramkumar RamachandraApr 8, 2013
  117. Junio C HamanoApr 8, 2013
  118. Junio C HamanoApr 8, 2013
  119. Duy NguyenApr 17, 2013
  120. Ramkumar RamachandraApr 17, 2013
  121. Duy NguyenApr 17, 2013
  122. Ramkumar RamachandraApr 17, 2013
  123. Duy NguyenApr 17, 2013
  124. Ramkumar RamachandraApr 17, 2013
  125. Philip OakleyApr 17, 2013
  126. Ramkumar RamachandraApr 18, 2013
  127. Jens LehmannApr 19, 2013
  128. Junio C HamanoApr 17, 2013
  129. Jens LehmannApr 8, 2013
  130. Jeff KingApr 8, 2013
  131. John KeepingApr 7, 2013
  132. Ramkumar RamachandraApr 7, 2013
  133. Ramkumar RamachandraApr 7, 2013
  134. Ramkumar RamachandraApr 7, 2013
  135. Ramkumar RamachandraApr 7, 2013
  136. Ramkumar RamachandraApr 7, 2013
  137. Ramkumar RamachandraApr 7, 2013
  138. Ramkumar RamachandraApr 8, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.