git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] gitweb: Quote non-displayable characters in hex, not octal
From: Petr Baudis @ 2008-10-01 20:11 UTC (permalink / raw)
  To: git, git; +Cc: Petr Baudis

For the last 30 years, the mankind uses the octal representation of
characters only in rare cases and most character codes are hardly
recognizable in octal. In contrast, many programmers still know
hexadecimal well and that is also the representation of choice e.g.
for Unicode codepoints.

Signed-off-by: Petr Baudis <petr.baudis@novartis.com>

---
 gitweb/gitweb.perl |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index da474d0..1b5aa14 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -775,7 +775,7 @@ sub quot_cec {
 	);
 	my $chr = ( (exists $es{$cntrl})
 		    ? $es{$cntrl}
-		    : sprintf('\%03o', ord($cntrl)) );
+		    : sprintf('\%2x', ord($cntrl)) );
 	if ($opts{-nohtml}) {
 		return $chr;
 	} else {
-- 
tg: (c427559..) t/misc/quot-hex (depends on: vanilla/master)

^ permalink raw reply related

* [PATCH] config.c: Tolerate UTF8 BOM at the beginning of config file
From: Petr Baudis @ 2008-10-01 20:13 UTC (permalink / raw)
  To: git, git; +Cc: Petr Baudis

Unfortunately, the abomination of Windows Notepad likes to scatted
non-sensical UTF8 BOM marks across text files it edits. This is
especially troublesome when editing the Git configuration file,
and it does not appear to be particularly harmful to teach Git
to deal with this poo in the configfile.

Signed-off-by: Petr Baudis <petr.baudis@novartis.com>

---
 config.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/config.c b/config.c
index 53f04a0..1d30120 100644
--- a/config.c
+++ b/config.c
@@ -205,8 +205,27 @@ static int git_parse_file(config_fn_t fn, void *data)
 	int baselen = 0;
 	static char var[MAXNAME];
 
+	/* U+FEFF Byte Order Mark in UTF8 */
+	static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf";
+	const unsigned char *bomptr = utf8_bom;
+
 	for (;;) {
 		int c = get_next_char();
+		if (bomptr && *bomptr) {
+			/* We are at the file beginning; skip UTF8-encoded BOM
+			 * if present. Sane editors won't put this in on their
+			 * own, but e.g. Windows Notepad will do it happily. */
+			if ((unsigned char) c == *bomptr) {
+				bomptr++;
+				continue;
+			} else {
+				/* Do not tolerate partial BOM. */
+				if (bomptr != utf8_bom)
+					break;
+				/* No BOM at file beginning. Cool. */
+				bomptr = NULL;
+			}
+		}
 		if (c == '\n') {
 			if (config_file_eof)
 				return 0;
-- 
tg: (9800c0d..) t/config/utf8-bom (depends on: vanilla/master)

^ permalink raw reply related

* [TRACKER PATCH] Change color at specified threshold
From: Johannes Schindelin @ 2008-10-01 20:30 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <alpine.LFD.2.00.0810011240390.3575@nehalem.linux-foundation.org>


Now the color changes when a certain threshold of remaining seconds is
reached.

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

	On Wed, 1 Oct 2008, Linus Torvalds wrote:

	> But I also have a UI that the kids can run to _see_ how much 
	> time they have left, so that getting thrown off the machine doesn't 
	> come as a total surprise.

 tracker-ui.tcl |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/tracker-ui.tcl b/tracker-ui.tcl
index 16d00d7..1533db5 100755
--- a/tracker-ui.tcl
+++ b/tracker-ui.tcl
@@ -1,5 +1,7 @@
 #!/usr/bin/wish
 
+set red_threshold [expr 60 * 10]
+
 proc every {ms body} {
      eval $body
      after $ms [list every $ms $body]
@@ -7,14 +9,19 @@ proc every {ms body} {
 
 set user $env(USER)
 
-pack [label .tracker -textvariable time]
+pack [label .tracker -textvariable time -font "Times 36" -relief sunken]
 
 every 1000 {
-	global user
+	global user red_threshold
 	set f [open "/var/log/tracker/$user" "r"]
 	gets $f l1
 	gets $f l2
 	gets $f l3
 	close $f
 	set ::time "$l3"
+	if {[expr [lindex $l1 0] - [lindex $l1 1]] < $red_threshold} {
+		.tracker configure -foreground white -background red
+	} {
+		.tracker configure -foreground black -background white
+	}
 }
-- 
1.6.0.2.GIT

^ permalink raw reply related

* [PATCH] Add branch.autosetuppreservemerges and branch.<name>.preservemerges.
From: Stephen Haberman @ 2008-10-01 20:27 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: Git Mailing List
In-Reply-To: <48D95836.6040200@op5.se>

Signed-off-by: Stephen Haberman <stephen@exigencecorp.com>
---

This builds on top of Andreas's work on `git rebase -p`. I
basically copy/pasted how autosetuprebase works so that, if
appropriately configured, `git pull` will do the "right thing"
for our environment, i.e. rebasing and preserving merges.

I'm not sure how to handle patches on patches, so apologies
if I did this wrong. Let me know if there are things I should
be doing differently.

Thanks.

 Documentation/config.txt          |   20 ++++++++
 branch.c                          |   20 ++++++++
 cache.h                           |    9 ++++
 config.c                          |   15 ++++++
 environment.c                     |    1 +
 git-pull.sh                       |   10 +++-
 t/t3200-branch.sh                 |   89 ++++++++++++++++++++++++++++--------
 t/t3409-rebase-preserve-merges.sh |   65 ++++++++++++++++----------
 8 files changed, 182 insertions(+), 47 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index bea867d..0abf1b8 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -438,6 +438,21 @@ branch.autosetuprebase::
 	branch to track another branch.
 	This option defaults to never.
 
+branch.autosetuppreservemerges::
+	When a new branch is created with 'git-branch' or 'git-checkout'
+	that tracks another branch, this variable tells git to set
+	up pull to rebase with preserve merges (see "branch.<name>.rebase").
+	When `never`, rebase is never automatically set to true.
+	When `local`, rebase is set to true for tracked branches of
+	other local branches.
+	When `remote`, rebase is set to true for tracked branches of
+	remote branches.
+	When `always`, rebase will be set to true for all tracking
+	branches.
+	See "branch.autosetupmerge" for details on how to set up a
+	branch to track another branch.
+	This option defaults to never.
+
 branch.<name>.remote::
 	When in branch <name>, it tells 'git-fetch' which remote to fetch.
 	If this option is not given, 'git-fetch' defaults to remote "origin".
@@ -471,6 +486,11 @@ branch.<name>.rebase::
 	it unless you understand the implications (see linkgit:git-rebase[1]
 	for details).
 
+branch.<name>.preservemerges::
+	When true, and branch.<name>.rebase is true, preserve merges when
+	rebasing the branch <name> on top of the fetched branch when
+	"git pull" is run.
+
 browser.<tool>.cmd::
 	Specify the command to invoke the specified browser. The
 	specified command is evaluated in shell with the URLs passed
diff --git a/branch.c b/branch.c
index b1e59f2..a5e62c8 100644
--- a/branch.c
+++ b/branch.c
@@ -47,6 +47,21 @@ static int should_setup_rebase(const struct tracking *tracking)
 	return 0;
 }
 
+static int should_setup_preservemerges(const struct tracking *tracking)
+{
+	switch (autopreservemerges) {
+	case AUTOPRESERVEMERGES_NEVER:
+		return 0;
+	case AUTOPRESERVEMERGES_LOCAL:
+		return tracking->remote == NULL;
+	case AUTOPRESERVEMERGES_REMOTE:
+		return tracking->remote != NULL;
+	case AUTOPRESERVEMERGES_ALWAYS:
+		return 1;
+	}
+	return 0;
+}
+
 /*
  * This is called when new_ref is branched off of orig_ref, and tries
  * to infer the settings for branch.<new_ref>.{remote,merge} from the
@@ -91,6 +106,11 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
 		git_config_set(key, "true");
 		printf("This branch will rebase on pull.\n");
 	}
+	if (should_setup_preservemerges(&tracking)) {
+		sprintf(key, "branch.%s.preservemerges", new_ref);
+		git_config_set(key, "true");
+		printf("This branch will preserve merges on pull.\n");
+	}
 	free(tracking.src);
 
 	return 0;
diff --git a/cache.h b/cache.h
index de8c2b6..97be98c 100644
--- a/cache.h
+++ b/cache.h
@@ -467,8 +467,17 @@ enum rebase_setup_type {
 	AUTOREBASE_ALWAYS,
 };
 
+enum preservemerges_setup_type {
+	AUTOPRESERVEMERGES_NEVER = 0,
+	AUTOPRESERVEMERGES_LOCAL,
+	AUTOPRESERVEMERGES_REMOTE,
+	AUTOPRESERVEMERGES_ALWAYS,
+};
+
+
 extern enum branch_track git_branch_track;
 extern enum rebase_setup_type autorebase;
+extern enum preservemerges_setup_type autopreservemerges;
 
 #define GIT_REPO_VERSION 0
 extern int repository_format_version;
diff --git a/config.c b/config.c
index 53f04a0..6302f5a 100644
--- a/config.c
+++ b/config.c
@@ -536,6 +536,21 @@ static int git_default_branch_config(const char *var, const char *value)
 			return error("Malformed value for %s", var);
 		return 0;
 	}
+	if (!strcmp(var, "branch.autosetuppreservemerges")) {
+		if (!value)
+			return config_error_nonbool(var);
+		else if (!strcmp(value, "never"))
+			autopreservemerges = AUTOPRESERVEMERGES_NEVER;
+		else if (!strcmp(value, "local"))
+			autopreservemerges = AUTOPRESERVEMERGES_LOCAL;
+		else if (!strcmp(value, "remote"))
+			autopreservemerges = AUTOPRESERVEMERGES_REMOTE;
+		else if (!strcmp(value, "always"))
+			autopreservemerges = AUTOPRESERVEMERGES_ALWAYS;
+		else
+			return error("Malformed value for %s", var);
+		return 0;
+	}
 
 	/* Add other config variables here and to Documentation/config.txt. */
 	return 0;
diff --git a/environment.c b/environment.c
index 0c6d11f..72e735c 100644
--- a/environment.c
+++ b/environment.c
@@ -42,6 +42,7 @@ enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
 unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
 enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
 enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
+enum preservemerges_setup_type autopreservemerges = AUTOPRESERVEMERGES_NEVER;
 
 /* This is set by setup_git_dir_gently() and/or git_default_config() */
 char *git_work_tree_cfg;
diff --git a/git-pull.sh b/git-pull.sh
index 270a50d..03b7da0 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -20,6 +20,7 @@ strategy_args= no_stat= no_commit= squash= no_ff= log_arg=
 curr_branch=$(git symbolic-ref -q HEAD)
 curr_branch_short=$(echo "$curr_branch" | sed "s|refs/heads/||")
 rebase=$(git config --bool branch.$curr_branch_short.rebase)
+preservemerges=$(git config --bool branch.$curr_branch_short.preservemerges)
 while :
 do
 	case "$1" in
@@ -59,7 +60,7 @@ do
 		rebase=true
 		;;
 	--preserve-merges) # no short option for this
-		preserve_merges="--preserve-merges"
+		preservemerges=true
 		rebase=true
 		;;
 	--no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase)
@@ -181,9 +182,14 @@ then
 	exit
 fi
 
+if test true = "$preservemerges"
+then
+	preservemerges_flag="--preserve-merges"
+fi
+
 merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
 test true = "$rebase" &&
-	exec git-rebase $preserve_merges $strategy_args --onto $merge_head \
+	exec git-rebase $preservemerges_flag $strategy_args --onto $merge_head \
 	${oldremoteref:-$merge_head}
 exec git-merge $no_stat $no_commit $squash $no_ff $log_arg $strategy_args \
 	"$merge_name" HEAD $merge_head
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 2147eac..f10b8ac 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -228,103 +228,121 @@ test_expect_success 'autosetuprebase local on a tracked local branch' '
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	git config branch.autosetuprebase local &&
+	git config branch.autosetuppreservemerges local &&
 	(git show-ref -q refs/remotes/local/o || git fetch local) &&
 	git branch mybase &&
 	git branch --track myr1 mybase &&
 	test "$(git config branch.myr1.remote)" = . &&
 	test "$(git config branch.myr1.merge)" = refs/heads/mybase &&
-	test "$(git config branch.myr1.rebase)" = true
+	test "$(git config branch.myr1.rebase)" = true &&
+	test "$(git config branch.myr1.preservemerges)" = true
 '
 
 test_expect_success 'autosetuprebase always on a tracked local branch' '
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	git config branch.autosetuprebase always &&
+	git config branch.autosetuppreservemerges always &&
 	(git show-ref -q refs/remotes/local/o || git fetch local) &&
 	git branch mybase2 &&
 	git branch --track myr2 mybase &&
 	test "$(git config branch.myr2.remote)" = . &&
 	test "$(git config branch.myr2.merge)" = refs/heads/mybase &&
-	test "$(git config branch.myr2.rebase)" = true
+	test "$(git config branch.myr2.rebase)" = true &&
+	test "$(git config branch.myr2.preservemerges)" = true
 '
 
 test_expect_success 'autosetuprebase remote on a tracked local branch' '
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	git config branch.autosetuprebase remote &&
+	git config branch.autosetuppreservemerges remote &&
 	(git show-ref -q refs/remotes/local/o || git fetch local) &&
 	git branch mybase3 &&
 	git branch --track myr3 mybase2 &&
 	test "$(git config branch.myr3.remote)" = . &&
 	test "$(git config branch.myr3.merge)" = refs/heads/mybase2 &&
-	! test "$(git config branch.myr3.rebase)" = true
+	! test "$(git config branch.myr3.rebase)" = true &&
+	! test "$(git config branch.myr3.preservemerges)" = true
 '
 
 test_expect_success 'autosetuprebase never on a tracked local branch' '
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	git config branch.autosetuprebase never &&
+	git config branch.autosetuppreservemerges never &&
 	(git show-ref -q refs/remotes/local/o || git fetch local) &&
 	git branch mybase4 &&
 	git branch --track myr4 mybase2 &&
 	test "$(git config branch.myr4.remote)" = . &&
 	test "$(git config branch.myr4.merge)" = refs/heads/mybase2 &&
-	! test "$(git config branch.myr4.rebase)" = true
+	! test "$(git config branch.myr4.rebase)" = true &&
+	! test "$(git config branch.myr4.preservemerges)" = true
 '
 
 test_expect_success 'autosetuprebase local on a tracked remote branch' '
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	git config branch.autosetuprebase local &&
+	git config branch.autosetuppreservemerges local &&
 	(git show-ref -q refs/remotes/local/master || git fetch local) &&
 	git branch --track myr5 local/master &&
 	test "$(git config branch.myr5.remote)" = local &&
 	test "$(git config branch.myr5.merge)" = refs/heads/master &&
-	! test "$(git config branch.myr5.rebase)" = true
+	! test "$(git config branch.myr5.rebase)" = true &&
+	! test "$(git config branch.myr5.preservemerges)" = true
 '
 
 test_expect_success 'autosetuprebase never on a tracked remote branch' '
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	git config branch.autosetuprebase never &&
+	git config branch.autosetuppreservemerges never &&
 	(git show-ref -q refs/remotes/local/master || git fetch local) &&
 	git branch --track myr6 local/master &&
 	test "$(git config branch.myr6.remote)" = local &&
 	test "$(git config branch.myr6.merge)" = refs/heads/master &&
-	! test "$(git config branch.myr6.rebase)" = true
+	! test "$(git config branch.myr6.rebase)" = true &&
+	! test "$(git config branch.myr6.preservemerges)" = true
 '
 
 test_expect_success 'autosetuprebase remote on a tracked remote branch' '
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	git config branch.autosetuprebase remote &&
+	git config branch.autosetuppreservemerges remote &&
 	(git show-ref -q refs/remotes/local/master || git fetch local) &&
 	git branch --track myr7 local/master &&
 	test "$(git config branch.myr7.remote)" = local &&
 	test "$(git config branch.myr7.merge)" = refs/heads/master &&
-	test "$(git config branch.myr7.rebase)" = true
+	test "$(git config branch.myr7.rebase)" = true &&
+	test "$(git config branch.myr7.preservemerges)" = true
 '
 
 test_expect_success 'autosetuprebase always on a tracked remote branch' '
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	git config branch.autosetuprebase remote &&
+	git config branch.autosetuppreservemerges remote &&
 	(git show-ref -q refs/remotes/local/master || git fetch local) &&
 	git branch --track myr8 local/master &&
 	test "$(git config branch.myr8.remote)" = local &&
 	test "$(git config branch.myr8.merge)" = refs/heads/master &&
-	test "$(git config branch.myr8.rebase)" = true
+	test "$(git config branch.myr8.rebase)" = true &&
+	test "$(git config branch.myr8.preservemerges)" = true
 '
 
 test_expect_success 'autosetuprebase unconfigured on a tracked remote branch' '
 	git config --unset branch.autosetuprebase &&
+	git config --unset branch.autosetuppreservemerges &&
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	(git show-ref -q refs/remotes/local/master || git fetch local) &&
 	git branch --track myr9 local/master &&
 	test "$(git config branch.myr9.remote)" = local &&
 	test "$(git config branch.myr9.merge)" = refs/heads/master &&
-	test "z$(git config branch.myr9.rebase)" = z
+	test "z$(git config branch.myr9.rebase)" = z &&
+	test "z$(git config branch.myr9.preservemerges)" = z
 '
 
 test_expect_success 'autosetuprebase unconfigured on a tracked local branch' '
@@ -335,7 +353,8 @@ test_expect_success 'autosetuprebase unconfigured on a tracked local branch' '
 	git branch --track myr10 mybase2 &&
 	test "$(git config branch.myr10.remote)" = . &&
 	test "$(git config branch.myr10.merge)" = refs/heads/mybase2 &&
-	test "z$(git config branch.myr10.rebase)" = z
+	test "z$(git config branch.myr10.rebase)" = z &&
+	test "z$(git config branch.myr10.preservemerges)" = z
 '
 
 test_expect_success 'autosetuprebase unconfigured on untracked local branch' '
@@ -345,7 +364,8 @@ test_expect_success 'autosetuprebase unconfigured on untracked local branch' '
 	git branch --no-track myr11 mybase2 &&
 	test "z$(git config branch.myr11.remote)" = z &&
 	test "z$(git config branch.myr11.merge)" = z &&
-	test "z$(git config branch.myr11.rebase)" = z
+	test "z$(git config branch.myr11.rebase)" = z &&
+	test "z$(git config branch.myr11.preservemerges)" = z
 '
 
 test_expect_success 'autosetuprebase unconfigured on untracked remote branch' '
@@ -355,95 +375,112 @@ test_expect_success 'autosetuprebase unconfigured on untracked remote branch' '
 	git branch --no-track myr12 local/master &&
 	test "z$(git config branch.myr12.remote)" = z &&
 	test "z$(git config branch.myr12.merge)" = z &&
-	test "z$(git config branch.myr12.rebase)" = z
+	test "z$(git config branch.myr12.rebase)" = z &&
+	test "z$(git config branch.myr12.preservemerges)" = z
 '
 
 test_expect_success 'autosetuprebase never on an untracked local branch' '
 	git config branch.autosetuprebase never &&
+	git config branch.autosetuppreservemerges never &&
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	(git show-ref -q refs/remotes/local/master || git fetch local) &&
 	git branch --no-track myr13 mybase2 &&
 	test "z$(git config branch.myr13.remote)" = z &&
 	test "z$(git config branch.myr13.merge)" = z &&
-	test "z$(git config branch.myr13.rebase)" = z
+	test "z$(git config branch.myr13.rebase)" = z &&
+	test "z$(git config branch.myr13.preservemerges)" = z
 '
 
 test_expect_success 'autosetuprebase local on an untracked local branch' '
 	git config branch.autosetuprebase local &&
+	git config branch.autosetuppreservemerges local &&
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	(git show-ref -q refs/remotes/local/master || git fetch local) &&
 	git branch --no-track myr14 mybase2 &&
 	test "z$(git config branch.myr14.remote)" = z &&
 	test "z$(git config branch.myr14.merge)" = z &&
-	test "z$(git config branch.myr14.rebase)" = z
+	test "z$(git config branch.myr14.rebase)" = z &&
+	test "z$(git config branch.myr14.preservemerges)" = z
 '
 
 test_expect_success 'autosetuprebase remote on an untracked local branch' '
 	git config branch.autosetuprebase remote &&
+	git config branch.autosetuppreservemerges remote &&
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	(git show-ref -q refs/remotes/local/master || git fetch local) &&
 	git branch --no-track myr15 mybase2 &&
 	test "z$(git config branch.myr15.remote)" = z &&
 	test "z$(git config branch.myr15.merge)" = z &&
-	test "z$(git config branch.myr15.rebase)" = z
+	test "z$(git config branch.myr15.rebase)" = z &&
+	test "z$(git config branch.myr15.preservemerges)" = z
 '
 
 test_expect_success 'autosetuprebase always on an untracked local branch' '
 	git config branch.autosetuprebase always &&
+	git config branch.autosetuppreservemerges always &&
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	(git show-ref -q refs/remotes/local/master || git fetch local) &&
 	git branch --no-track myr16 mybase2 &&
 	test "z$(git config branch.myr16.remote)" = z &&
 	test "z$(git config branch.myr16.merge)" = z &&
-	test "z$(git config branch.myr16.rebase)" = z
+	test "z$(git config branch.myr16.rebase)" = z &&
+	test "z$(git config branch.myr16.preservemerges)" = z
 '
 
 test_expect_success 'autosetuprebase never on an untracked remote branch' '
 	git config branch.autosetuprebase never &&
+	git config branch.autosetuppreservemerges never &&
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	(git show-ref -q refs/remotes/local/master || git fetch local) &&
 	git branch --no-track myr17 local/master &&
 	test "z$(git config branch.myr17.remote)" = z &&
 	test "z$(git config branch.myr17.merge)" = z &&
-	test "z$(git config branch.myr17.rebase)" = z
+	test "z$(git config branch.myr17.rebase)" = z &&
+	test "z$(git config branch.myr17.preservemerges)" = z
 '
 
 test_expect_success 'autosetuprebase local on an untracked remote branch' '
 	git config branch.autosetuprebase local &&
+	git config branch.autosetuppreservemerges local &&
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	(git show-ref -q refs/remotes/local/master || git fetch local) &&
 	git branch --no-track myr18 local/master &&
 	test "z$(git config branch.myr18.remote)" = z &&
 	test "z$(git config branch.myr18.merge)" = z &&
-	test "z$(git config branch.myr18.rebase)" = z
+	test "z$(git config branch.myr18.rebase)" = z &&
+	test "z$(git config branch.myr18.preservemerges)" = z
 '
 
 test_expect_success 'autosetuprebase remote on an untracked remote branch' '
 	git config branch.autosetuprebase remote &&
+	git config branch.autosetuppreservemerges remote &&
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	(git show-ref -q refs/remotes/local/master || git fetch local) &&
 	git branch --no-track myr19 local/master &&
 	test "z$(git config branch.myr19.remote)" = z &&
 	test "z$(git config branch.myr19.merge)" = z &&
-	test "z$(git config branch.myr19.rebase)" = z
+	test "z$(git config branch.myr19.rebase)" = z &&
+	test "z$(git config branch.myr19.preservemerges)" = z
 '
 
 test_expect_success 'autosetuprebase always on an untracked remote branch' '
 	git config branch.autosetuprebase always &&
+	git config branch.autosetuppreservemerges always &&
 	git config remote.local.url . &&
 	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
 	(git show-ref -q refs/remotes/local/master || git fetch local) &&
 	git branch --no-track myr20 local/master &&
 	test "z$(git config branch.myr20.remote)" = z &&
 	test "z$(git config branch.myr20.merge)" = z &&
-	test "z$(git config branch.myr20.rebase)" = z
+	test "z$(git config branch.myr20.rebase)" = z &&
+	test "z$(git config branch.myr20.preservemerges)" = z
 '
 
 test_expect_success 'detect misconfigured autosetuprebase (bad value)' '
@@ -451,6 +488,11 @@ test_expect_success 'detect misconfigured autosetuprebase (bad value)' '
 	test_must_fail git branch
 '
 
+test_expect_success 'detect misconfigured autosetuppreservemerges (bad value)' '
+	git config branch.autosetuppreservemerges garbage &&
+	test_must_fail git branch
+'
+
 test_expect_success 'detect misconfigured autosetuprebase (no value)' '
 	git config --unset branch.autosetuprebase &&
 	echo "[branch] autosetuprebase" >> .git/config &&
@@ -458,4 +500,11 @@ test_expect_success 'detect misconfigured autosetuprebase (no value)' '
 	git config --unset branch.autosetuprebase
 '
 
+test_expect_success 'detect misconfigured autosetuppreservemerges (no value)' '
+	git config --unset branch.autosetuppreservemerges &&
+	echo "[branch] autosetuppreservemerges" >> .git/config &&
+	test_must_fail git branch &&
+	git config --unset branch.autosetuppreservemerges
+'
+
 test_done
diff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh
index 9a376ef..5f4ce56 100644
--- a/t/t3409-rebase-preserve-merges.sh
+++ b/t/t3409-rebase-preserve-merges.sh
@@ -25,44 +25,59 @@ export GIT_AUTHOR_EMAIL
 test_expect_success 'setup for merge-preserving rebase' \
 	'echo First > A &&
 	git add A &&
-	git-commit -m "Add A1" &&
+	git-commit -m A1 &&
 	git checkout -b topic &&
 	echo Second > B &&
 	git add B &&
-	git-commit -m "Add B1" &&
+	git-commit -m B1 &&
+	git tag B1 &&
+	echo Third >> B &&
+	git commit -a -m B2
 	git checkout -f master &&
-	echo Third >> A &&
-	git-commit -a -m "Modify A2" &&
+	echo Fourth >> A &&
+	git-commit -a -m A2 &&
+	git clone . clone
+'
 
-	git clone ./. clone1 &&
-	cd clone1 &&
+test_expect_success 'git pull --rebase -p on moved topic' '
+	cd clone &&
 	git checkout -b topic origin/topic &&
+	git reset --hard B1 &&
 	git merge origin/master &&
+	git pull --rebase --preserve-merges &&
+	test $(git rev-list --all --pretty=oneline | grep A2 | wc -l) = 1 &&
+	git checkout origin/topic &&
+	git branch -D topic &&
 	cd ..
+'
 
-	git clone ./. clone2
-	cd clone2 &&
+test_expect_success 'rebase -p merge on moved topic' '
+	cd clone &&
 	git checkout -b topic origin/topic &&
+	git reset --hard B1 &&
 	git merge origin/master &&
-	cd .. &&
-
-	git checkout topic &&
-	echo Fourth >> B &&
-	git commit -a -m "Modify B2"
-'
-
-test_expect_success 'git pull --rebase -p on moved topic' '
-	cd clone1 &&
-	git pull --rebase --preserve-merges &&
-	test $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) = 1
+	git rebase -p origin/topic &&
+	test 1 = $(git rev-list --all --pretty=oneline | grep A2 | wc -l) &&
+	test 1 = $(git rev-list --all --pretty=oneline | grep "Merge commit" | wc -l) &&
+	git checkout origin/topic &&
+	git branch -D topic &&
+	cd ..
 '
 
-test_expect_success 'rebase -p merge on moved topic' '
-	cd ../clone2 &&
-	git fetch &&
-	git rebase -p origin/topic &&
-	test 1 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) &&
-	test 1 = $(git rev-list --all --pretty=oneline | grep "Merge commit" | wc -l)
+test_expect_success 'git pull on moved topic' '
+	cd clone &&
+	git config branch.autosetuppreservemerges always &&
+	git checkout -b topic origin/topic &&
+	test true = $(git config branch.topic.preservemerges) &&
+	git reset --hard B1 &&
+	git merge origin/master &&
+	git pull &&
+	test 1 = $(git rev-list --all --pretty=oneline | grep A2 | wc -l) &&
+	test 1 = $(git rev-list --all --pretty=oneline | grep "Merge commit" | wc -l) &&
+	git checkout origin/topic &&
+	git branch -D topic &&
+	cd ..
 '
 
 test_done
