All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter.
@ 2015-09-23 18:11 Karthik Nayak
  2015-09-23 18:11 ` [PATCH v6 1/8] branch: refactor width computation Karthik Nayak
                   ` (9 more replies)
  0 siblings, 10 replies; 27+ messages in thread
From: Karthik Nayak @ 2015-09-23 18:11 UTC (permalink / raw)
  To: git; +Cc: christian.couder, Matthieu.Moy, gitster, Karthik Nayak

The previous iteration of the same can be found:
http://www.mail-archive.com/git@vger.kernel.org/msg78153.html

Changes in this version:
* use ref_default_sorting()
* Improve documentation, comments and commit message.

Karthik Nayak (8):
  branch: refactor width computation
  branch: bump get_head_description() to the top
  branch: roll show_detached HEAD into regular ref_list
  branch: move 'current' check down to the presentation layer
  branch: drop non-commit error reporting
  branch.c: use 'ref-filter' data structures
  branch.c: use 'ref-filter' APIs
  branch: add '--points-at' option

 Documentation/git-branch.txt |  16 +-
 builtin/branch.c             | 502 +++++++++++++------------------------------
 ref-filter.c                 |   2 +-
 ref-filter.h                 |   6 +-
 t/t1430-bad-ref-name.sh      |  31 ++-
 t/t3203-branch-output.sh     |  20 ++
 6 files changed, 211 insertions(+), 366 deletions(-)

Interdiff:

diff --git a/builtin/branch.c b/builtin/branch.c
index b0a96e1..b7a60f4 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -479,8 +479,6 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
 	struct ref_array array;
 	int maxwidth = 0;
 	const char *remote_prefix = "";
-	struct ref_sorting def_sorting;
-	const char *sort_type = "refname";
 
 	/*
 	 * If we are listing more than just remote branches,
@@ -498,12 +496,15 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
 	if (filter->verbose)
 		maxwidth = calc_maxwidth(&array, strlen(remote_prefix));
 
-	if (!sorting) {
-		def_sorting.next = NULL;
-		def_sorting.atom = parse_ref_filter_atom(sort_type,
-							 sort_type + strlen(sort_type));
-		sorting = &def_sorting;
-	}
+	/*
+	 * If no sorting parameter is given then we default to sorting
+	 * by 'refname'. This would give us an alphabetically sorted
+	 * array with the 'HEAD' ref at the beginning followed by
+	 * local branches 'refs/heads/...' and finally remote-tacking
+	 * branches 'refs/remotes/...'.
+	 */
+	if (!sorting)
+		sorting = ref_default_sorting();
 	ref_array_sort(sorting, &array);

diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 647a9cf..03c7af1 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -237,8 +235,11 @@ start-point is either a local or remote-tracking branch.
 	order of the value. You may use the --sort=<key> option
 	multiple times, in which case the last key becomes the primary
 	key. The keys supported are the same as those in `git
-	for-each-ref`. Sort order defaults to sorting based on branch
-	type.
+	for-each-ref`. Sort order defaults to sorting based on the
+	full refname (including `refs/...` prefix). This lists
+	detached HEAD (if present) first, then local branches and
+	finally remote-tracking branches.
+
 
 --points-at <object>::
 	Only list branches of the given object.

 
-- 
2.5.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v6 1/8] branch: refactor width computation
  2015-09-23 18:11 [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Karthik Nayak
@ 2015-09-23 18:11 ` Karthik Nayak
  2015-09-23 18:11 ` [PATCH v6 2/8] branch: bump get_head_description() to the top Karthik Nayak
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Karthik Nayak @ 2015-09-23 18:11 UTC (permalink / raw)
  To: git; +Cc: christian.couder, Matthieu.Moy, gitster, Karthik Nayak

From: Karthik Nayak <karthik.188@gmail.com>

Remove unnecessary variables from ref_list and ref_item which were
used for width computation. This is to make ref_item similar to
ref-filter's ref_array_item. This will ensure a smooth port of
branch.c to use ref-filter APIs in further patches.

Previously the maxwidth was computed when inserting the refs into the
ref_list. Now, we obtain the entire ref_list and then compute
maxwidth.

Based-on-patch-by: Jeff King <peff@peff.net>
Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 builtin/branch.c | 64 ++++++++++++++++++++++++++++++--------------------------
 1 file changed, 34 insertions(+), 30 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index 4fc8beb..28a10d6 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -282,14 +282,14 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
 struct ref_item {
 	char *name;
 	char *dest;
-	unsigned int kind, width;
+	unsigned int kind;
 	struct commit *commit;
 	int ignore;
 };
 
 struct ref_list {
 	struct rev_info revs;
-	int index, alloc, maxwidth, verbose, abbrev;
+	int index, alloc, verbose, abbrev;
 	struct ref_item *list;
 	struct commit_list *with_commit;
 	int kinds;
@@ -386,15 +386,8 @@ static int append_ref(const char *refname, const struct object_id *oid, int flag
 	newitem->name = xstrdup(refname);
 	newitem->kind = kind;
 	newitem->commit = commit;
-	newitem->width = utf8_strwidth(refname);
 	newitem->dest = resolve_symref(orig_refname, prefix);
 	newitem->ignore = 0;
-	/* adjust for "remotes/" */
-	if (newitem->kind == REF_REMOTE_BRANCH &&
-	    ref_list->kinds != REF_REMOTE_BRANCH)
-		newitem->width += 8;
-	if (newitem->width > ref_list->maxwidth)
-		ref_list->maxwidth = newitem->width;
 
 	return 0;
 }
@@ -505,11 +498,12 @@ static void add_verbose_info(struct strbuf *out, struct ref_item *item,
 }
 
 static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
-			   int abbrev, int current, char *prefix)
+			   int abbrev, int current, const char *remote_prefix)
 {
 	char c;
 	int color;
 	struct strbuf out = STRBUF_INIT, name = STRBUF_INIT;
+	const char *prefix = "";
 
 	if (item->ignore)
 		return;
@@ -520,6 +514,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 		break;
 	case REF_REMOTE_BRANCH:
 		color = BRANCH_COLOR_REMOTE;
+		prefix = remote_prefix;
 		break;
 	default:
 		color = BRANCH_COLOR_PLAIN;
@@ -557,16 +552,22 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 	strbuf_release(&out);
 }
 
-static int calc_maxwidth(struct ref_list *refs)
+static int calc_maxwidth(struct ref_list *refs, int remote_bonus)
 {
-	int i, w = 0;
+	int i, max = 0;
 	for (i = 0; i < refs->index; i++) {
-		if (refs->list[i].ignore)
+		struct ref_item *it = &refs->list[i];
+		int w;
+
+		if (it->ignore)
 			continue;
-		if (refs->list[i].width > w)
-			w = refs->list[i].width;
+		w = utf8_strwidth(it->name);
+		if (it->kind == REF_REMOTE_BRANCH)
+			w += remote_bonus;
+		if (w > max)
+			max = w;
 	}
-	return w;
+	return max;
 }
 
 static char *get_head_description(void)
@@ -600,21 +601,18 @@ static char *get_head_description(void)
 	return strbuf_detach(&desc, NULL);
 }
 
-static void show_detached(struct ref_list *ref_list)
+static void show_detached(struct ref_list *ref_list, int maxwidth)
 {
 	struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1);
 
 	if (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) {
 		struct ref_item item;
 		item.name = get_head_description();
-		item.width = utf8_strwidth(item.name);
 		item.kind = REF_LOCAL_BRANCH;
 		item.dest = NULL;
 		item.commit = head_commit;
 		item.ignore = 0;
-		if (item.width > ref_list->maxwidth)
-			ref_list->maxwidth = item.width;
-		print_ref_item(&item, ref_list->maxwidth, ref_list->verbose, ref_list->abbrev, 1, "");
+		print_ref_item(&item, maxwidth, ref_list->verbose, ref_list->abbrev, 1, "");
 		free(item.name);
 	}
 }
@@ -624,6 +622,16 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
 	int i;
 	struct append_ref_cb cb;
 	struct ref_list ref_list;
+	int maxwidth = 0;
+	const char *remote_prefix = "";
+
+	/*
+	 * If we are listing more than just remote branches,
+	 * then remote branches will have a "remotes/" prefix.
+	 * We need to account for this in the width.
+	 */
+	if (kinds != REF_REMOTE_BRANCH)
+		remote_prefix = "remotes/";
 
 	memset(&ref_list, 0, sizeof(ref_list));
 	ref_list.kinds = kinds;
@@ -667,26 +675,22 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
 			clear_commit_marks(item->commit, ALL_REV_FLAGS);
 		}
 		clear_commit_marks(filter, ALL_REV_FLAGS);
-
-		if (verbose)
-			ref_list.maxwidth = calc_maxwidth(&ref_list);
 	}
+	if (verbose)
+		maxwidth = calc_maxwidth(&ref_list, strlen(remote_prefix));
 
 	qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
 
 	detached = (detached && (kinds & REF_LOCAL_BRANCH));
 	if (detached && match_patterns(pattern, "HEAD"))
-		show_detached(&ref_list);
+		show_detached(&ref_list, maxwidth);
 
 	for (i = 0; i < ref_list.index; i++) {
 		int current = !detached &&
 			(ref_list.list[i].kind == REF_LOCAL_BRANCH) &&
 			!strcmp(ref_list.list[i].name, head);
-		char *prefix = (kinds != REF_REMOTE_BRANCH &&
-				ref_list.list[i].kind == REF_REMOTE_BRANCH)
-				? "remotes/" : "";
-		print_ref_item(&ref_list.list[i], ref_list.maxwidth, verbose,
-			       abbrev, current, prefix);
+		print_ref_item(&ref_list.list[i], maxwidth, verbose,
+			       abbrev, current, remote_prefix);
 	}
 
 	free_ref_list(&ref_list);
-- 
2.5.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v6 2/8] branch: bump get_head_description() to the top
  2015-09-23 18:11 [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Karthik Nayak
  2015-09-23 18:11 ` [PATCH v6 1/8] branch: refactor width computation Karthik Nayak
@ 2015-09-23 18:11 ` Karthik Nayak
  2015-09-23 18:11 ` [PATCH v6 3/8] branch: roll show_detached HEAD into regular ref_list Karthik Nayak
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Karthik Nayak @ 2015-09-23 18:11 UTC (permalink / raw)
  To: git; +Cc: christian.couder, Matthieu.Moy, gitster, Karthik Nayak, Karthik Nayak

This is a preperatory patch for 'roll show_detached HEAD into regular
ref_list'. This patch moves get_head_description() to the top so that
it can be used in print_ref_item().

Based-on-patch-by: Jeff King <peff@peff.net>
Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 builtin/branch.c | 62 ++++++++++++++++++++++++++++----------------------------
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index 28a10d6..193296a 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -497,6 +497,37 @@ static void add_verbose_info(struct strbuf *out, struct ref_item *item,
 	strbuf_release(&subject);
 }
 
+static char *get_head_description(void)
+{
+	struct strbuf desc = STRBUF_INIT;
+	struct wt_status_state state;
+	memset(&state, 0, sizeof(state));
+	wt_status_get_state(&state, 1);
+	if (state.rebase_in_progress ||
+	    state.rebase_interactive_in_progress)
+		strbuf_addf(&desc, _("(no branch, rebasing %s)"),
+			    state.branch);
+	else if (state.bisect_in_progress)
+		strbuf_addf(&desc, _("(no branch, bisect started on %s)"),
+			    state.branch);
+	else if (state.detached_from) {
+		/* TRANSLATORS: make sure these match _("HEAD detached at ")
+		   and _("HEAD detached from ") in wt-status.c */
+		if (state.detached_at)
+			strbuf_addf(&desc, _("(HEAD detached at %s)"),
+				state.detached_from);
+		else
+			strbuf_addf(&desc, _("(HEAD detached from %s)"),
+				state.detached_from);
+	}
+	else
+		strbuf_addstr(&desc, _("(no branch)"));
+	free(state.branch);
+	free(state.onto);
+	free(state.detached_from);
+	return strbuf_detach(&desc, NULL);
+}
+
 static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 			   int abbrev, int current, const char *remote_prefix)
 {
@@ -570,37 +601,6 @@ static int calc_maxwidth(struct ref_list *refs, int remote_bonus)
 	return max;
 }
 
-static char *get_head_description(void)
-{
-	struct strbuf desc = STRBUF_INIT;
-	struct wt_status_state state;
-	memset(&state, 0, sizeof(state));
-	wt_status_get_state(&state, 1);
-	if (state.rebase_in_progress ||
-	    state.rebase_interactive_in_progress)
-		strbuf_addf(&desc, _("(no branch, rebasing %s)"),
-			    state.branch);
-	else if (state.bisect_in_progress)
-		strbuf_addf(&desc, _("(no branch, bisect started on %s)"),
-			    state.branch);
-	else if (state.detached_from) {
-		/* TRANSLATORS: make sure these match _("HEAD detached at ")
-		   and _("HEAD detached from ") in wt-status.c */
-		if (state.detached_at)
-			strbuf_addf(&desc, _("(HEAD detached at %s)"),
-				state.detached_from);
-		else
-			strbuf_addf(&desc, _("(HEAD detached from %s)"),
-				state.detached_from);
-	}
-	else
-		strbuf_addstr(&desc, _("(no branch)"));
-	free(state.branch);
-	free(state.onto);
-	free(state.detached_from);
-	return strbuf_detach(&desc, NULL);
-}
-
 static void show_detached(struct ref_list *ref_list, int maxwidth)
 {
 	struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1);
-- 
2.5.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v6 3/8] branch: roll show_detached HEAD into regular ref_list
  2015-09-23 18:11 [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Karthik Nayak
  2015-09-23 18:11 ` [PATCH v6 1/8] branch: refactor width computation Karthik Nayak
  2015-09-23 18:11 ` [PATCH v6 2/8] branch: bump get_head_description() to the top Karthik Nayak
@ 2015-09-23 18:11 ` Karthik Nayak
  2015-09-23 18:11 ` [PATCH v6 4/8] branch: move 'current' check down to the presentation layer Karthik Nayak
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Karthik Nayak @ 2015-09-23 18:11 UTC (permalink / raw)
  To: git; +Cc: christian.couder, Matthieu.Moy, gitster, Karthik Nayak, Karthik Nayak

Remove show_detached() and make detached HEAD to be rolled into
regular ref_list by adding REF_DETACHED_HEAD as a kind of branch and
supporting the same in append_ref(). This eliminates the need for an
extra function and helps in easier porting of branch.c to use
ref-filter APIs.

Before show_detached() used to check if the HEAD branch satisfies the
'--contains' option, now that is taken care by append_ref().

Based-on-patch-by: Jeff King <peff@peff.net>
Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 builtin/branch.c | 61 ++++++++++++++++++++++++++++++--------------------------
 1 file changed, 33 insertions(+), 28 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index 193296a..a2a35f4 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -28,8 +28,9 @@ static const char * const builtin_branch_usage[] = {
 	NULL
 };
 
-#define REF_LOCAL_BRANCH    0x01
-#define REF_REMOTE_BRANCH   0x02
+#define REF_DETACHED_HEAD   0x01
+#define REF_LOCAL_BRANCH    0x02
+#define REF_REMOTE_BRANCH   0x04
 
 static const char *head;
 static unsigned char head_sha1[20];
@@ -352,8 +353,12 @@ static int append_ref(const char *refname, const struct object_id *oid, int flag
 			break;
 		}
 	}
