Git development
 help / color / mirror / Atom feed
* [PATCH/RFC v4 3/5] sha1_name: support @{-N} syntax in get_sha1()
From: Thomas Rast @ 2009-01-17 16:09 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Johannes Schindelin, Johannes Sixt, Johan Herland
In-Reply-To: <1232208597-29249-3-git-send-email-trast@student.ethz.ch>

Let get_sha1() parse the @{-N} syntax, with docs and tests.

Note that while @{-1}^2, @{-2}~5 and such are supported, @{-1}@{1} is
currently not allowed.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 Documentation/git-rev-parse.txt |    3 ++
 sha1_name.c                     |   16 +++++++--
 t/t1505-rev-parse-last.sh       |   71 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 87 insertions(+), 3 deletions(-)
 create mode 100755 t/t1505-rev-parse-last.sh

diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 2921da3..3ccef2f 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -212,6 +212,9 @@ when you run 'git-merge'.
   reflog of the current branch. For example, if you are on the
   branch 'blabla', then '@\{1\}' means the same as 'blabla@\{1\}'.
 
+* The special construct '@\{-<n>\}' means the <n>th branch checked out
+  before the current one.
+
 * A suffix '{caret}' to a revision parameter means the first parent of
   that commit object.  '{caret}<n>' means the <n>th parent (i.e.
   'rev{caret}'
diff --git a/sha1_name.c b/sha1_name.c
index 34e39db..9e1538e 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -297,6 +297,8 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
 	return logs_found;
 }
 
+static int get_sha1_1(const char *name, int len, unsigned char *sha1);
+
 static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
 {
 	static const char *warning = "warning: refname '%.*s' is ambiguous.\n";
@@ -307,7 +309,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
 	if (len == 40 && !get_sha1_hex(str, sha1))
 		return 0;
 
-	/* basic@{time or number} format to query ref-log */
+	/* basic@{time or number or -number} format to query ref-log */
 	reflog_len = at = 0;
 	if (str[len-1] == '}') {
 		for (at = 0; at < len - 1; at++) {
@@ -324,6 +326,16 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
 		return -1;
 
 	if (!len && reflog_len) {
+		struct strbuf buf = STRBUF_INIT;
+		int ret;
+		/* try the @{-N} syntax for n-th checkout */
+		ret = interpret_nth_last_branch(str+at, &buf);
+		if (ret > 0) {
+			/* substitute this branch name and restart */
+			return get_sha1_1(buf.buf, buf.len, sha1);
+		} else if (ret == 0) {
+			return -1;
+		}
 		/* allow "@{...}" to mean the current branch reflog */
 		refs_found = dwim_ref("HEAD", 4, sha1, &real_ref);
 	} else if (reflog_len)
@@ -379,8 +391,6 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
 	return 0;
 }
 
-static int get_sha1_1(const char *name, int len, unsigned char *sha1);
-
 static int get_parent(const char *name, int len,
 		      unsigned char *result, int idx)
 {
diff --git a/t/t1505-rev-parse-last.sh b/t/t1505-rev-parse-last.sh
new file mode 100755
index 0000000..1e49dd2
--- /dev/null
+++ b/t/t1505-rev-parse-last.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+test_description='test @{-N} syntax'
+
+. ./test-lib.sh
+
+
+make_commit () {
+	echo "$1" > "$1" &&
+	git add "$1" &&
+	git commit -m "$1"
+}
+
+
+test_expect_success 'setup' '
+
+	make_commit 1 &&
+	git branch side &&
+	make_commit 2 &&
+	make_commit 3 &&
+	git checkout side &&
+	make_commit 4 &&
+	git merge master &&
+	git checkout master
+
+'
+
+# 1 -- 2 -- 3 master
+#  \         \
+#   \         \
+#    --- 4 --- 5 side
+#
+# and 'side' should be the last branch
+
+git log --graph --all --pretty=oneline --decorate
+
+test_rev_equivalent () {
+
+	git rev-parse "$1" > expect &&
+	git rev-parse "$2" > output &&
+	test_cmp expect output
+
+}
+
+test_expect_success '@{-1} works' '
+	test_rev_equivalent side @{-1}
+'
+
+test_expect_success '@{-1}~2 works' '
+	test_rev_equivalent side~2 @{-1}~2
+'
+
+test_expect_success '@{-1}^2 works' '
+	test_rev_equivalent side^2 @{-1}^2
+'
+
+test_expect_failure '@{-1}@{1} works' '
+	test_rev_equivalent side@{1} @{-1}@{1}
+'
+
+test_expect_success '@{-2} works' '
+	test_rev_equivalent master @{-2}
+'
+
+test_expect_success '@{-3} fails' '
+	test_must_fail git rev-parse @{-3}
+'
+
+test_done
+
+
-- 
1.6.1.315.g92577

^ permalink raw reply related

* [PATCH/RFC v4 5/5] interpret_nth_last_branch(): avoid traversing the reflogs twice
From: Thomas Rast @ 2009-01-17 16:09 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Johannes Schindelin, Johannes Sixt, Johan Herland,
	Johannes Schindelin
In-Reply-To: <1232208597-29249-5-git-send-email-trast@student.ethz.ch>

From: Johannes Schindelin <Johannes.Schindelin@gmx.de>

Instead of traversing them twice, we just build a list of branch switches,
pick the one we're interested in, and free the list again.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 sha1_name.c |   61 ++++++++++++++++++++++++----------------------------------
 1 files changed, 25 insertions(+), 36 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 9e1538e..b21a1f0 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -5,6 +5,8 @@
 #include "blob.h"
 #include "tree-walk.h"
 #include "refs.h"
+#include "cache-tree.h"
+#include "string-list.h"
 
 static int find_short_object_filename(int len, const char *name, unsigned char *sha1)
 {
@@ -684,43 +686,31 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)
 	return retval;
 }
 
-struct grab_nth_branch_switch_cbdata {
-	int counting;
-	int nth;
-	struct strbuf *buf;
-};
-
-static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1,
+static int add_one_branch_switch(unsigned char *osha1, unsigned char *nsha1,
 				  const char *email, unsigned long timestamp, int tz,
 				  const char *message, void *cb_data)
 {
-	struct grab_nth_branch_switch_cbdata *cb = cb_data;
+	struct string_list *list = cb_data;
 	const char *match = NULL, *target = NULL;
 	size_t len;
 
-	if (!prefixcmp(message, "checkout: moving from ")) {
-		match = message + strlen("checkout: moving from ");
-		if ((target = strstr(match, " to ")) != NULL)
-			target += 4;
-	}
-
-	if (!match)
+	if (prefixcmp(message, "checkout: moving from "))
 		return 0;
 
-	len = target - match - 4;
-	if (target[len] == '\n' && !strncmp(match, target, len))
-		return 0;
+	match = message + strlen("checkout: moving from ");
 
-	if (cb->counting) {
-		cb->nth++;
-		return 0;
+	/* Is it "moving" from a branch to itself?  Then ignore it. */
+	if ((target = strstr(match, " to ")) != NULL) {
+		target += 4;
+		len = target - match - 4;
+		if (target[len] == '\n' && !strncmp(match, target, len))
+			return 0;
 	}
+	else
+		len = strchrnul(match, ' ') - match;
+
+	string_list_append(xstrndup(match, len), list);
 
-	if (cb->nth-- <= 0) {
-		strbuf_reset(cb->buf);
-		strbuf_add(cb->buf, match, len);
-		return 1;
-	}
 	return 0;
 }
 
@@ -738,7 +728,7 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1,
 int interpret_nth_last_branch(const char *name, struct strbuf *buf)
 {
 	int nth;
-	struct grab_nth_branch_switch_cbdata cb;
+	struct string_list branch_list = { NULL, 0, 0, 0 };
 	const char *brace;
 	char *num_end;
 
@@ -751,18 +741,17 @@ int interpret_nth_last_branch(const char *name, struct strbuf *buf)
 	if (num_end != brace)
 		return -1;
 
-	cb.counting = 1;
-	cb.nth = 0;
-	cb.buf = buf;
-	for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb);
+	for_each_reflog_ent("HEAD", add_one_branch_switch, &branch_list);
 
-	if (cb.nth < nth)
+	if (branch_list.nr < nth)
 		return 0;
 
-	cb.counting = 0;
-	cb.nth -= nth;
-	cb.buf = buf;
-	for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb);
+	strbuf_reset(buf);
+	strbuf_addstr(buf, branch_list.items[branch_list.nr - nth].string);
+
+	/* force free()ing the items */
+	branch_list.strdup_strings = 1;
+	string_list_clear(&branch_list, 0);
 
 	return brace-name+1;
 }
-- 
1.6.1.315.g92577

^ permalink raw reply related

* [PATCH/RFC v4 4/5] checkout: implement "-" abbreviation, add docs and tests
From: Thomas Rast @ 2009-01-17 16:09 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Johannes Schindelin, Johannes Sixt, Johan Herland
In-Reply-To: <1232208597-29249-4-git-send-email-trast@student.ethz.ch>

Have '-' mean the same as '@{-1}', i.e., the last branch we were on.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 Documentation/git-checkout.txt |    4 +++
 builtin-checkout.c             |    3 ++
 t/t2012-checkout-last.sh       |   50 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+), 0 deletions(-)
 create mode 100755 t/t2012-checkout-last.sh

diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 9cd5151..3bccffa 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -133,6 +133,10 @@ the conflicted merge in the specified paths.
 +
 When this parameter names a non-branch (but still a valid commit object),
 your HEAD becomes 'detached'.
++
+As a special case, the "`@\{-N\}`" syntax for the N-th last branch
+checks out the branch (instead of detaching).  You may also specify
+"`-`" which is synonymous with "`@\{-1\}`".
 
 
 Detached HEAD
diff --git a/builtin-checkout.c b/builtin-checkout.c
index dc1de06..b0a101b 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -679,6 +679,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		arg = argv[0];
 		has_dash_dash = (argc > 1) && !strcmp(argv[1], "--");
 
+		if (!strcmp(arg, "-"))
+			arg = "@{-1}";
+
 		if (get_sha1(arg, rev)) {
 			if (has_dash_dash)          /* case (1) */
 				die("invalid reference: %s", arg);
diff --git a/t/t2012-checkout-last.sh b/t/t2012-checkout-last.sh
new file mode 100755
index 0000000..320f6eb
--- /dev/null
+++ b/t/t2012-checkout-last.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+test_description='checkout can switch to last branch'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+	echo hello >world &&
+	git add world &&
+	git commit -m initial &&
+	git branch other &&
+	echo "hello again" >>world &&
+	git add world &&
+	git commit -m second
+'
+
+test_expect_success '"checkout -" does not work initially' '
+	test_must_fail git checkout -
+'
+
+test_expect_success 'first branch switch' '
+	git checkout other
+'
+
+test_expect_success '"checkout -" switches back' '
+	git checkout - &&
+	test "z$(git symbolic-ref HEAD)" = "zrefs/heads/master"
+'
+
+test_expect_success '"checkout -" switches forth' '
+	git checkout - &&
+	test "z$(git symbolic-ref HEAD)" = "zrefs/heads/other"
+'
+
+test_expect_success 'detach HEAD' '
+	git checkout $(git rev-parse HEAD)
+'
+
+test_expect_success '"checkout -" attaches again' '
+	git checkout - &&
+	test "z$(git symbolic-ref HEAD)" = "zrefs/heads/other"
+'
+
+test_expect_success '"checkout -" detaches again' '
+	git checkout - &&
+	test "z$(git rev-parse HEAD)" = "z$(git rev-parse other)" &&
+	test_must_fail git symbolic-ref HEAD
+'
+
+test_done
-- 
1.6.1.315.g92577

^ permalink raw reply related

* [PATCH/RFC v4 1/5] checkout: implement "@{-N}" shortcut name for N-th last branch
From: Thomas Rast @ 2009-01-17 16:09 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Johannes Schindelin, Johannes Sixt, Johan Herland,
	Junio C Hamano
In-Reply-To: <1232208597-29249-1-git-send-email-trast@student.ethz.ch>

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

Implement a shortcut @{-N} for the N-th last branch checked out, that
works by parsing the reflog for the message added by previous
git-checkout invocations.  We expand the @{-N} to the branch name, so
that you end up on an attached HEAD on that branch.
---
 builtin-checkout.c |   10 +++++-
 cache.h            |    1 +
 sha1_name.c        |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/builtin-checkout.c b/builtin-checkout.c
index b5dd9c0..a3b69d6 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -361,8 +361,14 @@ struct branch_info {
 static void setup_branch_path(struct branch_info *branch)
 {
 	struct strbuf buf = STRBUF_INIT;
-	strbuf_addstr(&buf, "refs/heads/");
-	strbuf_addstr(&buf, branch->name);
+
+	if (!interpret_nth_last_branch(branch->name, &buf)) {
+		branch->name = xstrdup(buf.buf);
+		strbuf_splice(&buf, 0, 0, "refs/heads/", 11);
+	} else {
+		strbuf_addstr(&buf, "refs/heads/");
+		strbuf_addstr(&buf, branch->name);
+	}
 	branch->path = strbuf_detach(&buf, NULL);
 }
 
diff --git a/cache.h b/cache.h
index 8e1af26..0dd9168 100644
--- a/cache.h
+++ b/cache.h
@@ -663,6 +663,7 @@ static inline unsigned int hexval(unsigned char c)
 extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *);
 extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref);
 extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref);
+extern int interpret_nth_last_branch(const char *str, struct strbuf *);
 
 extern int refname_match(const char *abbrev_name, const char *full_name, const char **rules);
 extern const char *ref_rev_parse_rules[];
diff --git a/sha1_name.c b/sha1_name.c
index 159c2ab..6377264 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -674,6 +674,84 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)
 	return retval;
 }
 