+
-- 
1.6.0.2

^ permalink raw reply related

* Re: [PATCH 3/9] Docs: send-email: Man page option ordering
From: Michael Witten @ 2008-10-01 20:34 UTC (permalink / raw)
  To: Jeff King; +Cc: spearce, git
In-Reply-To: <20081001032701.GC24513@coredump.intra.peff.net>


On 30 Sep 2008, at 10:27 PM, Jeff King wrote:

> On Tue, Sep 30, 2008 at 07:58:26AM -0500, Michael Witten wrote:
>
>> Now the man page lists the options in alphabetical
>> order (in terms of the 'main' part of an option's
>> name).
>>
>> Signed-off-by: Michael Witten <mfwitten@mit.edu>
>
> After following this series through a number of revisions,
> it looks good to me now. So
>
> Acked-by: Jeff King <peff@peff.net>
>
> for the whole series.
>
> I believe this particular patch is probably redundant, since
> 8/9 just re-orders the manpage again later. So it could be
> dropped if somebody feels like doing the work to rebase the
> later patches.

I would suggest just leaving it there; it fixes a genuine
problem regardless of what the future patches do.

^ permalink raw reply

* [PATCH] Make maximum surf time really per day
From: Johannes Schindelin @ 2008-10-01 20:41 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0810012229390.22125@pacific.mpi-cbg.de.mpi-cbg.de>


