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

[PATCH 3/7] Softrefs: Add git-softref, a builtin command for adding, listing and administering softrefs

From
Johan Herland <johan@herland.net>
Date
Jun 9, 2007, 18:22 UTC
Message-ID
<200706092022.46933.johan@herland.net>
In-Reply-To
<200706092019.13185.johan@herland.net>

git-softref is meant to be used from shell scripts that need to interact with the softrefs database. The builtin command provides most of the functionality present in the softrefs C API.

Documentation to follow in a subsequent patch.
Signed-off-by: Johan Herland <johan@herland.net>
---
 builtin-softref.c |  167 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 167 insertions(+), 0 deletions(-)
 create mode 100644 builtin-softref.c
diff --git a/builtin-softref.c b/builtin-softref.c
new file mode 100644
index 0000000..f95db4e
--- /dev/null
+++ b/builtin-softref.c
@@ -0,0 +1,167 @@
+/*
+ * git softref builtin command
+ *
+ * Add, list and administer soft references (softrefs)
+ *
+ * Copyright (c) 2007 Johan Herland
+ */
+
+#include "cache.h"
+#include "tag.h"
+#include "refs.h"
+#include "softrefs.h"
+
+static const char builtin_softref_usage[] =
+	"git-softref [ --list [<from-object>]"
+		" | --has <from-object> <to-object>"
+		" | --add <from-object> <to-object>"
+		" | --rebuild-tags"
+		" | --merge-unsorted [<softrefs-file>]"
+		" | --merge-sorted <softrefs-file> ]";
+
+static int list_helper(
+		const unsigned char *from_sha1,
+		const unsigned char *to_sha1,
+		void *cb_data)
+{
+	printf("%s %s\n", sha1_to_hex(from_sha1), sha1_to_hex(to_sha1));
+	return 0;
+}
+
+int rebuild_tags_helper(
+		const char *refname,
+		const unsigned char *sha1,
+		int flags,
+		void *cb_data)
+{
+	struct object *o = parse_object(sha1);
+	if (o && o->type == OBJ_TAG) {
+		struct tag *t = (struct tag *) o;
+		struct softref_list **prev = (struct softref_list **) cb_data;
+		struct softref_list *current = xmalloc(sizeof(struct softref_list));
+		current->next = *prev;
+		hashcpy(current->from_sha1, t->tagged->sha1);
+		hashcpy(current->to_sha1,   t->object.sha1);
+		*prev = current;
+	}
+	return 0;
+}
+
+int cmd_softref(int argc, const char **argv, const char *prefix)
+{
+	int i;
+	int show_usage = 0, list = 0, has = 0, add = 0, rebuild_tags = 0,
+	    merge_unsorted = 0, merge_sorted = 0;
+	const char *from_name = NULL, *to_name = NULL, *softrefs_file = NULL;
+	unsigned char from_sha1[20], to_sha1[20];
+
+	git_config(git_default_config);
+
+	for (i = 1; i < argc; i++) {
+		const char *arg = argv[i];
+		if (!strcmp(arg, "--list")) {
+			list = 1;
+			if (i + 1 < argc) /* <from-object> given */
+				from_name = argv[++i];
+		}
+		else if (!strcmp(arg, "--has")) {
+			has = 1;
+			if (i + 2 >= argc)
+				show_usage = error("--has needs two arguments: <from-object> and <to-object>");
+			else {
+				from_name = argv[++i];
+				to_name = argv[++i];
+			}
+		}
+		else if (!strcmp(arg, "--add")) {
+			add = 1;
+			if (i + 2 >= argc)
+				show_usage = error("--add needs two arguments: <from-object> and <to-object>");
+			else {
+				from_name = argv[++i];
+				to_name = argv[++i];
+			}
+		}
+		else if (!strcmp(arg, "--rebuild-tags"))
+			rebuild_tags = 1;
+		else if (!strcmp(arg, "--merge-unsorted")) {
+			merge_unsorted = 1;
+			if (i + 1 < argc) /* <softrefs-file> given */
+				softrefs_file = argv[++i];
+		}
+		else if (!strcmp(arg, "--merge-sorted")) {
+			merge_sorted = 1;
+			if (i + 1 >= argc)
+				show_usage = error("--merge-sorted needs one argument: <softrefs-file>");
+			else
+				softrefs_file = argv[++i];
+		}
+		else
+			show_usage = error("Unknown argument '%s'", arg);
+	}
+
+	/* default to --list if no command given; fail if more than one */
+	switch(list + has + add + rebuild_tags + merge_unsorted + merge_sorted) {
+		case 0: list = 1; break;
+		case 1: break;
+		default: show_usage = 1;
+	}
+	if (show_usage)
+		usage(builtin_softref_usage);
+
+	if (list) {
+		if (from_name) { /* show from_name's softrefs */
+			if (get_sha1(from_name, from_sha1))
+				die("Not a valid object name %s", from_name);
+			if (for_each_softref_with_from(from_sha1, list_helper, 0))
+				die("Error encountered while listing softrefs");
+		}
+		else if (for_each_softref(list_helper, 0)) /* show all softrefs */
+			die("Error encountered while listing softrefs");
+	}
+	else if (has) {
+		if (get_sha1(from_name, from_sha1) || !has_sha1_file(from_sha1))
+			die("Not a valid object name %s", from_name);
+		if (get_sha1(to_name, to_sha1) || !has_sha1_file(to_sha1))
+			die("Not a valid object name %s", to_name);
+		return has_softref(from_sha1, to_sha1);
+	}
+	else if (add) {
+		if (get_sha1(from_name, from_sha1) || !has_sha1_file(from_sha1))
+			die("Not a valid object name %s", from_name);
+		if (get_sha1(to_name, to_sha1) || !has_sha1_file(to_sha1))
+			die("Not a valid object name %s", to_name);
+		if (add_softref(from_sha1, to_sha1) < 0)
+			die("Failed to create softref from %s to %s",
+				from_name, to_name);
+	}
+	else if (rebuild_tags) {
+		/*
+		 * Find all tag objects, and add their corresponding softrefs
+		 *
+		 * For now, we'll have to settle for referenced tag objects as
+		 * it seems to be non-trivial to find _all_ the tag objects in
+		 * the db (including unreachables).
+		 */
+		struct softref_list *to_add = NULL;
+		struct softref_list **p = &to_add;
+		int ret;
+		if (for_each_tag_ref(rebuild_tags_helper, (void *) p)) {
+			delete_softref_list(to_add);
+			die("Failed to find tag objects");
+		}
+		ret = add_softrefs(to_add);
+		delete_softref_list(to_add);
+		if (ret < 0)
+			die("Failed to add softrefs for tag objects");
+		printf("Added %i missing softrefs for tag objects.\n", ret);
+	}
+	else if (merge_unsorted) {
+		return merge_unsorted_softrefs(softrefs_file, 1);
+	}
+	else if (merge_sorted) {
+		return merge_sorted_softrefs(softrefs_file);
+	}
+
+	return 0;
+}
-- 
1.5.2.1.144.gabc40
Previous: Johan HerlandNext: Johan Herland
Message 30 of 52 in “Refactoring the tag object; Introducing soft references (softrefs); Git 'notes' (take 2)”
  1. Johan HerlandJun 4, 2007
  2. 0/6 Refactor the tag objectJohan Herland, Jun 4, 2007
  3. 1/6 Refactor git tag objects; make "tag" header optional; introduce new optional "keywords" headerJohan Herland, Jun 4, 2007
  4. Matthias LederhoferJun 4, 2007
  5. Johan HerlandJun 4, 2007
  6. 2/6 git-show: When showing tag objects with no tag name, show tag object's SHA1 instead of an empty stringJohan Herland, Jun 4, 2007
  7. 3/6 git-fsck: Do thorough verification of tag objects.Johan Herland, Jun 4, 2007
  8. Matthias LederhoferJun 4, 2007
  9. Johan HerlandJun 4, 2007
  10. Junio C HamanoJun 6, 2007
  11. 3/6 git-fsck: Do thorough verification of tag objects.Johan Herland, Jun 6, 2007
  12. Junio C HamanoJun 6, 2007
  13. Junio C HamanoJun 6, 2007
  14. Johan HerlandJun 6, 2007
  15. Junio C HamanoJun 6, 2007
  16. 4/6 Documentation/git-mktag: Document the changes in tag object structureJohan Herland, Jun 4, 2007
  17. 5/6 git-mktag tests: Fix and expand the mktag tests according to the new tag object structureJohan Herland, Jun 4, 2007
  18. 6/6 Add fsck_verify_ref_to_tag_object() to verify that refname matches name stored in tag objectJohan Herland, Jun 4, 2007
  19. Junio C HamanoJun 4, 2007
  20. Fix bug in tag parsing when thorough verification was in effectJohan Herland, Jun 7, 2007
  21. 0/7 Introduce soft references (softrefs)Johan Herland, Jun 9, 2007
  22. 1/7 Softrefs: Add softrefs header file with API documentationJohan Herland, Jun 9, 2007
  23. Johannes SchindelinJun 10, 2007
  24. Junio C HamanoJun 10, 2007
  25. Johannes SchindelinJun 10, 2007
  26. Johan HerlandJun 10, 2007
  27. Jakub NarebskiJun 10, 2007
  28. Teach git-gc to merge unsorted softrefsJohan Herland, Jun 10, 2007
  29. 2/7 Softrefs: Add implementation of softrefs APIJohan Herland, Jun 9, 2007
  30. 3/7 Softrefs: Add git-softref, a builtin command for adding, listing and administering softrefsJohan Herland, Jun 9, 2007
  31. 4/7 Softrefs: Add manual page documenting git-softref and softrefs subsystem in generalJohan Herland, Jun 9, 2007
  32. 5/7 Softrefs: Add testcases for basic softrefs behaviourJohan Herland, Jun 9, 2007
  33. 6/7 Softrefs: Administrivia associated with softrefs subsystem and git-softref builtinJohan Herland, Jun 9, 2007
  34. 7/7 Teach git-mktag to register softrefs for all tag objectsJohan Herland, Jun 9, 2007
  35. Change softrefs file format from text (82 bytes per entry) to binary (40 bytes per entry)Johan Herland, Jun 9, 2007
  36. Johannes SchindelinJun 10, 2007
  37. Junio C HamanoJun 10, 2007
  38. Johannes SchindelinJun 10, 2007
  39. Johan HerlandJun 10, 2007
  40. Comment on weak refsJunio C Hamano, Jun 9, 2007
  41. Johan HerlandJun 10, 2007
  42. Johannes SchindelinJun 10, 2007
  43. Johan HerlandJun 10, 2007
  44. Pierre HabouzitJun 10, 2007
  45. Pierre HabouzitJun 10, 2007
  46. Pierre HabouzitJun 10, 2007
  47. Jakub NarebskiJun 10, 2007
  48. Steven GrimmJun 9, 2007
  49. Johan HerlandJun 9, 2007
  50. Pierre HabouzitJun 10, 2007
  51. Johan HerlandJun 10, 2007
  52. Steven GrimmJun 10, 2007

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.