+struct grab_nth_branch_switch_cbdata {
+	int counting;
+	int nth;
+	struct strbuf *buf;
+};
+
+static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1,
+				  const char *email, unsigned long timestamp, int tz,
+				  const char *message, void *cb_data)
+{
+	struct grab_nth_branch_switch_cbdata *cb = cb_data;
+	const char *match = NULL;
+
+	if (!prefixcmp(message, "checkout: moving to "))
+		match = message + strlen("checkout: moving to ");
+	else if (!prefixcmp(message, "checkout: moving from ")) {
+		const char *cp = message + strlen("checkout: moving from ");
+		if ((cp = strstr(cp, " to ")) != NULL) {
+			match = cp + 4;
+		}
+	}
+
+	if (!match)
+		return 0;
+
+	if (cb->counting) {
+		cb->nth++;
+		return 0;
+	}
+
+	if (--cb->nth <= 0) {
+		size_t len = strlen(match);
+		while (match[len-1] == '\n')
+			len--;
+		strbuf_reset(cb->buf);
+		strbuf_add(cb->buf, match, len);
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * This reads "@{-N}" syntax, finds the name of the Nth previous
+ * branch we were on, and places the name of the branch in the given
+ * buf and returns 0 if successful.
+ *
+ * If the input is not of the accepted format, it returns a negative
+ * number to signal an error.
+ */
+int interpret_nth_last_branch(const char *name, struct strbuf *buf)
+{
+	int nth, i;
+	struct grab_nth_branch_switch_cbdata cb;
+
+	if (name[0] != '@' || name[1] != '{' || name[2] != '-')
+		return -1;
+	for (i = 3, nth = 0; name[i] && name[i] != '}'; i++) {
+		char ch = name[i];
+		if ('0' <= ch && ch <= '9')
+			nth = nth * 10 + ch - '0';
+		else
+			return -1;
+	}
+	if (nth < 0 || 10 <= nth)
+		return -1;
+
+	cb.counting = 1;
+	cb.nth = 0;
+	cb.buf = buf;
+	for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb);
+
+	cb.counting = 0;
+	cb.nth -= nth;
+	cb.buf = buf;
+	for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb);
+	return 0;
+}
+
 /*
  * This is like "get_sha1_basic()", except it allows "sha1 expressions",
  * notably "xyz^" for "parent of xyz"
-- 
1.6.1.315.g92577

^ permalink raw reply related

* [PATCH/RFC v4 2/5] sha1_name: tweak @{-N} lookup
From: Thomas Rast @ 2009-01-17 16:09 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Johannes Schindelin, Johannes Sixt, Johan Herland
In-Reply-To: <1232208597-29249-2-git-send-email-trast@student.ethz.ch>

Have the lookup only look at "interesting" checkouts, meaning those
that tell you "Already on ..." don't count even though they also cause
a reflog entry.

Let interpret_nth_last_branch() return the number of characters
parsed, so that git-checkout can verify that the branch spec was
@{-N}, not @{-1}^2 or something like that.  (The latter will be added
later.)

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 builtin-checkout.c |    4 ++-
 sha1_name.c        |   53 ++++++++++++++++++++++++++++-----------------------
 2 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/builtin-checkout.c b/builtin-checkout.c
index a3b69d6..dc1de06 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -361,8 +361,10 @@ struct branch_info {
 static void setup_branch_path(struct branch_info *branch)
 {
 	struct strbuf buf = STRBUF_INIT;
+	int ret;
 
-	if (!interpret_nth_last_branch(branch->name, &buf)) {
+	if ((ret = interpret_nth_last_branch(branch->name, &buf))
+	    && ret == strlen(branch->name)) {
 		branch->name = xstrdup(buf.buf);
 		strbuf_splice(&buf, 0, 0, "refs/heads/", 11);
 	} else {
diff --git a/sha1_name.c b/sha1_name.c
index 6377264..34e39db 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -685,29 +685,28 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1,
 				  const char *message, void *cb_data)
 {
 	struct grab_nth_branch_switch_cbdata *cb = cb_data;
-	const char *match = NULL;
-
-	if (!prefixcmp(message, "checkout: moving to "))
-		match = message + strlen("checkout: moving to ");
-	else if (!prefixcmp(message, "checkout: moving from ")) {
-		const char *cp = message + strlen("checkout: moving from ");
-		if ((cp = strstr(cp, " to ")) != NULL) {
-			match = cp + 4;
-		}
+	const char *match = NULL, *target = NULL;
+	size_t len;
+
+	if (!prefixcmp(message, "checkout: moving from ")) {
+		match = message + strlen("checkout: moving from ");
+		if ((target = strstr(match, " to ")) != NULL)
+			target += 4;
 	}
 
 	if (!match)
 		return 0;
 
+	len = target - match - 4;
+	if (target[len] == '\n' && !strncmp(match, target, len))
+		return 0;
+
 	if (cb->counting) {
 		cb->nth++;
 		return 0;
 	}
 
-	if (--cb->nth <= 0) {
-		size_t len = strlen(match);
-		while (match[len-1] == '\n')
-			len--;
+	if (cb->nth-- <= 0) {
 		strbuf_reset(cb->buf);
 		strbuf_add(cb->buf, match, len);
 		return 1;
@@ -718,26 +717,28 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1,
 /*
  * This reads "@{-N}" syntax, finds the name of the Nth previous
  * branch we were on, and places the name of the branch in the given
- * buf and returns 0 if successful.
+ * buf and returns the number of characters parsed if successful.
  *
  * If the input is not of the accepted format, it returns a negative
  * number to signal an error.
+ *
+ * If the input was ok but there are not N branch switches in the
+ * reflog, it returns 0.
  */
 int interpret_nth_last_branch(const char *name, struct strbuf *buf)
 {
-	int nth, i;
+	int nth;
 	struct grab_nth_branch_switch_cbdata cb;
+	const char *brace;
+	char *num_end;
 
 	if (name[0] != '@' || name[1] != '{' || name[2] != '-')
 		return -1;
-	for (i = 3, nth = 0; name[i] && name[i] != '}'; i++) {
-		char ch = name[i];
-		if ('0' <= ch && ch <= '9')
-			nth = nth * 10 + ch - '0';
-		else
-			return -1;
-	}
-	if (nth < 0 || 10 <= nth)
+	brace = strchr(name, '}');
+	if (!brace)
+		return -1;
+	nth = strtol(name+3, &num_end, 10);
+	if (num_end != brace)
 		return -1;
 
 	cb.counting = 1;
@@ -745,11 +746,15 @@ int interpret_nth_last_branch(const char *name, struct strbuf *buf)
 	cb.buf = buf;
 	for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb);
 
+	if (cb.nth < nth)
+		return 0;
+
 	cb.counting = 0;
 	cb.nth -= nth;
 	cb.buf = buf;
 	for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb);
-	return 0;
+
+	return brace-name+1;
 }
 
 /*
-- 
1.6.1.315.g92577

^ permalink raw reply related

* [PATCH/RFC v4 0/5] N-th last checked out branch
From: Thomas Rast @ 2009-01-17 16:09 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Johannes Schindelin, Johannes Sixt, Johan Herland
In-Reply-To: <alpine.DEB.1.00.0901171602340.3586@pacific.mpi-cbg.de>

Johannes Schindelin wrote:
> 
> Instead of traversing them twice, we just build a list of branch switches,
> pick the one we're interested in, and free the list again.
> 
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
> 
> On Sat, 17 Jan 2009, Thomas Rast wrote:
> 
> > Johannes Schindelin wrote:
> > 
> > > I really have to ask: why did you not work on top of Junio's 
> > > patch, just adding docs, tests, and checkout -?  And then -- maybe -- 
> > > the string_list...
> 
> Of course, I meant the patch as-is, with Junio as author.  But 
> hey, if he does not care...

*shrug*

For one thing there was no commit message.

I made up a message, split the changes I made into smaller patches,
and added a fixed up version of your patch on top, since it had some
context that is not in any version I have.


Johannes Schindelin (1):
  interpret_nth_last_branch(): avoid traversing the reflogs twice

Junio C Hamano (1):
  checkout: implement "@{-N}" shortcut name for N-th last branch

Thomas Rast (3):
  sha1_name: tweak @{-N} lookup
  sha1_name: support @{-N} syntax in get_sha1()
  checkout: implement "-" abbreviation, add docs and tests

 Documentation/git-checkout.txt  |    4 ++
 Documentation/git-rev-parse.txt |    3 +
 builtin-checkout.c              |   15 ++++++-
 cache.h                         |    1 +
 sha1_name.c                     |   88 +++++++++++++++++++++++++++++++++++++-
 t/t1505-rev-parse-last.sh       |   71 +++++++++++++++++++++++++++++++
 t/t2012-checkout-last.sh        |   50 ++++++++++++++++++++++
 7 files changed, 227 insertions(+), 5 deletions(-)
 create mode 100755 t/t1505-rev-parse-last.sh
 create mode 100755 t/t2012-checkout-last.sh

^ permalink raw reply

* [PATCH 4/4] Add is_regex_special()
From: René Scharfe @ 2009-01-17 15:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Alex Riesen, Git Mailing List
In-Reply-To: <7vy6xfd3oh.fsf@gitster.siamese.dyndns.org>

Add is_regex_special(), a character class macro for chars that have a
special meaning in regular expressions.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
This patch applies to next (plus the previous ones in this series).

 ctype.c           |    7 ++++---
 git-compat-util.h |    2 ++
 grep.c            |    9 +--------
 test-ctype.c      |    6 ++++++
 4 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/ctype.c b/ctype.c
index 9de187c..b90ec00 100644
--- a/ctype.c
+++ b/ctype.c
@@ -10,16 +10,17 @@ enum {
 	A = GIT_ALPHA,
 	D = GIT_DIGIT,
 	G = GIT_GLOB_SPECIAL,	/* *, ?, [, \\ */
+	R = GIT_REGEX_SPECIAL,	/* $, (, ), +, ., ^, {, | * */
 };
 
 unsigned char sane_ctype[256] = {
 	0, 0, 0, 0, 0, 0, 0, 0, 0, S, S, 0, 0, S, 0, 0,		/*   0.. 15 */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		/*  16.. 31 */
-	S, 0, 0, 0, 0, 0, 0, 0, 0, 0, G, 0, 0, 0, 0, 0,		/*  32.. 47 */
+	S, 0, 0, 0, R, 0, 0, 0, R, R, G, R, 0, 0, R, 0,		/*  32.. 47 */
 	D, D, D, D, D, D, D, D, D, D, 0, 0, 0, 0, 0, G,		/*  48.. 63 */
 	0, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,		/*  64.. 79 */
-	A, A, A, A, A, A, A, A, A, A, A, G, G, 0, 0, 0,		/*  80.. 95 */
+	A, A, A, A, A, A, A, A, A, A, A, G, G, 0, R, 0,		/*  80.. 95 */
 	0, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,		/*  96..111 */
-	A, A, A, A, A, A, A, A, A, A, A, 0, 0, 0, 0, 0,		/* 112..127 */
+	A, A, A, A, A, A, A, A, A, A, A, R, R, 0, 0, 0,		/* 112..127 */
 	/* Nothing in the 128.. range */
 };