Earlier, when the maximum time was reached, we would block for 8 hours.
The program description suggested that the maximum time should be per
day instead, however.  So rather check that.

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

	I am sure your kids will hate me.  Now the trick to surf before 
	school, after school, and then late at night does not work 
	anymore.  :-(

	Well, the "late at night" would have interfered with next day's 
	"before school" anyway.

 tracker.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/tracker.c b/tracker.c
index 1b26e7e..faa4a91 100644
--- a/tracker.c
+++ b/tracker.c
@@ -12,6 +12,9 @@
 
 #define TRACKER_FILE "/var/log/tracker/%s"
 
+/* Define this, just in case it changes some day */
+#define SECS_PER_DAY 86400
+
 enum state {
 	no_user, old_user, new_user
 };
@@ -43,7 +46,7 @@ static void update_fd(struct user *user, int fd, unsigned int s)
 	cur += s;
 
 	/* Has the user been logged out more than 8 hours? */
-	if (user->last - last >= 8*60*60)
+	if (user->last / SECS_PER_DAY != last / SECS_PER_DAY)
 		cur = 0;
 
 	left = max - cur;
-- 
1.6.0.2.GIT

^ permalink raw reply related

* Re: [PATCH 3/9] Docs: send-email: Man page option ordering
From: Shawn O. Pearce @ 2008-10-01 20:36 UTC (permalink / raw)
  To: Michael Witten; +Cc: Jeff King, git
In-Reply-To: <26288097-F87A-4F93-B030-40598D65BEEE@mit.edu>

Michael Witten <mfwitten@MIT.EDU> wrote:
> On 30 Sep 2008, at 10:27 PM, Jeff King wrote:
>>
>> I believe this particular patch is probably redundant, since
>> 8/9 just re-orders the manpage again later. So it could be
>> dropped if somebody feels like doing the work to rebase the
>> later patches.
>
> I would suggest just leaving it there; it fixes a genuine
> problem regardless of what the future patches do.

Not only that but the series is already merged into next.  I won't
be happy about having to revert it, rewrite history, and merge it
back into next.  :-)

-- 
Shawn.

^ permalink raw reply

* Re: [JGIT PATCH 4/5] Expose the critical receive configuration options to JGit
From: Robin Rosenberg @ 2008-10-01 20:54 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: git
In-Reply-To: <1222824690-7632-5-git-send-email-spearce@spearce.org>


The repo configuration setup fails. I'll squash this in