-	if (ARRAY_SIZE(ref_kind) <= i)
-		return 0;
+	if (ARRAY_SIZE(ref_kind) <= i) {
+		if (!strcmp(refname, "HEAD"))
+			kind = REF_DETACHED_HEAD;
+		else
+			return 0;
+	}
 
 	/* Don't add types the caller doesn't want */
 	if ((kind & ref_list->kinds) == 0)
@@ -535,6 +540,8 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 	int color;
 	struct strbuf out = STRBUF_INIT, name = STRBUF_INIT;
 	const char *prefix = "";
+	const char *desc = item->name;
+	char *to_free = NULL;
 
 	if (item->ignore)
 		return;
@@ -547,6 +554,10 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 		color = BRANCH_COLOR_REMOTE;
 		prefix = remote_prefix;
 		break;
+	case REF_DETACHED_HEAD:
+		color = BRANCH_COLOR_CURRENT;
+		desc = to_free = get_head_description();
+		break;
 	default:
 		color = BRANCH_COLOR_PLAIN;
 		break;
@@ -558,7 +569,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 		color = BRANCH_COLOR_CURRENT;
 	}
 
-	strbuf_addf(&name, "%s%s", prefix, item->name);
+	strbuf_addf(&name, "%s%s", prefix, desc);
 	if (verbose) {
 		int utf8_compensation = strlen(name.buf) - utf8_strwidth(name.buf);
 		strbuf_addf(&out, "%c %s%-*s%s", c, branch_get_color(color),
@@ -581,6 +592,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 	}
 	strbuf_release(&name);
 	strbuf_release(&out);
+	free(to_free);
 }
 
 static int calc_maxwidth(struct ref_list *refs, int remote_bonus)
@@ -601,22 +613,6 @@ static int calc_maxwidth(struct ref_list *refs, int remote_bonus)
 	return max;
 }
 
-static void show_detached(struct ref_list *ref_list, int maxwidth)
-{
-	struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1);
-
-	if (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) {
-		struct ref_item item;
-		item.name = get_head_description();
-		item.kind = REF_LOCAL_BRANCH;
-		item.dest = NULL;
-		item.commit = head_commit;
-		item.ignore = 0;
-		print_ref_item(&item, maxwidth, ref_list->verbose, ref_list->abbrev, 1, "");
-		free(item.name);
-	}
-}
-
 static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char **pattern)
 {
 	int i;
@@ -643,7 +639,14 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
 	cb.ref_list = &ref_list;
 	cb.pattern = pattern;
 	cb.ret = 0;
+	/*
+	 * First we obtain all regular branch refs and if the HEAD is
+	 * detached then we insert that ref to the end of the ref_fist
+	 * so that it can be printed and removed first.
+	 */
 	for_each_rawref(append_ref, &cb);
+	if (detached)
+		head_ref(append_ref, &cb);
 	/*
 	 * The following implementation is currently duplicated in ref-filter. It
 	 * will eventually be removed when we port branch.c to use ref-filter APIs.
@@ -681,14 +684,12 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
 
 	qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
 
-	detached = (detached && (kinds & REF_LOCAL_BRANCH));
-	if (detached && match_patterns(pattern, "HEAD"))
-		show_detached(&ref_list, maxwidth);
-
 	for (i = 0; i < ref_list.index; i++) {
-		int current = !detached &&
-			(ref_list.list[i].kind == REF_LOCAL_BRANCH) &&
+		int current = !detached && (ref_list.list[i].kind == REF_LOCAL_BRANCH) &&
 			!strcmp(ref_list.list[i].name, head);
+		/*  If detached the first ref_item is the current ref */
+		if (detached && i == 0)
+			current = 1;
 		print_ref_item(&ref_list.list[i], maxwidth, verbose,
 			       abbrev, current, remote_prefix);
 	}