diff --git a/git-compat-util.h b/git-compat-util.h
index 7c92588..079cbe9 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -328,12 +328,14 @@ extern unsigned char sane_ctype[256];
 #define GIT_DIGIT 0x02
 #define GIT_ALPHA 0x04
 #define GIT_GLOB_SPECIAL 0x08
+#define GIT_REGEX_SPECIAL 0x10
 #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
 #define isspace(x) sane_istest(x,GIT_SPACE)
 #define isdigit(x) sane_istest(x,GIT_DIGIT)
 #define isalpha(x) sane_istest(x,GIT_ALPHA)
 #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
 #define is_glob_special(x) sane_istest(x,GIT_GLOB_SPECIAL)
+#define is_regex_special(x) sane_istest(x,GIT_GLOB_SPECIAL | GIT_REGEX_SPECIAL)
 #define tolower(x) sane_case((unsigned char)(x), 0x20)
 #define toupper(x) sane_case((unsigned char)(x), 0)
 
diff --git a/grep.c b/grep.c
index f9a4525..062b2b6 100644
--- a/grep.c
+++ b/grep.c
@@ -28,16 +28,9 @@ void append_grep_pattern(struct grep_opt *opt, const char *pat,
 	p->next = NULL;
 }
 
-static int isregexspecial(int c)
-{
-	return c == '\0' || is_glob_special(c) ||
-		c == '$' || c == '(' || c == ')' || c == '+' ||
-		c == '.' || c == '^' || c == '{' || c == '|';
-}
-
 static int is_fixed(const char *s)
 {
-	while (!isregexspecial(*s))
+	while (*s && !is_regex_special(*s))
 		s++;
 	return !*s;
 }
diff --git a/test-ctype.c b/test-ctype.c
index d6425d5..033c749 100644
--- a/test-ctype.c
+++ b/test-ctype.c
@@ -26,6 +26,11 @@ static int test_is_glob_special(int c)
 	return is_glob_special(c);
 }
 
+static int test_is_regex_special(int c)
+{
+	return is_regex_special(c);
+}
+
 #define DIGIT "0123456789"
 #define LOWER "abcdefghijklmnopqrstuvwxyz"
 #define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -40,6 +45,7 @@ static const struct ctype_class {
 	{ "isalpha", test_isalpha, LOWER UPPER },
 	{ "isalnum", test_isalnum, LOWER UPPER DIGIT },
 	{ "is_glob_special", test_is_glob_special, "*?[\\" },
+	{ "is_regex_special", test_is_regex_special, "$()*+.?[\\^{|" },
 	{ NULL }
 };
 
-- 
1.6.1

^ permalink raw reply related

* [PATCH 3/4] Change NUL char handling of isspecial()
From: René Scharfe @ 2009-01-17 15:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Alex Riesen, Git Mailing List
In-Reply-To: <7vy6xfd3oh.fsf@gitster.siamese.dyndns.org>

Replace isspecial() by the new macro is_glob_special(), which is more,
well, specialized.  The former included the NUL char in its character
class, while the letter only included characters that are special to
file name globbing.

The new name contains underscores because they enhance readability
considerably now that it's made up of three words.  Renaming the
function is necessary to document its changed scope.

The call sites of isspecial() are updated to check explicitly for NUL.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
This patch applies to next (plus the previous ones in this series).

 ctype.c           |    4 ++--
 dir.c             |    4 ++--
 git-compat-util.h |    4 ++--
 grep.c            |    5 +++--
 test-ctype.c      |    6 ++++++
 5 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/ctype.c b/ctype.c
index 6528687..9de187c 100644
--- a/ctype.c
+++ b/ctype.c
@@ -9,11 +9,11 @@ enum {
 	S = GIT_SPACE,
 	A = GIT_ALPHA,
 	D = GIT_DIGIT,
-	G = GIT_SPECIAL,	/* \0, *, ?, [, \\ */
+	G = GIT_GLOB_SPECIAL,	/* *, ?, [, \\ */
 };
 
 unsigned char sane_ctype[256] = {
-	G, 0, 0, 0, 0, 0, 0, 0, 0, S, S, 0, 0, S, 0, 0,		/*   0.. 15 */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, S, S, 0, 0, S, 0, 0,		/*   0.. 15 */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		/*  16.. 31 */
 	S, 0, 0, 0, 0, 0, 0, 0, 0, 0, G, 0, 0, 0, 0, 0,		/*  32.. 47 */
 	D, D, D, D, D, D, D, D, D, D, 0, 0, 0, 0, 0, G,		/*  48.. 63 */
diff --git a/dir.c b/dir.c
index 7c59829..d55a41a 100644
--- a/dir.c
+++ b/dir.c
@@ -75,7 +75,7 @@ static int match_one(const char *match, const char *name, int namelen)
 	for (;;) {
 		unsigned char c1 = *match;
 		unsigned char c2 = *name;
-		if (isspecial(c1))
+		if (c1 == '\0' || is_glob_special(c1))
 			break;
 		if (c1 != c2)
 			return 0;
@@ -678,7 +678,7 @@ static int simple_length(const char *match)
 	for (;;) {
 		unsigned char c = *match++;
 		len++;
-		if (isspecial(c))
+		if (c == '\0' || is_glob_special(c))
 			return len;
 	}
 }
diff --git a/git-compat-util.h b/git-compat-util.h
index e20b1e8..7c92588 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -327,13 +327,13 @@ extern unsigned char sane_ctype[256];
 #define GIT_SPACE 0x01
 #define GIT_DIGIT 0x02
 #define GIT_ALPHA 0x04
-#define GIT_SPECIAL 0x08
+#define GIT_GLOB_SPECIAL 0x08
 #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
 #define isspace(x) sane_istest(x,GIT_SPACE)
 #define isdigit(x) sane_istest(x,GIT_DIGIT)
 #define isalpha(x) sane_istest(x,GIT_ALPHA)
 #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
-#define isspecial(x) sane_istest(x,GIT_SPECIAL)
+#define is_glob_special(x) sane_istest(x,GIT_GLOB_SPECIAL)
 #define tolower(x) sane_case((unsigned char)(x), 0x20)
 #define toupper(x) sane_case((unsigned char)(x), 0)
 
diff --git a/grep.c b/grep.c
index 6485760..f9a4525 100644
--- a/grep.c
+++ b/grep.c
@@ -30,8 +30,9 @@ void append_grep_pattern(struct grep_opt *opt, const char *pat,
 
 static int isregexspecial(int c)
 {
-	return isspecial(c) || c == '$' || c == '(' || c == ')' || c == '+' ||
-			       c == '.' || c == '^' || c == '{' || c == '|';
+	return c == '\0' || is_glob_special(c) ||
+		c == '$' || c == '(' || c == ')' || c == '+' ||
+		c == '.' || c == '^' || c == '{' || c == '|';
 }
 
 static int is_fixed(const char *s)
diff --git a/test-ctype.c b/test-ctype.c
index 723eff4..d6425d5 100644
--- a/test-ctype.c
+++ b/test-ctype.c
@@ -21,6 +21,11 @@ static int test_isalnum(int c)
 	return isalnum(c);
 }
 
+static int test_is_glob_special(int c)
+{
+	return is_glob_special(c);
+}
+
 #define DIGIT "0123456789"
 #define LOWER "abcdefghijklmnopqrstuvwxyz"
 #define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -34,6 +39,7 @@ static const struct ctype_class {
 	{ "isspace", test_isspace, " \n\r\t" },
 	{ "isalpha", test_isalpha, LOWER UPPER },
 	{ "isalnum", test_isalnum, LOWER UPPER DIGIT },
+	{ "is_glob_special", test_is_glob_special, "*?[\\" },
 	{ NULL }
 };
 
-- 
1.6.1

^ permalink raw reply related

* [PATCH 2/4] Reformat ctype.c
From: René Scharfe @ 2009-01-17 15:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Alex Riesen, Git Mailing List
In-Reply-To: <7vy6xfd3oh.fsf@gitster.siamese.dyndns.org>

Enhance the readability of ctype.c by using an enum instead of macros
to initialize the character class table.  This allows the use of a single
letter to mark a char, making the table fit within 80 columns.

Also list the index of the last entry in each row in the following comment.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 ctype.c |   32 ++++++++++++++------------------
 1 files changed, 14 insertions(+), 18 deletions(-)