--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RepositoryConfig.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RepositoryConfig.java
@@ -534,6 +534,7 @@ public void create() {
                add(e);

                core = new CoreConfig(this);
+               transfer = new TransferConfig(this);
        }

        /**

i.e. initialize the transfer object when creating a new repo in junit tests.

I also noted we try to read ~/.gitconfig which may give us som headaches
later on.

-- robin

^ permalink raw reply

* Re: Help with a tcl/tk gui thing..
From: Mikael Magnusson @ 2008-10-01 21:03 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <alpine.LFD.2.00.0810011240390.3575@nehalem.linux-foundation.org>

How's this?

git clone git://mika.l3ib.org/tracker.git

I wrote it in pygtk since I know zero to no tcl/tk, hope that's okay.
It has a label with the time remaining (simply read from the daemon file),
and shows the text in red if less than 10% is remaining. You'll need to
change the ./ in cb_function to /var/log/tracker since I forgot to change
that and I'm lazy :).

2008/10/1 Linus Torvalds <torvalds@linux-foundation.org>:
>
> Ok, this is ridiculous, and has nothing to do with git apart from being
> hosted in it, but I thought I'd send out an email about it since the git
> community is the only one I know that does any GUI work at all...
>
> I've got three girls, all wasting their time on their computer, and we set
> up this rule that they get to have a maximum of an hour of internet time
> each day. Of course, being the geek I am, I wrote a stupid time tracker
> for that purpose, and then totally forgot about it.
>
> Until the harddisk in their computer broke down, and I had to re-install,
> and realized that I didn't have a copy of my stupid tracker sources
> anywhere. So I had to re-write it, and to make sure that I didn't lose it
> _again_, I put it in a git repo this time, and now have it on my desktop
> machine.
>
> I _also_ have it on kernel.org, because I tend to change machines often
> enough that files get lost because I decide that switching machines is
> also a great way of doing "generational GC" on my home directory.
>
> [ iow, I copy my old home directory as "old-home" when I switch machines,
>  and anything I didn't end up copying by the time I switch machines
>  again, just gets deleted. Very neat, and a great way to lose things that
>  you only care about every other year or so. ]
>
> Whatever.
>
> To make a long story short, I have a very small program that does all the
> tracking, and I have no problems with that. It doesn't have much of a
> admin interface, but I can do "echo 3600 > /var/log/tracker/celeste" to
> reset the time etc. _I_ have no need for pretty GUI's.
>
> But I also have a UI that the kids can run to _see_ how much time they
> have left, so that getting thrown off the machine doesn't come as a total
> surprise. And yesterday Patricia asked why it has to be that ugly. And I
> had to admit that her dad is just not very good at UI's - and my
> re-implementation may in fact have been EVEN UGLIER than my original
> version. If that is even possible.
>
> But hey, I'm not above impressing my kids with pretty bling if I can get
> somebody else who actually knows what they are doing to enhance my wish
> scripts to something reasonable.
>
> Anybody?
>
> The repository is at
>
>        git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/tracker.git
>
> if somebody knows how to make the text turn red when the end is near
> and/or make it have some nice graphical bar that fills up as time is about
> to expire.
>
> And if nobody does, no worries. At least I tried. My kids can continue to
> watch ugly/small/monochrome fonts with just a count-down clock.
>
>                        Linus
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
Mikael Magnusson

^ permalink raw reply

* [PATCH] git commit: Repaint the output format bikeshed (again)
From: Andreas Ericsson @ 2008-10-01 21:06 UTC (permalink / raw)
  To: Shawn Pearce, Git Mailing List, Jeff King
In-Reply-To: <20081001154425.GE21310@spearce.org>

Since we want the most important information furthest
left while at the same time preserving valuable screen
estate, we move the branch-name to the leftmost side
of the commit result output. To make it read properly
we get rid of "Created", which I just can't fit into
a sentence without putting the branch-name last.

Having taken inspiration from the "git reset" command,
output for the three conceivable cases now look thus:

  normal commit
  <branch> is now at b930c4a (i386: Snib the sprock)

  detached commit
  DETACHED HEAD is now at b930c4a (i386: Snib the sprock)

  initial commit
  History has begun anew. Root-commit created.
  <branch> is now at bc930c4a (i386: Snib the sprock)

As a nice side-effect, we can get rid of the get_commit_format
helper function and thereby remove more code than we add.

This is a substantial rewrite of a patch originally sent by
Jeff King <peff@peff.net>.

Signed-off-by: Andreas Ericsson <ae@op5.se>
---

"Created" is a problem when one wants to put branch-name before the
subject line, because the subject has to follow the hash (it doesn't
describe the pre-state of the branch/detached head), but the newly
added commit. "Created, on branch, hash (subject)" just looks
stilted and stupid, so I had to change it. Hopefully this can be
accepted. If not, count me out.

I'm not sure if the last "else" case setting branch = head; can
ever happen, but I figured it can't hurt to make sure. Feel free
to modify commentary around it or the entire section when applying.

This is based on current next (798a2a426a).

 builtin-commit.c |   47 ++++++++++++++++++-----------------------------
 1 files changed, 18 insertions(+), 29 deletions(-)

diff --git a/builtin-commit.c b/builtin-commit.c
index e4e1448..3b43344 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -878,35 +878,12 @@ int cmd_status(int argc, const char **argv, const char *prefix)
 	return commitable ? 0 : 1;
 }
 
-static char *get_commit_format_string(void)
-{
-	unsigned char sha[20];
-	const char *head = resolve_ref("HEAD", sha, 0, NULL);
-	struct strbuf buf = STRBUF_INIT;
-
-	/* use shouty-caps if we're on detached HEAD */
-	strbuf_addf(&buf, "format:%s", strcmp("HEAD", head) ? "" : "DETACHED commit");
-	strbuf_addstr(&buf, "%h (%s)");
-
-	if (!prefixcmp(head, "refs/heads/")) {
-		const char *cp;
-		strbuf_addstr(&buf, " on ");
-		for (cp = head + 11; *cp; cp++) {
-			if (*cp == '%')
-				strbuf_addstr(&buf, "%x25");
-			else
-				strbuf_addch(&buf, *cp);
-		}
-	}
-
-	return strbuf_detach(&buf, NULL);
-}
-
 static void print_summary(const char *prefix, const unsigned char *sha1)
 {
 	struct rev_info rev;
 	struct commit *commit;
-	char *format = get_commit_format_string();
+	unsigned char head_sha1[20];
+	const char *branch, *head, *format = "format:%h (%s)";
 
 	commit = lookup_commit(sha1);
 	if (!commit)
@@ -931,15 +908,27 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
 	rev.diffopt.break_opt = 0;
 	diff_setup_done(&rev.diffopt);
 
-	printf("Created %s", initial_commit ? "root-commit " : "");
+	/* a pretty rare occurrance, so let's celebrate it specially */
+	if (initial_commit)
+		printf("History has begun anew. Root-commit created.\n");
+
+	head = resolve_ref("HEAD", head_sha1, 0, NULL);
+	if (!strcmp(head, "HEAD"))
+		branch = "DETACHED HEAD";
+	else if (!prefixcmp(head, "refs/heads/"))
+		branch = &head[strlen("refs/heads/")];
+	else {
+		/* refs/git-svn, fe */
+		branch = head;
+	}
+
+	printf("%s is now at ", branch);
 
 	if (!log_tree_commit(&rev, commit)) {
 		struct strbuf buf = STRBUF_INIT;
 		format_commit_message(commit, format + 7, &buf, DATE_NORMAL);
-		printf("%s\n", buf.buf);
-		strbuf_release(&buf);
+		printf("%s\n", strbuf_detach(&buf, NULL));
 	}
-	free(format);
 }
 
 static int git_commit_config(const char *k, const char *v, void *cb)
-- 
1.6.0.2.529.g37dbc.dirty

^ permalink raw reply related

* [PATCH] GUI: Add a progressbar to visualize the time that is left
From: Björn Steinbrink @ 2008-10-01 21:09 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <alpine.LFD.2.00.0810011240390.3575@nehalem.linux-foundation.org>

Signed-off-by: Björn Steinbrink <B.Steinbrink@gmx.de>
---
OK, this bar doesn't fill up as you requested, but instead gets empty,
that's just how I feel it should be ;-)

Might require Tcl/Tk 8.5...

 tracker-ui.tcl |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/tracker-ui.tcl b/tracker-ui.tcl
index 16d00d7..5314c57 100755
--- a/tracker-ui.tcl
+++ b/tracker-ui.tcl
@@ -8,6 +8,7 @@ proc every {ms body} {
 set user $env(USER)
 
 pack [label .tracker -textvariable time]
+pack [ttk::progressbar .bar]
 
 every 1000 {
 	global user
@@ -17,4 +18,9 @@ every 1000 {
 	gets $f l3
 	close $f
 	set ::time "$l3"
+	set times [split "$l1" " "]
+	set max [lindex $times 0]
+	set cur [lindex $times 1]
+	set left [expr $max - $cur]
+	.bar configure -max $max -value $left
 }
-- 
1.6.0.2.307.gc427

^ permalink raw reply related

* Re: interactive rebase not rebasing
From: Andreas Ericsson @ 2008-10-01 21:26 UTC (permalink / raw)
  To: Stephen Haberman; +Cc: git
In-Reply-To: <20081001121321.5761fc7e.stephen@exigencecorp.com>

Stephen Haberman wrote:
>>> I've attempted to do that. Now that I sent in the patch, if you could
>>> review it, I would appreciate your feedback.
>> I'm heading home from work now. I'll look it over tonight or tomorrow
>> morning.
> 
> Cool, thanks.
> 
> Question: how taboo is it to just add another test file?
> 

Not so taboo. Especially not if there are compelling technical reasons
not to add stuff to an existing one.

> I'm attempting to integrate my test into t3404, which is the existing
> interactive rebase test. The two test_expect_success's I added worked
> when I ran them at the start of the test and then reset --hard the
> branches back for the other tests, but if I paste my tests where they
> should probably be, in the middle after the other -p tests, they break
> because the 10 or tests before this have screwed with the DAG already.
> 

Where you add the tests doesn't matter much. Many tests are grouped by
feature simply because they were added along with the feature they're
testing. There's no other value of grouping tests together.

> I can suffer through getting it to work, but a t3409 would be much
> easier, and probably easier to read as well as a I could setup my own
> DAG instead of hacking onto 3404s.
> 

t3409 is already in spearce.git's next branch. You should be able to
add stuff to that, or add t3410 if that doesn't work so good.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

^ permalink raw reply

* corrupted repository?
From: Francois Pepin @ 2008-10-01 21:29 UTC (permalink / raw)
  To: git

Hi,

The repository on my OS X machine (10.5.5) seems to have been suddenly 
become corrupted in a strange way.

Everything seems to be working properly there (git fsck --full returns 
normally with no output), but I cannot clone or pull from my other machines:

(iduna is the name of the OS X machine)
[francois@monch ~]$ git clone iduna:git iduna2
Initialized empty Git repository in /bioinfo/home/francois/iduna2/.git/
Password:
error: git upload-pack: git-pack-objects died with error.
fatal: git upload-pack: aborting due to possible repository corruption 
on the remote side.
remote: fatal: exec pack-objects failed.
remote: aborting due to possible repository corruption on the remote side.
fatal: early EOF
fatal: index-pack failed

I have the same issue from the same machine:
[francois@Iduna ~]$ git clone localhost:git git2
Initialized empty Git repository in /Users/francois/git2/.git/
remote: fatal: exec pack-objects failed.
error: git upload-pack: git-pack-objects died with error.
fatal: git upload-pack: aborting due to possible repository corruption 
on the remote side.
remote: aborting due to possible repository corruption on the remote side.
fatal: early EOF
fatal: index-pack failed

But not if I just do it locally:
[francois@Iduna ~]$ git clone git git2
Initialized empty Git repository in /Users/francois/git2/.git/
Checking out files:   2% (140/5273)
[I cancelled it at this point]

I am running git 1.6.0.2 on the mac, and have only recently updated it 
so that might have a role to play.

Any suggestion would be welcome to fix this issue, and I'll be more than 
happy to provide whatever more information could useful.

Francois

^ permalink raw reply

* Re: [PATCH] git commit: Repaint the output format bikeshed (again)
From: Jeff King @ 2008-10-01 22:06 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: Shawn Pearce, Git Mailing List
In-Reply-To: <48E3E66E.7020501@op5.se>

On Wed, Oct 01, 2008 at 11:06:54PM +0200, Andreas Ericsson wrote:

> of the commit result output. To make it read properly
> we get rid of "Created", which I just can't fit into
> a sentence without putting the branch-name last.

All of the other proposals indicate the hash and subject as the object
of creation. IOW, "created: <hash>: subject" or similar.

> Having taken inspiration from the "git reset" command,
> output for the three conceivable cases now look thus:
>
>  normal commit
>  <branch> is now at b930c4a (i386: Snib the sprock)

I think I still like your other proposal:

  [branch] created b930c4a: "i386: Snib the sprock"

better. But in the interests of just agreeing on something, I am willing
to accept this. FWIW, the git-reset command doesn't use any delimiter
for the message:

   <branch> is now at <hash> <subject>

So perhaps they should be the same. I don't think it overly matters.

>  detached commit
>  DETACHED HEAD is now at b930c4a (i386: Snib the sprock)

You mentioned the shouty caps before. I think "detached HEAD" is
probably caps enough, but not enough to argue for it (I just want to
mention as an informal vote if Shawn wants to mark it up while
applying).

>  initial commit
>  History has begun anew. Root-commit created.
>  <branch> is now at bc930c4a (i386: Snib the sprock)

Heh.

> "Created" is a problem when one wants to put branch-name before the
> subject line, because the subject has to follow the hash (it doesn't
> describe the pre-state of the branch/detached head), but the newly
> added commit. "Created, on branch, hash (subject)" just looks
> stilted and stupid, so I had to change it. Hopefully this can be
> accepted. If not, count me out.

That was the reason for the helper function that was deleted. It
actually created a format string like "Created %h on <branch>: %s" and
properly escaped the percents in <branch>. So you would have to keep it
if you wanted to interleave the data (but I think what you have is
better -- the branch name or the detached status is the thing that
should be first).

> I'm not sure if the last "else" case setting branch = head; can
> ever happen, but I figured it can't hurt to make sure. Feel free
> to modify commentary around it or the entire section when applying.

It should definitely be there, if only for the sanity of future
expansion (and because I can technically put whatever ref I want into
HEAD :) ).

> -		printf("%s\n", buf.buf);
> -		strbuf_release(&buf);
> +		printf("%s\n", strbuf_detach(&buf, NULL));

This change is bogus. "release" frees a strbuf. "detach" says "Give me
the buffer, and I will take care of freeing it later myself". So you
introduced a leak.

-Peff

^ permalink raw reply

* Re: [PATCH] git commit: Repaint the output format bikeshed (again)
From: Jeff King @ 2008-10-01 22:31 UTC (permalink / raw)
  To: Andreas Ericsson; +Cc: Shawn Pearce, Git Mailing List
In-Reply-To: <20081001220604.GB18058@coredump.intra.peff.net>

On Wed, Oct 01, 2008 at 06:06:04PM -0400, Jeff King wrote:

> I think I still like your other proposal:
> 
>   [branch] created b930c4a: "i386: Snib the sprock"

And here is the patch, since it was sitting uncommitted in my working
tree. Feel free to ignore.

BTW, we should apply _something_ since what is currently in next has a
bug: it lacks a space between "DETACHED commit" and the hash:

  Created DETACHED commit4fde0d0 (subject line)

-- >8 --
reformat informational commit message

When committing, we print a message like:

  Created [DETACHED commit] <hash> (<subject>) on <branch>

The most useful bit of information there (besides the
detached status, if it is present) is which branch you made
the commit on. However,  it is sometimes hard to see because
the subject dominates the line.

Instead, let's put the most useful information (detached
status and commit branch) on the far left, with the subject
(which is least likely to be interesting) on the far right.