@@ -914,7 +915,11 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 			die(_("branch name required"));
 		return delete_branches(argc, argv, delete > 1, kinds, quiet);
 	} else if (list) {
-		int ret = print_ref_list(kinds, detached, verbose, abbrev,
+		int ret;
+		/*  git branch --local also shows HEAD when it is detached */
+		if (kinds & REF_LOCAL_BRANCH)
+			kinds |= REF_DETACHED_HEAD;
+		ret = print_ref_list(kinds, detached, verbose, abbrev,
 					 with_commit, argv);
 		print_columns(&output, colopts, NULL);
 		string_list_clear(&output, 0);
-- 
2.5.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v6 4/8] branch: move 'current' check down to the presentation layer
  2015-09-23 18:11 [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Karthik Nayak
                   ` (2 preceding siblings ...)
  2015-09-23 18:11 ` [PATCH v6 3/8] branch: roll show_detached HEAD into regular ref_list Karthik Nayak
@ 2015-09-23 18:11 ` Karthik Nayak
  2015-09-23 18:11 ` [PATCH v6 5/8] branch: drop non-commit error reporting Karthik Nayak
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Karthik Nayak @ 2015-09-23 18:11 UTC (permalink / raw)
  To: git; +Cc: christian.couder, Matthieu.Moy, gitster, Karthik Nayak, Karthik Nayak

We check if given ref is the current branch in print_ref_list(). Move
this check to print_ref_item() where it is checked right before
printing. This enables a smooth transition to using ref-filter APIs,
as we can later replace the current check while printing to just check
for FILTER_REFS_DETACHED instead.

Based-on-patch-by: Jeff King <peff@peff.net>
Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 builtin/branch.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index a2a35f4..1a664ed 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -534,9 +534,10 @@ static char *get_head_description(void)
 }
 
 static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
-			   int abbrev, int current, const char *remote_prefix)
+			   int abbrev, int detached, const char *remote_prefix)
 {
 	char c;
+	int current = 0;
 	int color;
 	struct strbuf out = STRBUF_INIT, name = STRBUF_INIT;
 	const char *prefix = "";
@@ -548,15 +549,18 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 
 	switch (item->kind) {
 	case REF_LOCAL_BRANCH:
-		color = BRANCH_COLOR_LOCAL;
+		if (!detached && !strcmp(item->name, head))
+			current = 1;
+		else
+			color = BRANCH_COLOR_LOCAL;
 		break;
 	case REF_REMOTE_BRANCH:
 		color = BRANCH_COLOR_REMOTE;
 		prefix = remote_prefix;
 		break;
 	case REF_DETACHED_HEAD:
-		color = BRANCH_COLOR_CURRENT;
 		desc = to_free = get_head_description();
+		current = 1;
 		break;
 	default:
 		color = BRANCH_COLOR_PLAIN;
@@ -684,15 +688,9 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
 
 	qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
 
-	for (i = 0; i < ref_list.index; i++) {
-		int current = !detached && (ref_list.list[i].kind == REF_LOCAL_BRANCH) &&
-			!strcmp(ref_list.list[i].name, head);
-		/*  If detached the first ref_item is the current ref */
-		if (detached && i == 0)
-			current = 1;
+	for (i = 0; i < ref_list.index; i++)
 		print_ref_item(&ref_list.list[i], maxwidth, verbose,
-			       abbrev, current, remote_prefix);
-	}
+			       abbrev, detached, remote_prefix);
 
 	free_ref_list(&ref_list);
 
-- 
2.5.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v6 5/8] branch: drop non-commit error reporting
  2015-09-23 18:11 [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Karthik Nayak
                   ` (3 preceding siblings ...)
  2015-09-23 18:11 ` [PATCH v6 4/8] branch: move 'current' check down to the presentation layer Karthik Nayak
@ 2015-09-23 18:11 ` Karthik Nayak
  2015-09-23 18:57   ` Matthieu Moy
  2015-09-23 19:14   ` Junio C Hamano
  2015-09-23 18:11 ` [PATCH v6 6/8] branch.c: use 'ref-filter' data structures Karthik Nayak
                   ` (4 subsequent siblings)
  9 siblings, 2 replies; 27+ messages in thread
From: Karthik Nayak @ 2015-09-23 18:11 UTC (permalink / raw)
  To: git; +Cc: christian.couder, Matthieu.Moy, gitster, Karthik Nayak, Karthik Nayak

Remove the error reporting variable to make the code easier to port
over to using ref-filter APIs.

This also removes the error from being displayed. As branch.c will use
ref-filter APIs in the following patches, the error checking becomes
redundant with the error reporting system found in the ref-filter
(ref-filter.c:1336).

Based-on-patch-by: Jeff King <peff@peff.net>
Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 builtin/branch.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index 1a664ed..ebc3742 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -313,7 +313,6 @@ static char *resolve_symref(const char *src, const char *prefix)
 struct append_ref_cb {
 	struct ref_list *ref_list;
 	const char **pattern;
-	int ret;
 };
 
 static int match_patterns(const char **pattern, const char *refname)
@@ -370,10 +369,8 @@ static int append_ref(const char *refname, const struct object_id *oid, int flag
 	commit = NULL;
 	if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {
 		commit = lookup_commit_reference_gently(oid->hash, 1);
-		if (!commit) {
-			cb->ret = error(_("branch '%s' does not point at a commit"), refname);
+		if (!commit)
 			return 0;
-		}
 
 		/* Filter with with_commit if specified */
 		if (!is_descendant_of(commit, ref_list->with_commit))
@@ -617,7 +614,7 @@ static int calc_maxwidth(struct ref_list *refs, int remote_bonus)
 	return max;
 }
 
-static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char **pattern)
+static void print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char **pattern)
 {
 	int i;
 	struct append_ref_cb cb;
@@ -642,7 +639,6 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
 		init_revisions(&ref_list.revs, NULL);
 	cb.ref_list = &ref_list;
 	cb.pattern = pattern;
-	cb.ret = 0;
 	/*
 	 * First we obtain all regular branch refs and if the HEAD is
 	 * detached then we insert that ref to the end of the ref_fist
@@ -693,11 +689,6 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
 			       abbrev, detached, remote_prefix);
 
 	free_ref_list(&ref_list);
-
-	if (cb.ret)
-		error(_("some refs could not be read"));
-
-	return cb.ret;
 }
 
 static void rename_branch(const char *oldname, const char *newname, int force)
@@ -913,15 +904,14 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 			die(_("branch name required"));
 		return delete_branches(argc, argv, delete > 1, kinds, quiet);
 	} else if (list) {
-		int ret;
 		/*  git branch --local also shows HEAD when it is detached */
 		if (kinds & REF_LOCAL_BRANCH)
 			kinds |= REF_DETACHED_HEAD;
-		ret = print_ref_list(kinds, detached, verbose, abbrev,
+		print_ref_list(kinds, detached, verbose, abbrev,
 					 with_commit, argv);
 		print_columns(&output, colopts, NULL);
 		string_list_clear(&output, 0);
-		return ret;
+		return 0;
 	}
 	else if (edit_description) {
 		const char *branch_name;
-- 
2.5.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v6 6/8] branch.c: use 'ref-filter' data structures
  2015-09-23 18:11 [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Karthik Nayak
                   ` (4 preceding siblings ...)
  2015-09-23 18:11 ` [PATCH v6 5/8] branch: drop non-commit error reporting Karthik Nayak
@ 2015-09-23 18:11 ` Karthik Nayak
  2015-09-23 18:11 ` [PATCH v6 7/8] branch.c: use 'ref-filter' APIs Karthik Nayak
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Karthik Nayak @ 2015-09-23 18:11 UTC (permalink / raw)
  To: git; +Cc: christian.couder, Matthieu.Moy, gitster, Karthik Nayak, Karthik Nayak

Make 'branch.c' use 'ref-filter' data structures and make changes to
support the new data structures. This is a part of the process of
porting 'branch.c' to use 'ref-filter' APIs.

This is a temporary step before porting 'branch.c' to use 'ref-filter'
completely. As this is a temporary step, most of the code introduced
here will be removed when 'branch.c' is ported over to use
'ref-filter' APIs.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 builtin/branch.c | 317 ++++++++++++++++++++++---------------------------------
 ref-filter.h     |   7 +-
 2 files changed, 134 insertions(+), 190 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index ebc3742..bfbba2f 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -19,6 +19,7 @@
 #include "column.h"
 #include "utf8.h"
 #include "wt-status.h"
+#include "ref-filter.h"
 
 static const char * const builtin_branch_usage[] = {
 	N_("git branch [<options>] [-r | -a] [--merged | --no-merged]"),
@@ -28,10 +29,6 @@ static const char * const builtin_branch_usage[] = {
 	NULL
 };
 
-#define REF_DETACHED_HEAD   0x01
-#define REF_LOCAL_BRANCH    0x02
-#define REF_REMOTE_BRANCH   0x04
-
 static const char *head;
 static unsigned char head_sha1[20];
 
@@ -53,13 +50,6 @@ enum color_branch {
 	BRANCH_COLOR_UPSTREAM = 5
 };
 
-static enum merge_filter {
-	NO_FILTER = 0,
-	SHOW_NOT_MERGED,
-	SHOW_MERGED
-} merge_filter;
-static unsigned char merge_filter_ref[20];
-
 static struct string_list output = STRING_LIST_INIT_DUP;
 static unsigned int colopts;
 
@@ -122,7 +112,7 @@ static int branch_merged(int kind, const char *name,
 	void *reference_name_to_free = NULL;
 	int merged;
 
-	if (kind == REF_LOCAL_BRANCH) {
+	if (kind == FILTER_REFS_BRANCHES) {
 		struct branch *branch = branch_get(name);
 		const char *upstream = branch_get_upstream(branch, NULL);
 		unsigned char sha1[20];
@@ -200,14 +190,14 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
 	struct strbuf bname = STRBUF_INIT;
 
 	switch (kinds) {
-	case REF_REMOTE_BRANCH:
+	case FILTER_REFS_REMOTES:
 		fmt = "refs/remotes/%s";
 		/* For subsequent UI messages */
 		remote_branch = 1;
 
 		force = 1;
 		break;
-	case REF_LOCAL_BRANCH:
+	case FILTER_REFS_BRANCHES:
 		fmt = "refs/heads/%s";
 		break;
 	default:
@@ -224,7 +214,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
 		int flags = 0;
 
 		strbuf_branchname(&bname, argv[i]);
-		if (kinds == REF_LOCAL_BRANCH && !strcmp(head, bname.buf)) {
+		if (kinds == FILTER_REFS_BRANCHES && !strcmp(head, bname.buf)) {
 			error(_("Cannot delete the branch '%s' "
 			      "which you are currently on."), bname.buf);
 			ret = 1;
@@ -280,22 +270,6 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
 	return(ret);
 }
 
-struct ref_item {
-	char *name;
-	char *dest;
-	unsigned int kind;
-	struct commit *commit;
-	int ignore;
-};
-
-struct ref_list {
-	struct rev_info revs;
-	int index, alloc, verbose, abbrev;
-	struct ref_item *list;
-	struct commit_list *with_commit;
-	int kinds;
-};
-
 static char *resolve_symref(const char *src, const char *prefix)
 {
 	unsigned char sha1[20];
@@ -310,11 +284,6 @@ static char *resolve_symref(const char *src, const char *prefix)
 	return xstrdup(dst);
 }
 
-struct append_ref_cb {
-	struct ref_list *ref_list;
-	const char **pattern;
-};
-
 static int match_patterns(const char **pattern, const char *refname)
 {
 	if (!*pattern)
@@ -327,11 +296,29 @@ static int match_patterns(const char **pattern, const char *refname)
 	return 0;
 }
 
+/*
+ * Allocate memory for a new ref_array_item and insert that into the
+ * given ref_array. Doesn't take the objectname unlike
+ * new_ref_array_item(). This is a temporary function which will be
+ * removed when we port branch.c to use ref-filter APIs.
+ */
+static struct ref_array_item *ref_array_append(struct ref_array *array, const char *refname)
+{
+	size_t len = strlen(refname);
+	struct ref_array_item *ref = xcalloc(1, sizeof(struct ref_array_item) + len + 1);
+	memcpy(ref->refname, refname, len);
+	ref->refname[len] = '\0';
+	REALLOC_ARRAY(array->items, array->nr + 1);
+	array->items[array->nr++] = ref;
+	return ref;
+}
+
 static int append_ref(const char *refname, const struct object_id *oid, int flags, void *cb_data)
 {
-	struct append_ref_cb *cb = (struct append_ref_cb *)(cb_data);
-	struct ref_list *ref_list = cb->ref_list;
-	struct ref_item *newitem;
+	struct ref_filter_cbdata *cb = (struct ref_filter_cbdata *)(cb_data);
+	struct ref_filter *filter = cb->filter;
+	struct ref_array *array = cb->array;
+	struct ref_array_item *item;
 	struct commit *commit;
 	int kind, i;
 	const char *prefix, *orig_refname = refname;
@@ -340,8 +327,8 @@ static int append_ref(const char *refname, const struct object_id *oid, int flag
 		int kind;
 		const char *prefix;
 	} ref_kind[] = {
-		{ REF_LOCAL_BRANCH, "refs/heads/" },
-		{ REF_REMOTE_BRANCH, "refs/remotes/" },
+		{ FILTER_REFS_BRANCHES, "refs/heads/" },
+		{ FILTER_REFS_REMOTES, "refs/remotes/" },
 	};
 
 	/* Detect kind */
@@ -354,65 +341,52 @@ static int append_ref(const char *refname, const struct object_id *oid, int flag
 	}
 	if (ARRAY_SIZE(ref_kind) <= i) {
 		if (!strcmp(refname, "HEAD"))
-			kind = REF_DETACHED_HEAD;
+			kind = FILTER_REFS_DETACHED_HEAD;
 		else
 			return 0;
 	}
 
 	/* Don't add types the caller doesn't want */
-	if ((kind & ref_list->kinds) == 0)
+	if ((kind & filter->kind) == 0)
 		return 0;
 
-	if (!match_patterns(cb->pattern, refname))
+	if (!match_patterns(filter->name_patterns, refname))
 		return 0;
 
 	commit = NULL;
-	if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {
+	if (filter->verbose || filter->with_commit || filter->merge != REF_FILTER_MERGED_NONE) {
 		commit = lookup_commit_reference_gently(oid->hash, 1);
 		if (!commit)
 			return 0;
 
 		/* Filter with with_commit if specified */
-		if (!is_descendant_of(commit, ref_list->with_commit))
+		if (!is_descendant_of(commit, filter->with_commit))
 			return 0;
 
-		if (merge_filter != NO_FILTER)
-			add_pending_object(&ref_list->revs,
+		if (filter->merge != REF_FILTER_MERGED_NONE)
+			add_pending_object(array->revs,
 					   (struct object *)commit, refname);
 	}
 
-	ALLOC_GROW(ref_list->list, ref_list->index + 1, ref_list->alloc);
+	item = ref_array_append(array, refname);
 
 	/* Record the new item */
-	newitem = &(ref_list->list[ref_list->index++]);
-	newitem->name = xstrdup(refname);
-	newitem->kind = kind;
-	newitem->commit = commit;
-	newitem->dest = resolve_symref(orig_refname, prefix);
-	newitem->ignore = 0;
+	item->kind = kind;
+	item->commit = commit;
+	item->symref = resolve_symref(orig_refname, prefix);
+	item->ignore = 0;
 
 	return 0;
 }
 
-static void free_ref_list(struct ref_list *ref_list)
-{
-	int i;
-
-	for (i = 0; i < ref_list->index; i++) {
-		free(ref_list->list[i].name);
-		free(ref_list->list[i].dest);
-	}
-	free(ref_list->list);
-}
-
 static int ref_cmp(const void *r1, const void *r2)
 {
-	struct ref_item *c1 = (struct ref_item *)(r1);
-	struct ref_item *c2 = (struct ref_item *)(r2);
+	struct ref_array_item *c1 = *((struct ref_array_item **)r1);
+	struct ref_array_item *c2 = *((struct ref_array_item **)r2);
 
 	if (c1->kind != c2->kind)
 		return c1->kind - c2->kind;
-	return strcmp(c1->name, c2->name);
+	return strcmp(c1->refname, c2->refname);
 }
 
 static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
@@ -477,8 +451,8 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
 	free(ref);
 }
 
-static void add_verbose_info(struct strbuf *out, struct ref_item *item,
-			     int verbose, int abbrev)
+static void add_verbose_info(struct strbuf *out, struct ref_array_item *item,
+			     struct ref_filter *filter)
 {
 	struct strbuf subject = STRBUF_INIT, stat = STRBUF_INIT;
 	const char *sub = _(" **** invalid ref ****");
@@ -489,11 +463,11 @@ static void add_verbose_info(struct strbuf *out, struct ref_item *item,
 		sub = subject.buf;
 	}
 
-	if (item->kind == REF_LOCAL_BRANCH)
-		fill_tracking_info(&stat, item->name, verbose > 1);
+	if (item->kind == FILTER_REFS_BRANCHES)
+		fill_tracking_info(&stat, item->refname, filter->verbose > 1);
 
 	strbuf_addf(out, " %s %s%s",
-		find_unique_abbrev(item->commit->object.sha1, abbrev),
+		find_unique_abbrev(item->commit->object.sha1, filter->abbrev),
 		stat.buf, sub);
 	strbuf_release(&stat);
 	strbuf_release(&subject);
@@ -530,32 +504,32 @@ static char *get_head_description(void)
 	return strbuf_detach(&desc, NULL);
 }
 
-static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
-			   int abbrev, int detached, const char *remote_prefix)
+static void print_ref_item(struct ref_array_item *item, int maxwidth,
+			   struct ref_filter *filter, const char *remote_prefix)
 {
 	char c;
 	int current = 0;
 	int color;
 	struct strbuf out = STRBUF_INIT, name = STRBUF_INIT;
 	const char *prefix = "";
-	const char *desc = item->name;
+	const char *desc = item->refname;
 	char *to_free = NULL;
 
 	if (item->ignore)
 		return;
 
 	switch (item->kind) {
-	case REF_LOCAL_BRANCH:
-		if (!detached && !strcmp(item->name, head))
+	case FILTER_REFS_BRANCHES:
+		if (!filter->detached && !strcmp(item->refname, head))
 			current = 1;
 		else
 			color = BRANCH_COLOR_LOCAL;
 		break;
-	case REF_REMOTE_BRANCH:
+	case FILTER_REFS_REMOTES:
 		color = BRANCH_COLOR_REMOTE;
 		prefix = remote_prefix;
 		break;
-	case REF_DETACHED_HEAD:
+	case FILTER_REFS_DETACHED_HEAD:
 		desc = to_free = get_head_description();
 		current = 1;
 		break;
@@ -571,7 +545,7 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 	}
 
 	strbuf_addf(&name, "%s%s", prefix, desc);
-	if (verbose) {
+	if (filter->verbose) {
 		int utf8_compensation = strlen(name.buf) - utf8_strwidth(name.buf);
 		strbuf_addf(&out, "%c %s%-*s%s", c, branch_get_color(color),
 			    maxwidth + utf8_compensation, name.buf,
@@ -580,13 +554,13 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 		strbuf_addf(&out, "%c %s%s%s", c, branch_get_color(color),
 			    name.buf, branch_get_color(BRANCH_COLOR_RESET));
 
-	if (item->dest)
-		strbuf_addf(&out, " -> %s", item->dest);
-	else if (verbose)
+	if (item->symref)
+		strbuf_addf(&out, " -> %s", item->symref);
+	else if (filter->verbose)
 		/* " f7c0c00 [ahead 58, behind 197] vcs-svn: drop obj_pool.h" */
-		add_verbose_info(&out, item, verbose, abbrev);
+		add_verbose_info(&out, item, filter);
 	if (column_active(colopts)) {
-		assert(!verbose && "--column and --verbose are incompatible");
+		assert(!filter->verbose && "--column and --verbose are incompatible");
 		string_list_append(&output, out.buf);
 	} else {
 		printf("%s\n", out.buf);
@@ -596,17 +570,17 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 	free(to_free);
 }
 
-static int calc_maxwidth(struct ref_list *refs, int remote_bonus)
+static int calc_maxwidth(struct ref_array *refs, int remote_bonus)
 {
 	int i, max = 0;
-	for (i = 0; i < refs->index; i++) {
-		struct ref_item *it = &refs->list[i];
+	for (i = 0; i < refs->nr; i++) {
+		struct ref_array_item *it = refs->items[i];
 		int w;
 
 		if (it->ignore)
 			continue;
-		w = utf8_strwidth(it->name);
-		if (it->kind == REF_REMOTE_BRANCH)
+		w = utf8_strwidth(it->refname);
+		if (it->kind == FILTER_REFS_REMOTES)
 			w += remote_bonus;
 		if (w > max)
 			max = w;
@@ -614,81 +588,74 @@ static int calc_maxwidth(struct ref_list *refs, int remote_bonus)
 	return max;
 }
 
-static void print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char **pattern)
+static void print_ref_list(struct ref_filter *filter)
 {
 	int i;
-	struct append_ref_cb cb;
-	struct ref_list ref_list;
+	struct ref_array array;
+	struct ref_filter_cbdata data;
 	int maxwidth = 0;
 	const char *remote_prefix = "";
+	struct rev_info revs;
 
 	/*
 	 * If we are listing more than just remote branches,
 	 * then remote branches will have a "remotes/" prefix.
 	 * We need to account for this in the width.
 	 */
-	if (kinds != REF_REMOTE_BRANCH)
+	if (filter->kind != FILTER_REFS_REMOTES)
 		remote_prefix = "remotes/";
 
-	memset(&ref_list, 0, sizeof(ref_list));
-	ref_list.kinds = kinds;
-	ref_list.verbose = verbose;
-	ref_list.abbrev = abbrev;
-	ref_list.with_commit = with_commit;
-	if (merge_filter != NO_FILTER)
-		init_revisions(&ref_list.revs, NULL);
-	cb.ref_list = &ref_list;
-	cb.pattern = pattern;
+	memset(&array, 0, sizeof(array));
+	if (filter->merge != REF_FILTER_MERGED_NONE)
+		init_revisions(&revs, NULL);
+
+	data.array = &array;
+	data.filter = filter;
+	array.revs = &revs;
+
 	/*
 	 * First we obtain all regular branch refs and if the HEAD is
 	 * detached then we insert that ref to the end of the ref_fist
 	 * so that it can be printed and removed first.
 	 */
-	for_each_rawref(append_ref, &cb);
-	if (detached)
-		head_ref(append_ref, &cb);
+	for_each_rawref(append_ref, &data);
+	if (filter->detached)
+		head_ref(append_ref, &data);
 	/*
 	 * The following implementation is currently duplicated in ref-filter. It
 	 * will eventually be removed when we port branch.c to use ref-filter APIs.
 	 */
-	if (merge_filter != NO_FILTER) {
-		struct commit *filter;
-		filter = lookup_commit_reference_gently(merge_filter_ref, 0);
-		if (!filter)
-			die(_("object '%s' does not point to a commit"),
-			    sha1_to_hex(merge_filter_ref));
-
-		filter->object.flags |= UNINTERESTING;
-		add_pending_object(&ref_list.revs,
-				   (struct object *) filter, "");
-		ref_list.revs.limited = 1;
-
-		if (prepare_revision_walk(&ref_list.revs))
+	if (filter->merge != REF_FILTER_MERGED_NONE) {
+		filter->merge_commit->object.flags |= UNINTERESTING;
+		add_pending_object(&revs, &filter->merge_commit->object, "");
+		revs.limited = 1;
+
+		if (prepare_revision_walk(&revs))
 			die(_("revision walk setup failed"));
 
-		for (i = 0; i < ref_list.index; i++) {
-			struct ref_item *item = &ref_list.list[i];
+		for (i = 0; i < array.nr; i++) {
+			struct ref_array_item *item = array.items[i];
 			struct commit *commit = item->commit;
 			int is_merged = !!(commit->object.flags & UNINTERESTING);
-			item->ignore = is_merged != (merge_filter == SHOW_MERGED);
+			item->ignore = is_merged != (filter->merge == REF_FILTER_MERGED_INCLUDE);
 		}
 
-		for (i = 0; i < ref_list.index; i++) {
-			struct ref_item *item = &ref_list.list[i];
+		for (i = 0; i < array.nr; i++) {
+			struct ref_array_item *item = array.items[i];
 			clear_commit_marks(item->commit, ALL_REV_FLAGS);
 		}
-		clear_commit_marks(filter, ALL_REV_FLAGS);
+		clear_commit_marks(filter->merge_commit, ALL_REV_FLAGS);
 	}
-	if (verbose)
-		maxwidth = calc_maxwidth(&ref_list, strlen(remote_prefix));
 
-	qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
+	if (filter->verbose)
+		maxwidth = calc_maxwidth(&array, strlen(remote_prefix));
+
+	qsort(array.items, array.nr, sizeof(struct ref_array_item *), ref_cmp);
 
-	for (i = 0; i < ref_list.index; i++)
-		print_ref_item(&ref_list.list[i], maxwidth, verbose,
-			       abbrev, detached, remote_prefix);
+	for (i = 0; i < array.nr; i++)
+		print_ref_item(array.items[i], maxwidth, filter, remote_prefix);
 
-	free_ref_list(&ref_list);
+	ref_array_clear(&array);
 }
 
 static void rename_branch(const char *oldname, const char *newname, int force)
@@ -744,24 +711,6 @@ static void rename_branch(const char *oldname, const char *newname, int force)
 	strbuf_release(&newsection);
 }
 
-/*
- * This function is duplicated in ref-filter. It will eventually be removed
- * when we port branch.c to use ref-filter APIs.
- */
-static int opt_parse_merge_filter(const struct option *opt, const char *arg, int unset)
-{
-	merge_filter = ((opt->long_name[0] == 'n')
-			? SHOW_NOT_MERGED
-			: SHOW_MERGED);
-	if (unset)
-		merge_filter = SHOW_NOT_MERGED; /* b/c for --no-merged */
-	if (!arg)
-		arg = "HEAD";
-	if (get_sha1(arg, merge_filter_ref))
-		die(_("malformed object name %s"), arg);
-	return 0;
-}
-
 static const char edit_description[] = "BRANCH_DESCRIPTION";
 
 static int edit_branch_description(const char *branch_name)
@@ -801,17 +750,15 @@ static int edit_branch_description(const char *branch_name)
 int cmd_branch(int argc, const char **argv, const char *prefix)
 {
 	int delete = 0, rename = 0, force = 0, list = 0;
-	int verbose = 0, abbrev = -1, detached = 0;
 	int reflog = 0, edit_description = 0;
 	int quiet = 0, unset_upstream = 0;
 	const char *new_upstream = NULL;
 	enum branch_track track;
-	int kinds = REF_LOCAL_BRANCH;
-	struct commit_list *with_commit = NULL;
+	struct ref_filter filter;
 
 	struct option options[] = {
 		OPT_GROUP(N_("Generic options")),
-		OPT__VERBOSE(&verbose,
+		OPT__VERBOSE(&filter.verbose,
 			N_("show hash and subject, give twice for upstream branch")),
 		OPT__QUIET(&quiet, N_("suppress informational messages")),
 		OPT_SET_INT('t', "track",  &track, N_("set up tracking mode (see git-pull(1))"),
@@ -821,15 +768,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		OPT_STRING('u', "set-upstream-to", &new_upstream, "upstream", "change the upstream info"),
 		OPT_BOOL(0, "unset-upstream", &unset_upstream, "Unset the upstream info"),
 		OPT__COLOR(&branch_use_color, N_("use colored output")),
-		OPT_SET_INT('r', "remotes",     &kinds, N_("act on remote-tracking branches"),
-			REF_REMOTE_BRANCH),
-		OPT_CONTAINS(&with_commit, N_("print only branches that contain the commit")),
-		OPT_WITH(&with_commit, N_("print only branches that contain the commit")),
-		OPT__ABBREV(&abbrev),
+		OPT_SET_INT('r', "remotes",     &filter.kind, N_("act on remote-tracking branches"),
+			FILTER_REFS_REMOTES),
+		OPT_CONTAINS(&filter.with_commit, N_("print only branches that contain the commit")),
+		OPT_WITH(&filter.with_commit, N_("print only branches that contain the commit")),
+		OPT__ABBREV(&filter.abbrev),
 
 		OPT_GROUP(N_("Specific git-branch actions:")),
-		OPT_SET_INT('a', "all", &kinds, N_("list both remote-tracking and local branches"),
-			REF_REMOTE_BRANCH | REF_LOCAL_BRANCH),
+		OPT_SET_INT('a', "all", &filter.kind, N_("list both remote-tracking and local branches"),
+			FILTER_REFS_REMOTES | FILTER_REFS_BRANCHES),
 		OPT_BIT('d', "delete", &delete, N_("delete fully merged branch"), 1),
 		OPT_BIT('D', NULL, &delete, N_("delete branch (even if not merged)"), 2),
 		OPT_BIT('m', "move", &rename, N_("move/rename a branch and its reflog"), 1),
@@ -839,22 +786,16 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		OPT_BOOL(0, "edit-description", &edit_description,
 			 N_("edit the description for the branch")),
 		OPT__FORCE(&force, N_("force creation, move/rename, deletion")),
-		{
-			OPTION_CALLBACK, 0, "no-merged", &merge_filter_ref,
-			N_("commit"), N_("print only not merged branches"),
-			PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG,
-			opt_parse_merge_filter, (intptr_t) "HEAD",
-		},
-		{
-			OPTION_CALLBACK, 0, "merged", &merge_filter_ref,
-			N_("commit"), N_("print only merged branches"),
-			PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG,
-			opt_parse_merge_filter, (intptr_t) "HEAD",
-		},
+		OPT_MERGED(&filter, N_("print only branches that are merged")),
+		OPT_NO_MERGED(&filter, N_("print only branches that are not merged")),
 		OPT_COLUMN(0, "column", &colopts, N_("list branches in columns")),
 		OPT_END(),
 	};
 
+	memset(&filter, 0, sizeof(filter));
+	filter.kind = FILTER_REFS_BRANCHES;
+	filter.abbrev = -1;
+
 	if (argc == 2 && !strcmp(argv[1], "-h"))
 		usage_with_options(builtin_branch_usage, options);
 
@@ -866,11 +807,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 	if (!head)
 		die(_("Failed to resolve HEAD as a valid ref."));
 	if (!strcmp(head, "HEAD"))
-		detached = 1;
+		filter.detached = 1;
 	else if (!skip_prefix(head, "refs/heads/", &head))
 		die(_("HEAD not found below refs/heads!"));
-	hashcpy(merge_filter_ref, head_sha1);
-
 
 	argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
 			     0);
@@ -878,17 +817,17 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 	if (!delete && !rename && !edit_description && !new_upstream && !unset_upstream && argc == 0)
 		list = 1;
 
-	if (with_commit || merge_filter != NO_FILTER)
+	if (filter.with_commit || filter.merge != REF_FILTER_MERGED_NONE)
 		list = 1;
 
 	if (!!delete + !!rename + !!new_upstream +
 	    list + unset_upstream > 1)
 		usage_with_options(builtin_branch_usage, options);
 
-	if (abbrev == -1)
-		abbrev = DEFAULT_ABBREV;
+	if (filter.abbrev == -1)
+		filter.abbrev = DEFAULT_ABBREV;
 	finalize_colopts(&colopts, -1);
-	if (verbose) {
+	if (filter.verbose) {
 		if (explicitly_enable_column(colopts))
 			die(_("--column and --verbose are incompatible"));
 		colopts = 0;
@@ -902,13 +841,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 	if (delete) {
 		if (!argc)
 			die(_("branch name required"));
-		return delete_branches(argc, argv, delete > 1, kinds, quiet);
+		return delete_branches(argc, argv, delete > 1, filter.kind, quiet);
 	} else if (list) {
 		/*  git branch --local also shows HEAD when it is detached */
-		if (kinds & REF_LOCAL_BRANCH)
-			kinds |= REF_DETACHED_HEAD;
-		print_ref_list(kinds, detached, verbose, abbrev,
-					 with_commit, argv);
+		if ((filter.kind & FILTER_REFS_BRANCHES) && filter.detached)
+			filter.kind |= FILTER_REFS_DETACHED_HEAD;
+		filter.name_patterns = argv;
+		print_ref_list(&filter);
 		print_columns(&output, colopts, NULL);
 		string_list_clear(&output, 0);
 		return 0;
@@ -918,7 +857,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		struct strbuf branch_ref = STRBUF_INIT;
 
 		if (!argc) {
-			if (detached)
+			if (filter.detached)
 				die(_("Cannot give description to detached HEAD"));
 			branch_name = head;
 		} else if (argc == 1)
@@ -1006,7 +945,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		if (!branch)
 			die(_("no such branch '%s'"), argv[0]);
 
-		if (kinds != REF_LOCAL_BRANCH)
+		if (filter.kind != FILTER_REFS_BRANCHES)
 			die(_("-a and -r options to 'git branch' do not make sense with a branch name"));
 
 		if (track == BRANCH_TRACK_OVERRIDE)
diff --git a/ref-filter.h b/ref-filter.h
index a5cfa5e..fadebc5 100644
--- a/ref-filter.h
+++ b/ref-filter.h
@@ -36,6 +36,7 @@ struct ref_array_item {
 	unsigned char objectname[20];
 	int flag;
 	unsigned int kind;
+	int ignore : 1; /* To be removed in the next patch */
 	const char *symref;
 	struct commit *commit;
 	struct atom_value *value;
@@ -45,6 +46,7 @@ struct ref_array_item {
 struct ref_array {
 	int nr, alloc;
 	struct ref_array_item **items;
+	struct rev_info *revs;
 };
 
 struct ref_filter {
@@ -60,9 +62,12 @@ struct ref_filter {
 	struct commit *merge_commit;
 
 	unsigned int with_commit_tag_algo : 1,
-		match_as_path : 1;
+		match_as_path : 1,
+		detached : 1;
 	unsigned int kind,
 		lines;
+	int abbrev,
+		verbose;
 };
 
 struct ref_filter_cbdata {
-- 
2.5.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v6 7/8] branch.c: use 'ref-filter' APIs
  2015-09-23 18:11 [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Karthik Nayak
                   ` (5 preceding siblings ...)
  2015-09-23 18:11 ` [PATCH v6 6/8] branch.c: use 'ref-filter' data structures Karthik Nayak
@ 2015-09-23 18:11 ` Karthik Nayak
  2015-09-23 18:11 ` [PATCH v6 8/8] branch: add '--points-at' option Karthik Nayak
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 27+ messages in thread
From: Karthik Nayak @ 2015-09-23 18:11 UTC (permalink / raw)
  To: git; +Cc: christian.couder, Matthieu.Moy, gitster, Karthik Nayak, Karthik Nayak

Make 'branch.c' use 'ref-filter' APIs for iterating through refs
sorting. This removes most of the code used in 'branch.c' replacing it
with calls to the 'ref-filter' library.

Make 'branch.c' use the 'filter_refs()' function provided by 'ref-filter'
to filter out tags based on the options set.

We provide a sorting option provided for 'branch.c' by using the
sorting options provided by 'ref-filter'. Also by default, we sort by
'refname'.  Since 'HEAD' is alphabatically before 'refs/...' we end up
with an array consisting of the 'HEAD' ref then the local branches and
finally the remote-tracking branches.

Also remove the 'ignore' variable from ref_array_item as it was
previously used for the '--merged' option and now that is handled by
ref-filter.

Modify some of the tests in t1430 to check the stderr for a warning
regarding the broken ref. This is done as ref-filter throws a warning
for broken refs rather than directly printing them.

Add tests and documentation for the same.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 Documentation/git-branch.txt |  12 ++-
 builtin/branch.c             | 213 +++++++------------------------------------
 ref-filter.c                 |   2 +-
 ref-filter.h                 |   1 -
 t/t1430-bad-ref-name.sh      |  31 ++++---
 t/t3203-branch-output.sh     |  11 +++
 6 files changed, 78 insertions(+), 192 deletions(-)

diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index a67138a..c45295d 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -11,7 +11,7 @@ SYNOPSIS
 'git branch' [--color[=<when>] | --no-color] [-r | -a]
 	[--list] [-v [--abbrev=<length> | --no-abbrev]]
 	[--column[=<options>] | --no-column]
-	[(--merged | --no-merged | --contains) [<commit>]] [<pattern>...]
+	[(--merged | --no-merged | --contains) [<commit>]] [--sort=<key>] [<pattern>...]
 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
 'git branch' (--set-upstream-to=<upstream> | -u <upstream>) [<branchname>]
 'git branch' --unset-upstream [<branchname>]
@@ -229,6 +229,16 @@ start-point is either a local or remote-tracking branch.
 	The new name for an existing branch. The same restrictions as for
 	<branchname> apply.
 
+--sort=<key>::
+	Sort based on the key given. Prefix `-` to sort in descending
+	order of the value. You may use the --sort=<key> option
+	multiple times, in which case the last key becomes the primary
+	key. The keys supported are the same as those in `git
+	for-each-ref`. Sort order defaults to sorting based on the
+	full refname (including `refs/...` prefix). This lists
+	detached HEAD (if present) first, then local branches and
+	finally remote-tracking branches.
+
 
 Examples
 --------
diff --git a/builtin/branch.c b/builtin/branch.c
index bfbba2f..b83116a 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -270,125 +270,6 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
 	return(ret);
 }
 
-static char *resolve_symref(const char *src, const char *prefix)
-{
-	unsigned char sha1[20];
-	int flag;
-	const char *dst;
-
-	dst = resolve_ref_unsafe(src, 0, sha1, &flag);
-	if (!(dst && (flag & REF_ISSYMREF)))
-		return NULL;
-	if (prefix)
-		skip_prefix(dst, prefix, &dst);
-	return xstrdup(dst);
-}
-
-static int match_patterns(const char **pattern, const char *refname)
-{
-	if (!*pattern)
-		return 1; /* no pattern always matches */
-	while (*pattern) {
-		if (!wildmatch(*pattern, refname, 0, NULL))
-			return 1;
-		pattern++;
-	}
-	return 0;
-}
-
-/*
- * Allocate memory for a new ref_array_item and insert that into the
- * given ref_array. Doesn't take the objectname unlike
- * new_ref_array_item(). This is a temporary function which will be
- * removed when we port branch.c to use ref-filter APIs.
- */
-static struct ref_array_item *ref_array_append(struct ref_array *array, const char *refname)
-{
-	size_t len = strlen(refname);
-	struct ref_array_item *ref = xcalloc(1, sizeof(struct ref_array_item) + len + 1);
-	memcpy(ref->refname, refname, len);
-	ref->refname[len] = '\0';
-	REALLOC_ARRAY(array->items, array->nr + 1);
-	array->items[array->nr++] = ref;
-	return ref;
-}
-
-static int append_ref(const char *refname, const struct object_id *oid, int flags, void *cb_data)
-{
-	struct ref_filter_cbdata *cb = (struct ref_filter_cbdata *)(cb_data);
-	struct ref_filter *filter = cb->filter;
-	struct ref_array *array = cb->array;
-	struct ref_array_item *item;
-	struct commit *commit;
-	int kind, i;
-	const char *prefix, *orig_refname = refname;
-
-	static struct {
-		int kind;
-		const char *prefix;
-	} ref_kind[] = {
-		{ FILTER_REFS_BRANCHES, "refs/heads/" },
-		{ FILTER_REFS_REMOTES, "refs/remotes/" },
-	};
-
-	/* Detect kind */
-	for (i = 0; i < ARRAY_SIZE(ref_kind); i++) {
-		prefix = ref_kind[i].prefix;
-		if (skip_prefix(refname, prefix, &refname)) {
-			kind = ref_kind[i].kind;
-			break;
-		}
-	}
-	if (ARRAY_SIZE(ref_kind) <= i) {
-		if (!strcmp(refname, "HEAD"))
-			kind = FILTER_REFS_DETACHED_HEAD;
-		else
-			return 0;
-	}
-
-	/* Don't add types the caller doesn't want */
-	if ((kind & filter->kind) == 0)
-		return 0;
-
-	if (!match_patterns(filter->name_patterns, refname))
-		return 0;
-
-	commit = NULL;
-	if (filter->verbose || filter->with_commit || filter->merge != REF_FILTER_MERGED_NONE) {
-		commit = lookup_commit_reference_gently(oid->hash, 1);
-		if (!commit)
-			return 0;
-
-		/* Filter with with_commit if specified */
-		if (!is_descendant_of(commit, filter->with_commit))
-			return 0;
-
-		if (filter->merge != REF_FILTER_MERGED_NONE)
-			add_pending_object(array->revs,
-					   (struct object *)commit, refname);
-	}
-
-	item = ref_array_append(array, refname);
-
-	/* Record the new item */
-	item->kind = kind;
-	item->commit = commit;
-	item->symref = resolve_symref(orig_refname, prefix);
-	item->ignore = 0;
-
-	return 0;
-}
-
-static int ref_cmp(const void *r1, const void *r2)
-{
-	struct ref_array_item *c1 = *((struct ref_array_item **)r1);
-	struct ref_array_item *c2 = *((struct ref_array_item **)r2);
-
-	if (c1->kind != c2->kind)
-		return c1->kind - c2->kind;
-	return strcmp(c1->refname, c2->refname);
-}
-
 static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
 		int show_upstream_ref)
 {
@@ -452,7 +333,7 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
 }
 
 static void add_verbose_info(struct strbuf *out, struct ref_array_item *item,
-			     struct ref_filter *filter)
+			     struct ref_filter *filter, const char *refname)
 {
 	struct strbuf subject = STRBUF_INIT, stat = STRBUF_INIT;
 	const char *sub = _(" **** invalid ref ****");
@@ -464,7 +345,7 @@ static void add_verbose_info(struct strbuf *out, struct ref_array_item *item,
 	}
 
 	if (item->kind == FILTER_REFS_BRANCHES)
-		fill_tracking_info(&stat, item->refname, filter->verbose > 1);
+		fill_tracking_info(&stat, refname, filter->verbose > 1);
 
 	strbuf_addf(out, " %s %s%s",
 		find_unique_abbrev(item->commit->object.sha1, filter->abbrev),
@@ -504,8 +385,8 @@ static char *get_head_description(void)
 	return strbuf_detach(&desc, NULL);
 }
 
-static void print_ref_item(struct ref_array_item *item, int maxwidth,
-			   struct ref_filter *filter, const char *remote_prefix)
+static void format_and_print_ref_item(struct ref_array_item *item, int maxwidth,
+				      struct ref_filter *filter, const char *remote_prefix)
 {
 	char c;
 	int current = 0;
@@ -515,17 +396,16 @@ static void print_ref_item(struct ref_array_item *item, int maxwidth,
 	const char *desc = item->refname;
 	char *to_free = NULL;
 
-	if (item->ignore)
-		return;
-
 	switch (item->kind) {
 	case FILTER_REFS_BRANCHES:
-		if (!filter->detached && !strcmp(item->refname, head))
+		skip_prefix(desc, "refs/heads/", &desc);
+		if (!filter->detached && !strcmp(desc, head))
 			current = 1;
 		else
 			color = BRANCH_COLOR_LOCAL;
 		break;
 	case FILTER_REFS_REMOTES:
+		skip_prefix(desc, "refs/remotes/", &desc);
 		color = BRANCH_COLOR_REMOTE;
 		prefix = remote_prefix;
 		break;
@@ -554,11 +434,13 @@ static void print_ref_item(struct ref_array_item *item, int maxwidth,
 		strbuf_addf(&out, "%c %s%s%s", c, branch_get_color(color),
 			    name.buf, branch_get_color(BRANCH_COLOR_RESET));
 
-	if (item->symref)
-		strbuf_addf(&out, " -> %s", item->symref);
+	if (item->symref) {
+		skip_prefix(item->symref, "refs/remotes/", &desc);
+		strbuf_addf(&out, " -> %s", desc);
+	}
 	else if (filter->verbose)
 		/* " f7c0c00 [ahead 58, behind 197] vcs-svn: drop obj_pool.h" */
-		add_verbose_info(&out, item, filter);
+		add_verbose_info(&out, item, filter, desc);
 	if (column_active(colopts)) {
 		assert(!filter->verbose && "--column and --verbose are incompatible");
 		string_list_append(&output, out.buf);
@@ -575,11 +457,13 @@ static int calc_maxwidth(struct ref_array *refs, int remote_bonus)
 	int i, max = 0;
 	for (i = 0; i < refs->nr; i++) {
 		struct ref_array_item *it = refs->items[i];
+		const char *desc = it->refname;
 		int w;
 
-		if (it->ignore)
-			continue;
-		w = utf8_strwidth(it->refname);
+		skip_prefix(it->refname, "refs/heads/", &desc);
+		skip_prefix(it->refname, "refs/remotes/", &desc);
+		w = utf8_strwidth(desc);
+
 		if (it->kind == FILTER_REFS_REMOTES)
 			w += remote_bonus;
 		if (w > max)
@@ -588,14 +472,12 @@ static int calc_maxwidth(struct ref_array *refs, int remote_bonus)
 	return max;
 }
 
-static void print_ref_list(struct ref_filter *filter)
+static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sorting)
 {
 	int i;
 	struct ref_array array;
-	struct ref_filter_cbdata data;
 	int maxwidth = 0;
 	const char *remote_prefix = "";
-	struct rev_info revs;
 
 	/*
 	 * If we are listing more than just remote branches,
@@ -606,54 +488,26 @@ static void print_ref_list(struct ref_filter *filter)
 		remote_prefix = "remotes/";
 
 	memset(&array, 0, sizeof(array));
-	if (filter->merge != REF_FILTER_MERGED_NONE)
-		init_revisions(&revs, NULL);
-
-	data.array = &array;
-	data.filter = filter;
-	array.revs = &revs;
-
-	/*
-	 * First we obtain all regular branch refs and if the HEAD is
-	 * detached then we insert that ref to the end of the ref_fist
-	 * so that it can be printed and removed first.
-	 */
-	for_each_rawref(append_ref, &data);
-	if (filter->detached)
-		head_ref(append_ref, &data);
-	/*
-	 * The following implementation is currently duplicated in ref-filter. It
-	 * will eventually be removed when we port branch.c to use ref-filter APIs.
-	 */
-	if (filter->merge != REF_FILTER_MERGED_NONE) {
-		filter->merge_commit->object.flags |= UNINTERESTING;
-		add_pending_object(&revs, &filter->merge_commit->object, "");
-		revs.limited = 1;
-
-		if (prepare_revision_walk(&revs))
-			die(_("revision walk setup failed"));
-
-		for (i = 0; i < array.nr; i++) {
-			struct ref_array_item *item = array.items[i];
-			struct commit *commit = item->commit;
-			int is_merged = !!(commit->object.flags & UNINTERESTING);
-			item->ignore = is_merged != (filter->merge == REF_FILTER_MERGED_INCLUDE);
-		}
 
-		for (i = 0; i < array.nr; i++) {
-			struct ref_array_item *item = array.items[i];
-			clear_commit_marks(item->commit, ALL_REV_FLAGS);
-		}
-		clear_commit_marks(filter->merge_commit, ALL_REV_FLAGS);
-	}
+	verify_ref_format("%(refname)%(symref)");
+	filter_refs(&array, filter, filter->kind | FILTER_REFS_INCLUDE_BROKEN);
 
 	if (filter->verbose)
 		maxwidth = calc_maxwidth(&array, strlen(remote_prefix));
 
-	qsort(array.items, array.nr, sizeof(struct ref_array_item *), ref_cmp);
+	/*
+	 * If no sorting parameter is given then we default to sorting
+	 * by 'refname'. This would give us an alphabetically sorted
+	 * array with the 'HEAD' ref at the beginning followed by
+	 * local branches 'refs/heads/...' and finally remote-tacking
+	 * branches 'refs/remotes/...'.
+	 */
+	if (!sorting)
+		sorting = ref_default_sorting();
+	ref_array_sort(sorting, &array);
 
 	for (i = 0; i < array.nr; i++)
-		print_ref_item(array.items[i], maxwidth, filter, remote_prefix);
+		format_and_print_ref_item(array.items[i], maxwidth, filter, remote_prefix);
 
 	ref_array_clear(&array);
 }
@@ -755,6 +609,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 	const char *new_upstream = NULL;
 	enum branch_track track;
 	struct ref_filter filter;
+	static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
 
 	struct option options[] = {
 		OPT_GROUP(N_("Generic options")),
@@ -789,6 +644,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		OPT_MERGED(&filter, N_("print only branches that are merged")),
 		OPT_NO_MERGED(&filter, N_("print only branches that are not merged")),
 		OPT_COLUMN(0, "column", &colopts, N_("list branches in columns")),
+		OPT_CALLBACK(0 , "sort", sorting_tail, N_("key"),
+			     N_("field name to sort on"), &parse_opt_ref_sorting),
 		OPT_END(),
 	};
 
@@ -847,7 +704,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		if ((filter.kind & FILTER_REFS_BRANCHES) && filter.detached)
 			filter.kind |= FILTER_REFS_DETACHED_HEAD;
 		filter.name_patterns = argv;
-		print_ref_list(&filter);
+		print_ref_list(&filter, sorting);
 		print_columns(&output, colopts, NULL);
 		string_list_clear(&output, 0);
 		return 0;
diff --git a/ref-filter.c b/ref-filter.c
index fd839ac..dbd8fce 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -1331,7 +1331,7 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid,
 	 * obtain the commit using the 'oid' available and discard all
 	 * non-commits early. The actual filtering is done later.
 	 */
-	if (filter->merge_commit || filter->with_commit) {
+	if (filter->merge_commit || filter->with_commit || filter->verbose) {
 		commit = lookup_commit_reference_gently(oid->hash, 1);
 		if (!commit)
 			return 0;
diff --git a/ref-filter.h b/ref-filter.h
index fadebc5..14d435e 100644
--- a/ref-filter.h
+++ b/ref-filter.h
@@ -36,7 +36,6 @@ struct ref_array_item {
 	unsigned char objectname[20];
 	int flag;
 	unsigned int kind;
-	int ignore : 1; /* To be removed in the next patch */
 	const char *symref;
 	struct commit *commit;
 	struct atom_value *value;
diff --git a/t/t1430-bad-ref-name.sh b/t/t1430-bad-ref-name.sh
index 16d0b8b..c465abe 100755
--- a/t/t1430-bad-ref-name.sh
+++ b/t/t1430-bad-ref-name.sh
@@ -38,18 +38,20 @@ test_expect_success 'fast-import: fail on invalid branch name "bad[branch]name"'
 	test_must_fail git fast-import <input
 '
 
-test_expect_success 'git branch shows badly named ref' '
+test_expect_success 'git branch shows badly named ref as warning' '
 	cp .git/refs/heads/master .git/refs/heads/broken...ref &&
 	test_when_finished "rm -f .git/refs/heads/broken...ref" &&
-	git branch >output &&
-	grep -e "broken\.\.\.ref" output
+	git branch >output 2>error &&
+	grep -e "broken\.\.\.ref" error &&
+	! grep -e "broken\.\.\.ref" output
 '
 
 test_expect_success 'branch -d can delete badly named ref' '
 	cp .git/refs/heads/master .git/refs/heads/broken...ref &&
 	test_when_finished "rm -f .git/refs/heads/broken...ref" &&
 	git branch -d broken...ref &&
-	git branch >output &&
+	git branch >output 2>error &&
+	! grep -e "broken\.\.\.ref" error &&
 	! grep -e "broken\.\.\.ref" output
 '
 
@@ -57,7 +59,8 @@ test_expect_success 'branch -D can delete badly named ref' '
 	cp .git/refs/heads/master .git/refs/heads/broken...ref &&
 	test_when_finished "rm -f .git/refs/heads/broken...ref" &&
 	git branch -D broken...ref &&
-	git branch >output &&
+	git branch >output 2>error &&
+	! grep -e "broken\.\.\.ref" error &&
 	! grep -e "broken\.\.\.ref" output
 '
 
@@ -85,7 +88,8 @@ test_expect_success 'branch -D cannot delete absolute path' '
 test_expect_success 'git branch cannot create a badly named ref' '
 	test_when_finished "rm -f .git/refs/heads/broken...ref" &&
 	test_must_fail git branch broken...ref &&
-	git branch >output &&
+	git branch >output 2>error &&
+	! grep -e "broken\.\.\.ref" error &&
 	! grep -e "broken\.\.\.ref" output
 '
 
@@ -95,7 +99,8 @@ test_expect_success 'branch -m cannot rename to a bad ref name' '
 	git branch goodref &&
 	test_must_fail git branch -m goodref broken...ref &&
 	test_cmp_rev master goodref &&
-	git branch >output &&
+	git branch >output 2>error &&
+	! grep -e "broken\.\.\.ref" error &&
 	! grep -e "broken\.\.\.ref" output
 '
 
@@ -104,14 +109,16 @@ test_expect_failure 'branch -m can rename from a bad ref name' '
 	test_when_finished "rm -f .git/refs/heads/broken...ref" &&
 	git branch -m broken...ref renamed &&
 	test_cmp_rev master renamed &&
-	git branch >output &&
+	git branch >output 2>error &&
+	! grep -e "broken\.\.\.ref" error &&
 	! grep -e "broken\.\.\.ref" output
 '
 
 test_expect_success 'push cannot create a badly named ref' '
 	test_when_finished "rm -f .git/refs/heads/broken...ref" &&
 	test_must_fail git push "file://$(pwd)" HEAD:refs/heads/broken...ref &&
-	git branch >output &&
+	git branch >output 2>error &&
+	! grep -e "broken\.\.\.ref" error &&
 	! grep -e "broken\.\.\.ref" output
 '
 
@@ -131,7 +138,8 @@ test_expect_failure 'push --mirror can delete badly named ref' '
 		cp .git/refs/heads/master .git/refs/heads/broken...ref
 	) &&
 	git -C src push --mirror "file://$top/dest" &&
-	git -C dest branch >output &&
+	git -C dest branch >output 2>error &&
+	! grep -e "broken\.\.\.ref" error &&
 	! grep -e "broken\.\.\.ref" output
 '
 
@@ -159,7 +167,8 @@ test_expect_success 'update-ref -d can delete broken name' '
 	cp .git/refs/heads/master .git/refs/heads/broken...ref &&
 	test_when_finished "rm -f .git/refs/heads/broken...ref" &&
 	git update-ref -d refs/heads/broken...ref &&
-	git branch >output &&
+	git branch >output 2>error &&
+	! grep -e "broken\.\.\.ref" error &&
 	! grep -e "broken\.\.\.ref" output
 '
 
diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh
index f51d0f3..a427163 100755
--- a/t/t3203-branch-output.sh
+++ b/t/t3203-branch-output.sh
@@ -143,4 +143,15 @@ EOF
 	test_i18ncmp expect actual
 '
 
+test_expect_success 'git branch `--sort` option' '
+	cat >expect <<-\EOF &&
+	  branch-two
+	* (HEAD detached from fromtag)
+	  branch-one
+	  master
+	EOF
+	git branch --sort=objectsize >actual &&
+	test_i18ncmp expect actual
+'
+
 test_done
-- 
2.5.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v6 8/8] branch: add '--points-at' option
  2015-09-23 18:11 [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Karthik Nayak
                   ` (6 preceding siblings ...)
  2015-09-23 18:11 ` [PATCH v6 7/8] branch.c: use 'ref-filter' APIs Karthik Nayak
@ 2015-09-23 18:11 ` Karthik Nayak
  2015-09-23 19:00 ` [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Matthieu Moy
  2015-09-24 18:09 ` [PATCH v6b 5/8] branch: drop non-commit error reporting Karthik Nayak
  9 siblings, 0 replies; 27+ messages in thread
From: Karthik Nayak @ 2015-09-23 18:11 UTC (permalink / raw)
  To: git; +Cc: christian.couder, Matthieu.Moy, gitster, Karthik Nayak, Karthik Nayak

Add the '--points-at' option provided by 'ref-filter'. The option lets
the user to list only branches which points at the given object.

Add documentation and tests for the same.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 Documentation/git-branch.txt | 6 +++++-
 builtin/branch.c             | 7 ++++++-
 t/t3203-branch-output.sh     | 9 +++++++++
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index c45295d..03c7af1 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -11,7 +11,8 @@ SYNOPSIS
 'git branch' [--color[=<when>] | --no-color] [-r | -a]
 	[--list] [-v [--abbrev=<length> | --no-abbrev]]
 	[--column[=<options>] | --no-column]
-	[(--merged | --no-merged | --contains) [<commit>]] [--sort=<key>] [<pattern>...]
+	[(--merged | --no-merged | --contains) [<commit>]] [--sort=<key>]
+	[--points-at <object>] [<pattern>...]
 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
 'git branch' (--set-upstream-to=<upstream> | -u <upstream>) [<branchname>]
 'git branch' --unset-upstream [<branchname>]
@@ -240,6 +241,9 @@ start-point is either a local or remote-tracking branch.
 	finally remote-tracking branches.
 
 
+--points-at <object>::
+	Only list branches of the given object.
+
 Examples
 --------
 
diff --git a/builtin/branch.c b/builtin/branch.c
index b83116a..b7a60f4 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -26,6 +26,7 @@ static const char * const builtin_branch_usage[] = {
 	N_("git branch [<options>] [-l] [-f] <branch-name> [<start-point>]"),
 	N_("git branch [<options>] [-r] (-d | -D) <branch-name>..."),
 	N_("git branch [<options>] (-m | -M) [<old-branch>] <new-branch>"),
+	N_("git branch [<options>] [-r | -a] [--points-at]"),
 	NULL
 };
 
@@ -646,6 +647,10 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 		OPT_COLUMN(0, "column", &colopts, N_("list branches in columns")),
 		OPT_CALLBACK(0 , "sort", sorting_tail, N_("key"),
 			     N_("field name to sort on"), &parse_opt_ref_sorting),
+		{
+			OPTION_CALLBACK, 0, "points-at", &filter.points_at, N_("object"),
+			N_("print only branches of the object"), 0, parse_opt_object_name
+		},
 		OPT_END(),
 	};
 