diff --git a/ctype.c b/ctype.c
index 9208d67..6528687 100644
--- a/ctype.c
+++ b/ctype.c
@@ -5,25 +5,21 @@
  */
 #include "cache.h"
 
-/* Just so that no insane platform contaminate namespace with these symbols */
-#undef SS
-#undef AA
-#undef DD
-#undef GS
-
-#define SS GIT_SPACE
-#define AA GIT_ALPHA
-#define DD GIT_DIGIT
-#define GS GIT_SPECIAL  /* \0, *, ?, [, \\ */
+enum {
+	S = GIT_SPACE,
+	A = GIT_ALPHA,
+	D = GIT_DIGIT,
+	G = GIT_SPECIAL,	/* \0, *, ?, [, \\ */
+};
 
 unsigned char sane_ctype[256] = {
-	GS,  0,  0,  0,  0,  0,  0,  0,  0, SS, SS,  0,  0, SS,  0,  0,		/* 0-15 */
-	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,		/* 16-15 */
-	SS,  0,  0,  0,  0,  0,  0,  0,  0,  0, GS,  0,  0,  0,  0,  0,		/* 32-15 */
-	DD, DD, DD, DD, DD, DD, DD, DD, DD, DD,  0,  0,  0,  0,  0, GS,		/* 48-15 */
-	 0, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA,		/* 64-15 */
-	AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, GS, GS,  0,  0,  0,		/* 80-15 */
-	 0, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA,		/* 96-15 */
-	AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA,  0,  0,  0,  0,  0,		/* 112-15 */
+	G, 0, 0, 0, 0, 0, 0, 0, 0, S, S, 0, 0, S, 0, 0,		/*   0.. 15 */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		/*  16.. 31 */
+	S, 0, 0, 0, 0, 0, 0, 0, 0, 0, G, 0, 0, 0, 0, 0,		/*  32.. 47 */
+	D, D, D, D, D, D, D, D, D, D, 0, 0, 0, 0, 0, G,		/*  48.. 63 */
+	0, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,		/*  64.. 79 */
+	A, A, A, A, A, A, A, A, A, A, A, G, G, 0, 0, 0,		/*  80.. 95 */
+	0, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,		/*  96..111 */
+	A, A, A, A, A, A, A, A, A, A, A, 0, 0, 0, 0, 0,		/* 112..127 */
 	/* Nothing in the 128.. range */
 };
-- 
1.6.1

^ permalink raw reply related

* [PATCH 1/4] Add ctype test
From: René Scharfe @ 2009-01-17 15:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Alex Riesen, Git Mailing List
In-Reply-To: <7vy6xfd3oh.fsf@gitster.siamese.dyndns.org>

Manipulating the character class table in ctype.c by hand is error prone.
To ensure that typos are found quickly, add a test program and script.

test-ctype checks the output of the character class macros isspace() et.
al. by applying them on all possible char values and consulting a list of
all characters in the particular class.  It doesn't check tolower() and
toupper(); this could be added later.

The test script t0070-fundamental.sh is created because there is no good
place for the ctype test, yet -- except for t0000-basic.sh perhaps, but
it doesn't run well on Windows, yet.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 Makefile               |    3 ++
 t/t0070-fundamental.sh |   15 +++++++++++
 test-ctype.c           |   66 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 84 insertions(+), 0 deletions(-)
 create mode 100755 t/t0070-fundamental.sh
 create mode 100644 test-ctype.c

diff --git a/Makefile b/Makefile
index 4b1d488..dca61f5 100644
--- a/Makefile
+++ b/Makefile
@@ -1360,6 +1360,7 @@ endif
 ### Testing rules
 
 TEST_PROGRAMS += test-chmtime$X
+TEST_PROGRAMS += test-ctype$X
 TEST_PROGRAMS += test-date$X
 TEST_PROGRAMS += test-delta$X
 TEST_PROGRAMS += test-genrandom$X
@@ -1379,6 +1380,8 @@ export NO_SVN_TESTS
 test: all
 	$(MAKE) -C t/ all
 
+test-ctype$X: ctype.o
+
 test-date$X: date.o ctype.o
 
 test-delta$X: diff-delta.o patch-delta.o
diff --git a/t/t0070-fundamental.sh b/t/t0070-fundamental.sh
new file mode 100755
index 0000000..680d7d6
--- /dev/null
+++ b/t/t0070-fundamental.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+test_description='check that the most basic functions work
+
+
+Verify wrappers and compatibility functions.
+'
+
+. ./test-lib.sh
+
+test_expect_success 'character classes (isspace, isalpha etc.)' '
+	test-ctype
+'
+
+test_done
diff --git a/test-ctype.c b/test-ctype.c
new file mode 100644
index 0000000..723eff4
--- /dev/null
+++ b/test-ctype.c
@@ -0,0 +1,66 @@
+#include "cache.h"
+
+
+static int test_isdigit(int c)
+{
+	return isdigit(c);
+}
+
+static int test_isspace(int c)
+{
+	return isspace(c);
+}
+
+static int test_isalpha(int c)
+{
+	return isalpha(c);
+}
+
+static int test_isalnum(int c)
+{
+	return isalnum(c);
+}
+
+#define DIGIT "0123456789"
+#define LOWER "abcdefghijklmnopqrstuvwxyz"
+#define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+
+static const struct ctype_class {
+	const char *name;
+	int (*test_fn)(int);
+	const char *members;
+} classes[] = {
+	{ "isdigit", test_isdigit, DIGIT },
+	{ "isspace", test_isspace, " \n\r\t" },
+	{ "isalpha", test_isalpha, LOWER UPPER },
+	{ "isalnum", test_isalnum, LOWER UPPER DIGIT },
+	{ NULL }
+};
+
+static int test_class(const struct ctype_class *test)
+{
+	int i, rc = 0;
+
+	for (i = 0; i < 256; i++) {
+		int expected = i ? !!strchr(test->members, i) : 0;
+		int actual = test->test_fn(i);
+
+		if (actual != expected) {
+			rc = 1;
+			printf("%s classifies char %d (0x%02x) wrongly\n",
+			       test->name, i, i);
+		}
+	}
+	return rc;
+}
+
+int main(int argc, char **argv)
+{
+	const struct ctype_class *test;
+	int rc = 0;
+
+	for (test = classes; test->name; test++)
+		rc |= test_class(test);
+
+	return rc;
+}
-- 
1.6.1

^ permalink raw reply related

* Re: [RFC] Making format-patch output better when blank line is missing?
From: Jeff King @ 2009-01-17 15:47 UTC (permalink / raw)
  To: Adeodato Simó; +Cc: git
In-Reply-To: <20090117123545.GA22842@chistera.yi.org>

On Sat, Jan 17, 2009 at 01:35:45PM +0100, Adeodato Simó wrote:

> I'm using git-format-patch to send commit diff emails, and it was
> recently brought to my atention that if a commit message consists
> entirely in a paragraph with no blank lines (particluarly, no blank line
> after the first line, which is not a summary but just the first line of
> the paragraph), git-format-patch will place all the commit message in
> the Subject, which is inconvenient to read.

Yeah, such messages don't really interact well with the idea of a
subject/body commit format.

> Do you think it would be good to have format-patch do something like
> this in this case?:
> 
>     Subject: [PATCH] This commit introduces a new function bla() that [...]
> 
>     [...] makes it possible to apply the frobniz operation to objects
>     that don't bla bla bla bla.
> 
> (I realize that, with this, the applying logic would have to learn about
> it. Hm.)

I think it would be more readable to simply limit the subject line, add
"...", and then repeat the whole paragraph in the body. Then worst case,
the person applying just gets the text repeated, like:

  This commit introduces a new function bla() that...

  This commit introduces a new function bla() that makes it possible to
  aply the forbniz operation to objects that don't bla bla bla bla.

which is actually pretty reasonable. And best case, the person applying
fixes it up appropriately. But I don't know if it is worth trying to
come up with a reversible format. Patches sent through email are meant
to preserve what's on the other end, but it doesn't _have_ to be exact,
especially in the face of somebody ignoring the workflow conventions
that the patch format is meant to support.

-Peff

^ permalink raw reply

* Re: Cyellow, was Re: [a way-too-long line]
From: Johannes Schindelin @ 2009-01-17 15:46 UTC (permalink / raw)
  To: Jeff King
  Cc: Markus Heidelberg, Baz, Adeodato Simó,
	Boyd Stephen Smith Jr., Shawn O. Pearce, Ted Pavlic, git,
	Junio C Hamano