We'll use brackets to offset the branch name so the line is
not mistaken for an error line of the form "program: some
sort of error". E.g.,:

  [jk/bikeshed] created bd8098f: "reformat informational commit message"
---
 builtin-commit.c |   37 ++++++++++---------------------------
 1 files changed, 10 insertions(+), 27 deletions(-)

diff --git a/builtin-commit.c b/builtin-commit.c
index e4e1448..7a66e5a 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -878,35 +878,13 @@ int cmd_status(int argc, const char **argv, const char *prefix)
 	return commitable ? 0 : 1;
 }
 
-static char *get_commit_format_string(void)
-{
-	unsigned char sha[20];
-	const char *head = resolve_ref("HEAD", sha, 0, NULL);
-	struct strbuf buf = STRBUF_INIT;
-
-	/* use shouty-caps if we're on detached HEAD */
-	strbuf_addf(&buf, "format:%s", strcmp("HEAD", head) ? "" : "DETACHED commit");
-	strbuf_addstr(&buf, "%h (%s)");
-
-	if (!prefixcmp(head, "refs/heads/")) {
-		const char *cp;
-		strbuf_addstr(&buf, " on ");
-		for (cp = head + 11; *cp; cp++) {
-			if (*cp == '%')
-				strbuf_addstr(&buf, "%x25");
-			else
-				strbuf_addch(&buf, *cp);
-		}
-	}
-
-	return strbuf_detach(&buf, NULL);
-}
-
 static void print_summary(const char *prefix, const unsigned char *sha1)
 {
 	struct rev_info rev;
 	struct commit *commit;
-	char *format = get_commit_format_string();
+	static const char *format = "format:%h: \"%s\"";
+	unsigned char junk_sha1[20];
+	const char *head = resolve_ref("HEAD", junk_sha1, 0, NULL);
 
 	commit = lookup_commit(sha1);
 	if (!commit)
@@ -931,7 +909,13 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
 	rev.diffopt.break_opt = 0;
 	diff_setup_done(&rev.diffopt);
 
-	printf("Created %s", initial_commit ? "root-commit " : "");
+	printf("[%s%s]: created ",
+		!prefixcmp(head, "refs/heads/") ?
+			head + 11 :
+			!strcmp(head, "HEAD") ?
+				"detached HEAD" :
+				head,
+		initial_commit ? " (root-commit)" : "");
 
 	if (!log_tree_commit(&rev, commit)) {
 		struct strbuf buf = STRBUF_INIT;
@@ -939,7 +923,6 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
 		printf("%s\n", buf.buf);
 		strbuf_release(&buf);
 	}
-	free(format);
 }
 
 static int git_commit_config(const char *k, const char *v, void *cb)
-- 
1.6.0.2.570.g2c958

^ permalink raw reply related

* Re: Help with a tcl/tk gui thing..
From: Linus Torvalds @ 2008-10-01 23:06 UTC (permalink / raw)
  To: Mikael Magnusson; +Cc: Git Mailing List
In-Reply-To: <237967ef0810011403i2b18255and988df29a71798bf@mail.gmail.com>



On Wed, 1 Oct 2008, Mikael Magnusson wrote:
> 
> git clone git://mika.l3ib.org/tracker.git
> 
> I wrote it in pygtk since I know zero to no tcl/tk, hope that's okay.
> It has a label with the time remaining (simply read from the daemon file),
> and shows the text in red if less than 10% is remaining. You'll need to
> change the ./ in cb_function to /var/log/tracker since I forgot to change
> that and I'm lazy :).

Well, it doesn't do anything at all for me except change the cursor to a 
cross, and if I'm a n00b with tcl/tk, I'm even more of one with pygtk.

I merged the two other suggestions, though. And am open to seeing that 
pygtk thing too as an alternative, but only if it actually works for me ;)

		Linus

^ permalink raw reply

* Re: [PATCH] Make maximum surf time really per day
From: Linus Torvalds @ 2008-10-01 23:09 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0810012239030.22125@pacific.mpi-cbg.de.mpi-cbg.de>



On Wed, 1 Oct 2008, Johannes Schindelin wrote:
> 
> Earlier, when the maximum time was reached, we would block for 8 hours.
> The program description suggested that the maximum time should be per
> day instead, however.  So rather check that.

I actually prefer the old behavior. Your new one has a "flag time" when 
you get all your time back, and it's not even something logical like 
midnight, it is (if I read the patch right), "midnight UTC" that will do 
it.

So the "you have to be offline for at least 8 hours" thing is actually 
something that even my old tracker worked with, and at least with my kids, 
there is no worry that they'd wake up early just to do it both before 
_and_ after school ;)

		Linus

^ permalink raw reply

* [PATCH] Solaris: Use OLD_ICONV to avoid compile warnings
From: David Soria Parra @ 2008-10-02  0:08 UTC (permalink / raw)
  To: git; +Cc: David Soria Parra

From: David Soria Parra <dsp@php.net>

Solaris systems use the old styled iconv(3) call and therefore
the OLD_ICONV variable should be set. Otherwise we get annoying compile
warnings.

Signed-off-by: David Soria Parra <dsp@php.net>
---
 Makefile |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile
index 7db2ccc..3abbb4e 100644
--- a/Makefile
+++ b/Makefile
@@ -649,6 +649,7 @@ ifeq ($(uname_S),SunOS)
 	NO_MEMMEM = YesPlease
 	NO_HSTRERROR = YesPlease
 	NO_MKDTEMP = YesPlease
+	OLD_ICONV = UnfortunatelyYes
 	ifeq ($(uname_R),5.8)
 		NEEDS_LIBICONV = YesPlease
 		NO_UNSETENV = YesPlease
-- 
1.6.0.2.569.g798a2a

^ permalink raw reply related

* [PATCHv4] gitweb: PATH_INFO support improvements
From: Giuseppe Bilotta @ 2008-10-02  0:10 UTC (permalink / raw)
  To: git
  Cc: Jakub Narebski, Petr Baudis, Junio C Hamano, Shawn O. Pearce,
	Giuseppe Bilotta

Fourth version of my gitweb PATH_INFO patchset, whose purpose is to
reduce the use of CGI parameters by embedding as many parameters as
possible in the URL path itself, provided the pathinfo feature is
enabled.

The new typical gitweb URL is therefore in the form

$project/$action/$parent:$file..$hash:$file

(with useless parts stripped). Backwards compatibility for old-style
$project/$hash URLs is kept, as long as $hash is not a refname whose
name happens to match a git action.

The main implementation is provided by paired patches (#1#3, #5#6)
that implement parsing and generation of the new style URLs.

Patch #2 deals with a refactoring of the input parameters parsing and
validation, so that the rest of gitweb can be agnostic wrt to the
parameters' origin (CGI vs PATH_INFO vs possible other future inputs
such as CLI).

Patch #4 is a minor improvement to the URL syntax that allows web
documents to be properly browsable in raw mode.

Giuseppe Bilotta (6):
  gitweb: parse project/action/hash_base:filename PATH_INFO
  gitweb: refactor input parameters parse/validation
  gitweb: generate project/action/hash URLs
  gitweb: use_pathinfo filenames start with /
  gitweb: parse parent..current syntax from pathinfo
  gitweb: generate parent..current URLs

 gitweb/gitweb.perl |  392 ++++++++++++++++++++++++++++++++++------------------
 1 files changed, 254 insertions(+), 138 deletions(-)

^ permalink raw reply