@@ -674,7 +679,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 	if (!delete && !rename && !edit_description && !new_upstream && !unset_upstream && argc == 0)
 		list = 1;
 
-	if (filter.with_commit || filter.merge != REF_FILTER_MERGED_NONE)
+	if (filter.with_commit || filter.merge != REF_FILTER_MERGED_NONE || filter.points_at.nr)
 		list = 1;
 
 	if (!!delete + !!rename + !!new_upstream +
diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh
index a427163..f1ae5ff 100755
--- a/t/t3203-branch-output.sh
+++ b/t/t3203-branch-output.sh
@@ -154,4 +154,13 @@ test_expect_success 'git branch `--sort` option' '
 	test_i18ncmp expect actual
 '
 
+test_expect_success 'git branch --points-at option' '
+	cat >expect <<-\EOF &&
+	  branch-one
+	  master
+	EOF
+	git branch --points-at=branch-one >actual &&
+	test_cmp expect actual
+'
+
 test_done
-- 
2.5.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v6 5/8] branch: drop non-commit error reporting
  2015-09-23 18:11 ` [PATCH v6 5/8] branch: drop non-commit error reporting Karthik Nayak
@ 2015-09-23 18:57   ` Matthieu Moy
  2015-09-24  6:19     ` Karthik Nayak
  2015-09-23 19:14   ` Junio C Hamano
  1 sibling, 1 reply; 27+ messages in thread