In-Reply-To: <20090117154052.GC27071@coredump.intra.peff.net>

Hi,

On Sat, 17 Jan 2009, Jeff King wrote:

> On Sat, Jan 17, 2009 at 04:39:10PM +0100, Johannes Schindelin wrote:
> 
> > > True. I was going to suggest %Cyellow, but for some reason only red, 
> > > green, and blue are implemented. How silly. Patch series to follow.
> > 
> > http://repo.or.cz/w/git/dscho.git?a=commitdiff;h=af6ee188b3533e9c8eb665066ed0be32d58be875
> 
> :) Yes, that does work, but please see the series I just posted:
> 
>   http://article.gmane.org/gmane.comp.version-control.git/106062
> 
> which I think is a better solution.

Definitely.

Mail from the list seems to be lagging these days... Sigh.

Ciao,
Dscho

^ permalink raw reply

* [PATCH] t5540: clarify that http-push does not handle packed-refs on the remote
From: Johannes Schindelin @ 2009-01-17 15:41 UTC (permalink / raw)
  To: git, gitster
In-Reply-To: <alpine.DEB.1.00.0901171632330.3586@pacific.mpi-cbg.de>


Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	On Sat, 17 Jan 2009, Johannes Schindelin wrote:

	> 	Note that the push in t5540 is still broken, as http-push does
	> 	not handle packed-refs (when looking what branches are on the 
	> 	remote side).

	... and this clarifies the issue.

 t/t5540-http-push.sh |   18 +++++++++++++++---
 1 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/t/t5540-http-push.sh b/t/t5540-http-push.sh
index 22cfbb6..c236b5e 100755
--- a/t/t5540-http-push.sh
+++ b/t/t5540-http-push.sh
@@ -51,17 +51,29 @@ test_expect_success 'clone remote repository' '
 	git clone $HTTPD_URL/test_repo.git test_repo_clone
 '
 
-test_expect_failure 'push to remote repository' '
+test_expect_failure 'push to remote repository with packed refs' '
 	cd "$ROOT_PATH"/test_repo_clone &&
 	: >path2 &&
 	git add path2 &&
 	test_tick &&
 	git commit -m path2 &&
+	HEAD=$(git rev-parse --verify HEAD) &&
 	git push &&
-	[ -f "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/refs/heads/master" ]
+	(cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
+	 test $HEAD = $(git rev-parse --verify HEAD))
 '
 
-test_expect_failure 'create and delete remote branch' '
+test_expect_success ' push to remote repository with unpacked refs' '
+	(cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
+	 rm packed-refs &&
+	 git update-ref refs/heads/master \
+		0c973ae9bd51902a28466f3850b543fa66a6aaf4) &&
+	git push &&
+	(cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
+	 test $HEAD = $(git rev-parse --verify HEAD))
+'
+
+test_expect_success 'create and delete remote branch' '
 	cd "$ROOT_PATH"/test_repo_clone &&
 	git checkout -b dev &&
 	: >path3 &&
-- 
1.6.1.325.g062d4

^ permalink raw reply related

* Re: Cyellow, was Re: [a way-too-long line]
From: Jeff King @ 2009-01-17 15:40 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Markus Heidelberg, Baz, Adeodato Simó,
	Boyd Stephen Smith Jr., Shawn O. Pearce, Ted Pavlic, git,
	Junio C Hamano
In-Reply-To: <alpine.DEB.1.00.0901171638250.3586@pacific.mpi-cbg.de>

On Sat, Jan 17, 2009 at 04:39:10PM +0100, Johannes Schindelin wrote:

> > True. I was going to suggest %Cyellow, but for some reason only red, 
> > green, and blue are implemented. How silly. Patch series to follow.
> 
> http://repo.or.cz/w/git/dscho.git?a=commitdiff;h=af6ee188b3533e9c8eb665066ed0be32d58be875

:) Yes, that does work, but please see the series I just posted:

  http://article.gmane.org/gmane.comp.version-control.git/106062

which I think is a better solution.

-Peff

^ permalink raw reply

* Where's Nick?, was Re: [PATCH] http-push: fix off-by-path_len
From: Johannes Schindelin @ 2009-01-17 15:40 UTC (permalink / raw)
  To: git
In-Reply-To: <alpine.DEB.1.00.0901171632330.3586@pacific.mpi-cbg.de>

Hi,

Nick's email address seems to be no longer functional.  Any idea where 
he's hanging about these days?

Ciao,
Dscho

^ permalink raw reply

* [PATCH 2/2] expand --pretty=format color options
From: Jeff King @ 2009-01-17 15:38 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Markus Heidelberg, git, René Scharfe
In-Reply-To: <20090117152108.GA24899@coredump.intra.peff.net>

Currently, the only colors available to --pretty=format
users are red, green, and blue. Rather than expand it with a
few new colors, this patch makes the usual config color
syntax available, including more colors, backgrounds, and
attributes.

Because colors are no longer bounded to a single word (e.g.,
%Cred), this uses a more advanced syntax that features a
beginning and end delimiter (but the old syntax still
works). So you can now do:

  git log --pretty=tformat:'%C(yellow)%h%C(reset) %s'

to emulate --pretty=oneline, or even

  git log --pretty=tformat:'%C(cyan magenta bold)%s%C(reset)'

if you want to relive the awesomeness of 4-color CGA.

Signed-off-by: Jeff King <peff@peff.net>
---
René: I saw you mention an end goal of implementing the other --pretty
formats in terms of --pretty=format:. So maybe this will help just a
little.

 Documentation/pretty-formats.txt |    1 +
 pretty.c                         |   12 ++++++++++++
 t/t6006-rev-list-format.sh       |    9 ++++++++-
 3 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 0a8a948..3d87d3e 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -124,6 +124,7 @@ The placeholders are:
 - '%Cgreen': switch color to green
 - '%Cblue': switch color to blue
 - '%Creset': reset color
+- '%C(...)': color specification, as described in color.branch.* config option
 - '%m': left, right or boundary mark
 - '%n': newline
 - '%x00': print a byte from a hex code
diff --git a/pretty.c b/pretty.c
index 343dca5..b1b8620 100644
--- a/pretty.c
+++ b/pretty.c
@@ -6,6 +6,7 @@
 #include "string-list.h"
 #include "mailmap.h"
 #include "log-tree.h"
+#include "color.h"
 
 static char *user_format;
 