* [PATCHv4] gitweb: parse project/action/hash_base:filename PATH_INFO
From: Giuseppe Bilotta @ 2008-10-02  0:10 UTC (permalink / raw)
  To: git
  Cc: Jakub Narebski, Petr Baudis, Junio C Hamano, Shawn O. Pearce,
	Giuseppe Bilotta
In-Reply-To: <1222906234-8182-1-git-send-email-giuseppe.bilotta@gmail.com>

This patch enables gitweb to parse URLs with more information embedded
in PATH_INFO, reducing the need for CGI parameters. The typical gitweb
path is now $project/$action/$hash_base:$file_name or
$project/$action/$hash

This is mostly backwards compatible with the old-style gitweb paths,
except when $project/$branch was used to access a branch whose name
matches a gitweb action.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---
 gitweb/gitweb.perl |   90 +++++++++++++++++++++++++++++++---------------------
 1 files changed, 54 insertions(+), 36 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index e7e4d6b..f088681 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -495,6 +495,37 @@ if (defined $searchtext) {
 	$search_regexp = $search_use_regexp ? $searchtext : quotemeta $searchtext;
 }
 
+# dispatch
+my %actions = (
+	"blame" => \&git_blame,
+	"blobdiff" => \&git_blobdiff,
+	"blobdiff_plain" => \&git_blobdiff_plain,
+	"blob" => \&git_blob,
+	"blob_plain" => \&git_blob_plain,
+	"commitdiff" => \&git_commitdiff,
+	"commitdiff_plain" => \&git_commitdiff_plain,
+	"commit" => \&git_commit,
+	"forks" => \&git_forks,
+	"heads" => \&git_heads,
+	"history" => \&git_history,
+	"log" => \&git_log,
+	"rss" => \&git_rss,
+	"atom" => \&git_atom,
+	"search" => \&git_search,
+	"search_help" => \&git_search_help,
+	"shortlog" => \&git_shortlog,
+	"summary" => \&git_summary,
+	"tag" => \&git_tag,
+	"tags" => \&git_tags,
+	"tree" => \&git_tree,
+	"snapshot" => \&git_snapshot,
+	"object" => \&git_object,
+	# those below don't need $project
+	"opml" => \&git_opml,
+	"project_list" => \&git_project_list,
+	"project_index" => \&git_project_index,
+);
+
 # now read PATH_INFO and use it as alternative to parameters
 sub evaluate_path_info {
 	return if defined $project;
@@ -519,9 +550,19 @@ sub evaluate_path_info {
 	# do not change any parameters if an action is given using the query string
 	return if $action;
 	$path_info =~ s,^\Q$project\E/*,,;
+
+	# next comes the action
+	$action = $path_info;
+	$action =~ s,/.*$,,;
+	if (exists $actions{$action}) {
+		$path_info =~ s,^$action/*,,;
+	} else {
+		$action  = undef;
+	}
+
 	my ($refname, $pathname) = split(/:/, $path_info, 2);
 	if (defined $pathname) {
-		# we got "project.git/branch:filename" or "project.git/branch:dir/"
+		# we got "project.git/action/branch:filename" or "project.git/action/branch:dir/"
 		# we could use git_get_type(branch:pathname), but it needs $git_dir
 		$pathname =~ s,^/+,,;
 		if (!$pathname || substr($pathname, -1) eq "/") {
@@ -534,8 +575,9 @@ sub evaluate_path_info {
 		$file_name ||= validate_pathname($pathname);
 	} elsif (defined $refname) {
 		# we got "project.git/branch"
-		$action ||= "shortlog";
-		$hash   ||= validate_refname($refname);
+		$action    ||= "shortlog";
+		$hash      ||= validate_refname($refname);
+		$hash_base ||= validate_refname($refname);
 	}
 }
 evaluate_path_info();
@@ -544,37 +586,6 @@ evaluate_path_info();
 our $git_dir;
 $git_dir = "$projectroot/$project" if $project;
 
-# dispatch
-my %actions = (
-	"blame" => \&git_blame,
-	"blobdiff" => \&git_blobdiff,
-	"blobdiff_plain" => \&git_blobdiff_plain,
-	"blob" => \&git_blob,
-	"blob_plain" => \&git_blob_plain,
-	"commitdiff" => \&git_commitdiff,
-	"commitdiff_plain" => \&git_commitdiff_plain,
-	"commit" => \&git_commit,
-	"forks" => \&git_forks,
-	"heads" => \&git_heads,
-	"history" => \&git_history,
-	"log" => \&git_log,
-	"rss" => \&git_rss,
-	"atom" => \&git_atom,
-	"search" => \&git_search,
-	"search_help" => \&git_search_help,
-	"shortlog" => \&git_shortlog,
-	"summary" => \&git_summary,
-	"tag" => \&git_tag,
-	"tags" => \&git_tags,
-	"tree" => \&git_tree,
-	"snapshot" => \&git_snapshot,
-	"object" => \&git_object,
-	# those below don't need $project
-	"opml" => \&git_opml,
-	"project_list" => \&git_project_list,
-	"project_index" => \&git_project_index,
-);
-
 if (!defined $action) {
 	if (defined $hash) {
 		$action = git_get_type($hash);
@@ -631,8 +642,15 @@ sub href (%) {
 	if ($params{-replay}) {
 		while (my ($name, $symbol) = each %mapping) {
 			if (!exists $params{$name}) {
-				# to allow for multivalued params we use arrayref form
-				$params{$name} = [ $cgi->param($symbol) ];
+				# the parameter we want to recycle may be either part of the
+				# list of CGI parameter, or recovered from PATH_INFO
+				if ($cgi->param($symbol)) {
+					# to allow for multivalued params we use arrayref form
+					$params{$name} = [ $cgi->param($symbol) ];
+				} else {
+					no strict 'refs';
+					$params{$name} = $$name if $$name;
+				}
 			}
 		}
 	}
-- 
1.5.6.5

^ permalink raw reply related

* [PATCHv4] gitweb: refactor input parameters parse/validation
From: Giuseppe Bilotta @ 2008-10-02  0:10 UTC (permalink / raw)
  To: git
  Cc: Jakub Narebski, Petr Baudis, Junio C Hamano, Shawn O. Pearce,
	Giuseppe Bilotta
In-Reply-To: <1222906234-8182-2-git-send-email-giuseppe.bilotta@gmail.com>

Since input parameters can now be obtained both from CGI parameters and
PATH_INFO, we would like most of the code to be agnostic about the way
parameters were retrieved.

We thus collect all the parameters into the new %input_params hash,
removing the need for ad-hoc kludgy code in href(). As much of the
parameters validation code is now shared between CGI and PATH_INFO,
although this requires PATH_INFO parsing to be interleaved into the main
code instead of being factored out into its own routine.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---
 gitweb/gitweb.perl |  336 ++++++++++++++++++++++++++++------------------------
 1 files changed, 183 insertions(+), 153 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f088681..ec4326f 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -28,8 +28,10 @@ our $my_url = $cgi->url();
 our $my_uri = $cgi->url(-absolute => 1);
 
 # if we're called with PATH_INFO, we have to strip that
-# from the URL to find our real URL
-if (my $path_info = $ENV{"PATH_INFO"}) {
+# from the URL to find our real URL. PATH_INFO is kept
+# as it's used later on for parameter extraction
+my $path_info = $ENV{"PATH_INFO"};
+if ($path_info) {
 	$my_url =~ s,\Q$path_info\E$,,;
 	$my_uri =~ s,\Q$path_info\E$,,;
 }
@@ -390,15 +392,111 @@ $projects_list ||= $projectroot;
 
 # ======================================================================
 # input validation and dispatch
-our $action = $cgi->param('a');
-if (defined $action) {
-	if ($action =~ m/[^0-9a-zA-Z\.\-_]/) {
-		die_error(400, "Invalid action parameter");
+
+# input parameters can be collected from a variety of sources (presently, CGI
+# and PATH_INFO), so we define an %input_params hash that collects them all
+# together during validation: this allows subsequent uses (e.g. href()) to be
+# agnostic of the parameter origin
+
+my %input_params = ();
+
+# input parameters are stored with the long parameter name as key, so we need
+# the name -> CGI key mapping here. This will also be used in the href
+# subroutine to convert parameters to their CGI equivalent.
+#
+# XXX: Warning: If you touch this, check the search form for updating,
+# too.
+
+my @cgi_param_mapping = (
+	project => "p",
+	action => "a",
+	file_name => "f",
+	file_parent => "fp",
+	hash => "h",
+	hash_parent => "hp",
+	hash_base => "hb",
+	hash_parent_base => "hpb",
+	page => "pg",
+	order => "o",
+	searchtext => "s",
+	searchtype => "st",
+	snapshot_format => "sf",
+	extra_options => "opt",
+	search_use_regexp => "sr",
+);
+my %cgi_param_mapping = @cgi_param_mapping;
+
+# we will also need to know the possible actions, for validation
+my %actions = (
+	"blame" => \&git_blame,
+	"blobdiff" => \&git_blobdiff,
+	"blobdiff_plain" => \&git_blobdiff_plain,
+	"blob" => \&git_blob,
+	"blob_plain" => \&git_blob_plain,
+	"commitdiff" => \&git_commitdiff,
+	"commitdiff_plain" => \&git_commitdiff_plain,
+	"commit" => \&git_commit,
+	"forks" => \&git_forks,
+	"heads" => \&git_heads,
+	"history" => \&git_history,
+	"log" => \&git_log,
+	"rss" => \&git_rss,
+	"atom" => \&git_atom,
+	"search" => \&git_search,
+	"search_help" => \&git_search_help,
+	"shortlog" => \&git_shortlog,
+	"summary" => \&git_summary,
+	"tag" => \&git_tag,
+	"tags" => \&git_tags,
+	"tree" => \&git_tree,
+	"snapshot" => \&git_snapshot,
+	"object" => \&git_object,
+	# those below don't need $project
+	"opml" => \&git_opml,
+	"project_list" => \&git_project_list,
+	"project_index" => \&git_project_index,
+);
+
+# fill %input_params with the CGI parameters. All values except for 'opt'
+# should be single values, but opt can be an array. We should probably
+# build an array of parameters that can be multi-valued, but since for the time
+# being it's only this one, we just single it out
+while (my ($name, $symbol) = each %cgi_param_mapping) {
+	if ($symbol eq 'opt') {
+		$input_params{$name} = [$cgi->param($symbol)];
+	} else {
+		$input_params{$name} = $cgi->param($symbol);
 	}
 }
 
-# parameters which are pathnames
-our $project = $cgi->param('p');
+# next, we want to parse PATH_INFO (which was already stored in $path_info at
+# the beginning). This is a little hairy because PATH_INFO parsing needs some
+# form of parameter validation, so we interleave parsing and validation.
+#
+# The accepted PATH_INFO syntax is $project/$action/$hash or
+# $project/$action/$hash_base:$file_name, where $action may be missing (mostly for
+# backwards compatibility), so we need to parse and validate the parameters in
+# this same order.
+
+# clear $path_info of any leading /
+$path_info =~ s,^/+,,;
+
+our $project = $input_params{'project'};
+if ($path_info && !defined $project) {
+	# if $project was not defined by CGI, we try to extract it from
+	# $path_info
+	$project = $path_info;
+	$project =~ s,/+$,,;
+	while ($project && !check_head_link("$projectroot/$project")) {
+		$project =~ s,/*[^/]*$,,;
+	}
+	$input_params{'project'} = $project;
+} else {
+	# otherwise, we suppress $path_info parsing altogether
+	$path_info = undef;
+}
+
+# project name validation
 if (defined $project) {
 	if (!validate_pathname($project) ||
 	    !(-d "$projectroot/$project") ||
@@ -408,16 +506,66 @@ if (defined $project) {
 		undef $project;
 		die_error(404, "No such project");
 	}
+
+	# we purge the $project name from the $path_info, preparing it for
+	# subsequent parameters extraction
+	$path_info =~ s,^\Q$project\E/*,, if defined $path_info;
+} else {
+	# we also suppress $path_info parsing if no project was defined
+	$path_info = undef;
+}
+
+# action parsing/validation
+our $action = $input_params{'action'};
+if ($path_info && !defined $action) {
+	# next comes the action
+	$action = $path_info;
+	$action =~ s,/.*$,,;
+	if (exists $actions{$action}) {
+		# remove the action from $path_info, and sync %input_params
+		$path_info =~ s,^$action/*,,;
+		$input_params{'action'} = $action;
+	} else {
+		$action  = undef;
+	}
+} elsif (defined $action && !exists $actions{$action}) {
+	die_error(400, "Invalid action parameter");
+}
+
+# we can now parse ref and pathnames in PATH_INFO
+if ($path_info) {
+	my ($refname, $pathname) = split(/:/, $path_info, 2);
+	if (defined $pathname) {
+		# we got "project.git/action/branch:filename" or "project.git/action/branch:dir/"
+		# we could use git_get_type(branch:pathname), but it needs $git_dir
+		$pathname =~ s,^/+,,;
+		if (!$pathname || substr($pathname, -1) eq "/") {
+			$input_params{'action'} ||= "tree";
+			$pathname =~ s,/$,,;
+		} else {
+			$input_params{'action'}  ||= "blob_plain";
+		}
+		$input_params{'hash_base'} ||= $refname;
+		$input_params{'file_name'} ||= $pathname;
+	} elsif (defined $refname) {
+		# we got "project.git/branch"
+		$input_params{'action'}    ||= "shortlog";
+		$input_params{'hash'}      ||= $refname;
+		$input_params{'hash_base'} ||= $refname;
+	}
 }
 
-our $file_name = $cgi->param('f');
+# and now the rest of the validation
+
+# parameters which are pathnames
+our $file_name = $input_params{'file_name'};
 if (defined $file_name) {
 	if (!validate_pathname($file_name)) {
 		die_error(400, "Invalid file parameter");
 	}
 }
 
-our $file_parent = $cgi->param('fp');
+our $file_parent = $input_params{'file_parent'};
 if (defined $file_parent) {
 	if (!validate_pathname($file_parent)) {
 		die_error(400, "Invalid file parent parameter");
@@ -425,21 +573,21 @@ if (defined $file_parent) {
 }
 
 # parameters which are refnames
-our $hash = $cgi->param('h');
+our $hash = $input_params{'hash'};
 if (defined $hash) {
 	if (!validate_refname($hash)) {
 		die_error(400, "Invalid hash parameter");
 	}
 }
 
-our $hash_parent = $cgi->param('hp');
+our $hash_parent = $input_params{'hash_parent'};
 if (defined $hash_parent) {
 	if (!validate_refname($hash_parent)) {
 		die_error(400, "Invalid hash parent parameter");
 	}
 }
 
-our $hash_base = $cgi->param('hb');
+our $hash_base = $input_params{'hash_base'};
 if (defined $hash_base) {
 	if (!validate_refname($hash_base)) {
 		die_error(400, "Invalid hash base parameter");
@@ -450,19 +598,19 @@ my %allowed_options = (
 	"--no-merges" => [ qw(rss atom log shortlog history) ],
 );
 
-our @extra_options = $cgi->param('opt');
-if (defined @extra_options) {
-	foreach my $opt (@extra_options) {
-		if (not exists $allowed_options{$opt}) {
-			die_error(400, "Invalid option parameter");
-		}
-		if (not grep(/^$action$/, @{$allowed_options{$opt}})) {
-			die_error(400, "Invalid option parameter for this action");
-		}
+our @extra_options = @{$input_params{'extra_options'}};
+# @extra_options is always defined, since it can only be (currently) set from
+# CGI, and $cgi->param() returns the empty array in array context
+foreach my $opt (@extra_options) {
+	if (not exists $allowed_options{$opt}) {
+		die_error(400, "Invalid option parameter");
+	}
+	if (not grep(/^$action$/, @{$allowed_options{$opt}})) {
+		die_error(400, "Invalid option parameter for this action");
 	}
 }
 
-our $hash_parent_base = $cgi->param('hpb');
+our $hash_parent_base = $input_params{'hash_parent_base'};
 if (defined $hash_parent_base) {
 	if (!validate_refname($hash_parent_base)) {
 		die_error(400, "Invalid hash parent base parameter");
@@ -470,23 +618,23 @@ if (defined $hash_parent_base) {
 }
 
 # other parameters
-our $page = $cgi->param('pg');
+our $page = $input_params{'page'};
 if (defined $page) {
 	if ($page =~ m/[^0-9]/) {
 		die_error(400, "Invalid page parameter");
 	}
 }
 
-our $searchtype = $cgi->param('st');
+our $searchtype = $input_params{'searchtype'};
 if (defined $searchtype) {
 	if ($searchtype =~ m/[^a-z]/) {
 		die_error(400, "Invalid searchtype parameter");
 	}
 }
 
-our $search_use_regexp = $cgi->param('sr');
+our $search_use_regexp = $input_params{'search_use_regexp'};
 
-our $searchtext = $cgi->param('s');
+our $searchtext = $input_params{'searchtext'};
 our $search_regexp;
 if (defined $searchtext) {
 	if (length($searchtext) < 2) {
@@ -495,93 +643,6 @@ if (defined $searchtext) {
 	$search_regexp = $search_use_regexp ? $searchtext : quotemeta $searchtext;
 }
 
-# dispatch
-my %actions = (
-	"blame" => \&git_blame,
-	"blobdiff" => \&git_blobdiff,
-	"blobdiff_plain" => \&git_blobdiff_plain,
-	"blob" => \&git_blob,
-	"blob_plain" => \&git_blob_plain,
-	"commitdiff" => \&git_commitdiff,
-	"commitdiff_plain" => \&git_commitdiff_plain,
-	"commit" => \&git_commit,
-	"forks" => \&git_forks,
-	"heads" => \&git_heads,
-	"history" => \&git_history,
-	"log" => \&git_log,
-	"rss" => \&git_rss,
-	"atom" => \&git_atom,
-	"search" => \&git_search,
-	"search_help" => \&git_search_help,
-	"shortlog" => \&git_shortlog,
-	"summary" => \&git_summary,
-	"tag" => \&git_tag,
-	"tags" => \&git_tags,
-	"tree" => \&git_tree,
-	"snapshot" => \&git_snapshot,
-	"object" => \&git_object,
-	# those below don't need $project
-	"opml" => \&git_opml,
-	"project_list" => \&git_project_list,
-	"project_index" => \&git_project_index,
-);
-
-# now read PATH_INFO and use it as alternative to parameters
-sub evaluate_path_info {
-	return if defined $project;
-	my $path_info = $ENV{"PATH_INFO"};
-	return if !$path_info;
-	$path_info =~ s,^/+,,;
-	return if !$path_info;
-	# find which part of PATH_INFO is project
-	$project = $path_info;
-	$project =~ s,/+$,,;
-	while ($project && !check_head_link("$projectroot/$project")) {
-		$project =~ s,/*[^/]*$,,;
-	}
-	# validate project
-	$project = validate_pathname($project);
-	if (!$project ||
-	    ($export_ok && !-e "$projectroot/$project/$export_ok") ||
-	    ($strict_export && !project_in_list($project))) {
-		undef $project;
-		return;
-	}
-	# do not change any parameters if an action is given using the query string
-	return if $action;
-	$path_info =~ s,^\Q$project\E/*,,;
-
-	# next comes the action
-	$action = $path_info;
-	$action =~ s,/.*$,,;
-	if (exists $actions{$action}) {
-		$path_info =~ s,^$action/*,,;
-	} else {
-		$action  = undef;
-	}
-
-	my ($refname, $pathname) = split(/:/, $path_info, 2);
-	if (defined $pathname) {
-		# we got "project.git/action/branch:filename" or "project.git/action/branch:dir/"
-		# we could use git_get_type(branch:pathname), but it needs $git_dir
-		$pathname =~ s,^/+,,;
-		if (!$pathname || substr($pathname, -1) eq "/") {
-			$action  ||= "tree";
-			$pathname =~ s,/$,,;
-		} else {
-			$action  ||= "blob_plain";
-		}
-		$hash_base ||= validate_refname($refname);
-		$file_name ||= validate_pathname($pathname);
-	} elsif (defined $refname) {
-		# we got "project.git/branch"
-		$action    ||= "shortlog";
-		$hash      ||= validate_refname($refname);
-		$hash_base ||= validate_refname($refname);
-	}
-}
-evaluate_path_info();
-
 # path to the current git repository
 our $git_dir;
 $git_dir = "$projectroot/$project" if $project;
@@ -615,43 +676,12 @@ sub href (%) {
 	# default is to use -absolute url() i.e. $my_uri
 	my $href = $params{-full} ? $my_url : $my_uri;
 
-	# XXX: Warning: If you touch this, check the search form for updating,
-	# too.
-
-	my @mapping = (
-		project => "p",
-		action => "a",
-		file_name => "f",
-		file_parent => "fp",
-		hash => "h",
-		hash_parent => "hp",
-		hash_base => "hb",
-		hash_parent_base => "hpb",
-		page => "pg",
-		order => "o",
-		searchtext => "s",
-		searchtype => "st",
-		snapshot_format => "sf",
-		extra_options => "opt",
-		search_use_regexp => "sr",
-	);
-	my %mapping = @mapping;
-
 	$params{'project'} = $project unless exists $params{'project'};
 
 	if ($params{-replay}) {
-		while (my ($name, $symbol) = each %mapping) {
-			if (!exists $params{$name}) {
-				# the parameter we want to recycle may be either part of the
-				# list of CGI parameter, or recovered from PATH_INFO
-				if ($cgi->param($symbol)) {
-					# to allow for multivalued params we use arrayref form
-					$params{$name} = [ $cgi->param($symbol) ];
-				} else {
-					no strict 'refs';
-					$params{$name} = $$name if $$name;
-				}
-			}
+		while (my ($name, $val) = each %input_params) {
+			$params{$name} = $input_params{$name}
+				unless (exists $params{$name});
 		}
 	}
 
@@ -669,8 +699,8 @@ sub href (%) {
 
 	# now encode the parameters explicitly
 	my @result = ();
-	for (my $i = 0; $i < @mapping; $i += 2) {
-		my ($name, $symbol) = ($mapping[$i], $mapping[$i+1]);
+	for (my $i = 0; $i < @cgi_param_mapping; $i += 2) {
+		my ($name, $symbol) = ($cgi_param_mapping[$i], $cgi_param_mapping[$i+1]);
 		if (defined $params{$name}) {
 			if (ref($params{$name}) eq "ARRAY") {
 				foreach my $par (@{$params{$name}}) {
@@ -4006,7 +4036,7 @@ sub git_search_grep_body {
 ## actions
 
 sub git_project_list {
-	my $order = $cgi->param('o');
+	my $order = $input_params{'order'};
 	if (defined $order && $order !~ m/none|project|descr|owner|age/) {
 		die_error(400, "Unknown order parameter");
 	}
@@ -4029,7 +4059,7 @@ sub git_project_list {
 }
 
 sub git_forks {
-	my $order = $cgi->param('o');
+	my $order = $input_params{'order'};
 	if (defined $order && $order !~ m/none|project|descr|owner|age/) {
 		die_error(400, "Unknown order parameter");
 	}
@@ -4562,7 +4592,7 @@ sub git_snapshot {
 	my @supported_fmts = gitweb_check_feature('snapshot');
 	@supported_fmts = filter_snapshot_fmts(@supported_fmts);
 
-	my $format = $cgi->param('sf');
+	my $format = $input_params{'snapshot_format'};
 	if (!@supported_fmts) {
 		die_error(403, "Snapshots not allowed");
 	}
-- 
1.5.6.5

^ permalink raw reply related

* [PATCHv4] gitweb: generate project/action/hash URLs
From: Giuseppe Bilotta @ 2008-10-02  0:10 UTC (permalink / raw)
  To: git
  Cc: Jakub Narebski, Petr Baudis, Junio C Hamano, Shawn O. Pearce,
	Giuseppe Bilotta
In-Reply-To: <1222906234-8182-3-git-send-email-giuseppe.bilotta@gmail.com>

When generating path info URLs, reduce the number of CGI parameters by
embedding action and hash_parent:filename or hash in the path.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---
 gitweb/gitweb.perl |   32 +++++++++++++++++++++++++++++---
 1 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index ec4326f..2c380ac 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -687,14 +687,40 @@ sub href (%) {
 
 	my ($use_pathinfo) = gitweb_check_feature('pathinfo');
 	if ($use_pathinfo) {
-		# use PATH_INFO for project name
+		# try to put as many parameters as possible in PATH_INFO:
+		#   - project name
+		#   - action
+		#   - hash or hash_base:filename
+
+		# Strip any trailing / from $href, or we might get double
+		# slashes when the script is the DirectoryIndex
+		#
+		$href =~ s,/$,,;
+
+		# Then add the project name, if present
 		$href .= "/".esc_url($params{'project'}) if defined $params{'project'};
 		delete $params{'project'};
 
-		# Summary just uses the project path URL
-		if (defined $params{'action'} && $params{'action'} eq 'summary') {
+		# Summary just uses the project path URL, any other action is
+		# added to the URL
+		if (defined $params{'action'}) {
+			$href .= "/".esc_url($params{'action'}) unless $params{'action'} eq 'summary';
 			delete $params{'action'};
 		}
+
+		# Finally, we put either hash_base:file_name or hash
+		if (defined $params{'hash_base'}) {
+			$href .= "/".esc_url($params{'hash_base'});
+			if (defined $params{'file_name'}) {
+				$href .= ":".esc_url($params{'file_name'});
+				delete $params{'file_name'};
+			}
+			delete $params{'hash'};
+			delete $params{'hash_base'};
+		} elsif (defined $params{'hash'}) {
+			$href .= "/".esc_url($params{'hash'});
+			delete $params{'hash'};
+		}
 	}
 
 	# now encode the parameters explicitly
-- 
1.5.6.5

^ permalink raw reply related

* [PATCHv4] gitweb: use_pathinfo filenames start with /
From: Giuseppe Bilotta @ 2008-10-02  0:10 UTC (permalink / raw)
  To: git
  Cc: Jakub Narebski, Petr Baudis, Junio C Hamano, Shawn O. Pearce,
	Giuseppe Bilotta
In-Reply-To: <1222906234-8182-4-git-send-email-giuseppe.bilotta@gmail.com>

When using path info, make filenames start with a / (right after the :
that separates them from the hash base). This minimal change allows
relative navigation to work properly when viewing HTML files.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---
 gitweb/gitweb.perl |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 2c380ac..3e5b2b7 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -690,7 +690,7 @@ sub href (%) {
 		# try to put as many parameters as possible in PATH_INFO:
 		#   - project name
 		#   - action
-		#   - hash or hash_base:filename
+		#   - hash or hash_base:/filename
 
 		# Strip any trailing / from $href, or we might get double
 		# slashes when the script is the DirectoryIndex
@@ -708,11 +708,11 @@ sub href (%) {
 			delete $params{'action'};
 		}
 
-		# Finally, we put either hash_base:file_name or hash
+		# Finally, we put either hash_base:/file_name or hash
 		if (defined $params{'hash_base'}) {
 			$href .= "/".esc_url($params{'hash_base'});
 			if (defined $params{'file_name'}) {
-				$href .= ":".esc_url($params{'file_name'});
+				$href .= ":/".esc_url($params{'file_name'});
 				delete $params{'file_name'};
 			}
 			delete $params{'hash'};
-- 
1.5.6.5

^ permalink raw reply related

* [PATCHv4] gitweb: parse parent..current syntax from pathinfo
From: Giuseppe Bilotta @ 2008-10-02  0:10 UTC (permalink / raw)
  To: git
  Cc: Jakub Narebski, Petr Baudis, Junio C Hamano, Shawn O. Pearce,
	Giuseppe Bilotta
In-Reply-To: <1222906234-8182-5-git-send-email-giuseppe.bilotta@gmail.com>

This makes it possible to use an URL such as
$project/somebranch..otherbranch:/filename to get a diff between
different version of a file. Paths like
$project/$action/somebranch:/somefile..otherbranch:/otherfile are parsed
as well.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---
 gitweb/gitweb.perl |   26 ++++++++++++++++++++++++--
 1 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 3e5b2b7..89e360f 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -534,7 +534,9 @@ if ($path_info && !defined $action) {
 
 # we can now parse ref and pathnames in PATH_INFO
 if ($path_info) {
-	my ($refname, $pathname) = split(/:/, $path_info, 2);
+	$path_info =~ /^((.+?)(:(.+))?\.\.)?(.+?)(:(.+))?$/;
+	my ($parentrefname, $parentpathname, $refname, $pathname) = (
+		$2, $4, $5, $7);
 	if (defined $pathname) {
 		# we got "project.git/action/branch:filename" or "project.git/action/branch:dir/"
 		# we could use git_get_type(branch:pathname), but it needs $git_dir
@@ -543,7 +545,11 @@ if ($path_info) {
 			$input_params{'action'} ||= "tree";
 			$pathname =~ s,/$,,;
 		} else {
-			$input_params{'action'}  ||= "blob_plain";
+			if ($parentrefname) {
+				$input_params{'action'} ||= "blobdiff_plain";
+			} else {
+				$input_params{'action'} ||= "blob_plain";
+			}
 		}
 		$input_params{'hash_base'} ||= $refname;
 		$input_params{'file_name'} ||= $pathname;
@@ -553,6 +559,22 @@ if ($path_info) {
 		$input_params{'hash'}      ||= $refname;
 		$input_params{'hash_base'} ||= $refname;
 	}
+	# the parent part might be missing the pathname, in which case we use the $file_name, if present
+	if (defined $parentrefname) {
+		$input_params{'hash_parent_base'} ||= $parentrefname;
+		if ($parentpathname) {
+			$parentpathname =~ s,^/+,,;
+			$parentpathname =~ s,/$,,;
+			$input_params{'file_parent'} ||= $parentpathname;
+		} else {
+			$input_params{'file_parent'} ||= $input_params{'file_name'};
+		}
+		if (defined $input_params{'file_parent'}) {
+			$input_params{'hash_parent'} ||= git_get_hash_by_path($input_params{'hash_parent_base'}, $input_params{'file_parent'});
+		} else {
+			$input_params{'hash_parent'} ||= $parentrefname;
+		}
+	}
 }
 
 # and now the rest of the validation
-- 
1.5.6.5

^ permalink raw reply related

* [PATCHv4] gitweb: generate parent..current URLs
From: Giuseppe Bilotta @ 2008-10-02  0:10 UTC (permalink / raw)
  To: git
  Cc: Jakub Narebski, Petr Baudis, Junio C Hamano, Shawn O. Pearce,
	Giuseppe Bilotta
In-Reply-To: <1222906234-8182-6-git-send-email-giuseppe.bilotta@gmail.com>

If use_pathinfo is enabled, href now creates links that contain paths in
the form $project/$action/oldhash:/oldname..newhash:/newname for actions
that use hash_parent etc.

If any of the filename contains two consecutive dots, it's kept as a CGI
parameter since the resulting path would otherwise be ambiguous.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---
 gitweb/gitweb.perl |   30 +++++++++++++++++++++++++-----
 1 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 89e360f..d863ef7 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -712,7 +712,8 @@ sub href (%) {
 		# try to put as many parameters as possible in PATH_INFO:
 		#   - project name
 		#   - action
-		#   - hash or hash_base:/filename
+		#   - hash_parent or hash_parent_base:/file_parent
+		#   - hash or hash_base:/file_name
 
 		# Strip any trailing / from $href, or we might get double
 		# slashes when the script is the DirectoryIndex
@@ -730,17 +731,36 @@ sub href (%) {
 			delete $params{'action'};
 		}
 
-		# Finally, we put either hash_base:/file_name or hash
+		# Next, we put hash_parent_base:/file_parent..hash_base:/file_name,
+		# stripping nonexistent or useless pieces
+		$href .= "/" if ($params{'hash_base'} || $params{'hash_parent_base'}
+			|| $params{'hash_parent'} || $params{'hash'});
 		if (defined $params{'hash_base'}) {
-			$href .= "/".esc_url($params{'hash_base'});
-			if (defined $params{'file_name'}) {
+			if (defined $params{'hash_parent_base'}) {
+				$href .= esc_url($params{'hash_parent_base'});
+				# skip the file_parent if it's the same as the file_name
+				delete $params{'file_parent'} if $params{'file_parent'} eq $params{'file_name'};
+				if (defined $params{'file_parent'} && $params{'file_parent'} !~ /\.\./) {
+					$href .= ":/".esc_url($params{'file_parent'});
+					delete $params{'file_parent'};
+				}
+				$href .= "..";
+				delete $params{'hash_parent'};
+				delete $params{'hash_parent_base'};
+			} elsif (defined $params{'hash_parent'}) {
+				$href .= esc_url($params{'hash_parent'}). "..";
+				delete $params{'hash_parent'};
+			}
+
+			$href .= esc_url($params{'hash_base'});
+			if (defined $params{'file_name'} && $params{'file_name'} !~ /\.\./) {
 				$href .= ":/".esc_url($params{'file_name'});
 				delete $params{'file_name'};
 			}
 			delete $params{'hash'};
 			delete $params{'hash_base'};
 		} elsif (defined $params{'hash'}) {
-			$href .= "/".esc_url($params{'hash'});
+			$href .= esc_url($params{'hash'});
 			delete $params{'hash'};
 		}
 	}
-- 
1.5.6.5

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).