From: Matthieu Moy @ 2015-09-23 18:57 UTC (permalink / raw)
  To: Karthik Nayak; +Cc: git, christian.couder, gitster

Karthik Nayak <karthik.188@gmail.com> writes:

> Remove the error reporting variable to make the code easier to port
> over to using ref-filter APIs.
>
> This also removes the error from being displayed. As branch.c will use
> ref-filter APIs in the following patches, the error checking becomes
> redundant with the error reporting system found in the ref-filter
> (ref-filter.c:1336).

I would have written

As branch.c will use ref-filter APIs in the following patches, the error
checking becomes redundant with the error reporting system found in the
ref-filter: error "branch '%s' does not point at a commit" is redundant
with the check performed in ref_filter_handler (ref-filter.c:1336).
Error "some refs could not be read" can only be triggered as a
consequence of the first one hence becomes useless.

> @@ -370,10 +369,8 @@ static int append_ref(const char *refname, const struct object_id *oid, int flag
>  	commit = NULL;
>  	if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {
>  		commit = lookup_commit_reference_gently(oid->hash, 1);
> -		if (!commit) {
> -			cb->ret = error(_("branch '%s' does not point at a commit"), refname);
> +		if (!commit)
>  			return 0;
> -		}

Am I correct that the "return 0" statement above is dead code after the
end of the series?

If so, you should add a comment explaining that it's there "just in
case" but not supposed to happen, or replace the if statement with
"assert(commit);" IMHO. I have a preference for assert(): I don't like
silent failures.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter.
  2015-09-23 18:11 [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Karthik Nayak
                   ` (7 preceding siblings ...)
  2015-09-23 18:11 ` [PATCH v6 8/8] branch: add '--points-at' option Karthik Nayak
@ 2015-09-23 19:00 ` Matthieu Moy
  2015-09-23 19:16   ` Junio C Hamano
  2015-09-24 18:09 ` [PATCH v6b 5/8] branch: drop non-commit error reporting Karthik Nayak
  9 siblings, 1 reply; 27+ messages in thread
From: Matthieu Moy @ 2015-09-23 19:00 UTC (permalink / raw)
  To: Karthik Nayak; +Cc: git, christian.couder, gitster

Karthik Nayak <karthik.188@gmail.com> writes:

> --- a/builtin/branch.c
> +++ b/builtin/branch.c
> @@ -479,8 +479,6 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
>  	struct ref_array array;
>  	int maxwidth = 0;
>  	const char *remote_prefix = "";
> -	struct ref_sorting def_sorting;
> -	const char *sort_type = "refname";

This was allocated on stack ...

> @@ -498,12 +496,15 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
> +	if (!sorting)
> +		sorting = ref_default_sorting();

and it's now allocated by xcalloc within ref_default_sorting(). In
theory, you need a free(). But the sensible place to add this free would
be after the call to print_ref_list(), and this is right before the
process terminates. So it's probably overkill to add a free().

The series looks good to me. I did a minor remark on PATCH 5/8 but this
should not block inclusion.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v6 5/8] branch: drop non-commit error reporting
  2015-09-23 18:11 ` [PATCH v6 5/8] branch: drop non-commit error reporting Karthik Nayak
  2015-09-23 18:57   ` Matthieu Moy
@ 2015-09-23 19:14   ` Junio C Hamano
  2015-09-23 20:10     ` Matthieu Moy
  2015-09-24  6:23     ` Karthik Nayak
  1 sibling, 2 replies; 27+ messages in thread
From: Junio C Hamano @ 2015-09-23 19:14 UTC (permalink / raw)
  To: Karthik Nayak; +Cc: git, christian.couder, Matthieu.Moy

Karthik Nayak <karthik.188@gmail.com> writes:

> Remove the error reporting variable to make the code easier to port
> over to using ref-filter APIs.
>
> This also removes the error from being displayed. As branch.c will use
> ref-filter APIs in the following patches, the error checking becomes
> redundant with the error reporting system found in the ref-filter
> (ref-filter.c:1336).

Hmm, do you mean these lines by the above reference?

	if (filter->merge_commit || filter->with_commit) {
		commit = lookup_commit_reference_gently(oid->hash, 1);
		if (!commit)
			return 0;

That is "silently return ignoring it if it is not a commit", i.e.  I
do not think that deserves to be called error REPORTING system.

Do you really understand what the error message you are removing is
trying to diagnose?  A branch ref must not point at a blob or any
non-commit object, and if we find such a branch ref, we report it as
error.  That is what the error message is about.

Now, ref-filter.c:1336 has in no position to issue that same error
message because it does not know what it is looking at is supposed
to be a branch ref, so it is WRONG if it gave the same error
message.  After all, the caller may be using ref-filter to filter
refs/tags/* with merge_commit or with_commit and found a
light-weight tag in refs/tags/* that points at a blob.  That is not
an event we want to get an error at all.

I do not think we terribly mind if this message goes away from this
location.  "It is a wrong codepath whose purpose is not to diagnose
and report a repository corruption.  If we care about such a
repository corruption, we should report it from fsck instead", would
bea valid justification for the removal of the message.

It is not a valid justification to claim that it is made redundant,
when you actually are simply LOSING the error reporting without
giving the same error message from another codepath to make it truly
redundant.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter.
  2015-09-23 19:00 ` [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Matthieu Moy
@ 2015-09-23 19:16   ` Junio C Hamano
  2015-09-24  6:01     ` Karthik Nayak
  0 siblings, 1 reply; 27+ messages in thread
From: Junio C Hamano @ 2015-09-23 19:16 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Karthik Nayak, git, christian.couder

Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:

> The series looks good to me. I did a minor remark on PATCH 5/8 but this
> should not block inclusion.

Thanks.  As long as the log message is telling the truth, I do not
mind the actual lossage of the error message shown to the user.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v6 5/8] branch: drop non-commit error reporting
  2015-09-23 19:14   ` Junio C Hamano
@ 2015-09-23 20:10     ` Matthieu Moy
  2015-09-23 20:29       ` Junio C Hamano
  2015-09-23 22:50       ` Junio C Hamano
  2015-09-24  6:23     ` Karthik Nayak
  1 sibling, 2 replies; 27+ messages in thread
From: Matthieu Moy @ 2015-09-23 20:10 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Karthik Nayak, git, christian.couder

Junio C Hamano <gitster@pobox.com> writes:

> Karthik Nayak <karthik.188@gmail.com> writes:
>
>> Remove the error reporting variable to make the code easier to port
>> over to using ref-filter APIs.
>>
>> This also removes the error from being displayed. As branch.c will use
>> ref-filter APIs in the following patches, the error checking becomes
>> redundant with the error reporting system found in the ref-filter
>> (ref-filter.c:1336).
>
> Hmm, do you mean these lines by the above reference?
>
> 	if (filter->merge_commit || filter->with_commit) {
> 		commit = lookup_commit_reference_gently(oid->hash, 1);
> 		if (!commit)
> 			return 0;

Note: the test becomes

      if (filter->merge_commit || filter->with_commit || filter->verbose) {

When the code starts using ref-filter, so the condition of the if
becomes the same as it is here. Not related to your concern, but I was
worried about "verbose" being used on one side but not the other, and
it's actually OK.

> That is "silently return ignoring it if it is not a commit", i.e.  I
> do not think that deserves to be called error REPORTING system.
>
> Do you really understand what the error message you are removing is
> trying to diagnose?  A branch ref must not point at a blob or any
> non-commit object, and if we find such a branch ref, we report it as
> error.

More precisely: if we find such a branch ref and we're used with an
option that requires us to lookup the commit, then we report it as an
error.

To be sure, I tried:

  echo ee0f5eeeae36cd1b5a346a1e2ae5c8cb841cd5da > .git/refs/heads/broken

where the sha1 is the one of a blob.

$ git branch   
  broken
* master
$ git branch -v
error: branch 'broken' does not point at a commit
* master 5cc76d7 foo
error: some refs could not be read

After the series, I get:

$ git branch
  broken
* master
$ git branch -v
* master 5cc76d7 foo

So I agree with Junio that the commit message is not sufficient: there
is a behavioral change. I'm OK with it, but the commit message shouldn't
claim that there isn't.

Porting to ref-filter drops the commit before we get an opportunity to
complain, so we stop complaining because it's not worth the trouble.

BTW, this looks like an fsck bug:

$ git fsck --strict
Checking object directories: 100% (256/256), done.
error: refs/heads/broken: not a commit
$ echo $?
0

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v6 5/8] branch: drop non-commit error reporting
  2015-09-23 20:10     ` Matthieu Moy
@ 2015-09-23 20:29       ` Junio C Hamano
  2015-09-23 20:38         ` Junio C Hamano
  2015-09-23 22:50       ` Junio C Hamano
  1 sibling, 1 reply; 27+ messages in thread
From: Junio C Hamano @ 2015-09-23 20:29 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Karthik Nayak, git, christian.couder

Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:

> More precisely: if we find such a branch ref and we're used with an
> option that requires us to lookup the commit, then we report it as an
> error.
> ...
> So I agree with Junio that the commit message is not sufficient: there
> is a behavioral change. I'm OK with it, but the commit message shouldn't
> claim that there isn't.
>
> Porting to ref-filter drops the commit before we get an opportunity to
> complain, so we stop complaining because it's not worth the trouble.

I share the same conclusion.  It may be an unfortunate fallout but
giving the diagnosis was not really the job for this codepath in the
first place.

If it were, then I would have said we should fix it to keep the
behaviour, even if the fix is involved, and that is why I would not
necessarily agree with "not worth the trouble".

> BTW, this looks like an fsck bug:
>
> $ git fsck --strict
> Checking object directories: 100% (256/256), done.
> error: refs/heads/broken: not a commit
> $ echo $?
> 0

Interesting.  Perhaps leave it as a MicroProject for GSoC next year?
;-)

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v6 5/8] branch: drop non-commit error reporting
  2015-09-23 20:29       ` Junio C Hamano
@ 2015-09-23 20:38         ` Junio C Hamano
  2015-09-23 21:44           ` Junio C Hamano
  0 siblings, 1 reply; 27+ messages in thread
From: Junio C Hamano @ 2015-09-23 20:38 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Karthik Nayak, git, christian.couder

Junio C Hamano <gitster@pobox.com> writes:

>> BTW, this looks like an fsck bug:
>>
>> $ git fsck --strict
>> Checking object directories: 100% (256/256), done.
>> error: refs/heads/broken: not a commit
>> $ echo $?
>> 0
>
> Interesting.  Perhaps leave it as a MicroProject for GSoC next year?
> ;-)

Perhaps something like this (not even compile tested as both of my
worktrees are doing something else).  I didn't invent another error
class for cache-tree entry, as that falls into the same category as
"refs" where integrity constraint is that it has to point at a valid
object of an expected type.

 builtin/fsck.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/builtin/fsck.c b/builtin/fsck.c
index 0794703..b9a74f0 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -38,6 +38,7 @@ static int show_dangling = 1;
 #define ERROR_OBJECT 01
 #define ERROR_REACHABLE 02
 #define ERROR_PACK 04
+#define ERROR_REFS 010
 
 #ifdef NO_D_INO_IN_DIRENT
 #define SORT_DIRENT 0
@@ -521,8 +522,10 @@ static int fsck_handle_ref(const char *refname, const struct object_id *oid,
 		/* We'll continue with the rest despite the error.. */
 		return 0;
 	}
-	if (obj->type != OBJ_COMMIT && is_branch(refname))
+	if (obj->type != OBJ_COMMIT && is_branch(refname)) {
 		error("%s: not a commit", refname);
+		errors_found |= ERROR_REFS;
+	}
 	default_refs++;
 	obj->used = 1;
 	mark_object_reachable(obj);
@@ -585,17 +588,23 @@ static int fsck_head_link(void)
 		fprintf(stderr, "Checking HEAD link\n");
 
 	head_points_at = resolve_ref_unsafe("HEAD", 0, head_oid.hash, &flag);
-	if (!head_points_at)
+	if (!head_points_at) {
+		errors_found |= ERROR_REFS;
 		return error("Invalid HEAD");
+	}
 	if (!strcmp(head_points_at, "HEAD"))
 		/* detached HEAD */
 		null_is_error = 1;
-	else if (!starts_with(head_points_at, "refs/heads/"))
+	else if (!starts_with(head_points_at, "refs/heads/")) {
+		errors_found |= ERROR_REFS;
 		return error("HEAD points to something strange (%s)",
 			     head_points_at);
+	}
 	if (is_null_oid(&head_oid)) {
-		if (null_is_error)
+		if (null_is_error) {
+			errors_found |= ERROR_REFS;
 			return error("HEAD: detached HEAD points at nothing");
+		}
 		fprintf(stderr, "notice: HEAD points to an unborn branch (%s)\n",
 			head_points_at + 11);
 	}
@@ -615,6 +624,7 @@ static int fsck_cache_tree(struct cache_tree *it)
 		if (!obj) {
 			error("%s: invalid sha1 pointer in cache-tree",
 			      sha1_to_hex(it->sha1));
+			errors_found |= ERROR_REFS;
 			return 1;
 		}
 		obj->used = 1;

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v6 5/8] branch: drop non-commit error reporting
  2015-09-23 20:38         ` Junio C Hamano
@ 2015-09-23 21:44           ` Junio C Hamano
  2015-09-24  6:46             ` Matthieu Moy
  0 siblings, 1 reply; 27+ messages in thread
From: Junio C Hamano @ 2015-09-23 21:44 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Karthik Nayak, git, christian.couder

Junio C Hamano <gitster@pobox.com> writes:

> Perhaps something like this (not even compile tested as both of my
> worktrees are doing something else)....

This time with a few additional tests.

-- >8 --
Subject: [PATCH] fsck: exit with non-zero when problems are found

After finding some problems (e.g. a ref refs/heads/X points at an
object that is not a commit) and issuing an error message, the
program failed to signal the fact that it found an error by a
non-zero exit status.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/fsck.c  | 18 ++++++++++++++----
 t/t1450-fsck.sh | 22 +++++++++++++++++++++-
 2 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/builtin/fsck.c b/builtin/fsck.c
index 4e8e2ee..63ab0bb 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -35,6 +35,7 @@ static int show_dangling = 1;
 #define ERROR_OBJECT 01
 #define ERROR_REACHABLE 02
 #define ERROR_PACK 04
+#define ERROR_REFS 010
 
 #ifdef NO_D_INO_IN_DIRENT
 #define SORT_DIRENT 0
@@ -495,8 +496,10 @@ static int fsck_handle_ref(const char *refname, const struct object_id *oid,
 		/* We'll continue with the rest despite the error.. */
 		return 0;
 	}
-	if (obj->type != OBJ_COMMIT && is_branch(refname))
+	if (obj->type != OBJ_COMMIT && is_branch(refname)) {
 		error("%s: not a commit", refname);
+		errors_found |= ERROR_REFS;
+	}
 	default_refs++;
 	obj->used = 1;
 	mark_object_reachable(obj);
@@ -559,17 +562,23 @@ static int fsck_head_link(void)
 		fprintf(stderr, "Checking HEAD link\n");
 
 	head_points_at = resolve_ref_unsafe("HEAD", 0, head_oid.hash, &flag);
-	if (!head_points_at)
+	if (!head_points_at) {
+		errors_found |= ERROR_REFS;
 		return error("Invalid HEAD");
+	}
 	if (!strcmp(head_points_at, "HEAD"))
 		/* detached HEAD */
 		null_is_error = 1;
-	else if (!starts_with(head_points_at, "refs/heads/"))
+	else if (!starts_with(head_points_at, "refs/heads/")) {
+		errors_found |= ERROR_REFS;
 		return error("HEAD points to something strange (%s)",
 			     head_points_at);
+	}
 	if (is_null_oid(&head_oid)) {
-		if (null_is_error)
+		if (null_is_error) {
+			errors_found |= ERROR_REFS;
 			return error("HEAD: detached HEAD points at nothing");
+		}
 		fprintf(stderr, "notice: HEAD points to an unborn branch (%s)\n",
 			head_points_at + 11);
 	}
@@ -589,6 +598,7 @@ static int fsck_cache_tree(struct cache_tree *it)
 		if (!obj) {
 			error("%s: invalid sha1 pointer in cache-tree",
 			      sha1_to_hex(it->sha1));
+			errors_found |= ERROR_REFS;
 			return 1;
 		}
 		obj->used = 1;
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index cfb32b6..0ad04da 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -77,11 +77,31 @@ test_expect_success 'object with bad sha1' '
 test_expect_success 'branch pointing to non-commit' '
 	git rev-parse HEAD^{tree} >.git/refs/heads/invalid &&
 	test_when_finished "git update-ref -d refs/heads/invalid" &&
-	git fsck 2>out &&
+	test_must_fail git fsck 2>out &&
 	cat out &&
 	grep "not a commit" out
 '
 
+test_expect_success 'HEAD link pointing at a funny object' '
+	test_when_finished "mv .git/SAVED_HEAD .git/HEAD" &&
+	mv .git/HEAD .git/SAVED_HEAD &&
+	echo 0000000000000000000000000000000000000000 >.git/HEAD &&
+	# avoid corrupt/broken HEAD from interfering with repo discovery
+	test_must_fail env GIT_DIR=.git git fsck 2>out &&
+	cat out &&
+	grep "detached HEAD points" out
+'
+
+test_expect_success 'HEAD link pointing at a funny place' '
+	test_when_finished "mv .git/SAVED_HEAD .git/HEAD" &&
+	mv .git/HEAD .git/SAVED_HEAD &&
+	echo "ref: refs/funny/place" >.git/HEAD &&
+	# avoid corrupt/broken HEAD from interfering with repo discovery
+	test_must_fail env GIT_DIR=.git git fsck 2>out &&
+	cat out &&
+	grep "HEAD points to something strange" out
+'
+
 test_expect_success 'email without @ is okay' '
 	git cat-file commit HEAD >basis &&
 	sed "s/@/AT/" basis >okay &&
-- 
2.6.0-rc3-173-gf6e0645

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v6 5/8] branch: drop non-commit error reporting
  2015-09-23 20:10     ` Matthieu Moy
  2015-09-23 20:29       ` Junio C Hamano
@ 2015-09-23 22:50       ` Junio C Hamano
  1 sibling, 0 replies; 27+ messages in thread
From: Junio C Hamano @ 2015-09-23 22:50 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Karthik Nayak, git, christian.couder

Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:

> To be sure, I tried:
>
>   echo ee0f5eeeae36cd1b5a346a1e2ae5c8cb841cd5da > .git/refs/heads/broken
>
> where the sha1 is the one of a blob.
> ...

After doing (something like) the above, running "git push --mirror"
to various Git repositories shows their slightly different
behaviour.

The most intriguing one was github.com:gitster/git.git repository.

To github.com:gitster/git.git
 ! [remote rejected] jk/transfer-limit-protocol -> jk/transfer-limit-protocol (failed)
 ! [remote rejected] ls/p4-lfs -> ls/p4-lfs (failed)
 ...
 ! [remote rejected] pu -> pu (failed)
 ! [remote rejected] broken -> broken (failed)
 ! [remote rejected] jc/fsck-dropped-errors -> jc/fsck-dropped-errors (failed)
 ! [remote rejected] kn/for-each-branch -> kn/for-each-branch (failed)

After removing the broken branch, retrying "git push --mirror
github.com:gitster/git.git" was successful.  I didn't dig further
(it didn't reproduce with a pair of toy local repositories).

It is puzzling that it is behaving as if I am trying to perform an
atomic push and rejection of "broken" is causing everything else to
be rejected or something like that.

Perhaps GitHub has a pre-receive hook to reject such nonsense?

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter.
  2015-09-23 19:16   ` Junio C Hamano
@ 2015-09-24  6:01     ` Karthik Nayak
  0 siblings, 0 replies; 27+ messages in thread
From: Karthik Nayak @ 2015-09-24  6:01 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Matthieu Moy, Git, Christian Couder

On Thu, Sep 24, 2015 at 12:46 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:
>
>> The series looks good to me. I did a minor remark on PATCH 5/8 but this
>> should not block inclusion.
>
> Thanks.  As long as the log message is telling the truth, I do not
> mind the actual lossage of the error message shown to the user.
>

That needs to be changed, I'll reply with a changed commit, thanks!

-- 
Regards,
Karthik Nayak

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v6 5/8] branch: drop non-commit error reporting
  2015-09-23 18:57   ` Matthieu Moy
@ 2015-09-24  6:19     ` Karthik Nayak
  0 siblings, 0 replies; 27+ messages in thread
From: Karthik Nayak @ 2015-09-24  6:19 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Git, Christian Couder, Junio C Hamano

On Thu, Sep 24, 2015 at 12:27 AM, Matthieu Moy
<Matthieu.Moy@grenoble-inp.fr> wrote:
> Karthik Nayak <karthik.188@gmail.com> writes:
>
>> Remove the error reporting variable to make the code easier to port
>> over to using ref-filter APIs.
>>
>> This also removes the error from being displayed. As branch.c will use
>> ref-filter APIs in the following patches, the error checking becomes
>> redundant with the error reporting system found in the ref-filter
>> (ref-filter.c:1336).
>
> I would have written
>
> As branch.c will use ref-filter APIs in the following patches, the error
> checking becomes redundant with the error reporting system found in the
> ref-filter: error "branch '%s' does not point at a commit" is redundant
> with the check performed in ref_filter_handler (ref-filter.c:1336).
> Error "some refs could not be read" can only be triggered as a
> consequence of the first one hence becomes useless.

This looks better thanks.

>
>> @@ -370,10 +369,8 @@ static int append_ref(const char *refname, const struct object_id *oid, int flag
>>       commit = NULL;
>>       if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {
>>               commit = lookup_commit_reference_gently(oid->hash, 1);
>> -             if (!commit) {
>> -                     cb->ret = error(_("branch '%s' does not point at a commit"), refname);
>> +             if (!commit)
>>                       return 0;
>> -             }
>
> Am I correct that the "return 0" statement above is dead code after the
> end of the series?
>
> If so, you should add a comment explaining that it's there "just in
> case" but not supposed to happen, or replace the if statement with
> "assert(commit);" IMHO. I have a preference for assert(): I don't like
> silent failures.

This code is removed by the end of the series. We could use an assert()
in this patch, but I don't see the point, its removed later either ways when
we use ref-filter APIs.

-- 
Regards,
Karthik Nayak

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v6 5/8] branch: drop non-commit error reporting
  2015-09-23 19:14   ` Junio C Hamano
  2015-09-23 20:10     ` Matthieu Moy
@ 2015-09-24  6:23     ` Karthik Nayak
  1 sibling, 0 replies; 27+ messages in thread
From: Karthik Nayak @ 2015-09-24  6:23 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git, Christian Couder, Matthieu Moy

On Thu, Sep 24, 2015 at 12:44 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Karthik Nayak <karthik.188@gmail.com> writes:
>
>> Remove the error reporting variable to make the code easier to port
>> over to using ref-filter APIs.
>>
>> This also removes the error from being displayed. As branch.c will use
>> ref-filter APIs in the following patches, the error checking becomes
>> redundant with the error reporting system found in the ref-filter
>> (ref-filter.c:1336).
>
> Hmm, do you mean these lines by the above reference?
>
>         if (filter->merge_commit || filter->with_commit) {
>                 commit = lookup_commit_reference_gently(oid->hash, 1);
>                 if (!commit)
>                         return 0;
>
> That is "silently return ignoring it if it is not a commit", i.e.  I
> do not think that deserves to be called error REPORTING system.
>
> Do you really understand what the error message you are removing is
> trying to diagnose?  A branch ref must not point at a blob or any
> non-commit object, and if we find such a branch ref, we report it as
> error.  That is what the error message is about.

What you're saying makes sense, It doesn't reflect the fact that the error
reporting is dropped, rather seems to be substituted by ref-filter.

>
> Now, ref-filter.c:1336 has in no position to issue that same error
> message because it does not know what it is looking at is supposed
> to be a branch ref, so it is WRONG if it gave the same error
> message.  After all, the caller may be using ref-filter to filter
> refs/tags/* with merge_commit or with_commit and found a
> light-weight tag in refs/tags/* that points at a blob.  That is not
> an event we want to get an error at all.
>
> I do not think we terribly mind if this message goes away from this
> location.  "It is a wrong codepath whose purpose is not to diagnose
> and report a repository corruption.  If we care about such a
> repository corruption, we should report it from fsck instead", would
> bea valid justification for the removal of the message.

Seems good, I'll incorporate this into the commit message.

>
> It is not a valid justification to claim that it is made redundant,
> when you actually are simply LOSING the error reporting without
> giving the same error message from another codepath to make it truly
> redundant.

Yes, my bad, Will resend the patch.

-- 
Regards,
Karthik Nayak

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v6 5/8] branch: drop non-commit error reporting
  2015-09-23 21:44           ` Junio C Hamano
@ 2015-09-24  6:46             ` Matthieu Moy
  0 siblings, 0 replies; 27+ messages in thread
From: Matthieu Moy @ 2015-09-24  6:46 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Karthik Nayak, git, christian.couder

Junio C Hamano <gitster@pobox.com> writes:

> Junio C Hamano <gitster@pobox.com> writes:
>
>> Perhaps something like this (not even compile tested as both of my
>> worktrees are doing something else)....
>
> This time with a few additional tests.
>
> -- >8 --
> Subject: [PATCH] fsck: exit with non-zero when problems are found

Seems straightforwardly correct. And manually tested on my case, it does
work.

Thanks,

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v6b 5/8] branch: drop non-commit error reporting
  2015-09-23 18:11 [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Karthik Nayak
                   ` (8 preceding siblings ...)
  2015-09-23 19:00 ` [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Matthieu Moy
@ 2015-09-24 18:09 ` Karthik Nayak
  2015-09-25  5:55   ` Matthieu Moy
  9 siblings, 1 reply; 27+ messages in thread
From: Karthik Nayak @ 2015-09-24 18:09 UTC (permalink / raw)
  To: git; +Cc: christian.couder, Matthieu.Moy, gitster, Karthik Nayak, Karthik Nayak

Remove the error "branch '%s' does not point at a commit" in
apppend_ref() which reports branch refs which do not point to
commits. Also remove the error "some refs could not be read" in
print_ref_list() which is triggered as a consequence of the first
error.

This seems to be the wrong codepath whose purpose is not to diagnose
and report a repository corruption. If we care about such a repository
corruption, we should report it from fsck instead.

This also helps in a smooth port of branch.c to use ref-filter APIs
over the following patches. On the other hand, ref-filter ignores refs
which do not point at commits silently.

Based-on-patch-by: Jeff King <peff@peff.net>
Helped-by: Junio C Hamano <gitster@pobox.com>
Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 builtin/branch.c | 18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index 1a664ed..ebc3742 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -313,7 +313,6 @@ static char *resolve_symref(const char *src, const char *prefix)
 struct append_ref_cb {
 	struct ref_list *ref_list;
 	const char **pattern;
-	int ret;
 };
 
 static int match_patterns(const char **pattern, const char *refname)
@@ -370,10 +369,8 @@ static int append_ref(const char *refname, const struct object_id *oid, int flag
 	commit = NULL;
 	if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {
 		commit = lookup_commit_reference_gently(oid->hash, 1);
-		if (!commit) {
-			cb->ret = error(_("branch '%s' does not point at a commit"), refname);
+		if (!commit)
 			return 0;
-		}
 
 		/* Filter with with_commit if specified */
 		if (!is_descendant_of(commit, ref_list->with_commit))
@@ -617,7 +614,7 @@ static int calc_maxwidth(struct ref_list *refs, int remote_bonus)
 	return max;
 }
 
-static int print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char **pattern)
+static void print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit, const char **pattern)
 {
 	int i;
 	struct append_ref_cb cb;
@@ -642,7 +639,6 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
 		init_revisions(&ref_list.revs, NULL);
 	cb.ref_list = &ref_list;
 	cb.pattern = pattern;
-	cb.ret = 0;
 	/*
 	 * First we obtain all regular branch refs and if the HEAD is
 	 * detached then we insert that ref to the end of the ref_fist
@@ -693,11 +689,6 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru
 			       abbrev, detached, remote_prefix);
 
 	free_ref_list(&ref_list);
-
-	if (cb.ret)
-		error(_("some refs could not be read"));
-
-	return cb.ret;
 }
 
 static void rename_branch(const char *oldname, const char *newname, int force)
@@ -913,15 +904,14 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
 			die(_("branch name required"));
 		return delete_branches(argc, argv, delete > 1, kinds, quiet);
 	} else if (list) {
-		int ret;
 		/*  git branch --local also shows HEAD when it is detached */
 		if (kinds & REF_LOCAL_BRANCH)
 			kinds |= REF_DETACHED_HEAD;
-		ret = print_ref_list(kinds, detached, verbose, abbrev,
+		print_ref_list(kinds, detached, verbose, abbrev,
 					 with_commit, argv);
 		print_columns(&output, colopts, NULL);
 		string_list_clear(&output, 0);
-		return ret;
+		return 0;
 	}
 	else if (edit_description) {
 		const char *branch_name;
-- 
2.5.1

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v6b 5/8] branch: drop non-commit error reporting
  2015-09-24 18:09 ` [PATCH v6b 5/8] branch: drop non-commit error reporting Karthik Nayak
@ 2015-09-25  5:55   ` Matthieu Moy
  2015-09-25 16:00     ` Junio C Hamano
  0 siblings, 1 reply; 27+ messages in thread
From: Matthieu Moy @ 2015-09-25  5:55 UTC (permalink / raw)
  To: Karthik Nayak; +Cc: git, christian.couder, gitster

Karthik Nayak <karthik.188@gmail.com> writes:

> Remove the error "branch '%s' does not point at a commit" in
> apppend_ref() which reports branch refs which do not point to
> commits. Also remove the error "some refs could not be read" in
> print_ref_list() which is triggered as a consequence of the first
> error.
>
> This seems to be the wrong codepath whose purpose is not to diagnose
> and report a repository corruption. If we care about such a repository
> corruption, we should report it from fsck instead.

(We actually already report it from fsck indeed)

> This also helps in a smooth port of branch.c to use ref-filter APIs
> over the following patches. On the other hand, ref-filter ignores refs
> which do not point at commits silently.

Seems much better. Thanks,

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v6b 5/8] branch: drop non-commit error reporting
  2015-09-25  5:55   ` Matthieu Moy
@ 2015-09-25 16:00     ` Junio C Hamano
  2015-09-25 16:30       ` Matthieu Moy
  2015-09-25 18:37       ` Karthik Nayak
  0 siblings, 2 replies; 27+ messages in thread
From: Junio C Hamano @ 2015-09-25 16:00 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Karthik Nayak, git, christian.couder

Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:

> Karthik Nayak <karthik.188@gmail.com> writes:
>
>> Remove the error "branch '%s' does not point at a commit" in
>> apppend_ref() which reports branch refs which do not point to
>> commits. Also remove the error "some refs could not be read" in
>> print_ref_list() which is triggered as a consequence of the first
>> error.
>>
>> This seems to be the wrong codepath whose purpose is not to diagnose
>> and report a repository corruption. If we care about such a repository
>> corruption, we should report it from fsck instead.
>
> (We actually already report it from fsck indeed)
>
>> This also helps in a smooth port of branch.c to use ref-filter APIs
>> over the following patches. On the other hand, ref-filter ignores refs
>> which do not point at commits silently.
>
> Seems much better. Thanks,

Yes, it seems that I can just replace 5/8 with this and the
remainder can stay as they are.

While I was trying to address your "actually already report", I
spotted a typo and then found that the early part of the second
paragraph is a bit hard, so here is what I ended up with.

    branch: drop non-commit error reporting
    
    Remove the error "branch '%s' does not point at a commit" in
    append_ref(), which reports branch refs which do not point to
    commits.  Also remove the error "some refs could not be read" in
    print_ref_list() which is triggered as a consequence of the first
    error.
    
    The purpose of these codepaths is not to diagnose and report a
    repository corruption.  If we care about such a corruption, we
    should report it from fsck instead, which we already do.
    
    This also helps in a smooth port of branch.c to use ref-filter APIs
    over the following patches. On the other hand, ref-filter ignores refs
    which do not point at commits silently.
    
    Based-on-patch-by: Jeff King <peff@peff.net>
    Helped-by: Junio C Hamano <gitster@pobox.com>
    Mentored-by: Christian Couder <christian.couder@gmail.com>
    Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
    Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>

Thanks.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v6b 5/8] branch: drop non-commit error reporting
  2015-09-25 16:00     ` Junio C Hamano
@ 2015-09-25 16:30       ` Matthieu Moy
  2015-09-25 18:37       ` Karthik Nayak
  1 sibling, 0 replies; 27+ messages in thread
From: Matthieu Moy @ 2015-09-25 16:30 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Karthik Nayak, git, christian.couder

Junio C Hamano <gitster@pobox.com> writes:

> While I was trying to address your "actually already report", I
> spotted a typo and then found that the early part of the second
> paragraph is a bit hard, so here is what I ended up with.

LGTM.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v6b 5/8] branch: drop non-commit error reporting
  2015-09-25 16:00     ` Junio C Hamano
  2015-09-25 16:30       ` Matthieu Moy
@ 2015-09-25 18:37       ` Karthik Nayak
  1 sibling, 0 replies; 27+ messages in thread
From: Karthik Nayak @ 2015-09-25 18:37 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Matthieu Moy, Git, Christian Couder

On Fri, Sep 25, 2015 at 9:30 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:
>
>> Karthik Nayak <karthik.188@gmail.com> writes:
>>
>>> Remove the error "branch '%s' does not point at a commit" in
>>> apppend_ref() which reports branch refs which do not point to
>>> commits. Also remove the error "some refs could not be read" in
>>> print_ref_list() which is triggered as a consequence of the first
>>> error.
>>>
>>> This seems to be the wrong codepath whose purpose is not to diagnose
>>> and report a repository corruption. If we care about such a repository
>>> corruption, we should report it from fsck instead.
>>
>> (We actually already report it from fsck indeed)
>>
>>> This also helps in a smooth port of branch.c to use ref-filter APIs
>>> over the following patches. On the other hand, ref-filter ignores refs
>>> which do not point at commits silently.
>>
>> Seems much better. Thanks,
>
> Yes, it seems that I can just replace 5/8 with this and the
> remainder can stay as they are.
>
> While I was trying to address your "actually already report", I
> spotted a typo and then found that the early part of the second
> paragraph is a bit hard, so here is what I ended up with.
>
>     branch: drop non-commit error reporting
>
>     Remove the error "branch '%s' does not point at a commit" in
>     append_ref(), which reports branch refs which do not point to
>     commits.  Also remove the error "some refs could not be read" in
>     print_ref_list() which is triggered as a consequence of the first
>     error.
>
>     The purpose of these codepaths is not to diagnose and report a
>     repository corruption.  If we care about such a corruption, we
>     should report it from fsck instead, which we already do.
>
>     This also helps in a smooth port of branch.c to use ref-filter APIs
>     over the following patches. On the other hand, ref-filter ignores refs
>     which do not point at commits silently.
>
>     Based-on-patch-by: Jeff King <peff@peff.net>
>     Helped-by: Junio C Hamano <gitster@pobox.com>
>     Mentored-by: Christian Couder <christian.couder@gmail.com>
>     Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
>     Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
>     Signed-off-by: Junio C Hamano <gitster@pobox.com>
>
> Thanks.

Looks good to me, thanks :)

-- 
Regards,
Karthik Nayak

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2015-09-25 18:37 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-23 18:11 [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Karthik Nayak
2015-09-23 18:11 ` [PATCH v6 1/8] branch: refactor width computation Karthik Nayak
2015-09-23 18:11 ` [PATCH v6 2/8] branch: bump get_head_description() to the top Karthik Nayak
2015-09-23 18:11 ` [PATCH v6 3/8] branch: roll show_detached HEAD into regular ref_list Karthik Nayak
2015-09-23 18:11 ` [PATCH v6 4/8] branch: move 'current' check down to the presentation layer Karthik Nayak
2015-09-23 18:11 ` [PATCH v6 5/8] branch: drop non-commit error reporting Karthik Nayak
2015-09-23 18:57   ` Matthieu Moy
2015-09-24  6:19     ` Karthik Nayak
2015-09-23 19:14   ` Junio C Hamano
2015-09-23 20:10     ` Matthieu Moy
2015-09-23 20:29       ` Junio C Hamano
2015-09-23 20:38         ` Junio C Hamano
2015-09-23 21:44           ` Junio C Hamano
2015-09-24  6:46             ` Matthieu Moy
2015-09-23 22:50       ` Junio C Hamano
2015-09-24  6:23     ` Karthik Nayak
2015-09-23 18:11 ` [PATCH v6 6/8] branch.c: use 'ref-filter' data structures Karthik Nayak
2015-09-23 18:11 ` [PATCH v6 7/8] branch.c: use 'ref-filter' APIs Karthik Nayak
2015-09-23 18:11 ` [PATCH v6 8/8] branch: add '--points-at' option Karthik Nayak
2015-09-23 19:00 ` [PATCH v6 0/8] port branch.c to use the filtering part of ref-filter Matthieu Moy
2015-09-23 19:16   ` Junio C Hamano
2015-09-24  6:01     ` Karthik Nayak
2015-09-24 18:09 ` [PATCH v6b 5/8] branch: drop non-commit error reporting Karthik Nayak
2015-09-25  5:55   ` Matthieu Moy
2015-09-25 16:00     ` Junio C Hamano
2015-09-25 16:30       ` Matthieu Moy
2015-09-25 18:37       ` Karthik Nayak

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.