@@ -554,6 +555,17 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 	/* these are independent of the commit */
 	switch (placeholder[0]) {
 	case 'C':
+		if (placeholder[1] == '(') {
+			const char *end = strchr(placeholder + 2, ')');
+			char color[COLOR_MAXLEN];
+			if (!end)
+				return 0;
+			color_parse_mem(placeholder + 2,
+					end - (placeholder + 2),
+					"--pretty format", color);
+			strbuf_addstr(sb, color);
+			return end - placeholder + 1;
+		}
 		if (!prefixcmp(placeholder + 1, "red")) {
 			strbuf_addstr(sb, "\033[31m");
 			return 4;
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index 86bf7e1..59d1f62 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -14,7 +14,7 @@ touch foo && git add foo && git commit -m "added foo" &&
 test_format() {
 	cat >expect.$1
 	test_expect_success "format $1" "
-git rev-list --pretty=format:$2 master >output.$1 &&
+git rev-list --pretty=format:'$2' master >output.$1 &&
 test_cmp expect.$1 output.$1
 "
 }
@@ -101,6 +101,13 @@ commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
 ^[[31mfoo^[[32mbar^[[34mbaz^[[mxyzzy
 EOF
 
+test_format advanced-colors '%C(red yellow bold)foo%C(reset)' <<'EOF'
+commit 131a310eb913d107dd3c09a65d1651175898735d
+^[[1;31;43mfoo^[[m
+commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
+^[[1;31;43mfoo^[[m
+EOF
+
 cat >commit-msg <<'EOF'
 Test printing of complex bodies
 
-- 
1.6.1.238.g32268.dirty

^ permalink raw reply related

* Cyellow, was Re: [a way-too-long line]
From: Johannes Schindelin @ 2009-01-17 15:39 UTC (permalink / raw)
  To: Jeff King
  Cc: Markus Heidelberg, Baz, Adeodato Simó,
	Boyd Stephen Smith Jr., Shawn O. Pearce, Ted Pavlic, git,
	Junio C Hamano
In-Reply-To: <20090117152108.GA24899@coredump.intra.peff.net>

Hi,

On Sat, 17 Jan 2009, Jeff King wrote:

> True. I was going to suggest %Cyellow, but for some reason only red, 
> green, and blue are implemented. How silly. Patch series to follow.

http://repo.or.cz/w/git/dscho.git?a=commitdiff;h=af6ee188b3533e9c8eb665066ed0be32d58be875

Ciao,
Dscho

^ permalink raw reply

* [PATCH] http-push: fix off-by-path_len
From: Johannes Schindelin @ 2009-01-17 15:36 UTC (permalink / raw)
  To: Kirill A. Korinskiy, git, gitster; +Cc: Mike Hommey, Ray Chuan, Nick Hengeveld


When getting the result of remote_ls(), we were advancing the variable
"path" to the relative path inside the repository.

However, then we went on to malloc a bogus amount of memory: we were
subtracting the prefix length _again_, quite possibly getting something
negative, which xmalloc() interprets as really, really much.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	Note that the push in t5540 is still broken, as http-push does
	not handle packed-refs (when looking what branches are on the 
	remote side).

	It should not even try to access the directory structure under
	refs/ to begin with, but read info/refs instead.

	However, that is just one example of the ugliness that is 
	http-push.c; it also seems to be a perfect example of a copy-pasting 
	hell; just look at the output of "git grep
	curl_easy_setopt http-push.c".

	There _has_ to be lot of room for improvement.

 http-push.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/http-push.c b/http-push.c
index 9fcccee..cb5bf95 100644
--- a/http-push.c
+++ b/http-push.c
@@ -1435,10 +1435,8 @@ static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed)
 			}
 			if (path) {
 				path += remote->path_len;
+				ls->dentry_name = xstrdup(path);
 			}
-			ls->dentry_name = xmalloc(strlen(path) -
-						  remote->path_len + 1);
-			strcpy(ls->dentry_name, path + remote->path_len);
 		} else if (!strcmp(ctx->name, DAV_PROPFIND_COLLECTION)) {
 			ls->dentry_flags |= IS_DIR;
 		}
@@ -1449,6 +1447,12 @@ static void handle_remote_ls_ctx(struct xml_ctx *ctx, int tag_closed)
 	}
 }
 
+/*
+ * NEEDSWORK: remote_ls() ignores info/refs on the remote side.  But it
+ * should _only_ heed the information from that file, instead of trying to
+ * determine the refs from the remote file system (badly: it does not even
+ * know about packed-refs).
+ */
 static void remote_ls(const char *path, int flags,
 		      void (*userFunc)(struct remote_ls_ctx *ls),
 		      void *userData)
-- 
1.6.1.325.g062d4

^ permalink raw reply related

* [PATCH 1/2] color: make it easier for non-config to parse color specs
From: Jeff King @ 2009-01-17 15:32 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Markus Heidelberg, git
In-Reply-To: <20090117152108.GA24899@coredump.intra.peff.net>

We have very featureful color-parsing routines which are
used for color.diff.* and other options. Let's make it
easier to use those routines from other parts of the code.

This patch adds a color_parse_mem() helper function which
takes a length-bounded string instead of a NUL-terminated
one. While the helper is only a few lines long, it is nice
to abstract this out so that:

 - callers don't forget to free() the temporary buffer

 - right now, it is implemented in terms of color_parse().
   But it would be more efficient to reverse this and
   implement color_parse in terms of color_parse_mem.

This also changes the error string for an invalid color not
to mention the word "config", since it is not always
appropriate (and when it is, the context is obvious since
the offending config variable is given).

Finally, while we are in the area, we clean up the parameter
names in the declaration of color_parse; the var and value
parameters were reversed from the actual implementation.

Signed-off-by: Jeff King <peff@peff.net>
---
Just setup for the next patch.

 color.c |    9 ++++++++-
 color.h |    3 ++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/color.c b/color.c
index fc0b72a..54a3da1 100644
--- a/color.c
+++ b/color.c
@@ -115,7 +115,7 @@ void color_parse(const char *value, const char *var, char *dst)
 	*dst = 0;
 	return;
 bad:
-	die("bad config value '%s' for variable '%s'", value, var);
+	die("bad color value '%s' for variable '%s'", value, var);
 }
 
 int git_config_colorbool(const char *var, const char *value, int stdout_is_tty)
@@ -191,3 +191,10 @@ int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...)
 	va_end(args);
 	return r;
 }
+
+void color_parse_mem(const char *value, int len, const char *var, char *dst)
+{
+	char *tmp = xmemdupz(value, len);
+	color_parse(tmp, var, dst);
+	free(tmp);
+}
diff --git a/color.h b/color.h
index 6cf5c88..7066099 100644
--- a/color.h
+++ b/color.h
@@ -16,7 +16,8 @@ extern int git_use_color_default;
 int git_color_default_config(const char *var, const char *value, void *cb);
 
 int git_config_colorbool(const char *var, const char *value, int stdout_is_tty);
-void color_parse(const char *var, const char *value, char *dst);
+void color_parse(const char *value, const char *var, char *dst);
+void color_parse_mem(const char *value, int len, const char *var, char *dst);
 int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
 int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
 
-- 
1.6.1.238.g32268.dirty

^ permalink raw reply related

* Re: [PATCH 3/3] Adds a #!bash to the top of bash completions so that editors can recognize, it as a bash script. Also adds a few simple comments above commands that, take arguments. The comments are meant to remind editors of potential, problems that
From: Jeff King @ 2009-01-17 15:21 UTC (permalink / raw)
  To: Markus Heidelberg
  Cc: Baz, Adeodato Simó, Boyd Stephen Smith Jr., Shawn O. Pearce,
	Ted Pavlic, git, Junio C Hamano
In-Reply-To: <200901171337.49938.markus.heidelberg@web.de>

On Sat, Jan 17, 2009 at 01:37:48PM +0100, Markus Heidelberg wrote:

> > Personally, I find --pretty=oneline unreadable because so much of the
> > screen real estate is wasted on random characters that I don't care
> > about. I find --pretty=tformat:'%h %s' much nicer
> 
> But it doesn't automatically color the SHA1.

True. I was going to suggest %Cyellow, but for some reason only red,
green, and blue are implemented. How silly. Patch series to follow.

-Peff

^ permalink raw reply

* Re: 'mail' link on http://repo.or.cz/w/git.git no workee?
From: Johannes Schindelin @ 2009-01-17 15:19 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Junio C Hamano, git
In-Reply-To: <alpine.DEB.1.00.0901161235380.3586@pacific.mpi-cbg.de>

Hi,

On Fri, 16 Jan 2009, Johannes Schindelin wrote:

> The site seems to be down ATM, but it should be
> 
> http://search.gmane.org/search.php?group=gmane.comp.version-control.git&query=pasky

FWIW, it is up again.

Ciao,
Dscho

^ permalink raw reply

* Re: Possible git bug
From: Johannes Schindelin @ 2009-01-17 15:16 UTC (permalink / raw)
  To: Damon LaCrosse; +Cc: git
In-Reply-To: <87zlhqca4m.fsf@inbox.ru>

Hi,

On Sat, 17 Jan 2009, Damon LaCrosse wrote:

> any chances the attached patch reveals a git bug?

You mean that it produces a merge conflict when a file was modified in one 
branch, and deleted in the other?

Because that's what you did, basically.  You did not rename file1 to 
file2.  You completely changed the contents.  I mean, completely.

Ciao,
Dscho

^ permalink raw reply

* [PATCH] http-push: when making directories, have a trailing slash in the path name
From: Johannes Schindelin @ 2009-01-17 15:11 UTC (permalink / raw)
  To: Ray Chuan; +Cc: git
In-Reply-To: <be6fef0d0901170028t3b418220wa024880235776037@mail.gmail.com>


The function lock_remote() sends MKCOL requests to make leading
directories; However, if it does not put a forward slash '/' at the end of
the path, the server sends a 301 redirect.

By leaving the '/' in place, we can avoid this additional step.

Incidentally, at least one version of Curl (7.16.3) does not resend
credentials when it follows a 301 redirect, so this commit also fixes
a bug.

Original patch by Tay Ray Chuan <rctay89@gmail.com>.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	On Sat, 17 Jan 2009, Ray Chuan wrote:

	>  http-push.c |   20 +++++++++++++++-----
	>  1 files changed, 15 insertions(+), 5 deletions(-)

	Actually, I had more something like this in mind.  Please note 
	that I am not the best patch writer of the world, and I know it.  
	However, a few things I do try to follow:

	- our commit messages are not really uniform, but they do share a 
	  certain likeliness, e.g. all sentences start with a capital, we 
	  try to use a less personal form than "I", and we avoid 
	  abbreviations like "don't" and write "do not" instead.

	- if you can come up with a patch that is shorter, but still clear 
	  in what it does (the commit message might need to help there), 
	  it is preferred: the less lines changed, the less lines for bugs 
	  to hide in.

	- this patch includes a test case.

	The latter part cannot be stressed enough: my first idea was to 
	test for 301, but I realized then and there that _my_ Apache does not 
	care, but always returns a 201.

	However, I remember that I had an Apache something like 2 years 
	ago which cared, and therefore I think this patch should go in.

 http-push.c             |    5 +++--
 t/lib-httpd/apache.conf |    2 ++
 t/t5540-http-push.sh    |    6 ++++++
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/http-push.c b/http-push.c
index bbe7a8e..9fcccee 100644
--- a/http-push.c
+++ b/http-push.c
@@ -1201,7 +1201,8 @@ static struct remote_lock *lock_remote(const char *path, long timeout)
 	/* Make sure leading directories exist for the remote ref */
 	ep = strchr(url + strlen(remote->url) + 1, '/');
 	while (ep) {
-		*ep = 0;
+		char saved_character = ep[1];
+		ep[1] = '\0';
 		slot = get_active_slot();
 		slot->results = &results;
 		curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
@@ -1223,7 +1224,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout)
 			free(url);
 			return NULL;
 		}
-		*ep = '/';
+		ep[1] = saved_character;
 		ep = strchr(ep + 1, '/');
 	}
 
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index 4717c2d..fdb19a5 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -1,6 +1,8 @@
 ServerName dummy
 PidFile httpd.pid
 DocumentRoot www
+LogFormat "%h %l %u %t \"%r\" %>s %b" common
+CustomLog access.log common
 ErrorLog error.log
 
 <IfDefine SSL>
diff --git a/t/t5540-http-push.sh b/t/t5540-http-push.sh
index da95886..22cfbb6 100755
--- a/t/t5540-http-push.sh
+++ b/t/t5540-http-push.sh
@@ -76,6 +76,12 @@ test_expect_failure 'create and delete remote branch' '
 	test_must_fail git show-ref --verify refs/remotes/origin/dev
 '
 
+test_expect_success 'MKCOL sends directory names with trailing slashes' '
+
+	! grep "\"MKCOL.*[^/] HTTP/[^ ]*\"" < "$HTTPD_ROOT_PATH"/access.log
+
+'
+
 stop_httpd
 
 test_done
-- 
1.6.1.325.g062d4

^ permalink raw reply related

* [PATCH] interpret_nth_last_branch(): avoid traversing the reflogs twice
From: Johannes Schindelin @ 2009-01-17 15:04 UTC (permalink / raw)
  To: Thomas Rast; +Cc: git, Junio C Hamano, Johannes Sixt, Johan Herland
In-Reply-To: <200901171438.22504.trast@student.ethz.ch>


Instead of traversing them twice, we just build a list of branch switches,
pick the one we're interested in, and free the list again.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	On Sat, 17 Jan 2009, Thomas Rast wrote:

	> Johannes Schindelin wrote:
	> 
	> > I really have to ask: why did you not work on top of Junio's 
	> > patch, just adding docs, tests, and checkout -?  And then -- maybe -- 
	> > the string_list...

	Of course, I meant the patch as-is, with Junio as author.  But 
	hey, if he does not care...

	> > Although I have to admit that I am not _that_ convinced the 
	> > string_list is worth it: reflogs are not evaluated all the time, so 
	> > it is definitely not performance critical.
	>
	> I take it you have some idea where and how string_list fits into 
	> this topic?

	Indeed.

	This patch was generated using --collapse-non-alnums for readability.
	Did not really help much.

 sha1_name.c |   72 ++++++++++++++++++++++++----------------------------------
 1 files changed, 30 insertions(+), 42 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 2bbc5f1..306d04b 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -6,6 +6,7 @@
 #include "tree-walk.h"
 #include "refs.h"
 #include "cache-tree.h"
+#include "string-list.h"
 
 static int find_short_object_filename(int len, const char *name, unsigned char *sha1)
 {
@@ -691,43 +692,31 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)
 	return retval;
 }
 
-struct grab_nth_branch_switch_cbdata {
-	int counting;
-	int nth;
-	struct strbuf *buf;
-};
-
-static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1,
+static int add_one_branch_switch(unsigned char *osha1, unsigned char *nsha1,
 				  const char *email, unsigned long timestamp, int tz,
 				  const char *message, void *cb_data)
 {
-	struct grab_nth_branch_switch_cbdata *cb = cb_data;
+	struct string_list *list = cb_data;
 	const char *match = NULL, *target = NULL;
 	size_t len;
-
-	if (!prefixcmp(message, "checkout: moving from ")) {
-		match = message + strlen("checkout: moving from ");
-		if ((target = strstr(match, " to ")) != NULL)
-			target += 4;
-	}
-
-	if (!match)
+
+	if (prefixcmp(message, "checkout: moving from "))
 		return 0;
 
-	len = target - match - 4;
-	if (target[len] == '\n' && !strncmp(match, target, len))
-		return 0;
-
-	if (cb->counting) {
-		cb->nth++;
-		return 0;
-	}
-
-	if (cb->nth-- <= 0) {
-		strbuf_reset(cb->buf);
-		strbuf_add(cb->buf, match, len);
-		return 1;
-	}
+	match = message + strlen("checkout: moving from ");
+
+	/* Is it "moving" from a branch to itself?  Then ignore it. */
+	if ((target = strstr(match, " to ")) != NULL) {
+		target += 4;
+		len = target - match - 4;
+		if (target[len] == '\n' && !strncmp(match, target, len))
+			return 0;
+	}
+	else
+		len = strchrnul(match, ' ') - match;
+
+	string_list_append(xstrndup(match, len), list);
+
 	return 0;
 }
 
@@ -745,7 +734,7 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1,
 int interpret_nth_last_branch(const char *name, struct strbuf *buf)
 {
 	int nth;
-	struct grab_nth_branch_switch_cbdata cb;
+	struct string_list branch_list = { NULL, 0, 0, 0 };
 	const char *brace;
 	char *num_end;
 
@@ -758,18 +747,17 @@ int interpret_nth_last_branch(const char *name, struct strbuf *buf)
 	if (num_end != brace)
 		return -1;
 
-	cb.counting = 1;
-	cb.nth = 0;
-	cb.buf = buf;
-	for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb);
-
-	if (cb.nth < nth)
+	for_each_reflog_ent("HEAD", add_one_branch_switch, &branch_list);
+
+	if (branch_list.nr < nth)
 		return 0;
-
-	cb.counting = 0;
-	cb.nth -= nth;
-	cb.buf = buf;
-	for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb);
+
+	strbuf_reset(buf);
+	strbuf_addstr(buf, branch_list.items[branch_list.nr - nth].string);
+
+	/* force free()ing the items */
+	branch_list.strdup_strings = 1;
+	string_list_clear(&branch_list, 0);
 
 	return brace-name+1;
 }
-- 
1.6.1.325.g062d4

^ permalink raw reply related

* Possible git bug
From: Damon LaCrosse @ 2009-01-17 13:52 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 66 bytes --]

HiQ,

any chances the attached patch reveals a git bug?

Cheers,


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: git-bug.patch --]
[-- Type: text/x-patch, Size: 596 bytes --]

diff -Nru old/git-bug.sh new/git-bug.sh
--- old/git-bug.sh	1970-01-01 01:00:00.000000000 +0100
+++ new/git-bug.sh	2008-09-16 09:52:18.000000000 +0200
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+mkdir bug
+cd bug
+git init-db
+
+echo one > file1
+git add file1
+echo "Bug Test Example" | git commit --all -F -
+
+git checkout -b branch
+echo two >> file1
+echo "Branch modification" | git commit --all -F -
+
+git checkout master
+git mv file1 file2
+
+echo "Master rename" | git commit --all -F -
+
+echo three >> file2
+
+echo "Master modification" | git commit --all -F -
+
+git merge -s recursive branch

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox