Git development
 help / color / mirror / Atom feed
* [PATCH 1/8] Add is_absolute_path() and make_absolute_path()
From: Johannes Schindelin @ 2007-07-27 18:56 UTC (permalink / raw)
  To: gitster, git, matled
In-Reply-To: <Pine.LNX.4.64.0707271851370.14781@racer.site>


This patch adds convenience functions to work with absolute paths.
The function is_absolute_path() should help the efforts to integrate
the MinGW fork.

Note that make_absolute_path() returns a pointer to a static buffer.

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

	Okay, gone is normalize_path().  In contrast, "make_absolute_path()"
	does the getcwd() && chdir() && getcwd() && chdir(back) mantra, to
	follow symlinks.

	AFAICT, make_absolute_path() would be a Good Thing to use for the
	recent lockfile stuff.

 Makefile             |    2 +-
 cache.h              |    5 ++++
 path.c               |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++
 t/t0000-basic.sh     |   16 +++++++++++++
 test-absolute-path.c |   11 +++++++++
 5 files changed, 95 insertions(+), 1 deletions(-)
 create mode 100644 test-absolute-path.c

diff --git a/Makefile b/Makefile
index d8100ad..546e008 100644
--- a/Makefile
+++ b/Makefile
@@ -936,7 +936,7 @@ endif
 
 ### Testing rules
 
-TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X
+TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-absolute-path$X
 
 all:: $(TEST_PROGRAMS)
 
diff --git a/cache.h b/cache.h
index 53801b8..98af530 100644
--- a/cache.h
+++ b/cache.h
@@ -358,6 +358,11 @@ int git_config_perm(const char *var, const char *value);
 int adjust_shared_perm(const char *path);
 int safe_create_leading_directories(char *path);
 char *enter_repo(char *path, int strict);
+static inline int is_absolute_path(const char *path)
+{
+	return path[0] == '/';
+}
+const char *make_absolute_path(const char *path);
 
 /* Read and unpack a sha1 file into memory, write memory to a sha1 file */
 extern int sha1_object_info(const unsigned char *, unsigned long *);
diff --git a/path.c b/path.c
index c4ce962..0f7012f 100644
--- a/path.c
+++ b/path.c
@@ -292,3 +292,65 @@ int adjust_shared_perm(const char *path)
 		return -2;
 	return 0;
 }
+
+/* We allow "recursive" symbolic links. Only within reason, though. */
+#define MAXDEPTH 5
+
+const char *make_absolute_path(const char *path)
+{
+	static char bufs[2][PATH_MAX + 1], *buf = bufs[0], *next_buf = bufs[1];
+	char cwd[1024] = "";
+	int buf_index = 1, len;
+
+	int depth = MAXDEPTH;
+	char *last_elem = NULL;
+	struct stat st;
+
+	if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX)
+		die ("Too long path: %.*s", 60, path);
+
+	while (depth--) {
+		if (stat(buf, &st) || !S_ISDIR(st.st_mode)) {
+			char *last_slash = strrchr(buf, '/');
+			*last_slash = '\0';
+			last_elem = xstrdup(last_slash + 1);
+		}
+
+		if (*buf) {
+			if (!*cwd && getcwd(cwd, sizeof(cwd)) < 0)
+				die ("Could not get current working directory");
+
+			if (chdir(buf))
+				die ("Could not switch to '%s'", buf);
+		}
+		if (getcwd(buf, PATH_MAX) < 0)
+			die ("Could not get current working directory");
+
+		if (last_elem) {
+			int len = strlen(buf);
+			if (len + strlen(last_elem) + 2 > PATH_MAX)
+				die ("Too long path name: '%s/%s'",
+						buf, last_elem);
+			buf[len] = '/';
+			strcpy(buf + len + 1, last_elem);
+			free(last_elem);
+			last_elem = NULL;
+		}
+
+		if (!lstat(buf, &st) && S_ISLNK(st.st_mode)) {
+			len = readlink(buf, next_buf, PATH_MAX);
+			if (len < 0)
+				die ("Invalid symlink: %s", buf);
+			next_buf[len] = '\0';
+			buf = next_buf;
+			buf_index = 1 - buf_index;
+			next_buf = bufs[buf_index];
+		} else
+			break;
+	}
+
+	if (*cwd && chdir(cwd))
+		die ("Could not change back to '%s'", cwd);
+
+	return buf;
+}
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 4bba9c0..4e49d59 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -281,4 +281,20 @@ test_expect_success 'update-index D/F conflict' '
 	test $numpath0 = 1
 '
 
+test_expect_success 'absolute path works as expected' '
+	mkdir first &&
+	ln -s ../.git first/.git &&
+	mkdir second &&
+	ln -s ../first second/other &&
+	mkdir third &&
+	dir="$(cd .git; pwd -P)" &&
+	dir2=third/../second/other/.git &&
+	test "$dir" = "$(test-absolute-path $dir2)" &&
+	file="$dir"/index &&
+	test "$file" = "$(test-absolute-path $dir2/index)" &&
+	ln -s ../first/file .git/syml &&
+	sym="$(cd first; pwd -P)"/file &&
+	test "$sym" = "$(test-absolute-path $dir2/syml)"
+'
+
 test_done
diff --git a/test-absolute-path.c b/test-absolute-path.c
new file mode 100644
index 0000000..c959ea2
--- /dev/null
+++ b/test-absolute-path.c
@@ -0,0 +1,11 @@
+#include "cache.h"
+
+int main(int argc, char **argv)
+{
+	while (argc > 1) {
+		puts(make_absolute_path(argv[1]));
+		argc--;
+		argv++;
+	}
+	return 0;
+}
-- 
1.5.3.rc3.18.g49a1

^ permalink raw reply related

* [PATCH 0/8 REVISION2] work-tree cleanups
From: Johannes Schindelin @ 2007-07-27 18:55 UTC (permalink / raw)
  To: gitster, git, matled

Hi,

the patch series I sent was almost as bogus as the original work-tree 
patch series.  However, thanks to the comments, and a night's sleep, here 
comes a revised patch series which is not only readable (it was readable 
before, too), but which actually works as expected.

Not only does it pass the tests, but it also adds some tests of its own.

And yes, you can "GIT_DIR=/some/where git add <file>..." now.  Even if you 
are not at your working tree's root.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH] use lockfile.c routines in git_commit_set_multivar()
From: Bradford Smith @ 2007-07-27 18:24 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, git
In-Reply-To: <7v7iom5twd.fsf@assigned-by-dhcp.cox.net>

That's great!

I've added this patch to my local branch and confirmed that all tests,
including the new ones, run successfully.

Thanks!

Bradford

On 7/27/07, Junio C Hamano <gitster@pobox.com> wrote:
> Junio C Hamano <gitster@pobox.com> writes:
>
> > "Bradford Smith" <bradford.carl.smith@gmail.com> writes:
> >
> >> FWIW, I have successfully run 'make test' and also verified that it
> >> behaves as I expect with my ~/.gitconfig symlink (in conjunction with
> >> the my other patch for resolving symlinks).
> >
> > Existing "make test" testsuite is not an appropriate thing to
> > say this patch is safe, as we do not have much symlinking in the
> > test git repository there.  Care to add a new test or two?
>
> How about this?  On top of your "lockfile to keep symlink" and
> "set-multivar to use lockfile protocol" patches.
>
> ---
>
>  t/t1300-repo-config.sh |   15 +++++++++++++++
>  1 files changed, 15 insertions(+), 0 deletions(-)
>
> diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
> index 1c43cc3..187ca2d 100755
> --- a/t/t1300-repo-config.sh
> +++ b/t/t1300-repo-config.sh
> @@ -595,4 +595,19 @@ echo >>result
>
>  test_expect_success '--null --get-regexp' 'cmp result expect'
>
> +test_expect_success 'symlinked configuration' '
> +
> +       ln -s notyet myconfig &&
> +       GIT_CONFIG=myconfig git config test.frotz nitfol &&
> +       test -h myconfig &&
> +       test -f notyet &&
> +       test "z$(GIT_CONFIG=notyet git config test.frotz)" = znitfol &&
> +       GIT_CONFIG=myconfig git config test.xyzzy rezrov &&
> +       test -h myconfig &&
> +       test -f notyet &&
> +       test "z$(GIT_CONFIG=notyet git config test.frotz)" = znitfol &&
> +       test "z$(GIT_CONFIG=notyet git config test.xyzzy)" = zrezrov
> +
> +'
> +
>  test_done
>
>

^ permalink raw reply

* Can you do this with GIT?
From: CPD @ 2007-07-27 18:02 UTC (permalink / raw)
  To: git


Hi All,

I hope this is the right forum, it's all I could find. Sincere apologies in
advance if I in the wrong place.

I set up a source control system for the company around CVS, but GIT has
some very attractive features and I'd like to migrate if it can do some
other things that we need.

We produce variations based on a (mostly) common codebase. In CVS I set up
"environment" modules for each platform, then when you are working on that
platform, you simply check out the correct environment and build. Only the
needed code and tools are exposed in that environment (this is important as
clients must NOT see each other's code and most customers have some
customization). I do this by defining and renaming modules in the CVSROOT
modules file.

Does GIT support anything like this? Or another way to acheive the same end?

Thanks muchly, in advance, Colin
-- 
View this message in context: http://www.nabble.com/Can-you-do-this-with-GIT--tf4159350.html#a11834063
Sent from the git mailing list archive at Nabble.com.

^ permalink raw reply

* Re: git-gui: i18n introductory document (2nd draft)
From: Brett Schwarz @ 2007-07-27 17:58 UTC (permalink / raw)
  To: Christian Stimming, Junio C Hamano
  Cc: git, Irina Riesen, Johannes Schindelin, Nanako Shiraishi,
	Paolo Ciarrocchi, Shawn O. Pearce, Xudong Guan, stimming

> ----- Original Message ----
> From: Christian Stimming <Christian.Stimming@ibeo-as.com>
> To: Junio C Hamano <gitster@pobox.com>
> Cc: git@vger.kernel.org; Irina Riesen <irina.riesen@gmail.com>; Johannes Schindelin <johannes.schindelin@gmx.de>; Nanako Shiraishi <nanako3@bluebottle.com>; Paolo Ciarrocchi <paolo.ciarrocchi@gmail.com>; Shawn O. Pearce <spearce@spearce.org>; Xudong Guan <xudong.guan@gmail.com>; stimming@tuhh.de
> Sent: Friday, July 27, 2007 8:21:58 AM
> Subject: Re: git-gui: i18n introductory document (2nd draft)
>
> Junio C Hamano <gitster@pobox.com> schrieb am 27.07.2007 01:31:06:
> > I have tried to address issues raised in Christian's comments on
> > the first draft that was circulated privately.
>

<snip>

>
> > + - Often the messages being translated are format strings given to
> > +   "printf()"-like functions.  Make sure "%s", "%d", and "%%" in your
> > +   translated messages match the original.
> > +
> > +   When you have to change the order of words, you can add "<number>$"
> > +   between '%' and the conversion ('s', 'd', etc.) to say "<number>-th
> > +   parameter to the format string is used at this point".  For example,
> > +   if the original message is like this:
> > +
> > +   "Length is %d, Weight is %d"
> > +
> > +   and if for whatever reason your translation needs to say weight first
> > +   and then length, you can say something like:

> > +
> > +   "WEIGHT IS %2$d, LENGTH IS %1$d"

Since we are using quotes for the strings, and Tcl will do a round of substitutions
 and will think those $d's are variables, you might want to change that to:

        "WEIGHT IS %2\$d, LENGTH IS %1\$d"

You also may want to add a note about why the backslash

> > +
> > +   [NEEDSWORK: this whole "parameter permutation" part needs to be
> > +   verified if it works with Tcl at all]
>

bschwarz@desk1:~$ tclsh
% package require msgcat
1.3.4
% namespace import ::msgcat::*
% mcset en_us_brett "L is %d, W is %d" "WEIGHT IS %2\$d, LENGTH IS %1\$d" 
WEIGHT IS %2$d, LENGTH IS %1$d
% mcset en_us "L is %d, W is %d" "Length is %d, Weight is %d"
Length is %d, Weight is %d
% mclocale en_us
en_us
% set length 74
74
% set weight 220
220
% mc "L is %d, W is %d" $length $weight
Length is 74, Weight is 220
% mclocale en_us_brett
en_us_brett
% mc "L is %d, W is %d" $length $weight
WEIGHT IS 220, LENGTH IS 74
% 

Seems to work...

Regards,
     --brett




       
____________________________________________________________________________________
Get the free Yahoo! toolbar and rest assured with the added security of spyware protection.
http://new.toolbar.yahoo.com/toolbar/features/norton/index.php

^ permalink raw reply

* Re: [PATCH] rebase -i: fix interrupted squashing
From: Johannes Schindelin @ 2007-07-27 17:18 UTC (permalink / raw)
  To: gitster; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0707242139370.14781@racer.site>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 458 bytes --]

Hi,

On Tue, 24 Jul 2007, Johannes Schindelin wrote:

> 
> When a squashing merge failed, the first commit would not be replaced,
> due to "git reset --soft" being called with an unmerged index.
> 
> Noticed by Uwe Kleine-König.

Unfortunately, no Ack from him.

However, I have tested it myself (even unwantedly, when working on the 
work-tree sanitising, and it bit me again; I run 
"master"+branch--new-workdir ATM).

Junio, please apply...

Ciao,
Dscho

^ permalink raw reply

* Teach git-gui about merging around modified files?
From: Brian Downing @ 2007-07-27 17:03 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: git

"git merge" will happily merge a change with modified files in the tree
as long as the merge doesn't touch any of them.  However, it appears
"git gui" won't even try if there are modified files at all.

How hard would it be to fix this, or is this an intentional choice?
I realize that commiting even untouched files before a merge is safer,
but I'm tasked with migrating some CVS users to Git, and I'd prefer
to be able to introduce the new Git workflow slowly.

(I'm happy enough with disallowing merges that actually touch modified
files, so I'm not looking for any kind of in-working-directory merge
like some others were.  I'd just like the "git merge" behavior to work
in git-gui.)

-bcd

^ permalink raw reply

* Re: [PATCH] fully resolve symlinks when creating lockfiles
From: Bradford Smith @ 2007-07-27 16:50 UTC (permalink / raw)
  To: Morten Welinder; +Cc: git
In-Reply-To: <118833cc0707261234u59e30bchc274ae29569d8500@mail.gmail.com>

On 7/26/07, Morten Welinder <mwelinder@gmail.com> wrote:
> Why the lstat and that stat in the beginning?  That's just asking for race
> condition.  readlink will tell you if it wasn't a link, for example.

Here's an example of the sort of thing I'm trying to avoid:

foo is a symlink to bar
bar is a symlink back to foo

readlink() on either one will succeed, but I'll end up with infinite
recursion because I'll resolve foo to bar, then bar to foo, then foo
back to bar, etc.

To avoid craziness like this the OS refuses to follow a chain of more
than a very small number of symlinks.  By experimentation, I found the
limit to be 8 on my Linux box.

I am trying to avoid resolving symlinks manually that the OS would
refuse to resolve anyway.

However, I'm quite open to suggestions for a better way to do it.

Thanks,

Bradford

^ permalink raw reply

* Re: git-gui: i18n introductory document (2nd draft)
From: Christian Stimming @ 2007-07-27 15:21 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Irina Riesen, Johannes Schindelin, Nanako Shiraishi,
	Paolo Ciarrocchi, Shawn O. Pearce, Xudong Guan, stimming
In-Reply-To: <7v4pjq7net.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano <gitster@pobox.com> schrieb am 27.07.2007 01:31:06:
> I have tried to address issues raised in Christian's comments on
> the first draft that was circulated privately.

Yes, this looks very nice, concise, and good to read. Thanks.

> +to test the resulting translation out.  It also is a good idea to have
> +specialized so-called "po file editors" (e.g. emacs po-mode, KBabel,
> +poedit, GTranslator).  Please install them.

I'd rephrase the very last sentence into: Please install at least one of
them, whichever you feel comfortably with.

> + - Often the messages being translated are format strings given to
> +   "printf()"-like functions.  Make sure "%s", "%d", and "%%" in your
> +   translated messages match the original.
> +
> +   When you have to change the order of words, you can add "<number>$"
> +   between '%' and the conversion ('s', 'd', etc.) to say "<number>-th
> +   parameter to the format string is used at this point".  For example,
> +   if the original message is like this:
> +
> +   "Length is %d, Weight is %d"
> +
> +   and if for whatever reason your translation needs to say weight first
> +   and then length, you can say something like:
> +
> +   "WEIGHT IS %2$d, LENGTH IS %1$d"
> +
> +   [NEEDSWORK: this whole "parameter permutation" part needs to be
> +   verified if it works with Tcl at all]

I agree it needs to be verified, although the msgcat documentation claims
it works. Nevertheless I'd rather question whether this text is helpful at
this point in the document. How about moving the "positional codes" issues
to a separate section at the end, under the topic "Advanced translation
tips" or something like this?

> +You can test your translation by running "make install", which would
> +create po/af.msg file and installs the result, and then running the
> +resulting git-gui under your locale:
> +
> +   $ make install
> +   $ LANG=af git-gui

Right, this should always work.

> +There is a trick to test your translation without first installing, if
> +you prefer.  First, create this symbolic link in the source tree:
> +
> +   $ ln -s ../po lib/msgs
> +
> +After setting up such a symbolic link, you can:
> +
> +   $ make
> +   $ LANG=af ./git-gui
> +
> +[NEEDSWORK: this symlink trick needs to be verified if it works.]

It does work, but as Nanako Shiraishi already pointed out, one has to call
./git-gui.sh in contrast to the version without suffix.

> +   $ msgmerge -U po/af.po po/git-gui.pot
> +
> +[NEEDSWORK: who is responsible for updating po/git-gui.pot file by
> +running xgettext?  IIRC, Christian recommended against running it
> +nilly-willy because it can become a source of unnecessary merge
> +conflicts.  Perhaps we should mention something like "
> +
> +The po/git-gui.pot file is updated by the internationalization
> +coordinator from time to time.  You _could_ update it yourself, but
> +translators are discouraged from doing so because we would want all
> +language teams to be working off of the same version of git-gui.pot.
> +
> +" here?]

I wouldn't have put git-gui.pot into git to start with. Translators who can
msgmerge their translation by definition have the gettext toolchain
available, so they could very well just have git-gui.pot generated
themselves. We can just as well give instructions here on how to regenerate
git-gui.pot: "make po/git-gui.pot"; in gnucash, we added a separate rule
"make pot" because that one is easier to type.

As for merging the po file: I would encourage every *translator* to
"msgmerge" their po file as often as they like. This rule will only run
into problems if translators forget to merge their po file regularly, and
continue to work on the old string; so far I have no solution to this
problem.  I spoke up a few days ago to ask the maintainers not to merge the
*po* files, because this is where the translators work with, and merging
conflicts here will make translators unhappy. But this concerns the *po
file*. The pot file can just as well be updated by the maintainers or the
translators, but it would be best not to have it in SCM at all.

> + - The original text in English of an older message you already
> +   translated might have been changed.  You will notice a comment line
> +   that begins with "#, fuzzy" in front of such a message.  msgmerge
> +   tool made its best effort to match your old translation with the
> +   message from the updated software, but you may find cases that it
> +   matched your old translated message to a new msgid and the pairing
> +   does not make any sense -- you would need to fix them, and then
> +   remove the "#, fuzzy" line from the message.

I would add the sentence (because people frequently forget about the
implications of the fuzzy marker): A translation prepended by the '#,
fuzzy" line will not show up in the program. Gettext will treat this
message as if no translation existed.

Overall this is very nice. Thanks a lot.

Christian

IBEO Automobile Sensor GmbH - Sitz: Hamburg - Handelsregister: Hamburg HRB
67903
Geschäftsführer: Dr. Ulrich S. Lages

^ permalink raw reply

* [PATCH 2/2] gitk: Markup many strings for translation.
From: Christian Stimming @ 2007-07-27 15:03 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: git
In-Reply-To: <20070727165318.e96b1yxxwsooo884@webmail.tu-harburg.de>

Similar to the discussion in git-gui, all user-visible strings are  
passed through the [mc ...] procedure to have them translated by msgcat.

Signed-off-by: Christian Stimming <stimming@tuhh.de>
---
@Paul: Are you interested in applying this? If yes, I'd happily  
provide the Makefile rules for string extraction and translation  
catalog updates, but I'd like to hear a proposal or decision on where  
to place them. Should the po files for translation go into the po/  
subdirectory? And then a proposal/decision of where to install the  
compiled .msg catalogs will be necessary.

In case anyone comes up with the idea of using a single translation  
catalog for both gitk and git-gui: This is very well possible and  
potentially makes the translator's workflow easier. Only in terms of  
message saving there will be almost no benefit: Gitk has approx. 130  
messages, git-gui approx. 260, and exactly 8 (in words: eight) of them  
are identical between both programs.

  gitk |  358  
+++++++++++++++++++++++++++++++++---------------------------------
  1 files changed, 179 insertions(+), 179 deletions(-)

diff --git a/gitk b/gitk
index c01acfb..de131a6 100755
--- a/gitk
+++ b/gitk
@@ -128,7 +128,7 @@ proc getcommits {} {
      set phase getcommits
      initlayout
      start_rev_list $curview
-    show_status "Reading commits..."
+    show_status [mc "Reading commits..."]
  }

  proc getcommitlines {fd view}  {
@@ -273,7 +273,7 @@ proc chewcommits {view} {
  		#set ms [expr {[clock clicks -milliseconds] - $startmsecs}]
  		#puts "overall $ms ms for $numcommits commits"
  	    } else {
-		show_status "No commits selected"
+		show_status [mc "No commits selected"]
  	    }
  	    notbusy layout
  	    set phase {}
@@ -378,7 +378,7 @@ proc getcommit {id} {
      } else {
  	readcommit $id
  	if {![info exists commitinfo($id)]} {
-	    set commitinfo($id) {"No commit information available"}
+	    set commitinfo($id) {[mc "No commit information available"]}
  	}
      }
      return 1
@@ -464,7 +464,7 @@ proc removehead {id name} {
  proc show_error {w top msg} {
      message $w.m -text $msg -justify center -aspect 400
      pack $w.m -side top -fill x -padx 20 -pady 20
-    button $w.ok -text OK -command "destroy $top"
+    button $w.ok -text [mc OK] -command "destroy $top"
      pack $w.ok -side bottom -fill x
      bind $top <Visibility> "grab $top; focus $top"
      bind $top <Key-Return> "destroy $top"
@@ -486,9 +486,9 @@ proc confirm_popup msg {
      wm transient $w .
      message $w.m -text $msg -justify center -aspect 400
      pack $w.m -side top -fill x -padx 20 -pady 20
-    button $w.ok -text OK -command "set confirm_ok 1; destroy $w"
+    button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w"
      pack $w.ok -side left -fill x
-    button $w.cancel -text Cancel -command "destroy $w"
+    button $w.cancel -text [mc Cancel] -command "destroy $w"
      pack $w.cancel -side right -fill x
      bind $w <Visibility> "grab $w; focus $w"
      tkwait window $w
@@ -508,32 +508,32 @@ proc makewindow {} {
      global headctxmenu

      menu .bar
-    .bar add cascade -label "File" -menu .bar.file
+    .bar add cascade -label [mc "File"] -menu .bar.file
      .bar configure -font $uifont
      menu .bar.file
-    .bar.file add command -label "Update" -command updatecommits
-    .bar.file add command -label "Reread references" -command rereadrefs
-    .bar.file add command -label "Quit" -command doquit
+    .bar.file add command -label [mc "Update"] -command updatecommits
+    .bar.file add command -label [mc "Reread references"] -command rereadrefs
+    .bar.file add command -label [mc "Quit"] -command doquit
      .bar.file configure -font $uifont
      menu .bar.edit
-    .bar add cascade -label "Edit" -menu .bar.edit
-    .bar.edit add command -label "Preferences" -command doprefs
+    .bar add cascade -label [mc "Edit"] -menu .bar.edit
+    .bar.edit add command -label [mc "Preferences"] -command doprefs
      .bar.edit configure -font $uifont

      menu .bar.view -font $uifont
-    .bar add cascade -label "View" -menu .bar.view
-    .bar.view add command -label "New view..." -command {newview 0}
-    .bar.view add command -label "Edit view..." -command editview \
+    .bar add cascade -label [mc "View"] -menu .bar.view
+    .bar.view add command -label [mc "New view..."] -command {newview 0}
+    .bar.view add command -label [mc "Edit view..."] -command editview \
  	-state disabled
-    .bar.view add command -label "Delete view" -command delview  
-state disabled
+    .bar.view add command -label [mc "Delete view"] -command delview  
-state disabled
      .bar.view add separator
-    .bar.view add radiobutton -label "All files" -command {showview 0} \
+    .bar.view add radiobutton -label [mc "All files"] -command {showview 0} \
  	-variable selectedview -value 0

      menu .bar.help
-    .bar add cascade -label "Help" -menu .bar.help
-    .bar.help add command -label "About gitk" -command about
-    .bar.help add command -label "Key bindings" -command keys
+    .bar add cascade -label [mc "Help"] -menu .bar.help
+    .bar.help add command -label [mc "About gitk"] -command about
+    .bar.help add command -label [mc "Key bindings"] -command keys
      .bar.help configure -font $uifont
      . configure -menu .bar

@@ -590,7 +590,7 @@ proc makewindow {} {
      set sha1entry .tf.bar.sha1
      set entries $sha1entry
      set sha1but .tf.bar.sha1label
-    button $sha1but -text "SHA1 ID: " -state disabled -relief flat \
+    button $sha1but -text [mc "SHA1 ID: "] -state disabled -relief flat \
  	-command gotocommit -width 8 -font $uifont
      $sha1but conf -disabledforeground [$sha1but cget -foreground]
      pack .tf.bar.sha1label -side left
@@ -621,7 +621,7 @@ proc makewindow {} {
  	-state disabled -width 26
      pack .tf.bar.rightbut -side left -fill y

-    button .tf.bar.findbut -text "Find" -command dofind -font $uifont
+    button .tf.bar.findbut -text [mc "Find"] -command dofind -font $uifont
      pack .tf.bar.findbut -side left
      set findstring {}
      set fstring .tf.bar.findstring
@@ -631,13 +631,13 @@ proc makewindow {} {
      pack $fstring -side left -expand 1 -fill x -in .tf.bar
      set findtype Exact
      set findtypemenu [tk_optionMenu .tf.bar.findtype \
-		      findtype Exact IgnCase Regexp]
+			  findtype [mc Exact] [mc IgnCase] [mc Regexp]]
      trace add variable findtype write find_change
      .tf.bar.findtype configure -font $uifont
      .tf.bar.findtype.menu configure -font $uifont
-    set findloc "All fields"
-    tk_optionMenu .tf.bar.findloc findloc "All fields" Headline \
-	Comments Author Committer
+    set findloc [mc "All fields"]
+    tk_optionMenu .tf.bar.findloc findloc [mc "All fields"] [mc Headline] \
+	[mc Comments] [mc Author] [mc Committer]
      trace add variable findloc write find_change
      .tf.bar.findloc configure -font $uifont
      .tf.bar.findloc.menu configure -font $uifont
@@ -645,12 +645,12 @@ proc makewindow {} {
      pack .tf.bar.findtype -side right

      # build up the bottom bar of upper window
-    label .tf.lbar.flabel -text "Highlight:  Commits " \
+    label .tf.lbar.flabel -text [mc "Highlight:  Commits "] \
      -font $uifont
      pack .tf.lbar.flabel -side left -fill y
-    set gdttype "touching paths:"
-    set gm [tk_optionMenu .tf.lbar.gdttype gdttype "touching paths:" \
-	"adding/removing string:"]
+    set gdttype [mc "touching paths:"]
+    set gm [tk_optionMenu .tf.lbar.gdttype gdttype [mc "touching paths:"] \
+	[mc "adding/removing string:"]]
      trace add variable gdttype write hfiles_change
      $gm conf -font $uifont
      .tf.lbar.gdttype conf -font $uifont
@@ -660,19 +660,19 @@ proc makewindow {} {
      trace add variable highlight_files write hfiles_change
      lappend entries .tf.lbar.fent
      pack .tf.lbar.fent -side left -fill x -expand 1
-    label .tf.lbar.vlabel -text " OR in view" -font $uifont
+    label .tf.lbar.vlabel -text [mc " OR in view"] -font $uifont
      pack .tf.lbar.vlabel -side left -fill y
      global viewhlmenu selectedhlview
-    set viewhlmenu [tk_optionMenu .tf.lbar.vhl selectedhlview None]
+    set viewhlmenu [tk_optionMenu .tf.lbar.vhl selectedhlview [mc None]]
      $viewhlmenu entryconf None -command delvhighlight
      $viewhlmenu conf -font $uifont
      .tf.lbar.vhl conf -font $uifont
      pack .tf.lbar.vhl -side left -fill y
-    label .tf.lbar.rlabel -text " OR " -font $uifont
+    label .tf.lbar.rlabel -text [mc " OR "] -font $uifont
      pack .tf.lbar.rlabel -side left -fill y
      global highlight_related
-    set m [tk_optionMenu .tf.lbar.relm highlight_related None \
-	"Descendent" "Not descendent" "Ancestor" "Not ancestor"]
+    set m [tk_optionMenu .tf.lbar.relm highlight_related [mc None] \
+	[mc "Descendent"] [mc "Not descendent"] [mc "Ancestor"] [mc "Not ancestor"]]
      $m conf -font $uifont
      .tf.lbar.relm conf -font $uifont
      trace add variable highlight_related write vrel_change
@@ -700,7 +700,7 @@ proc makewindow {} {
      frame .bleft.top
      frame .bleft.mid

-    button .bleft.top.search -text "Search" -command dosearch \
+    button .bleft.top.search -text [mc "Search"] -command dosearch \
  	-font $uifont
      pack .bleft.top.search -side left -padx 5
      set sstring .bleft.top.sstring
@@ -708,11 +708,11 @@ proc makewindow {} {
      lappend entries $sstring
      trace add variable searchstring write incrsearch
      pack $sstring -side left -expand 1 -fill x
-    radiobutton .bleft.mid.diff -text "Diff" \
+    radiobutton .bleft.mid.diff -text [mc "Diff"] \
  	-command changediffdisp -variable diffelide -value {0 0}
-    radiobutton .bleft.mid.old -text "Old version" \
+    radiobutton .bleft.mid.old -text [mc "Old version"] \
  	-command changediffdisp -variable diffelide -value {0 1}
-    radiobutton .bleft.mid.new -text "New version" \
+    radiobutton .bleft.mid.new -text [mc "New version"] \
  	-command changediffdisp -variable diffelide -value {1 0}
      pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new -side left
      set ctext .bleft.ctext
@@ -761,10 +761,10 @@ proc makewindow {} {
      # lower right
      frame .bright
      frame .bright.mode
-    radiobutton .bright.mode.patch -text "Patch" \
+    radiobutton .bright.mode.patch -text [mc "Patch"] \
  	-command reselectline -variable cmitmode -value "patch"
      .bright.mode.patch configure -font $uifont
-    radiobutton .bright.mode.tree -text "Tree" \
+    radiobutton .bright.mode.tree -text [mc "Tree"] \
  	-command reselectline -variable cmitmode -value "tree"
      .bright.mode.tree configure -font $uifont
      grid .bright.mode.patch .bright.mode.tree -sticky ew
@@ -863,35 +863,35 @@ proc makewindow {} {

      set rowctxmenu .rowctxmenu
      menu $rowctxmenu -tearoff 0
-    $rowctxmenu add command -label "Diff this -> selected" \
+    $rowctxmenu add command -label [mc "Diff this -> selected"] \
  	-command {diffvssel 0}
-    $rowctxmenu add command -label "Diff selected -> this" \
+    $rowctxmenu add command -label [mc "Diff selected -> this"] \
  	-command {diffvssel 1}
-    $rowctxmenu add command -label "Make patch" -command mkpatch
-    $rowctxmenu add command -label "Create tag" -command mktag
-    $rowctxmenu add command -label "Write commit to file" -command  
writecommit
-    $rowctxmenu add command -label "Create new branch" -command mkbranch
-    $rowctxmenu add command -label "Cherry-pick this commit" \
+    $rowctxmenu add command -label [mc "Make patch"] -command mkpatch
+    $rowctxmenu add command -label [mc "Create tag"] -command mktag
+    $rowctxmenu add command -label [mc "Write commit to file"]  
-command writecommit
+    $rowctxmenu add command -label [mc "Create new branch"] -command mkbranch
+    $rowctxmenu add command -label [mc "Cherry-pick this commit"] \
  	-command cherrypick
-    $rowctxmenu add command -label "Reset HEAD branch to here" \
+    $rowctxmenu add command -label [mc "Reset HEAD branch to here"] \
  	-command resethead

      set fakerowmenu .fakerowmenu
      menu $fakerowmenu -tearoff 0
-    $fakerowmenu add command -label "Diff this -> selected" \
+    $fakerowmenu add command -label [mc "Diff this -> selected"] \
  	-command {diffvssel 0}
-    $fakerowmenu add command -label "Diff selected -> this" \
+    $fakerowmenu add command -label [mc "Diff selected -> this"] \
  	-command {diffvssel 1}
-    $fakerowmenu add command -label "Make patch" -command mkpatch
-#    $fakerowmenu add command -label "Commit" -command {mkcommit 0}
-#    $fakerowmenu add command -label "Commit all" -command {mkcommit 1}
-#    $fakerowmenu add command -label "Revert local changes" -command  
revertlocal
+    $fakerowmenu add command -label [mc "Make patch"] -command mkpatch
+#    $fakerowmenu add command -label [mc "Commit"] -command {mkcommit 0}
+#    $fakerowmenu add command -label [mc "Commit all"] -command {mkcommit 1}
+#    $fakerowmenu add command -label [mc "Revert local changes"]  
-command revertlocal

      set headctxmenu .headctxmenu
      menu $headctxmenu -tearoff 0
-    $headctxmenu add command -label "Check out this branch" \
+    $headctxmenu add command -label [mc "Check out this branch"] \
  	-command cobranch
-    $headctxmenu add command -label "Remove this branch" \
+    $headctxmenu add command -label [mc "Remove this branch"] \
  	-command rmbranch
  }

@@ -1063,17 +1063,17 @@ proc about {} {
  	return
      }
      toplevel $w
-    wm title $w "About gitk"
-    message $w.m -text {
+    wm title $w [mc "About gitk"]
+    message $w.m -text [mc "
  Gitk - a commit viewer for git

  Copyright © 2005-2006 Paul Mackerras

-Use and redistribute under the terms of the GNU General Public License} \
+Use and redistribute under the terms of the GNU General Public License"] \
  	    -justify center -aspect 400 -border 2 -bg white -relief groove
      pack $w.m -side top -fill x -padx 2 -pady 2
      $w.m configure -font $uifont
-    button $w.ok -text Close -command "destroy $w" -default active
+    button $w.ok -text [mc Close] -command "destroy $w" -default active
      pack $w.ok -side bottom
      $w.ok configure -font $uifont
      bind $w <Visibility> "focus $w.ok"
@@ -1089,8 +1089,8 @@ proc keys {} {
  	return
      }
      toplevel $w
-    wm title $w "Gitk key bindings"
-    message $w.m -text {
+    wm title $w [mc "Gitk key bindings"]
+    message $w.m -text [mc "
  Gitk key bindings:

  <Ctrl-Q>		Quit
@@ -1128,11 +1128,11 @@ f		Scroll diff view to next file
  <Ctrl-KP->	Decrease font size
  <Ctrl-minus>	Decrease font size
  <F5>		Update
-} \
+] \
  	    -justify left -bg white -border 2 -relief groove
      pack $w.m -side top -fill both -padx 2 -pady 2
      $w.m configure -font $uifont
-    button $w.ok -text Close -command "destroy $w" -default active
+    button $w.ok -text [mc Close] -command "destroy $w" -default active
      pack $w.ok -side bottom
      $w.ok configure -font $uifont
      bind $w <Visibility> "focus $w.ok"
@@ -1580,7 +1580,7 @@ proc newview {ishighlight} {
      set newviewname($nextviewnum) "View $nextviewnum"
      set newviewperm($nextviewnum) 0
      set newviewargs($nextviewnum) [shellarglist $revtreeargs]
-    vieweditor $top $nextviewnum "Gitk view definition"
+    vieweditor $top $nextviewnum [mc "Gitk view definition"]
  }

  proc editview {} {
@@ -1605,20 +1605,20 @@ proc vieweditor {top n title} {

      toplevel $top
      wm title $top $title
-    label $top.nl -text "Name" -font $uifont
+    label $top.nl -text [mc "Name"] -font $uifont
      entry $top.name -width 20 -textvariable newviewname($n) -font $uifont
      grid $top.nl $top.name -sticky w -pady 5
-    checkbutton $top.perm -text "Remember this view" -variable  
newviewperm($n) \
+    checkbutton $top.perm -text [mc "Remember this view"] -variable  
newviewperm($n) \
  	-font $uifont
      grid $top.perm - -pady 5 -sticky w
      message $top.al -aspect 1000 -font $uifont \
-	-text "Commits to include (arguments to git rev-list):"
+	-text [mc "Commits to include (arguments to git rev-list):"]
      grid $top.al - -sticky w -pady 5
      entry $top.args -width 50 -textvariable newviewargs($n) \
  	-background white -font $uifont
      grid $top.args - -sticky ew -padx 5
      message $top.l -aspect 1000 -font $uifont \
-	-text "Enter files and directories to include, one per line:"
+	-text [mc "Enter files and directories to include, one per line:"]
      grid $top.l - -sticky w
      text $top.t -width 40 -height 10 -background white -font $uifont
      if {[info exists viewfiles($n)]} {
@@ -1631,9 +1631,9 @@ proc vieweditor {top n title} {
      }
      grid $top.t - -sticky ew -padx 5
      frame $top.buts
-    button $top.buts.ok -text "OK" -command [list newviewok $top $n] \
+    button $top.buts.ok -text [mc "OK"] -command [list newviewok $top $n] \
  	-font $uifont
-    button $top.buts.can -text "Cancel" -command [list destroy $top] \
+    button $top.buts.can -text [mc "Cancel"] -command [list destroy $top] \
  	-font $uifont
      grid $top.buts.ok $top.buts.can
      grid columnconfigure $top.buts 0 -weight 1 -uniform a
@@ -1880,11 +1880,11 @@ proc showview {n} {
      }
      if {$phase ne {}} {
  	if {$phase eq "getcommits"} {
-	    show_status "Reading commits..."
+	    show_status [mc "Reading commits..."]
  	}
  	run chewcommits $n
      } elseif {$numcommits == 0} {
-	show_status "No commits selected"
+	show_status [mc "No commits selected"]
      }
  }

@@ -2176,9 +2176,9 @@ proc askfindhighlight {row id} {
      set isbold 0
      set fldtypes {Headline Author Date Committer CDate Comments}
      foreach f $info ty $fldtypes {
-	if {($findloc eq "All fields" || $findloc eq $ty) &&
+	if {($findloc eq [mc "All fields"] || $findloc eq $ty) &&
  	    [doesmatch $f]} {
-	    if {$ty eq "Author"} {
+	    if {$ty eq [mc "Author"]} {
  		set isbold 2
  		break
  	    }
@@ -2221,7 +2221,7 @@ proc vrel_change {name ix op} {
      global highlight_related

      rhighlight_none
-    if {$highlight_related ne "None"} {
+    if {$highlight_related ne [mc "None"]} {
  	run drawvisible
      }
  }
@@ -2235,7 +2235,7 @@ proc rhighlight_sel {a} {
      set desc_todo [list $a]
      catch {unset ancestor}
      set anc_todo [list $a]
-    if {$highlight_related ne "None"} {
+    if {$highlight_related ne [mc "None"]} {
  	rhighlight_none
  	run drawvisible
      }
@@ -2318,20 +2318,20 @@ proc askrelhighlight {row id} {

      if {![info exists selectedline]} return
      set isbold 0
-    if {$highlight_related eq "Descendent" ||
-	$highlight_related eq "Not descendent"} {
+    if {$highlight_related eq [mc "Descendent"] ||
+	$highlight_related eq [mc "Not descendent"]} {
  	if {![info exists descendent($id)]} {
  	    is_descendent $id
  	}
-	if {$descendent($id) == ($highlight_related eq "Descendent")} {
+	if {$descendent($id) == ($highlight_related eq [mc "Descendent"])} {
  	    set isbold 1
  	}
-    } elseif {$highlight_related eq "Ancestor" ||
-	      $highlight_related eq "Not ancestor"} {
+    } elseif {$highlight_related eq [mc "Ancestor"] ||
+	      $highlight_related eq [mc "Not ancestor"]} {
  	if {![info exists ancestor($id)]} {
  	    is_ancestor $id
  	}
-	if {$ancestor($id) == ($highlight_related eq "Ancestor")} {
+	if {$ancestor($id) == ($highlight_related eq [mc "Ancestor"])} {
  	    set isbold 1
  	}
      }
@@ -2369,7 +2369,7 @@ proc next_hlcont {} {
  	    }
  	    if {$nhighlights($row) > 0} break
  	}
-	if {$highlight_related ne "None"} {
+	if {$highlight_related ne [mc "None"]} {
  	    if {![info exists rhighlights($row)]} {
  		askrelhighlight $row $id
  	    }
@@ -2406,7 +2406,7 @@ proc next_highlight {dirn} {

      if {![info exists selectedline]} return
      if {!([info exists hlview] || $findstring ne {} ||
-	  $highlight_related ne "None" || [info exists filehighlight])} return
+	  $highlight_related ne [mc "None"] || [info exists filehighlight])} return
      set fhl_row [expr {$selectedline + $dirn}]
      set fhl_dirn $dirn
      next_hlcont
@@ -2738,7 +2738,7 @@ proc readdiffindex {fd serial} {
      if {$serial == $lserial && $localrow == -1} {
  	# add the line for the local diff to the graph
  	set localrow $commitrow($curview,$mainheadid)
-	set hl "Local uncommitted changes"
+	set hl [mc "Local uncommitted changes"]
  	set commitinfo($nullid) [list  $hl {} {} {} {} "    $hl\n"]
  	set commitdata($nullid) "\n    $hl\n"
  	insertrow $localrow $nullid
@@ -2867,7 +2867,7 @@ proc addextraid {id row} {
      set commitrow($curview,$id) $row
      readcommit $id
      if {![info exists commitinfo($id)]} {
-	set commitinfo($id) {"No commit information available"}
+	set commitinfo($id) {[mc "No commit information available"]}
      }
      if {![info exists children($curview,$id)]} {
  	set children($curview,$id) {}
@@ -3441,7 +3441,7 @@ proc drawcmitrow {row} {
      if {$findstring ne {} && ![info exists nhighlights($row)]} {
  	askfindhighlight $row $id
      }
-    if {$highlight_related ne "None" && ![info exists rhighlights($row)]} {
+    if {$highlight_related ne [mc "None"] && ![info exists  
rhighlights($row)]} {
  	askrelhighlight $row $id
      }
      if {[info exists iddrawn($id)]} return
@@ -3937,11 +3937,11 @@ proc notbusy {what} {

  proc findmatches {f} {
      global findtype findstring
-    if {$findtype == "Regexp"} {
+    if {$findtype == [mc "Regexp"]} {
  	set matches [regexp -indices -all -inline $findstring $f]
      } else {
  	set fs $findstring
-	if {$findtype == "IgnCase"} {
+	if {$findtype == [mc "IgnCase"]} {
  	    set f [string tolower $f]
  	    set fs [string tolower $fs]
  	}
@@ -4032,7 +4032,7 @@ proc findmore {} {
  	}
  	set info $commitinfo($id)
  	foreach f $info ty $fldtypes {
-	    if {($findloc eq "All fields" || $findloc eq $ty) &&
+	    if {($findloc eq [mc "All fields"] || $findloc eq $ty) &&
  		[doesmatch $f]} {
  		set markingmatches 1
  		findselectline $l
@@ -4078,7 +4078,7 @@ proc findmorerev {} {
  	}
  	set info $commitinfo($id)
  	foreach f $info ty $fldtypes {
-	    if {($findloc eq "All fields" || $findloc eq $ty) &&
+	    if {($findloc eq [mc "All fields"] || $findloc eq $ty) &&
  		[doesmatch $f]} {
  		set markingmatches 1
  		findselectline $l
@@ -4100,7 +4100,7 @@ proc findmorerev {} {
  proc findselectline {l} {
      global findloc commentend ctext
      selectline $l 1
-    if {$findloc == "All fields" || $findloc == "Comments"} {
+    if {$findloc == [mc "All fields"] || $findloc == [mc "Comments"]} {
  	# highlight the matches in the comments
  	set f [$ctext get 1.0 $commentend]
  	set matches [findmatches $f]
@@ -4388,11 +4388,11 @@ proc selectline {l isnew} {
      set linknum 0
      set info $commitinfo($id)
      set date [formatdate [lindex $info 2]]
-    $ctext insert end "Author: [lindex $info 1]  $date\n"
+    $ctext insert end "[mc "Author:"] [lindex $info 1]  $date\n"
      set date [formatdate [lindex $info 4]]
-    $ctext insert end "Committer: [lindex $info 3]  $date\n"
+    $ctext insert end "[mc "Committer:"] [lindex $info 3]  $date\n"
      if {[info exists idtags($id)]} {
-	$ctext insert end "Tags:"
+	$ctext insert end [mc "Tags:"]
  	foreach tag $idtags($id) {
  	    $ctext insert end " $tag"
  	}
@@ -4409,18 +4409,18 @@ proc selectline {l isnew} {
  	    } else {
  		set tag m$np
  	    }
-	    $ctext insert end "Parent: " $tag
+	    $ctext insert end "[mc "Parent:"] " $tag
  	    appendwithlinks [commit_descriptor $p] {}
  	    incr np
  	}
      } else {
  	foreach p $olds {
-	    append headers "Parent: [commit_descriptor $p]"
+	    append headers "[mc "Parent:"] [commit_descriptor $p]"
  	}
      }

      foreach c $children($curview,$id) {
-	append headers "Child:  [commit_descriptor $c]"
+	append headers "[mc "Child:"]  [commit_descriptor $c]"
      }

      # make anything that looks like a SHA1 ID be a clickable link
@@ -4429,13 +4429,13 @@ proc selectline {l isnew} {
  	if {![info exists allcommits]} {
  	    getallcommits
  	}
-	$ctext insert end "Branch: "
+	$ctext insert end "[mc "Branch:"] "
  	$ctext mark set branch "end -1c"
  	$ctext mark gravity branch left
-	$ctext insert end "\nFollows: "
+	$ctext insert end "\n[mc "Follows:"] "
  	$ctext mark set follows "end -1c"
  	$ctext mark gravity follows left
-	$ctext insert end "\nPrecedes: "
+	$ctext insert end "\n[mc "Precedes:"] "
  	$ctext mark set precedes "end -1c"
  	$ctext mark gravity precedes left
  	$ctext insert end "\n"
@@ -4452,7 +4452,7 @@ proc selectline {l isnew} {
      $ctext conf -state disabled
      set commentend [$ctext index "end - 1c"]

-    init_flist "Comments"
+    init_flist [mc "Comments"]
      if {$cmitmode eq "tree"} {
  	gettree $id
      } elseif {[llength $olds] <= 1} {
@@ -5238,9 +5238,9 @@ proc sha1change {n1 n2 op} {
      }
      if {[$sha1but cget -state] == $state} return
      if {$state == "normal"} {
-	$sha1but conf -state normal -relief raised -text "Goto: "
+	$sha1but conf -state normal -relief raised -text "[mc "Goto:"] "
      } else {
-	$sha1but conf -state disabled -relief flat -text "SHA1 ID: "
+	$sha1but conf -state disabled -relief flat -text "[mc "SHA1 ID:"] "
      }
  }

@@ -5265,7 +5265,7 @@ proc gotocommit {} {
  	    }
  	    if {$matches ne {}} {
  		if {[llength $matches] > 1} {
-		    error_popup "Short SHA1 id $id is ambiguous"
+		    error_popup [mc "Short SHA1 id %s is ambiguous" $id]
  		    return
  		}
  		set id [lindex $matches 0]
@@ -5413,17 +5413,17 @@ proc lineclick {x y id isnew} {
      $ctext tag conf link -foreground blue -underline 1
      $ctext tag bind link <Enter> { %W configure -cursor hand2 }
      $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
-    $ctext insert end "Parent:\t"
+    $ctext insert end "[mc "Parent:"]\t"
      $ctext insert end $id [list link link0]
      $ctext tag bind link0 <1> [list selbyid $id]
      set info $commitinfo($id)
      $ctext insert end "\n\t[lindex $info 0]\n"
-    $ctext insert end "\tAuthor:\t[lindex $info 1]\n"
+    $ctext insert end "\t[mc "Author:"]\t[lindex $info 1]\n"
      set date [formatdate [lindex $info 2]]
-    $ctext insert end "\tDate:\t$date\n"
+    $ctext insert end "\t[mc "Date:"]\t$date\n"
      set kids $children($curview,$id)
      if {$kids ne {}} {
-	$ctext insert end "\nChildren:"
+	$ctext insert end "\n[mc "Children:"]"
  	set i 0
  	foreach child $kids {
  	    incr i
@@ -5433,9 +5433,9 @@ proc lineclick {x y id isnew} {
  	    $ctext insert end $child [list link link$i]
  	    $ctext tag bind link$i <1> [list selbyid $child]
  	    $ctext insert end "\n\t[lindex $info 0]"
-	    $ctext insert end "\n\tAuthor:\t[lindex $info 1]"
+	    $ctext insert end "\n\t[mc "Author:"]\t[lindex $info 1]"
  	    set date [formatdate [lindex $info 2]]
-	    $ctext insert end "\n\tDate:\t$date\n"
+	    $ctext insert end "\n\t[mc "Date:"]\t$date\n"
  	}
      }
      $ctext conf -state disabled
@@ -5479,13 +5479,13 @@ proc rowmenu {x y id} {
      }
      if {$id ne $nullid} {
  	set menu $rowctxmenu
-	$menu entryconfigure 7 -label "Reset $mainhead branch to here"
+	$menu entryconfigure 7 -label [mc "Reset %s branch to here" $mainhead]
      } else {
  	set menu $fakerowmenu
      }
-    $menu entryconfigure "Diff this*" -state $state
-    $menu entryconfigure "Diff selected*" -state $state
-    $menu entryconfigure "Make patch" -state $state
+    $menu entryconfigure [mc "Diff this*"] -state $state
+    $menu entryconfigure [mc "Diff selected*"] -state $state
+    $menu entryconfigure [mc "Make patch"] -state $state
      tk_popup $menu $x $y
  }

@@ -5510,8 +5510,8 @@ proc doseldiff {oldid newid} {

      $ctext conf -state normal
      clear_ctext
-    init_flist "Top"
-    $ctext insert end "From "
+    init_flist [mc "Top"]
+    $ctext insert end [mc "From "]
      $ctext tag conf link -foreground blue -underline 1
      $ctext tag bind link <Enter> { %W configure -cursor hand2 }
      $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
@@ -5519,7 +5519,7 @@ proc doseldiff {oldid newid} {
      $ctext insert end $oldid [list link link0]
      $ctext insert end "\n     "
      $ctext insert end [lindex $commitinfo($oldid) 0]
-    $ctext insert end "\n\nTo   "
+    $ctext insert end "\n\n[mc "To"]   "
      $ctext tag bind link1 <1> [list selbyid $newid]
      $ctext insert end $newid [list link link1]
      $ctext insert end "\n     "
@@ -5542,9 +5542,9 @@ proc mkpatch {} {
      set patchtop $top
      catch {destroy $top}
      toplevel $top
-    label $top.title -text "Generate patch"
+    label $top.title -text [mc "Generate patch"]
      grid $top.title - -pady 10
-    label $top.from -text "From:"
+    label $top.from -text [mc "From:"]
      entry $top.fromsha1 -width 40 -relief flat
      $top.fromsha1 insert 0 $oldid
      $top.fromsha1 conf -state readonly
@@ -5553,7 +5553,7 @@ proc mkpatch {} {
      $top.fromhead insert 0 $oldhead
      $top.fromhead conf -state readonly
      grid x $top.fromhead -sticky w
-    label $top.to -text "To:"
+    label $top.to -text [mc "To:"]
      entry $top.tosha1 -width 40 -relief flat
      $top.tosha1 insert 0 $newid
      $top.tosha1 conf -state readonly
@@ -5562,16 +5562,16 @@ proc mkpatch {} {
      $top.tohead insert 0 $newhead
      $top.tohead conf -state readonly
      grid x $top.tohead -sticky w
-    button $top.rev -text "Reverse" -command mkpatchrev -padx 5
+    button $top.rev -text [mc "Reverse"] -command mkpatchrev -padx 5
      grid $top.rev x -pady 10
-    label $top.flab -text "Output file:"
+    label $top.flab -text [mc "Output file:"]
      entry $top.fname -width 60
      $top.fname insert 0 [file normalize "patch$patchnum.patch"]
      incr patchnum
      grid $top.flab $top.fname -sticky w
      frame $top.buts
-    button $top.buts.gen -text "Generate" -command mkpatchgo
-    button $top.buts.can -text "Cancel" -command mkpatchcan
+    button $top.buts.gen -text [mc "Generate"] -command mkpatchgo
+    button $top.buts.can -text [mc "Cancel"] -command mkpatchcan
      grid $top.buts.gen $top.buts.can
      grid columnconfigure $top.buts 0 -weight 1 -uniform a
      grid columnconfigure $top.buts 1 -weight 1 -uniform a
@@ -5630,9 +5630,9 @@ proc mktag {} {
      set mktagtop $top
      catch {destroy $top}
      toplevel $top
-    label $top.title -text "Create tag"
+    label $top.title -text [mc "Create tag"]
      grid $top.title - -pady 10
-    label $top.id -text "ID:"
+    label $top.id -text [mc "ID:"]
      entry $top.sha1 -width 40 -relief flat
      $top.sha1 insert 0 $rowmenuid
      $top.sha1 conf -state readonly
@@ -5641,12 +5641,12 @@ proc mktag {} {
      $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
      $top.head conf -state readonly
      grid x $top.head -sticky w
-    label $top.tlab -text "Tag name:"
+    label $top.tlab -text [mc "Tag name:"]
      entry $top.tag -width 60
      grid $top.tlab $top.tag -sticky w
      frame $top.buts
-    button $top.buts.gen -text "Create" -command mktaggo
-    button $top.buts.can -text "Cancel" -command mktagcan
+    button $top.buts.gen -text [mc "Create"] -command mktaggo
+    button $top.buts.can -text [mc "Cancel"] -command mktagcan
      grid $top.buts.gen $top.buts.can
      grid columnconfigure $top.buts 0 -weight 1 -uniform a
      grid columnconfigure $top.buts 1 -weight 1 -uniform a
@@ -5660,11 +5660,11 @@ proc domktag {} {
      set id [$mktagtop.sha1 get]
      set tag [$mktagtop.tag get]
      if {$tag == {}} {
-	error_popup "No tag name specified"
+	error_popup [mc "No tag name specified"]
  	return
      }
      if {[info exists tagids($tag)]} {
-	error_popup "Tag \"$tag\" already exists"
+	error_popup [mc "Tag \"%s\" already exists" $tag]
  	return
      }
      if {[catch {
@@ -5725,9 +5725,9 @@ proc writecommit {} {
      set wrcomtop $top
      catch {destroy $top}
      toplevel $top
-    label $top.title -text "Write commit to file"
+    label $top.title -text [mc "Write commit to file"]
      grid $top.title - -pady 10
-    label $top.id -text "ID:"
+    label $top.id -text [mc "ID:"]
      entry $top.sha1 -width 40 -relief flat
      $top.sha1 insert 0 $rowmenuid
      $top.sha1 conf -state readonly
@@ -5736,16 +5736,16 @@ proc writecommit {} {
      $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
      $top.head conf -state readonly
      grid x $top.head -sticky w
-    label $top.clab -text "Command:"
+    label $top.clab -text [mc "Command:"]
      entry $top.cmd -width 60 -textvariable wrcomcmd
      grid $top.clab $top.cmd -sticky w -pady 10
-    label $top.flab -text "Output file:"
+    label $top.flab -text [mc "Output file:"]
      entry $top.fname -width 60
      $top.fname insert 0 [file normalize "commit-[string range  
$rowmenuid 0 6]"]
      grid $top.flab $top.fname -sticky w
      frame $top.buts
-    button $top.buts.gen -text "Write" -command wrcomgo
-    button $top.buts.can -text "Cancel" -command wrcomcan
+    button $top.buts.gen -text [mc "Write"] -command wrcomgo
+    button $top.buts.can -text [mc "Cancel"] -command wrcomcan
      grid $top.buts.gen $top.buts.can
      grid columnconfigure $top.buts 0 -weight 1 -uniform a
      grid columnconfigure $top.buts 1 -weight 1 -uniform a
@@ -5779,19 +5779,19 @@ proc mkbranch {} {
      set top .makebranch
      catch {destroy $top}
      toplevel $top
-    label $top.title -text "Create new branch"
+    label $top.title -text [mc "Create new branch"]
      grid $top.title - -pady 10
-    label $top.id -text "ID:"
+    label $top.id -text [mc "ID:"]
      entry $top.sha1 -width 40 -relief flat
      $top.sha1 insert 0 $rowmenuid
      $top.sha1 conf -state readonly
      grid $top.id $top.sha1 -sticky w
-    label $top.nlab -text "Name:"
+    label $top.nlab -text [mc "Name:"]
      entry $top.name -width 40
      grid $top.nlab $top.name -sticky w
      frame $top.buts
-    button $top.buts.go -text "Create" -command [list mkbrgo $top]
-    button $top.buts.can -text "Cancel" -command "catch {destroy $top}"
+    button $top.buts.go -text [mc "Create"] -command [list mkbrgo $top]
+    button $top.buts.can -text [mc "Cancel"] -command "catch {destroy $top}"
      grid $top.buts.go $top.buts.can
      grid columnconfigure $top.buts 0 -weight 1 -uniform a
      grid columnconfigure $top.buts 1 -weight 1 -uniform a
@@ -5805,7 +5805,7 @@ proc mkbrgo {top} {
      set name [$top.name get]
      set id [$top.sha1 get]
      if {$name eq {}} {
-	error_popup "Please specify a name for the new branch"
+	error_popup [mc "Please specify a name for the new branch"]
  	return
      }
      catch {destroy $top}
@@ -5849,7 +5849,7 @@ proc cherrypick {} {
      set newhead [exec git rev-parse HEAD]
      if {$newhead eq $oldhead} {
  	notbusy cherrypick
-	error_popup "No changes committed"
+	error_popup [mc "No changes committed"]
  	return
      }
      addnewchild $newhead $oldhead
@@ -5873,28 +5873,28 @@ proc resethead {} {
      set w ".confirmreset"
      toplevel $w
      wm transient $w .
-    wm title $w "Confirm reset"
+    wm title $w [mc "Confirm reset"]
      message $w.m -text \
-	"Reset branch $mainhead to [string range $rowmenuid 0 7]?" \
+	[mc "Reset branch %s to %s?" $mainhead [string range $rowmenuid 0 7]] \
  	-justify center -aspect 1000
      pack $w.m -side top -fill x -padx 20 -pady 20
      frame $w.f -relief sunken -border 2
-    message $w.f.rt -text "Reset type:" -aspect 1000
+    message $w.f.rt -text [mc "Reset type:"] -aspect 1000
      grid $w.f.rt -sticky w
      set resettype mixed
      radiobutton $w.f.soft -value soft -variable resettype -justify left \
-	-text "Soft: Leave working tree and index untouched"
+	-text [mc "Soft: Leave working tree and index untouched"]
      grid $w.f.soft -sticky w
      radiobutton $w.f.mixed -value mixed -variable resettype -justify left \
-	-text "Mixed: Leave working tree untouched, reset index"
+	-text [mc "Mixed: Leave working tree untouched, reset index"]
      grid $w.f.mixed -sticky w
      radiobutton $w.f.hard -value hard -variable resettype -justify left \
-	-text "Hard: Reset working tree and index\n(discard ALL local changes)"
+	-text [mc "Hard: Reset working tree and index\n(discard ALL local changes)"]
      grid $w.f.hard -sticky w
      pack $w.f -side top -fill x
-    button $w.ok -text OK -command "set confirm_ok 1; destroy $w"
+    button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w"
      pack $w.ok -side left -fill x -padx 20 -pady 20
-    button $w.cancel -text Cancel -command "destroy $w"
+    button $w.cancel -text [mc Cancel] -command "destroy $w"
      pack $w.cancel -side right -fill x -padx 20 -pady 20
      bind $w <Visibility> "grab $w; focus $w"
      tkwait window $w
@@ -5908,8 +5908,8 @@ proc resethead {} {
  	filerun $fd [list readresetstat $fd $w]
  	toplevel $w
  	wm transient $w
-	wm title $w "Reset progress"
-	message $w.m -text "Reset in progress, please wait..." \
+	wm title $w [mc "Reset progress"]
+	message $w.m -text [mc "Reset in progress, please wait..."] \
  	    -justify center -aspect 1000
  	pack $w.m -side top -fill x -padx 20 -pady 5
  	canvas $w.c -width 150 -height 20 -bg white
@@ -6000,7 +6000,7 @@ proc rmbranch {} {
      set id $headmenuid
      # this check shouldn't be needed any more...
      if {$head eq $mainhead} {
-	error_popup "Cannot delete the currently checked-out branch"
+	error_popup [mc "Cannot delete the currently checked-out branch"]
  	return
      }
      set dheads [descheads $id]
@@ -6959,7 +6959,7 @@ proc showtag {tag isnew} {
      if {[info exists tagcontents($tag)]} {
  	set text $tagcontents($tag)
      } else {
-	set text "Tag: $tag\nId:  $tagids($tag)"
+	set text "[mc "Tag:"] $tag\n[mc "Id:"]  $tagids($tag)"
      }
      appendwithlinks $text {}
      $ctext conf -state disabled
@@ -6989,77 +6989,77 @@ proc doprefs {} {
  	set oldprefs($v) [set $v]
      }
      toplevel $top
-    wm title $top "Gitk preferences"
-    label $top.ldisp -text "Commit list display options"
+    wm title $top [mc "Gitk preferences"]
+    label $top.ldisp -text [mc "Commit list display options"]
      $top.ldisp configure -font $uifont
      grid $top.ldisp - -sticky w -pady 10
      label $top.spacer -text " "
-    label $top.maxwidthl -text "Maximum graph width (lines)" \
+    label $top.maxwidthl -text [mc "Maximum graph width (lines)"] \
  	-font optionfont
      spinbox $top.maxwidth -from 0 -to 100 -width 4 -textvariable maxwidth
      grid $top.spacer $top.maxwidthl $top.maxwidth -sticky w
-    label $top.maxpctl -text "Maximum graph width (% of pane)" \
+    label $top.maxpctl -text [mc "Maximum graph width (% of pane)"] \
  	-font optionfont
      spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
      grid x $top.maxpctl $top.maxpct -sticky w
      frame $top.showlocal
-    label $top.showlocal.l -text "Show local changes" -font optionfont
+    label $top.showlocal.l -text [mc "Show local changes"] -font optionfont
      checkbutton $top.showlocal.b -variable showlocalchanges
      pack $top.showlocal.b $top.showlocal.l -side left
      grid x $top.showlocal -sticky w

-    label $top.ddisp -text "Diff display options"
+    label $top.ddisp -text [mc "Diff display options"]
      $top.ddisp configure -font $uifont
      grid $top.ddisp - -sticky w -pady 10
-    label $top.diffoptl -text "Options for diff program" \
+    label $top.diffoptl -text [mc "Options for diff program"] \
  	-font optionfont
      entry $top.diffopt -width 20 -textvariable diffopts
      grid x $top.diffoptl $top.diffopt -sticky w
      frame $top.ntag
-    label $top.ntag.l -text "Display nearby tags" -font optionfont
+    label $top.ntag.l -text [mc "Display nearby tags"] -font optionfont
      checkbutton $top.ntag.b -variable showneartags
      pack $top.ntag.b $top.ntag.l -side left
      grid x $top.ntag -sticky w
-    label $top.tabstopl -text "tabstop" -font optionfont
+    label $top.tabstopl -text [mc "tabstop"] -font optionfont
      spinbox $top.tabstop -from 1 -to 20 -width 4 -textvariable tabstop
      grid x $top.tabstopl $top.tabstop -sticky w

-    label $top.cdisp -text "Colors: press to choose"
+    label $top.cdisp -text [mc "Colors: press to choose"]
      $top.cdisp configure -font $uifont
      grid $top.cdisp - -sticky w -pady 10
      label $top.bg -padx 40 -relief sunk -background $bgcolor
-    button $top.bgbut -text "Background" -font optionfont \
+    button $top.bgbut -text [mc "Background"] -font optionfont \
  	-command [list choosecolor bgcolor 0 $top.bg background setbg]
      grid x $top.bgbut $top.bg -sticky w
      label $top.fg -padx 40 -relief sunk -background $fgcolor
-    button $top.fgbut -text "Foreground" -font optionfont \
+    button $top.fgbut -text [mc "Foreground"] -font optionfont \
  	-command [list choosecolor fgcolor 0 $top.fg foreground setfg]
      grid x $top.fgbut $top.fg -sticky w
      label $top.diffold -padx 40 -relief sunk -background [lindex  
$diffcolors 0]
-    button $top.diffoldbut -text "Diff: old lines" -font optionfont \
+    button $top.diffoldbut -text [mc "Diff: old lines"] -font optionfont \
  	-command [list choosecolor diffcolors 0 $top.diffold "diff old lines" \
  		      [list $ctext tag conf d0 -foreground]]
      grid x $top.diffoldbut $top.diffold -sticky w
      label $top.diffnew -padx 40 -relief sunk -background [lindex  
$diffcolors 1]
-    button $top.diffnewbut -text "Diff: new lines" -font optionfont \
+    button $top.diffnewbut -text [mc "Diff: new lines"] -font optionfont \
  	-command [list choosecolor diffcolors 1 $top.diffnew "diff new lines" \
  		      [list $ctext tag conf d1 -foreground]]
      grid x $top.diffnewbut $top.diffnew -sticky w
      label $top.hunksep -padx 40 -relief sunk -background [lindex  
$diffcolors 2]
-    button $top.hunksepbut -text "Diff: hunk header" -font optionfont \
+    button $top.hunksepbut -text [mc "Diff: hunk header"] -font optionfont \
  	-command [list choosecolor diffcolors 2 $top.hunksep \
  		      "diff hunk header" \
  		      [list $ctext tag conf hunksep -foreground]]
      grid x $top.hunksepbut $top.hunksep -sticky w
      label $top.selbgsep -padx 40 -relief sunk -background $selectbgcolor
-    button $top.selbgbut -text "Select bg" -font optionfont \
+    button $top.selbgbut -text [mc "Select bg"] -font optionfont \
  	-command [list choosecolor selectbgcolor 0 $top.selbgsep background  
setselbg]
      grid x $top.selbgbut $top.selbgsep -sticky w

      frame $top.buts
-    button $top.buts.ok -text "OK" -command prefsok -default active
+    button $top.buts.ok -text [mc "OK"] -command prefsok -default active
      $top.buts.ok configure -font $uifont
-    button $top.buts.can -text "Cancel" -command prefscan -default normal
+    button $top.buts.can -text [mc "Cancel"] -command prefscan  
-default normal
      $top.buts.can configure -font $uifont
      grid $top.buts.ok $top.buts.can
      grid columnconfigure $top.buts 0 -weight 1 -uniform a
@@ -7072,7 +7072,7 @@ proc choosecolor {v vi w x cmd} {
      global $v

      set c [tk_chooseColor -initialcolor [lindex [set $v] $vi] \
-	       -title "Gitk: choose color for $x"]
+	       -title [mc "Gitk: choose color for %s" $x]]
      if {$c eq {}} return
      $w conf -background $c
      lset $v $vi $c
@@ -7569,7 +7569,7 @@ if {$cmdline_files ne {} || $revtreeargs ne {}} {
      set curview 1
      set selectedview 1
      set nextviewnum 2
-    set viewname(1) "Command line"
+    set viewname(1) [mc "Command line"]
      set viewfiles(1) $cmdline_files
      set viewargs(1) $revtreeargs
      set viewperm(1) 0
-- 
1.5.3.rc2.12.gbc280

^ permalink raw reply related

* [PATCH 1/2] gitk: Import msgcat for translation support
From: Christian Stimming @ 2007-07-27 14:53 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: git

Import tcl's msgcat package to have the [mc...] procedure for  
translation available.

However, in the current form gitk doesn't load any data a data  
directory or from anywhere; if it should load any translation  
catalogs, of course it needs to load them from a designated data  
directory. For testing, it uses the ./msgs/ subdirectory (marked as  
FIXME), but eventually a full-blown data directory needs to be added  
there instead.

Signed-off-by: Christian Stimming <stimming@tuhh.de>
---
Actual translation markup will follow.

  gitk |    7 +++++++
  1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/gitk b/gitk
index 39e452a..c01acfb 100755
--- a/gitk
+++ b/gitk
@@ -7463,6 +7463,13 @@ set fgcolor black
  set diffcolors {red "#00a000" blue}
  set selectbgcolor gray85

+## Internationalization (i18n) through msgcat and gettext. See
+## http://www.gnu.org/software/gettext/manual/html_node/Tcl.html
+package require msgcat
+namespace import ::msgcat::mc
+## FIXME: Need to define a suitable msgs/ directory here.
+::msgcat::mcload [file join . msgs]
+
  catch {source ~/.gitk}

  font create optionfont -family sans-serif -size -12
-- 
1.5.3.rc2.12.gbc280

^ permalink raw reply related

* [PATCH] git-svn: Translate invalid characters in refname
From: Robert Ewald @ 2007-07-27 14:40 UTC (permalink / raw)
  To: git

Hello,

My first patch, please be gentle.

This is a first attempt to get the escaping behavior into git-svn.
I hope I have not screwed up too badly since this I have been looking
at Perl for more or less the first time.

So I would appreciate if any mistakes would be pointed out to me.

The patch works for me during clone, fetch and dcommit. I haven't
tried anything else yet.

Robert

PS: There is a testing script I have used. I suppose it should be put into
the testing infrastructure, something I am not yet familiar with. If
someone is interested I can send it as is.

---

In git some characters are invalid as documented
in git-check-ref-format. In subversion these characters might
be valid, so a translation is required.

This patch does this translation by url escaping characters, that
are not allowed.

Credit for ideas and code snippets goes to Eric Wong, martin f. krafft and
Jan Hudec

Signed-off-by: Robert Ewald <robewald@gmx.net>
---
 git-svn.perl |   43 ++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/git-svn.perl b/git-svn.perl
index 6c692a7..68e62ab 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -938,8 +938,8 @@ sub resolve_local_globs {
        foreach (command(qw#for-each-ref --format=%(refname) refs/remotes#)) {
                next unless m#^refs/remotes/$ref->{regex}$#;
                my $p = $1;
-               my $pathname = $path->full_path($p);
-               my $refname = $ref->full_path($p);
+               my $pathname = desanitize_refname($path->full_path($p));
+               my $refname = desanitize_refname($ref->full_path($p));
                if (my $existing = $fetch->{$pathname}) {
                        if ($existing ne $refname) {
                                die "Refspec conflict:\n",
@@ -1239,7 +1239,44 @@ sub new {
        $self;
 }
 
-sub refname { "refs/remotes/$_[0]->{ref_id}" }
+sub refname { 
+        my ($refname) = "refs/remotes/$_[0]->{ref_id}" ;
+
+        # It cannot end with a slash /, we'll throw up on this because
+        # SVN can't have directories with a slash in their name, either:
+        if ($refname =~ m{/$}) {
+                die "ref: '$refname' ends with a trailing slash, this is ",
+                    "not permitted by git nor Subversion\n";
+        }
+
+        # It cannot have ASCII control character space, tilde ~, caret ^,
+        # colon :, question-mark ?, asterisk *, space, or open bracket[
anywhere
+       #
+        # Additionally, % must be escaped because it is used for escaping
+        # and we want our escaped refname to be reversible
+        $refname =~ s{([ \%~\^:\?\*\[\t])}{uc sprintf('%%%02x',ord($1))}eg;
+
+        # no slash-separated component can begin with a dot .
+        # /.* becomes /%2E*
+        $refname =~ s{/\.}{/%2E}g;
+        # It cannot have two consecutive dots .. anywhere
+        # .. becomes %2E%2E
+        $refname =~ s{\.\.}{%2E%2E}g;
+
+        $refname;
+}
+
+sub desanitize_refname {
+    my ($refname) = @_;
+
+    print "bob: desanitized from $refname ";
+
+    $refname =~ s{%(?:([0-9A-F]{2}))}{chr hex($1)}eg;
+
+    print " to $refname \n";
+
+    $refname;
+}
 
 sub svm_uuid {
        my ($self) = @_;
-- 
1.5.3.rc3-dirty

-- 
Robert Ewald

^ permalink raw reply related

* Re: Gitweb and submodules
From: Lars Hjemli @ 2007-07-27 14:31 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <200707271322.50114.jnareb@gmail.com>

On 7/27/07, Jakub Narebski <jnareb@gmail.com> wrote:
> I'd like to add submodule support to gitweb, among others marking
> submodules as such in the 'tree' view and adding 'log' view link to
> them.

A bit of advertising:
  http://hjemli.net/git/cgit/tree

The implementation can be found here:
  http://hjemli.net/git/cgit/tree/ui-tree.c#81

> But for that I need a question answered: how to find GIT_DIR of
> repository which contains submodule objects?

Generally, you can't. But if you just want to show the log of the
submodule path, you probably don't need to do anything at all (except
the special handling in 'tree' view). If you do want to show the log
of the referenced repository, I guess a new entry  in .gitmodules
could be helpful.

--
larsh

^ permalink raw reply

* Re: gitk screenshots of complex history
From: Brian Downing @ 2007-07-27 13:52 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: git
In-Reply-To: <20070727041300.GD20052@spearce.org>

On Fri, Jul 27, 2007 at 12:13:01AM -0400, Shawn O. Pearce wrote:
> I've mentioned both on list and on #git that one of my production
> repositories has a few weird points in time.  Some folks have asked
> to see at least screenshots of the line part of the gitk output,
> as apparently they've never seen ugly history in Git.  Lucky them.
> 
> The images are rather large so I have posted them on my website
> with a bit longer explanation of each:
> 
>   http://www.spearce.org/2007/07/difficult-gitk-graphs.html
 
> OK, no more screenshots from *that* repository!  I don't ever want
> to run `gitk --all` there again.  Ever.

Were those graphs generated with --topo-order (the default) or
--date-order?  I've found complex history usually looks a lot more
manageable with --date-order.  Certainly the Git history is a LOT less
wide with --all --date-order than --all.

Does this help your situation as well?

-bcd

^ permalink raw reply

* Re: index-pack died on pread
From: Nicolas Pitre @ 2007-07-27 13:38 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Junio C Hamano, Alex Riesen, Robin Rosenberg, Michal Rokos, GIT
In-Reply-To: <alpine.LFD.0.999.0707262231280.3442@woody.linux-foundation.org>

On Thu, 26 Jul 2007, Linus Torvalds wrote:

> 
> 
> On Thu, 26 Jul 2007, Junio C Hamano wrote:
> > 
> > If you mean the offset associated with fd, we actually do.
> 
> Ahh, for some reason I thought we didn't (probably because the user likely 
> doesn't care at all), but right you are..

The (only) user in Git does care indeed.  The sequence of events goes 
like this:

 - Receive pack from remote location, parsing objects along and writing
   a copy to the local pack file, as well as computing the SHA1 of non
   delta objects.

 - When all objects are parsed, the received pack SHA1 is verified.  
   If SHA1 doesn't match due to corruption in received data then everything 
   stops here with a "pack is corrupted (SHA1 mismatch)" error.

 - For each received deltas: resolve those deltas to compute their 
   object SHA1.  This is where pread() is involved on the local pack 
   file. If pread() fails to return proper data then the data won't 
   inflate properly and everything stops here with a "serious inflate 
   inconsistency" error.

 - [OPTIONAL] Complete a thin pack with missing base objects for deltas 
   that weren't resolved yet.  This involves pread() again, but it 
   _also_ append data to the same local pack file in the process.  In 
   this case it is important that pread() restores the file position 
   when it returns or the appended objects won't be written where they 
   should.  

   This is optional because a thin pack is not received all the time, 
   not on a clone for example.

 - Write trailing SHA1 to the local pack before moving it to its final 
   location.  This also relies on pread() restoring the file position on 
   the local pack file or the trailing pack SHA1 won't be written where 
   it should.

So if pread() doesn't properly restore the file position then local pack 
corruption will occur and the pack will be unusable.  If pread() doesn't 
properly read the asked data then index-pack will die.

> It really isn't that complex a system call. So I'm surprised at bugs 
> there, and that makes me worry that there is something in git that 
> triggers this.

Well, we have usage cases for a real pread() as well as our own 
emulation which work.  And the emulated pread() works in all cases so 
far, so...


Nicolas

^ permalink raw reply

* [PATCH] really plug memory leaks in git-svnimport
From: Stefan Sperling @ 2007-07-27 13:09 UTC (permalink / raw)
  To: git; +Cc: subversion

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


Hello,

trying to convert the rather large  subversion repo of the DSLinux project
I hit memory leaks in git-svnimport.

The repo has *lots* of files, a workspace is about 2GB in size.
URLs: www.dslinux.org, svnweb at http://dslinux.gits.kiev.ua

Trace showing the program running out of memory:

#0  0x28285f57 in kill () from /lib/libc.so.6
#1  0x28285ef6 in raise () from /lib/libc.so.6
#2  0x282849bb in abort () from /lib/libc.so.6
#3  0x283bd9ea in abort_on_pool_failure (retcode=12)
    at subversion/libsvn_subr/pool.c:46
#4  0x285c8f1f in apr_palloc (pool=0x2801a018, size=53840)
    at memory/unix/apr_pools.c:618
#5  0x28621519 in rep_read_contents (baton=0x2800d388, buf=0x28026018 "",
    len=0xbfbfdb38) at subversion/libsvn_fs_fs/fs_fs.c:1881


I know about the patch at http://marc.info/?l=git&m=114345884526971&w=2
but that is already applied to the version I have here and does not
help because it does not really solve the core of the problem.

The following is rather lengthy, but I guess people applying
my patch want to understand what they're doing so I might just
as well provide all the info upfront.

The core of the problem is that the subversion perl bindings
don't seem to suceed at abstracting dynamic memory handling
away from perl scripts. Ripping out all explicit dynamic memory
handling from git-svnimport (done via the SVN::Pool API) does
not make the problem go away.

I am still not sure whether the right place to fix this
are the subversion perl bindings or the script.
Handling dynamic memory explicitly in a scripting language
is certainly weird. But I cannot get the subversion perl bindings
from current subversion trunk to build on my system to try to find
out if it is possible to fix the problem there
(see http://svn.haxx.se/users/archive-2007-07/0784.shtml).

So I had to try to solve the problem in the script itself.
I was able to fix the script up to the point where I was
able to import the entire DSLinux repository in a single
go without the script running out of memory.

To understand the fix you need to understand how subversion
handles dynamic memory:

Basically, every function in subversion that needs temporary
scratch space gets handed a pointer to a "memory pool".

It can allocate memory from this pool and does not need to care
about freeing anything because only the scope that created a pool
is responsible for destroying it.

So in C this looks a bit like:

svn_error_t* some_func(struct my_struct **result, apr_pool_t *pool)
{
	/* allocate space for result from pool */
	struct my_struct *res = apr_palloc(pool, sizeof(struct my_struct));
	
	/* compute result and pass pool further down if needed */
	
	...

	/* don't care about freeing the pool */
	*result = res;
	return SVN_NO_ERROR;
}

The caller will know when it does not need the result any longer
and destroy the pool at that moment.

Loops are interesting, since we can also "clear" a pool which does
not deallocate the memory it holds but marks the memory ready for re-use.

So with loops the following idiom is used:

	apr_pool_t *subpool = svn_pool_create(pool);		

	while (condition) {
		svn_pool_clear(subpool);

		/* do stuff and pass subpool further down if needed */

		...
	}
	
	svn_pool_destroy(subpool);


So how do these pools work in perl?

Well, the SVN::Core man page states the following:

  The perl bindings significantly simplify the usage of pools, while
  still being manually adjustable.

Great. And what does mean exactly?

  Functions requiring pool as the last argument (which are, almost all of
  the subversion functions), the pool is optionally[sic]. The default pool
  is used if it is omitted. If default pool is not set, a new root pool will
  be created and set as default automatically when the first function
  requiring a default pool is called.

So there's a "default" pool that is used if the caller does not
specify a $pool argument. We can take more control via the way
we create pools in perl:

  Methods
  
  new ([$parent])
     Create a new pool. The pool is a root pool if $parent is not sup-
     plied.
  
  new_default ([$parent])
     Create a new pool. The pool is a root pool if $parent is not sup-
     plied.  Set the new pool as default pool.
  
  new_default_sub
     Create a new subpool of the current default pool, and set the
     resulting pool as new default pool.
  
  clear
     Clear the pool.
  
  destroy
     Destroy the pool. If the pool is the default pool, restore the pre-
     vious default pool as default. This is normally called automati-
     cally when the SVN::Pool object is no longer used and destroyed by
     the perl garbage collector.
  
So pools in perl get destroyed when the garbage collector runs.
The man page gives an example that implies that the garbage collector
runs when the pool falls out of scope:

  # create a root pool and set it as default pool for later use
  my $pool = SVN::Pool->new_default;

  sub something {
      # create a subpool of the current default pool
      my $pool = SVN::Pool->new_default_sub;
      # some svn operations...

      # $pool gets destroyed and the previous default pool
      # is restored when $pool's lexical scope ends
  }

git-svmimport uses the repository access (RA) layer of the subversion
library to talk to the repository. The SVN::Ra man page states
the following about the 'pool' argument of the SVN::Ra constructor:

  The pool for the ra session to use, and also the member functions
  will be called with this pool. Default to a newly created root
  pool.

The SVN::Ra man page fails to mention what the SVN::Core man page implies.
If a function gets passed an explicit pool, or if we change the
current default pool, our pool will be used instead of the one
specified to the constructor of the RA layer!

So the patch below does the following:

  * Create an explicit one-and-only root pool.

  * Override the default pool SVN::RA is using with our root pool.
    Since the connection to the repo must stay open during the whole
    script, the RA layer will depend on the pool staying alive throughout
    the whole program, so it might as well use the root pool.

  * Closely follow the example in the SVN::Core man page.

    Before calling a subversion function, create a subpool of our
    root pool and make it the new default pool. Then call the
    function without passing $pool argument. The function will use
    our subpool anyway because we made it the current default pool.
    The previous default pool will become default pool again when
    the subpool falls out of scope.

  * A major problem seemed to be that the script keeps creating
    new root pools with

      my $pool = SVN::Pool->new();
    
    inside a loop in *global* scope instead of using the loop idiom
    described above. These pools are never, ever destroyed.

    So create a subpool for the loop to use and clear (i.e. mark for
    reuse, don't decallocate) the subpool at the start of the loop
    instead of allocating new memory with each iteration.


With this patch, the script never exceeded the memory usage of firefox
to a large extend while converting the DSLinux repo :-)
I hope the patch will help even more stupid and ugly people switch to git.


diff --git a/git-svnimport.perl b/git-svnimport.perl
index b73d649..53526f4 100755
--- a/git-svnimport.perl
+++ b/git-svnimport.perl
@@ -54,6 +54,7 @@ my $branch_name = $opt_b || "branches";
 my $project_name = $opt_P || "";
 $project_name = "/" . $project_name if ($project_name);
 my $repack_after = $opt_R || 1000;
+my $root_pool = SVN::Pool->new_default;
 
 @ARGV == 1 or @ARGV == 2 or usage();
 
@@ -132,7 +133,7 @@ sub conn {
 	my $auth = SVN::Core::auth_open ([SVN::Client::get_simple_provider,
 			  SVN::Client::get_ssl_server_trust_file_provider,
 			  SVN::Client::get_username_provider]);
-	my $s = SVN::Ra->new(url => $repo, auth => $auth);
+	my $s = SVN::Ra->new(url => $repo, auth => $auth, pool => $root_pool);
 	die "SVN connection to $repo: $!\n" unless defined $s;
 	$self->{'svn'} = $s;
 	$self->{'repo'} = $repo;
@@ -147,11 +148,10 @@ sub file {
 
 	print "... $rev $path ...\n" if $opt_v;
 	my (undef, $properties);
-	my $pool = SVN::Pool->new();
 	$path =~ s#^/*##;
+	my $subpool = SVN::Pool::new_default_sub;
 	eval { (undef, $properties)
-		   = $self->{'svn'}->get_file($path,$rev,$fh,$pool); };
-	$pool->clear;
+		   = $self->{'svn'}->get_file($path,$rev,$fh); };
 	if($@) {
 		return undef if $@ =~ /Attempted to get checksum/;
 		die $@;
@@ -185,6 +185,7 @@ sub ignore {
 
 	print "... $rev $path ...\n" if $opt_v;
 	$path =~ s#^/*##;
+	my $subpool = SVN::Pool::new_default_sub;
 	my (undef,undef,$properties)
 	    = $self->{'svn'}->get_dir($path,$rev,undef);
 	if (exists $properties->{'svn:ignore'}) {
@@ -202,6 +203,7 @@ sub ignore {
 sub dir_list {
 	my($self,$path,$rev) = @_;
 	$path =~ s#^/*##;
+	my $subpool = SVN::Pool::new_default_sub;
 	my ($dirents,undef,$properties)
 	    = $self->{'svn'}->get_dir($path,$rev,undef);
 	return $dirents;
@@ -358,10 +360,9 @@ open BRANCHES,">>", "$git_dir/svn2git";
 
 sub node_kind($$) {
 	my ($svnpath, $revision) = @_;
-	my $pool=SVN::Pool->new;
 	$svnpath =~ s#^/*##;
-	my $kind = $svn->{'svn'}->check_path($svnpath,$revision,$pool);
-	$pool->clear;
+	my $subpool = SVN::Pool::new_default_sub;
+	my $kind = $svn->{'svn'}->check_path($svnpath,$revision);
 	return $kind;
 }
 
@@ -889,7 +890,7 @@ sub commit_all {
 	# Recursive use of the SVN connection does not work
 	local $svn = $svn2;
 
-	my ($changed_paths, $revision, $author, $date, $message, $pool) = @_;
+	my ($changed_paths, $revision, $author, $date, $message) = @_;
 	my %p;
 	while(my($path,$action) = each %$changed_paths) {
 		$p{$path} = [ $action->action,$action->copyfrom_path, $action->copyfrom_rev, $path ];
@@ -925,14 +926,14 @@ print "Processing from $current_rev to $opt_l ...\n" if $opt_v;
 my $from_rev;
 my $to_rev = $current_rev - 1;
 
+my $subpool = SVN::Pool::new_default_sub;
 while ($to_rev < $opt_l) {
+	$subpool->clear;
 	$from_rev = $to_rev + 1;
 	$to_rev = $from_rev + $repack_after;
 	$to_rev = $opt_l if $opt_l < $to_rev;
 	print "Fetching from $from_rev to $to_rev ...\n" if $opt_v;
-	my $pool=SVN::Pool->new;
-	$svn->{'svn'}->get_log("/",$from_rev,$to_rev,0,1,1,\&commit_all,$pool);
-	$pool->clear;
+	$svn->{'svn'}->get_log("/",$from_rev,$to_rev,0,1,1,\&commit_all);
 	my $pid = fork();
 	die "Fork: $!\n" unless defined $pid;
 	unless($pid) {

[-- Attachment #2: Type: application/pgp-signature, Size: 187 bytes --]

^ permalink raw reply related

* Re: [RFC] Git User's Survey 2007
From: Andy Parkins @ 2007-07-27 13:01 UTC (permalink / raw)
  To: git; +Cc: Jakub Narebski, Paolo Ciarrocchi
In-Reply-To: <200707271320.06313.jnareb@gmail.com>

On Friday 2007 July 27, Jakub Narebski wrote:

> Getting started with GIT
>
>     1. How did you hear about GIT?
>     2. Did you find GIT easy to learn?
>     -  very easy/easy/reasonably/hard/very hard
>     3. What helped you most in learning to use it?
>     4. What did you find hardest?
>     5. When did you start using git? From which version?

The primary assumption of the survey seems to be that the responder is already 
using git.  What about some questions for people _not_ using git; things like 
(badly written I'm sure, but you get the idea):

Not using GIT

  Have you heard of git?  i.e. do you know what it's for?
  Do you already use a VCS?  Which one?  Are you happy with it?
  If not, would you like to use a VCS?
  If you don't use a VCS already and don't want to - why not?
  If you do use a VCS already, but it's not git - why not?
  Would you like to use git but git doesn't supply a feature you need?
  What would you require from git to enable you to change?


> What you think of GIT
>
>     1. Overall, how happy are you with GIT?
>     -  unhappy/not so happy/happy/very happy/completely extatic

"extatic" should be "ecstatic"


Andy

-- 
Dr Andy Parkins, M Eng (hons), MIET
andyparkins@gmail.com

^ permalink raw reply

* Re: Gitweb and submodules
From: Sven Verdoolaege @ 2007-07-27 12:32 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <200707271322.50114.jnareb@gmail.com>

On Fri, Jul 27, 2007 at 01:22:49PM +0200, Jakub Narebski wrote:
> But for that I need a question answered: how to find GIT_DIR of 
> repository which contains submodule objects? We have to assume in 
> gitweb that repositories are bare...

You'll have to add a configuration variable for that.
The submodule may not even be on the same server.

skimo

^ permalink raw reply

* [ANNOUNCE] qgit-2.0rc2
From: Marco Costalba @ 2007-07-27 12:22 UTC (permalink / raw)
  To: Git Mailing List

This is the new rc of qgit4, qgit ported under Qt4.3.

You can download from git://git.kernel.org/pub/scm/qgit/qgit4.git
or from http://sourceforge.net/projects/qgit

qgit it's a git graphic history viewer (and more) written with Qt4.3 libraries.

A lot of work went in from last rc, both on performance and stability.

Quite a bunch of new features added too. Probably this will be the
last rc, stability seems very good and no regressions are known.


I'll be off line for a couple of weeks.

Have fun
Marco

^ permalink raw reply

* Re: [RFC] Git User's Survey 2007
From: Nguyen Thai Ngoc Duy @ 2007-07-27 12:21 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git, Paolo Ciarrocchi
In-Reply-To: <200707271320.06313.jnareb@gmail.com>

On 7/27/07, Jakub Narebski <jnareb@gmail.com> wrote:
> First there is a question about the form of survey. Should we use web
> based survey, as the survey before (http://www.survey.net.nz), sending
> emails with link to this survey, or perhaps do email based survey,
> with email Reply-To: address put for this survey alone?

Unless you have tools to auto-process email replies

> Third, where to send survey to? I was thinking about git mailing list,
> LKML, and mailing list for git projects found on GitProjects page on
> GIT wiki. Do you want to add some address? Or should info about GIT
> User's Survey 2007 be sent also to one of on-line magazines like
> LinuxToday, or asked to put on some blog?

lwn.net. It would be great if we have the survey announcement on
popular planet sites such as planet gnome, kde, mozilla....
-- 
Duy

^ permalink raw reply

* Re: git-gui-i18n: Make "Revert changes in these $n files" translatable.
From: Christian Stimming @ 2007-07-27 11:49 UTC (permalink / raw)
  To: Brett Schwarz
  Cc: Harri Ilari Tapio Liusvaara, Shawn O. Pearce, git, Paul Mackerras,
	Junio C Hamano
In-Reply-To: <53264.26898.qm@web38901.mail.mud.yahoo.com>

Quoting Brett Schwarz <brett_schwarz@yahoo.com>:
>> > - Buttons in hard reset confirmation (branch->revert or merge->abort,
>> >   and it is yes/no dialog).
>>
>> Maybe those need to be translated in the tcl/tk system libraries?
>
> These are indeed in the Tk libs. Unfortunately, there is no straight  
>  forward way to change the button text for tk_messageBox. I'll   
> probably submit a patch to Tcl core for this.

That would indeed be a very good solution here.

> In the mean time, if this is important, there are 2 ways around this:
>
> 1) override the button text in the msgcat. (...)
> So, somewhere in the git-gui, you would  have to do something like:
>     namespace eval ::Tk {
>       ::msgcat::mcset en_us &OK <new_term>
>       ::msgcat::mcset en_us &Cancel <new_term>
>       ::msgcat::mcset en_us &Yes <new_term>
>       ::msgcat::mcset en_us &No <new_term>
>       <continue for each language, if needed>
>     }

I think this wouldn't help much here. First of all, the original  
messages might be different between different Tcl versions. But  
secondly and more importantly, as Harri Ilari pointed out, we should  
prefer to provide button texts different from Yes/No but rather  
questions like "Revert"/"Cancel".

> 2) Re-write the tk_messageBox, to include an option to specify the   
> button text. This wouldn't be too hard actually, but this would live  
>  with git-gui.

This would indeed be the nicer solution and it would improve both the  
English button labels and their translations all in one.

> I don't think option #1 is robust enough, but would be the easiest   
> approach. Note also that this would only be for unix platforms,   
> since for windows and Mac, it calls the platform's equivalent.

By the way: I have been using git-gui on Windows with mingw-git(+msys)  
and ActiveTcl for several weeks by now. Works like a charm, and I'm  
looking forward to propose it as a fully localized, fully  
cross-platform, and simply the best SCM, to the co-workers in my  
company... :-)

Christian

^ permalink raw reply

* [PATCH v2] gitk: let you easily specify lines of context in diff view
From: Steffen Prohaska @ 2007-07-27 11:44 UTC (permalink / raw)
  To: paulus; +Cc: git, Steffen Prohaska
In-Reply-To: <18089.51584.704957.310331@cargo.ozlabs.ibm.com>

More lines of context sometimes help to better understand a diff.
This patch introduces a text field above the box displaying the
blobdiffs. You can type in the number of lines of context that
you wish to view. The number of lins ines of context is initially
always set to 3.

Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
 gitk |   41 +++++++++++++++++++++++++++++++++++++++--
 1 files changed, 39 insertions(+), 2 deletions(-)

I included the changes proposed by Paul. From my side, the patch
is ready to be applied.

    Steffen

diff --git a/gitk b/gitk
index 39e452a..9de9574 100755
--- a/gitk
+++ b/gitk
@@ -500,6 +500,7 @@ proc makewindow {} {
     global textfont mainfont uifont tabstop
     global findtype findtypemenu findloc findstring fstring geometry
     global entries sha1entry sha1string sha1but
+    global diffcontextstring diffcontext
     global maincursor textcursor curtextcursor
     global rowctxmenu fakerowmenu mergemax wrapcomment
     global highlight_files gdttype
@@ -714,7 +715,16 @@ proc makewindow {} {
 	-command changediffdisp -variable diffelide -value {0 1}
     radiobutton .bleft.mid.new -text "New version" \
 	-command changediffdisp -variable diffelide -value {1 0}
-    pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new -side left
+    label .bleft.mid.labeldiffcontext -text "      Lines of context: " \
+    -font $uifont
+    spinbox .bleft.mid.diffcontext -width 5 -font $textfont \
+    -from 1 -increment 1 -to 10000000 \
+    -validate all -validatecommand "diffcontextvalidate %P" \
+    -textvariable diffcontextstring
+    .bleft.mid.diffcontext set $diffcontext
+    trace add variable diffcontextstring write diffcontextchange
+    lappend entries .bleft.mid.diffcontext
+    pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new .bleft.mid.labeldiffcontext .bleft.mid.diffcontext -side left
     set ctext .bleft.ctext
     text $ctext -background $bgcolor -foreground $fgcolor \
 	-tabs "[expr {$tabstop * $charspc}]" \
@@ -4872,12 +4882,37 @@ proc gettreediffline {gdtf ids} {
     return 0
 }
 
+# empty strings or integers accepted
+proc diffcontextvalidate {v} {
+    if {[string length $v] == 0} {
+	return 1
+    }
+    if {[string is integer $v]} {
+	if {$v > 0} {
+	    return 1
+	}
+    }
+    return 0
+}
+
+proc diffcontextchange {n1 n2 op} {
+    global diffcontextstring diffcontext
+
+    if {[string is integer $diffcontextstring]} {
+        if {$diffcontextstring > 0} {
+            set diffcontext $diffcontextstring
+		    reselectline
+        }
+    }
+}
+
 proc getblobdiffs {ids} {
     global diffopts blobdifffd diffids env
     global diffinhdr treediffs
+    global diffcontext
 
     set env(GIT_DIFF_OPTS) $diffopts
-    if {[catch {set bdf [open [diffcmd $ids {-p -C}] r]} err]} {
+    if {[catch {set bdf [open [diffcmd $ids "-p -C -U$diffcontext"] r]} err]} {
 	puts "error getting diffs: $err"
 	return
     }
@@ -7537,6 +7572,8 @@ set markingmatches 0
 
 set optim_delay 16
 
+set diffcontext 3 
+
 set nextviewnum 1
 set curview 0
 set selectedview 0
-- 
1.5.3.rc3.21.g45610

^ permalink raw reply related

* Re: [PATCH] git-gui wording suggestions
From: Christian Stimming @ 2007-07-27 11:42 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Brett Schwarz, git, Paul Mackerras, Junio C Hamano
In-Reply-To: <20070727044009.GF20052@spearce.org>

Quoting "Shawn O. Pearce" <spearce@spearce.org>:
>> Unifiy wording to say "to stage" instead of "to add" always.
> ...
>> With this patch I'd propose to talk every only about "stage" instead
>> of "add". IMHO that's just the logical conclusion of the above wording
>> decision. What do you think?
>
> Yes, I agree.  This is a necessary change, the current wording is
> very confusing.  I would apply this earlier than the other i18n
> stuff, but this patch is written based upon the current i18n work.
> :-|

Well, of course I have supplied this patch on top of the current i18n  
markup work... on the other hand, back-porting the string changes to  
the non-i18n code means that the i18n changes themselves won't merge  
anymore. For that reason I wouldn't suggest to apply this separately  
from the i18n commits, unless you would want to adapt the i18n patches  
as well.

I'd rather suggest to consider the i18n changes rather soon by now,  
even if the actual translations will be merged later. The [mc...]  
calls itself don't change the behaviour of the application, so I don't  
think it would be very risky do merge them sooner than later.  
Eventually, that's of course up to you.

Christian

^ permalink raw reply

* Gitweb and submodules
From: Jakub Narebski @ 2007-07-27 11:22 UTC (permalink / raw)
  To: git

I'd like to add submodule support to gitweb, among others marking 
submodules as such in the 'tree' view and adding 'log' view link to 
them.

But for that I need a question answered: how to find GIT_DIR of 
repository which contains submodule objects? We have to assume in 
gitweb that repositories are bare...

-- 
Jakub Narebski
Poland

^ permalink raw reply

* [RFC] Git User's Survey 2007
From: Jakub Narebski @ 2007-07-27 11:20 UTC (permalink / raw)
  To: git; +Cc: Paolo Ciarrocchi
In-Reply-To: <200707250358.58637.jnareb@gmail.com>

It's been more than a year since last Git User's Survey. It would be
interesting to find what changed since then. Therefore the idea to
have another survey.

First there is a question about the form of survey. Should we use web
based survey, as the survey before (http://www.survey.net.nz), sending
emails with link to this survey, or perhaps do email based survey,
with email Reply-To: address put for this survey alone?

Second, what questions should be put in the survey, and in the case of
single choice and ultiple choice questions what possible answers
should be? Below are slightly extended questions from the last
survey. Please comment on it.

Third, where to send survey to? I was thinking about git mailing list,
LKML, and mailing list for git projects found on GitProjects page on
GIT wiki. Do you want to add some address? Or should info about GIT
User's Survey 2007 be sent also to one of on-line magazines like
LinuxToday, or asked to put on some blog?

References:
  http://marc.info/?l=git&m=115116592330648&w=2
  http://marc.info/?l=git&m=115364303813936&w=2
  http://git.or.cz/gitwiki/GitSurvey

----
About you

    1. What country are you in?
    2. What is your preferred non-programming language?
    3. Which programming languages you are proficient with?
       (zero or more: multiple choice)
    -  C, shell, Perl, Python, Tcl/Tk

Getting started with GIT

    1. How did you hear about GIT?
    2. Did you find GIT easy to learn?
    -  very easy/easy/reasonably/hard/very hard
    3. What helped you most in learning to use it?
    4. What did you find hardest?
    5. When did you start using git? From which version?

How you use GIT

    1. Do you use GIT for work, unpaid projects, or both?
       work/unpaid projects/work
    2. How do you obtain GIT?  Source tarball, binary package, or
       pull the main repository?
    -  binary package/source tarball/pull from main repository
    3. What hardware platforms do you use GIT on?
    *  examples: i386, x86_64, ARM, PowerPC, Alpha, g5, ...
    4. What OS (please include the version) do you use GIT on?
    *  examples: Linux, MS Windows (Cygwin/MinGW/gitbox), 
       IRIX, HP-UX, Solaris, FreeBSD, ...
       (please give kernel version and distribution for Linux)
    5. How many people do you collaborate with using GIT?
    6. How big are the repositories that you work on? (e.g. how many
       files, how much disk space, how deep is the history?)
    *  number of files in repository: "git ls-tree -r HEAD | wc -l"
    *  pack size of freshly cloned fully packed repository
    *  number of commits in straight line, number of commits in branch
       ("git rev-list --first-parent HEAD | wc -l", 
        "git rev-list HEAD | wc -l")
    7. How many different projects do you manage using GIT?
    8. Which porcelains do you use?
       (zero or more: multiple choice)
    -  core-git, cogito, StGIT, pg, guilt, other
    9. Which git GUI do you use
       (zero or more: multiple choice)
    -  gitk, git-gui, qgit, gitview, giggle, other
   10. Which git web interface do you use for your projects?
    -  gitweb/cgit/wit (Ruby)/git-php/other
   11. How do you publish/propagate your changes?
       (zero or more: multiple choice)
    -  push, pull request, format-patch + email, bundle, other
   12. Does git.git repository include code produced by you?
    -  yes/no

Internationalization
    1. Is translating GIT required for wider adoption?
    -  yes/no/somewhat
    2. What do you need translated?
       (zero or more: multiple choice)
    -  GUI (git-gui, gitk, qgit, ...), git-core messages,
        manpages, other documentation
    3. For what language do you need translation for?

What you think of GIT

    1. Overall, how happy are you with GIT?
    -  unhappy/not so happy/happy/very happy/completely extatic
    2. How does GIT compare to other SCM tools you have used?
    -  worse/equal (or comparable)/better
    3. What do you like about using GIT?
    4. What would you most like to see improved about GIT?
       (features, bugs, plugins, documentation, ...)
    5. If you want to see GIT more widely used, what do you
       think we could do to make this happen?

Documentation

    1. Do you use the GIT wiki?
    -  yes/no
    2. Do you find GIT wiki useful?
    -  yes/no/somewhat
    3. Do you contribute to GIT wiki?
    -  yes/no/only corrections or spam removal
    4. Do you find GIT's online help (homepage, documentation) useful?
    -  yes/no/somewhat
    5. Do you find help distributed with GIT useful
       (manpages, manual, tutorial, HOWTO, release notes)?
    -  yes/no/somewhat
    6. Do you contribute to GIT documentation?
    -  yes/no
    7. What is your favourite user documentation for any software
       projects or products you have used?
    8. What could be improved on the GIT homepage?

Getting help, staying in touch

    1. Have you tried to get GIT help from other people?
    -  yes/no
    2. If yes, did you get these problems resolved quickly
       and to your liking?
    -  yes/no
    3. Do you subscribe to the mailing list?
    -  yes/no
    4. Do you read the mailing list? What method do you use?
    -  subscribed/news interface/RSS interface/archives/
       /post + reply-to request/digests/I don't read it
    5. If yes, do you find it useful?
    -  yes/no (optional)
    6. Do you find traffic levels on GIT mailing list OK.
    -  yes/no? (optional)
    7. Do you use the IRC channel (#git on irc.freenode.net)?
    -  yes/no
    8. If yes, do you find IRC channel useful?
    -  yes/no (optional)

Open forum

    1. What other comments or suggestions do you have that are not
       covered by the questions above?

-- 
Jakub Narebski
Poland

^ 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