Merge branch 'jk/unused'

Code cleanup.

* jk/unused:
  dir.c: drop unused "untracked" from treat_path_fast()
  sequencer: handle ignore_footer when parsing trailers
  test-advise: check argument count with argc instead of argv
  sparse-checkout: fill in some options boilerplate
  sequencer: drop repository argument from run_git_commit()
  push: drop unused repo argument to do_push()
  assert PARSE_OPT_NONEG in parse-options callbacks
  env--helper: write to opt->value in parseopt helper
  drop unused argc parameters
  convert: drop unused crlf_action from check_global_conv_flags_eol()
diff --git a/.gitignore b/.gitignore
index 800b812..6232d33 100644
--- a/.gitignore
+++ b/.gitignore
@@ -242,3 +242,4 @@
 /git.VC.VC.opendb
 /git.VC.db
 *.dSYM
+/contrib/buildsystems/out
diff --git a/Documentation/RelNotes/2.29.0.txt b/Documentation/RelNotes/2.29.0.txt
index e430392..41a78a4 100644
--- a/Documentation/RelNotes/2.29.0.txt
+++ b/Documentation/RelNotes/2.29.0.txt
@@ -98,6 +98,18 @@
 
  * The transport protocol v2 has become the default again.
 
+ * The installation procedure learned to optionally omit "git-foo"
+   executable files for each 'foo' built-in subcommand, which are only
+   required by old timers that still rely on the age old promise that
+   prepending "git --exec-path" output to PATH early in their script
+   will keep the "git-foo" calls they wrote working.
+
+ * The command line completion (in contrib/) learned that "git restore
+   -s <TAB>" is often followed by a refname.
+
+ * "git shortlog" has been taught to group commits by the contents of
+   the trailer lines, like "Reviewed-by:", "Coauthored-by:", etc.
+
 
 Performance, Internal Implementation, Development Support etc.
 
@@ -409,6 +421,26 @@
    pull.ff configuration variable.
    (merge 54200cef86 ah/pull later to maint).
 
+ * Compilation fix around type punning.
+   (merge 176380fd11 jk/drop-unaligned-loads later to maint).
+
+ * "git blame --ignore-rev/--ignore-revs-file" failed to validate
+   their input are valid revision, and failed to take into account
+   that the user may want to give an annotated tag instead of a
+   commit, which has been corrected.
+   (merge 610e2b9240 jc/blame-ignore-fix later to maint).
+
+ * "git bisect start X Y", when X and Y are not valid committish
+   object names, should take X and Y as pathspec, but didn't.
+   (merge 73c6de06af cc/bisect-start-fix later to maint).
+
+ * The explanation of the "scissors line" has been clarified.
+   (merge 287416dba6 eg/mailinfo-doc-scissors later to maint).
+
+ * A race that leads to an access to a free'd data was corrected in
+   the codepath that reads pack files.
+   (merge bda959c476 mt/delta-base-cache-races later to maint).
+
  * Other code cleanup, docfix, build fix, etc.
    (merge 84544f2ea3 sk/typofixes later to maint).
    (merge b17f411ab5 ar/help-guides-doc later to maint).
@@ -440,3 +472,4 @@
    (merge 324efcf6b6 pw/add-p-leakfix later to maint).
    (merge 1c6ffb546b jk/add-i-fixes later to maint).
    (merge e40e936551 cd/commit-graph-doc later to maint).
+   (merge 0512eabd91 jc/sequencer-stopped-sha-simplify later to maint).
diff --git a/Documentation/config/fmt-merge-msg.txt b/Documentation/config/fmt-merge-msg.txt
index a8e8f74..3fbf40e 100644
--- a/Documentation/config/fmt-merge-msg.txt
+++ b/Documentation/config/fmt-merge-msg.txt
@@ -13,7 +13,7 @@
 	By adding a glob that matches the names of integration
 	branches to this multi-valued configuration variable, the
 	default merge message computed for merges into these
-	integration branches will omit " into <branch name>" from
+	integration branches will omit "into <branch name>" from
 	its title.
 +
 An element with an empty value can be used to clear the list
diff --git a/Documentation/config/uploadpack.txt b/Documentation/config/uploadpack.txt
index ee7b3ac..b0d7612 100644
--- a/Documentation/config/uploadpack.txt
+++ b/Documentation/config/uploadpack.txt
@@ -70,7 +70,7 @@
 	kinds must be allowed. Defaults to `uploadpackfilter.allow`.
 
 uploadpackfilter.tree.maxDepth::
-	Only allow `--filter=tree=<n>` when `n` is no more than the value of
+	Only allow `--filter=tree:<n>` when `<n>` is no more than the value of
 	`uploadpackfilter.tree.maxDepth`. If set, this also implies
 	`uploadpackfilter.tree.allow=true`, unless this configuration
 	variable had already been set. Has no effect if unset.
diff --git a/Documentation/git-mailinfo.txt b/Documentation/git-mailinfo.txt
index 3bbc731..7a6aed0 100644
--- a/Documentation/git-mailinfo.txt
+++ b/Documentation/git-mailinfo.txt
@@ -72,10 +72,9 @@
 	is useful in order to associate commits with mailing list discussions.
 
 --scissors::
-	Remove everything in body before a scissors line.  A line that
-	mainly consists of scissors (either ">8" or "8<") and perforation
-	(dash "-") marks is called a scissors line, and is used to request
-	the reader to cut the message at that line.  If such a line
+	Remove everything in body before a scissors line (e.g. "-- >8 --").
+	The line represents scissors and perforation marks, and is used to
+	request the reader to cut the message at that line.  If that line
 	appears in the body of the message before the patch, everything
 	before it (including the scissors line itself) is ignored when
 	this option is used.
diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt
index a72ea7f..fd93cd4 100644
--- a/Documentation/git-shortlog.txt
+++ b/Documentation/git-shortlog.txt
@@ -47,9 +47,38 @@
 
 	Each pretty-printed commit will be rewrapped before it is shown.
 
+--group=<type>::
+	Group commits based on `<type>`. If no `--group` option is
+	specified, the default is `author`. `<type>` is one of:
++
+--
+ - `author`, commits are grouped by author
+ - `committer`, commits are grouped by committer (the same as `-c`)
+ - `trailer:<field>`, the `<field>` is interpreted as a case-insensitive
+   commit message trailer (see linkgit:git-interpret-trailers[1]). For
+   example, if your project uses `Reviewed-by` trailers, you might want
+   to see who has been reviewing with
+   `git shortlog -ns --group=trailer:reviewed-by`.
++
+Note that commits that do not include the trailer will not be counted.
+Likewise, commits with multiple trailers (e.g., multiple signoffs) may
+be counted more than once (but only once per unique trailer value in
+that commit).
++
+Shortlog will attempt to parse each trailer value as a `name <email>`
+identity. If successful, the mailmap is applied and the email is omitted
+unless the `--email` option is specified. If the value cannot be parsed
+as an identity, it will be taken literally and completely.
+--
++
+If `--group` is specified multiple times, commits are counted under each
+value (but again, only once per unique value in that commit). For
+example, `git shortlog --group=author --group=trailer:co-authored-by`
+counts both authors and co-authors.
+
 -c::
 --committer::
-	Collect and show committer identities instead of authors.
+	This is an alias for `--group=committer`.
 
 -w[<width>[,<indent1>[,<indent2>]]]::
 	Linewrap the output by wrapping each line at `width`.  The first
diff --git a/Makefile b/Makefile
index de53954..fb521da 100644
--- a/Makefile
+++ b/Makefile
@@ -348,6 +348,9 @@
 # Define NO_INSTALL_HARDLINKS if you prefer to use either symbolic links or
 # copies to install built-in git commands e.g. git-cat-file.
 #
+# Define SKIP_DASHED_BUILT_INS if you do not need the dashed versions of the
+# built-ins to be linked/copied at all.
+#
 # Define USE_NED_ALLOCATOR if you want to replace the platforms default
 # memory allocators with the nedmalloc allocator written by Niall Douglas.
 #
@@ -775,6 +778,16 @@
 # what 'all' will build and 'install' will install in gitexecdir,
 # excluding programs for built-in commands
 ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
+ALL_COMMANDS_TO_INSTALL = $(ALL_PROGRAMS)
+ifeq (,$(SKIP_DASHED_BUILT_INS))
+ALL_COMMANDS_TO_INSTALL += $(BUILT_INS)
+else
+# git-upload-pack, git-receive-pack and git-upload-archive are special: they
+# are _expected_ to be present in the `bin/` directory in their dashed form.
+ALL_COMMANDS_TO_INSTALL += git-receive-pack$(X)
+ALL_COMMANDS_TO_INSTALL += git-upload-archive$(X)
+ALL_COMMANDS_TO_INSTALL += git-upload-pack$(X)
+endif
 
 # what 'all' will build but not install in gitexecdir
 OTHER_PROGRAMS = git$X
@@ -1219,7 +1232,6 @@
 BASIC_CFLAGS += -fsanitize=$(SANITIZE) -fno-sanitize-recover=$(SANITIZE)
 BASIC_CFLAGS += -fno-omit-frame-pointer
 ifneq ($(filter undefined,$(SANITIZERS)),)
-BASIC_CFLAGS += -DNO_UNALIGNED_LOADS
 BASIC_CFLAGS += -DSHA1DC_FORCE_ALIGNED_ACCESS
 endif
 ifneq ($(filter leak,$(SANITIZERS)),)
@@ -2089,9 +2101,9 @@
 	$(MAKE) PROFILE=USE all
 
 
-all:: $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS
+all:: $(ALL_COMMANDS_TO_INSTALL) $(SCRIPT_LIB) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS
 ifneq (,$X)
-	$(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), test -d '$p' -o '$p' -ef '$p$X' || $(RM) '$p';)
+	$(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) git$X)), test -d '$p' -o '$p' -ef '$p$X' || $(RM) '$p';)
 endif
 
 all::
@@ -2922,15 +2934,8 @@
 	# have already been rolled up into the exe's pdb file.
 	# We DO NOT have pdb files for the builtin commands (like git-status.exe)
 	# because it is just a copy/hardlink of git.exe, rather than a unique binary.
-	$(INSTALL) git.pdb '$(DESTDIR_SQ)$(bindir_SQ)'
-	$(INSTALL) git-shell.pdb '$(DESTDIR_SQ)$(bindir_SQ)'
-	$(INSTALL) git-daemon.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
-	$(INSTALL) git-http-backend.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
-	$(INSTALL) git-http-fetch.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
-	$(INSTALL) git-http-push.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
-	$(INSTALL) git-imap-send.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
-	$(INSTALL) git-remote-http.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
-	$(INSTALL) git-sh-i18n--envsubst.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
+	$(INSTALL) $(patsubst %.exe,%.pdb,$(filter-out $(BUILT_INS),$(patsubst %,%$X,$(BINDIR_PROGRAMS_NEED_X)))) '$(DESTDIR_SQ)$(bindir_SQ)'
+	$(INSTALL) $(patsubst %.exe,%.pdb,$(filter-out $(BUILT_INS) $(REMOTE_CURL_ALIASES),$(PROGRAMS))) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
 ifndef DEBUG
 	$(INSTALL) $(vcpkg_rel_bin)/*.dll '$(DESTDIR_SQ)$(bindir_SQ)'
 	$(INSTALL) $(vcpkg_rel_bin)/*.pdb '$(DESTDIR_SQ)$(bindir_SQ)'
@@ -2958,7 +2963,7 @@
 	$(MAKE) -C git-gui gitexecdir='$(gitexec_instdir_SQ)' install
 endif
 ifneq (,$X)
-	$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), test '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p' -ef '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p$X' || $(RM) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p';)
+	$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) git$X)), test '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p' -ef '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p$X' || $(RM) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p';)
 endif
 
 	bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
@@ -2976,21 +2981,27 @@
 	} && \
 	for p in $(filter $(install_bindir_programs),$(BUILT_INS)); do \
 		$(RM) "$$bindir/$$p" && \
-		test -n "$(INSTALL_SYMLINKS)" && \
-		ln -s "git$X" "$$bindir/$$p" || \
-		{ test -z "$(NO_INSTALL_HARDLINKS)" && \
-		  ln "$$bindir/git$X" "$$bindir/$$p" 2>/dev/null || \
-		  ln -s "git$X" "$$bindir/$$p" 2>/dev/null || \
-		  cp "$$bindir/git$X" "$$bindir/$$p" || exit; } \
+		if test -z "$(SKIP_DASHED_BUILT_INS)"; \
+		then \
+			test -n "$(INSTALL_SYMLINKS)" && \
+			ln -s "git$X" "$$bindir/$$p" || \
+			{ test -z "$(NO_INSTALL_HARDLINKS)" && \
+			  ln "$$bindir/git$X" "$$bindir/$$p" 2>/dev/null || \
+			  ln -s "git$X" "$$bindir/$$p" 2>/dev/null || \
+			  cp "$$bindir/git$X" "$$bindir/$$p" || exit; }; \
+		fi \
 	done && \
 	for p in $(BUILT_INS); do \
 		$(RM) "$$execdir/$$p" && \
-		test -n "$(INSTALL_SYMLINKS)" && \
-		ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/git$X" "$$execdir/$$p" || \
-		{ test -z "$(NO_INSTALL_HARDLINKS)" && \
-		  ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \
-		  ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \
-		  cp "$$execdir/git$X" "$$execdir/$$p" || exit; } \
+		if test -z "$(SKIP_DASHED_BUILT_INS)"; \
+		then \
+			test -n "$(INSTALL_SYMLINKS)" && \
+			ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/git$X" "$$execdir/$$p" || \
+			{ test -z "$(NO_INSTALL_HARDLINKS)" && \
+			  ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \
+			  ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \
+			  cp "$$execdir/git$X" "$$execdir/$$p" || exit; }; \
+		fi \
 	done && \
 	remote_curl_aliases="$(REMOTE_CURL_ALIASES)" && \
 	for p in $$remote_curl_aliases; do \
@@ -3084,7 +3095,7 @@
 OTHER_PROGRAMS += $(shell echo *.dll t/helper/*.dll)
 endif
 
-artifacts-tar:: $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS) \
+artifacts-tar:: $(ALL_COMMANDS_TO_INSTALL) $(SCRIPT_LIB) $(OTHER_PROGRAMS) \
 		GIT-BUILD-OPTIONS $(TEST_PROGRAMS) $(test_bindir_programs) \
 		$(MOFILES)
 	$(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1) \
@@ -3179,7 +3190,7 @@
 
 ### Check documentation
 #
-ALL_COMMANDS = $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS)
+ALL_COMMANDS = $(ALL_COMMANDS_TO_INSTALL) $(SCRIPT_LIB)
 ALL_COMMANDS += git
 ALL_COMMANDS += git-citool
 ALL_COMMANDS += git-gui
@@ -3219,7 +3230,7 @@
 		    -e 's/\.txt//'; \
 	) | while read how cmd; \
 	do \
-		case " $(patsubst %$X,%,$(ALL_COMMANDS) $(EXCLUDED_PROGRAMS)) " in \
+		case " $(patsubst %$X,%,$(ALL_COMMANDS) $(BUILT_INS) $(EXCLUDED_PROGRAMS)) " in \
 		*" $$cmd "*)	;; \
 		*) echo "removed but $$how: $$cmd" ;; \
 		esac; \
diff --git a/bisect.c b/bisect.c
index d42a3a3..f5b1368 100644
--- a/bisect.c
+++ b/bisect.c
@@ -988,8 +988,11 @@
  * the bisection process finished successfully.
  * In this case the calling function or command should not turn a
  * BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND return code into an error or a non zero exit code.
- * If no_checkout is non-zero, the bisection process does not
- * checkout the trial commit but instead simply updates BISECT_HEAD.
+ *
+ * Checking BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND
+ * in bisect_helper::bisect_next() and only transforming it to 0 at
+ * the end of bisect_helper::cmd_bisect__helper() helps bypassing
+ * all the code related to finding a commit to test.
  */
 enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
 {
@@ -999,6 +1002,10 @@
 	enum bisect_error res = BISECT_OK;
 	struct object_id *bisect_rev;
 	char *steps_msg;
+	/*
+	 * If no_checkout is non-zero, the bisection process does not
+	 * checkout the trial commit but instead simply updates BISECT_HEAD.
+	 */
 	int no_checkout = ref_exists("BISECT_HEAD");
 	unsigned bisect_flags = 0;
 
@@ -1082,6 +1089,8 @@
 		  "Bisecting: %d revisions left to test after this %s\n",
 		  nr), nr, steps_msg);
 	free(steps_msg);
+	/* Clean up objects used, as they will be reused. */
+	clear_commit_marks_all(ALL_REV_FLAGS);
 
 	return bisect_checkout(bisect_rev, no_checkout);
 }
diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
index 7dcc1b5..7512b88 100644
--- a/builtin/bisect--helper.c
+++ b/builtin/bisect--helper.c
@@ -8,6 +8,7 @@
 #include "run-command.h"
 #include "prompt.h"
 #include "quote.h"
+#include "revision.h"
 
 static GIT_PATH_FUNC(git_path_bisect_terms, "BISECT_TERMS")
 static GIT_PATH_FUNC(git_path_bisect_expected_rev, "BISECT_EXPECTED_REV")
@@ -29,9 +30,17 @@
 	N_("git bisect--helper --bisect-terms [--term-good | --term-old | --term-bad | --term-new]"),
 	N_("git bisect--helper --bisect-start [--term-{new,bad}=<term> --term-{old,good}=<term>]"
 					    " [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<paths>...]"),
+	N_("git bisect--helper --bisect-next"),
+	N_("git bisect--helper --bisect-auto-next"),
+	N_("git bisect--helper --bisect-autostart"),
 	NULL
 };
 
+struct add_bisect_ref_data {
+	struct rev_info *revs;
+	unsigned int object_flags;
+};
+
 struct bisect_terms {
 	char *term_good;
 	char *term_bad;
@@ -55,6 +64,8 @@
 static const char vocab_bad[] = "bad|new";
 static const char vocab_good[] = "good|old";
 
+static int bisect_autostart(struct bisect_terms *terms);
+
 /*
  * Check whether the string `term` belongs to the set of strings
  * included in the variable arguments.
@@ -74,6 +85,52 @@
 	return res;
 }
 
+static int write_in_file(const char *path, const char *mode, const char *format, va_list args)
+{
+	FILE *fp = NULL;
+	int res = 0;
+
+	if (strcmp(mode, "w") && strcmp(mode, "a"))
+		BUG("write-in-file does not support '%s' mode", mode);
+	fp = fopen(path, mode);
+	if (!fp)
+		return error_errno(_("cannot open file '%s' in mode '%s'"), path, mode);
+	res = vfprintf(fp, format, args);
+
+	if (res < 0) {
+		int saved_errno = errno;
+		fclose(fp);
+		errno = saved_errno;
+		return error_errno(_("could not write to file '%s'"), path);
+	}
+
+	return fclose(fp);
+}
+
+static int write_to_file(const char *path, const char *format, ...)
+{
+	int res;
+	va_list args;
+
+	va_start(args, format);
+	res = write_in_file(path, "w", format, args);
+	va_end(args);
+
+	return res;
+}
+
+static int append_to_file(const char *path, const char *format, ...)
+{
+	int res;
+	va_list args;
+
+	va_start(args, format);
+	res = write_in_file(path, "a", format, args);
+	va_end(args);
+
+	return res;
+}
+
 static int check_term_format(const char *term, const char *orig_term)
 {
 	int res;
@@ -104,7 +161,6 @@
 
 static int write_terms(const char *bad, const char *good)
 {
-	FILE *fp = NULL;
 	int res;
 
 	if (!strcmp(bad, good))
@@ -113,13 +169,9 @@
 	if (check_term_format(bad, "bad") || check_term_format(good, "good"))
 		return -1;
 
-	fp = fopen(git_path_bisect_terms(), "w");
-	if (!fp)
-		return error_errno(_("could not open the file BISECT_TERMS"));
+	res = write_to_file(git_path_bisect_terms(), "%s\n%s\n", bad, good);
 
-	res = fprintf(fp, "%s\n%s\n", bad, good);
-	res |= fclose(fp);
-	return (res < 0) ? -1 : 0;
+	return res;
 }
 
 static int is_expected_rev(const char *expected_hex)
@@ -421,6 +473,142 @@
 	return res;
 }
 
+static int add_bisect_ref(const char *refname, const struct object_id *oid,
+			  int flags, void *cb)
+{
+	struct add_bisect_ref_data *data = cb;
+
+	add_pending_oid(data->revs, refname, oid, data->object_flags);
+
+	return 0;
+}
+
+static int prepare_revs(struct bisect_terms *terms, struct rev_info *revs)
+{
+	int res = 0;
+	struct add_bisect_ref_data cb = { revs };
+	char *good = xstrfmt("%s-*", terms->term_good);
+
+	/*
+	 * We cannot use terms->term_bad directly in
+	 * for_each_glob_ref_in() and we have to append a '*' to it,
+	 * otherwise for_each_glob_ref_in() will append '/' and '*'.
+	 */
+	char *bad = xstrfmt("%s*", terms->term_bad);
+
+	/*
+	 * It is important to reset the flags used by revision walks
+	 * as the previous call to bisect_next_all() in turn
+	 * sets up a revision walk.
+	 */
+	reset_revision_walk();
+	init_revisions(revs, NULL);
+	setup_revisions(0, NULL, revs, NULL);
+	for_each_glob_ref_in(add_bisect_ref, bad, "refs/bisect/", &cb);
+	cb.object_flags = UNINTERESTING;
+	for_each_glob_ref_in(add_bisect_ref, good, "refs/bisect/", &cb);
+	if (prepare_revision_walk(revs))
+		res = error(_("revision walk setup failed\n"));
+
+	free(good);
+	free(bad);
+	return res;
+}
+
+static int bisect_skipped_commits(struct bisect_terms *terms)
+{
+	int res;
+	FILE *fp = NULL;
+	struct rev_info revs;
+	struct commit *commit;
+	struct pretty_print_context pp = {0};
+	struct strbuf commit_name = STRBUF_INIT;
+
+	res = prepare_revs(terms, &revs);
+	if (res)
+		return res;
+
+	fp = fopen(git_path_bisect_log(), "a");
+	if (!fp)
+		return error_errno(_("could not open '%s' for appending"),
+				  git_path_bisect_log());
+
+	if (fprintf(fp, "# only skipped commits left to test\n") < 0)
+		return error_errno(_("failed to write to '%s'"), git_path_bisect_log());
+
+	while ((commit = get_revision(&revs)) != NULL) {
+		strbuf_reset(&commit_name);
+		format_commit_message(commit, "%s",
+				      &commit_name, &pp);
+		fprintf(fp, "# possible first %s commit: [%s] %s\n",
+			terms->term_bad, oid_to_hex(&commit->object.oid),
+			commit_name.buf);
+	}
+
+	/*
+	 * Reset the flags used by revision walks in case
+	 * there is another revision walk after this one.
+	 */
+	reset_revision_walk();
+
+	strbuf_release(&commit_name);
+	fclose(fp);
+	return 0;
+}
+
+static int bisect_successful(struct bisect_terms *terms)
+{
+	struct object_id oid;
+	struct commit *commit;
+	struct pretty_print_context pp = {0};
+	struct strbuf commit_name = STRBUF_INIT;
+	char *bad_ref = xstrfmt("refs/bisect/%s",terms->term_bad);
+	int res;
+
+	read_ref(bad_ref, &oid);
+	commit = lookup_commit_reference_by_name(bad_ref);
+	format_commit_message(commit, "%s", &commit_name, &pp);
+
+	res = append_to_file(git_path_bisect_log(), "# first %s commit: [%s] %s\n",
+			    terms->term_bad, oid_to_hex(&commit->object.oid),
+			    commit_name.buf);
+
+	strbuf_release(&commit_name);
+	free(bad_ref);
+	return res;
+}
+
+static enum bisect_error bisect_next(struct bisect_terms *terms, const char *prefix)
+{
+	enum bisect_error res;
+
+	if (bisect_autostart(terms))
+		return BISECT_FAILED;
+
+	if (bisect_next_check(terms, terms->term_good))
+		return BISECT_FAILED;
+
+	/* Perform all bisection computation */
+	res = bisect_next_all(the_repository, prefix);
+
+	if (res == BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND) {
+		res = bisect_successful(terms);
+		return res ? res : BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND;
+	} else if (res == BISECT_ONLY_SKIPPED_LEFT) {
+		res = bisect_skipped_commits(terms);
+		return res ? res : BISECT_ONLY_SKIPPED_LEFT;
+	}
+	return res;
+}
+
+static enum bisect_error bisect_auto_next(struct bisect_terms *terms, const char *prefix)
+{
+	if (bisect_next_check(terms, NULL))
+		return BISECT_OK;
+
+	return bisect_next(terms, prefix);
+}
+
 static int bisect_start(struct bisect_terms *terms, const char **argv, int argc)
 {
 	int no_checkout = 0;
@@ -484,14 +672,13 @@
 			terms->term_bad = xstrdup(arg);
 		} else if (starts_with(arg, "--")) {
 			return error(_("unrecognized option: '%s'"), arg);
-		} else {
-			char *commit_id = xstrfmt("%s^{commit}", arg);
-			if (get_oid(commit_id, &oid) && has_double_dash)
-				die(_("'%s' does not appear to be a valid "
-				      "revision"), arg);
-
+		} else if (!get_oidf(&oid, "%s^{commit}", arg)) {
 			string_list_append(&revs, oid_to_hex(&oid));
-			free(commit_id);
+		} else if (has_double_dash) {
+			die(_("'%s' does not appear to be a valid "
+			      "revision"), arg);
+		} else {
+			break;
 		}
 	}
 	pathspec_pos = i;
@@ -624,6 +811,38 @@
 	return res;
 }
 
+static inline int file_is_not_empty(const char *path)
+{
+	return !is_empty_or_missing_file(path);
+}
+
+static int bisect_autostart(struct bisect_terms *terms)
+{
+	int res;
+	const char *yesno;
+
+	if (file_is_not_empty(git_path_bisect_start()))
+		return 0;
+
+	fprintf_ln(stderr, _("You need to start by \"git bisect "
+			  "start\"\n"));
+
+	if (!isatty(STDIN_FILENO))
+		return -1;
+
+	/*
+	 * TRANSLATORS: Make sure to include [Y] and [n] in your
+	 * translation. The program will only accept English input
+	 * at this point.
+	 */
+	yesno = git_prompt(_("Do you want me to do it for you "
+			     "[Y/n]? "), PROMPT_ECHO);
+	res = tolower(*yesno) == 'n' ?
+		-1 : bisect_start(terms, empty_strvec, 0);
+
+	return res;
+}
+
 int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
 {
 	enum {
@@ -636,7 +855,10 @@
 		CHECK_AND_SET_TERMS,
 		BISECT_NEXT_CHECK,
 		BISECT_TERMS,
-		BISECT_START
+		BISECT_START,
+		BISECT_AUTOSTART,
+		BISECT_NEXT,
+		BISECT_AUTO_NEXT
 	} cmdmode = 0;
 	int res = 0, nolog = 0;
 	struct option options[] = {
@@ -660,6 +882,12 @@
 			 N_("print out the bisect terms"), BISECT_TERMS),
 		OPT_CMDMODE(0, "bisect-start", &cmdmode,
 			 N_("start the bisect session"), BISECT_START),
+		OPT_CMDMODE(0, "bisect-next", &cmdmode,
+			 N_("find the next bisection commit"), BISECT_NEXT),
+		OPT_CMDMODE(0, "bisect-auto-next", &cmdmode,
+			 N_("verify the next bisection state then checkout the next bisection commit"), BISECT_AUTO_NEXT),
+		OPT_CMDMODE(0, "bisect-autostart", &cmdmode,
+			 N_("start the bisection if it has not yet been started"), BISECT_AUTOSTART),
 		OPT_BOOL(0, "no-log", &nolog,
 			 N_("no log for BISECT_WRITE")),
 		OPT_END()
@@ -719,8 +947,26 @@
 		set_terms(&terms, "bad", "good");
 		res = bisect_start(&terms, argv, argc);
 		break;
+	case BISECT_NEXT:
+		if (argc)
+			return error(_("--bisect-next requires 0 arguments"));
+		get_terms(&terms);
+		res = bisect_next(&terms, prefix);
+		break;
+	case BISECT_AUTO_NEXT:
+		if (argc)
+			return error(_("--bisect-auto-next requires 0 arguments"));
+		get_terms(&terms);
+		res = bisect_auto_next(&terms, prefix);
+		break;
+	case BISECT_AUTOSTART:
+		if (argc)
+			return error(_("--bisect-autostart does not accept arguments"));
+		set_terms(&terms, "bad", "good");
+		res = bisect_autostart(&terms);
+		break;
 	default:
-		return error("BUG: unknown subcommand '%d'", cmdmode);
+		BUG("unknown subcommand %d", cmdmode);
 	}
 	free_terms(&terms);
 
@@ -728,8 +974,8 @@
 	 * Handle early success
 	 * From check_merge_bases > check_good_are_ancestors_of_bad > bisect_next_all
 	 */
-	if (res == BISECT_INTERNAL_SUCCESS_MERGE_BASE)
+	if ((res == BISECT_INTERNAL_SUCCESS_MERGE_BASE) || (res == BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND))
 		res = BISECT_OK;
 
-	return abs(res);
+	return -res;
 }
diff --git a/builtin/blame.c b/builtin/blame.c
index eb513fb..bb0f293 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -27,6 +27,7 @@
 #include "object-store.h"
 #include "blame.h"
 #include "refs.h"
+#include "tag.h"
 
 static char blame_usage[] = N_("git blame [<options>] [<rev-opts>] [<rev>] [--] <file>");
 
@@ -803,6 +804,26 @@
 	return OBJ_NONE < oid_object_info(the_repository, &oid, NULL);
 }
 
+static int peel_to_commit_oid(struct object_id *oid_ret, void *cbdata)
+{
+	struct repository *r = ((struct blame_scoreboard *)cbdata)->repo;
+	struct object_id oid;
+
+	oidcpy(&oid, oid_ret);
+	while (1) {
+		struct object *obj;
+		int kind = oid_object_info(r, &oid, NULL);
+		if (kind == OBJ_COMMIT) {
+			oidcpy(oid_ret, &oid);
+			return 0;
+		}
+		if (kind != OBJ_TAG)
+			return -1;
+		obj = deref_tag(r, parse_object(r, &oid), NULL, 0);
+		oidcpy(&oid, &obj->oid);
+	}
+}
+
 static void build_ignorelist(struct blame_scoreboard *sb,
 			     struct string_list *ignore_revs_file_list,
 			     struct string_list *ignore_rev_list)
@@ -815,10 +836,12 @@
 		if (!strcmp(i->string, ""))
 			oidset_clear(&sb->ignore_list);
 		else
-			oidset_parse_file(&sb->ignore_list, i->string);
+			oidset_parse_file_carefully(&sb->ignore_list, i->string,
+						    peel_to_commit_oid, sb);
 	}
 	for_each_string_list_item(i, ignore_rev_list) {
-		if (get_oid_committish(i->string, &oid))
+		if (get_oid_committish(i->string, &oid) ||
+		    peel_to_commit_oid(&oid, sb))
 			die(_("cannot find revision %s to ignore"), i->string);
 		oidset_insert(&sb->ignore_list, &oid);
 	}
diff --git a/builtin/diff.c b/builtin/diff.c
index cb98811..cd4083f 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -203,8 +203,7 @@
 		revs->dense_combined_merges = revs->combine_merges = 1;
 	for (i = 1; i < ents; i++)
 		oid_array_append(&parents, &ent[i].item->oid);
-	diff_tree_combined(&ent[0].item->oid, &parents,
-			   revs->dense_combined_merges, revs);
+	diff_tree_combined(&ent[0].item->oid, &parents, revs);
 	oid_array_clear(&parents);
 	return 0;
 }
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 1b8fca3..d2e33f5 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -405,12 +405,12 @@
 {
 	static uint32_t counter = 1; /* avoid null oid */
 	const unsigned hashsz = the_hash_algo->rawsz;
-	unsigned char out[GIT_MAX_RAWSZ];
+	struct object_id oid;
 	char *hex = xmallocz(GIT_MAX_HEXSZ);
 
-	hashclr(out);
-	put_be32(out + hashsz - 4, counter++);
-	return hash_to_hex_algop_r(hex, out, the_hash_algo);
+	oidclr(&oid);
+	put_be32(oid.hash + hashsz - 4, counter++);
+	return oid_to_hex_r(hex, &oid);
 }
 
 static const char *anonymize_oid(const char *oid_hex)
@@ -1026,7 +1026,7 @@
 				/*
 				 * Getting here means we have a commit which
 				 * was excluded by a negative refspec (e.g.
-				 * fast-export ^master master).  If we are
+				 * fast-export ^HEAD HEAD).  If we are
 				 * referencing excluded commits, set the ref
 				 * to the exact commit.  Otherwise, the user
 				 * wants the branch exported but every commit
diff --git a/builtin/log.c b/builtin/log.c
index b8824d8..7f27e9e 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -1195,6 +1195,7 @@
 	log.in1 = 2;
 	log.in2 = 4;
 	log.file = rev->diffopt.file;
+	log.groups = SHORTLOG_GROUP_AUTHOR;
 	for (i = 0; i < nr; i++)
 		shortlog_add_commit(&log, list[i]);
 
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index c856c58..0a5c496 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -9,6 +9,7 @@
 #include "mailmap.h"
 #include "shortlog.h"
 #include "parse-options.h"
+#include "trailer.h"
 
 static char const * const shortlog_usage[] = {
 	N_("git shortlog [<options>] [<revision-range>] [[--] <path>...]"),
@@ -49,12 +50,12 @@
 }
 
 static void insert_one_record(struct shortlog *log,
-			      const char *author,
+			      const char *ident,
 			      const char *oneline)
 {
 	struct string_list_item *item;
 
-	item = string_list_insert(&log->list, author);
+	item = string_list_insert(&log->list, ident);
 
 	if (log->summary)
 		item->util = (void *)(UTIL_TO_INT(item) + 1);
@@ -97,8 +98,8 @@
 	}
 }
 
-static int parse_stdin_author(struct shortlog *log,
-			       struct strbuf *out, const char *in)
+static int parse_ident(struct shortlog *log,
+		       struct strbuf *out, const char *in)
 {
 	const char *mailbuf, *namebuf;
 	size_t namelen, maillen;
@@ -122,18 +123,33 @@
 
 static void read_from_stdin(struct shortlog *log)
 {
-	struct strbuf author = STRBUF_INIT;
-	struct strbuf mapped_author = STRBUF_INIT;
+	struct strbuf ident = STRBUF_INIT;
+	struct strbuf mapped_ident = STRBUF_INIT;
 	struct strbuf oneline = STRBUF_INIT;
 	static const char *author_match[2] = { "Author: ", "author " };
 	static const char *committer_match[2] = { "Commit: ", "committer " };
 	const char **match;
 
-	match = log->committer ? committer_match : author_match;
-	while (strbuf_getline_lf(&author, stdin) != EOF) {
+	if (HAS_MULTI_BITS(log->groups))
+		die(_("using multiple --group options with stdin is not supported"));
+
+	switch (log->groups) {
+	case SHORTLOG_GROUP_AUTHOR:
+		match = author_match;
+		break;
+	case SHORTLOG_GROUP_COMMITTER:
+		match = committer_match;
+		break;
+	case SHORTLOG_GROUP_TRAILER:
+		die(_("using --group=trailer with stdin is not supported"));
+	default:
+		BUG("unhandled shortlog group");
+	}
+
+	while (strbuf_getline_lf(&ident, stdin) != EOF) {
 		const char *v;
-		if (!skip_prefix(author.buf, match[0], &v) &&
-		    !skip_prefix(author.buf, match[1], &v))
+		if (!skip_prefix(ident.buf, match[0], &v) &&
+		    !skip_prefix(ident.buf, match[1], &v))
 			continue;
 		while (strbuf_getline_lf(&oneline, stdin) != EOF &&
 		       oneline.len)
@@ -142,23 +158,118 @@
 		       !oneline.len)
 			; /* discard blanks */
 
-		strbuf_reset(&mapped_author);
-		if (parse_stdin_author(log, &mapped_author, v) < 0)
+		strbuf_reset(&mapped_ident);
+		if (parse_ident(log, &mapped_ident, v) < 0)
 			continue;
 
-		insert_one_record(log, mapped_author.buf, oneline.buf);
+		insert_one_record(log, mapped_ident.buf, oneline.buf);
 	}
-	strbuf_release(&author);
-	strbuf_release(&mapped_author);
+	strbuf_release(&ident);
+	strbuf_release(&mapped_ident);
 	strbuf_release(&oneline);
 }
 
+struct strset_item {
+	struct hashmap_entry ent;
+	char value[FLEX_ARRAY];
+};
+
+struct strset {
+	struct hashmap map;
+};
+
+#define STRSET_INIT { { NULL } }
+
+static int strset_item_hashcmp(const void *hash_data,
+			       const struct hashmap_entry *entry,
+			       const struct hashmap_entry *entry_or_key,
+			       const void *keydata)
+{
+	const struct strset_item *a, *b;
+
+	a = container_of(entry, const struct strset_item, ent);
+	if (keydata)
+		return strcmp(a->value, keydata);
+
+	b = container_of(entry_or_key, const struct strset_item, ent);
+	return strcmp(a->value, b->value);
+}
+
+/*
+ * Adds "str" to the set if it was not already present; returns true if it was
+ * already there.
+ */
+static int strset_check_and_add(struct strset *ss, const char *str)
+{
+	unsigned int hash = strhash(str);
+	struct strset_item *item;
+
+	if (!ss->map.table)
+		hashmap_init(&ss->map, strset_item_hashcmp, NULL, 0);
+
+	if (hashmap_get_from_hash(&ss->map, hash, str))
+		return 1;
+
+	FLEX_ALLOC_STR(item, value, str);
+	hashmap_entry_init(&item->ent, hash);
+	hashmap_add(&ss->map, &item->ent);
+	return 0;
+}
+
+static void strset_clear(struct strset *ss)
+{
+	if (!ss->map.table)
+		return;
+	hashmap_free_entries(&ss->map, struct strset_item, ent);
+}
+
+static void insert_records_from_trailers(struct shortlog *log,
+					 struct strset *dups,
+					 struct commit *commit,
+					 struct pretty_print_context *ctx,
+					 const char *oneline)
+{
+	struct trailer_iterator iter;
+	const char *commit_buffer, *body;
+	struct strbuf ident = STRBUF_INIT;
+
+	/*
+	 * Using format_commit_message("%B") would be simpler here, but
+	 * this saves us copying the message.
+	 */
+	commit_buffer = logmsg_reencode(commit, NULL, ctx->output_encoding);
+	body = strstr(commit_buffer, "\n\n");
+	if (!body)
+		return;
+
+	trailer_iterator_init(&iter, body);
+	while (trailer_iterator_advance(&iter)) {
+		const char *value = iter.val.buf;
+
+		if (!string_list_has_string(&log->trailers, iter.key.buf))
+			continue;
+
+		strbuf_reset(&ident);
+		if (!parse_ident(log, &ident, value))
+			value = ident.buf;
+
+		if (strset_check_and_add(dups, value))
+			continue;
+		insert_one_record(log, value, oneline);
+	}
+	trailer_iterator_release(&iter);
+
+	strbuf_release(&ident);
+	unuse_commit_buffer(commit, commit_buffer);
+}
+
 void shortlog_add_commit(struct shortlog *log, struct commit *commit)
 {
-	struct strbuf author = STRBUF_INIT;
+	struct strbuf ident = STRBUF_INIT;
 	struct strbuf oneline = STRBUF_INIT;
+	struct strset dups = STRSET_INIT;
 	struct pretty_print_context ctx = {0};
-	const char *fmt;
+	const char *oneline_str;
 
 	ctx.fmt = CMIT_FMT_USERFORMAT;
 	ctx.abbrev = log->abbrev;
@@ -166,21 +277,38 @@
 	ctx.date_mode.type = DATE_NORMAL;
 	ctx.output_encoding = get_log_output_encoding();
 
-	fmt = log->committer ?
-		(log->email ? "%cN <%cE>" : "%cN") :
-		(log->email ? "%aN <%aE>" : "%aN");
-
-	format_commit_message(commit, fmt, &author, &ctx);
 	if (!log->summary) {
 		if (log->user_format)
 			pretty_print_commit(&ctx, commit, &oneline);
 		else
 			format_commit_message(commit, "%s", &oneline, &ctx);
 	}
+	oneline_str = oneline.len ? oneline.buf : "<none>";
 
-	insert_one_record(log, author.buf, oneline.len ? oneline.buf : "<none>");
+	if (log->groups & SHORTLOG_GROUP_AUTHOR) {
+		strbuf_reset(&ident);
+		format_commit_message(commit,
+				      log->email ? "%aN <%aE>" : "%aN",
+				      &ident, &ctx);
+		if (!HAS_MULTI_BITS(log->groups) ||
+		    !strset_check_and_add(&dups, ident.buf))
+			insert_one_record(log, ident.buf, oneline_str);
+	}
+	if (log->groups & SHORTLOG_GROUP_COMMITTER) {
+		strbuf_reset(&ident);
+		format_commit_message(commit,
+				      log->email ? "%cN <%cE>" : "%cN",
+				      &ident, &ctx);
+		if (!HAS_MULTI_BITS(log->groups) ||
+		    !strset_check_and_add(&dups, ident.buf))
+			insert_one_record(log, ident.buf, oneline_str);
+	}
+	if (log->groups & SHORTLOG_GROUP_TRAILER) {
+		insert_records_from_trailers(log, &dups, commit, &ctx, oneline_str);
+	}
 
-	strbuf_release(&author);
+	strset_clear(&dups);
+	strbuf_release(&ident);
 	strbuf_release(&oneline);
 }
 
@@ -241,6 +369,28 @@
 	return 0;
 }
 
+static int parse_group_option(const struct option *opt, const char *arg, int unset)
+{
+	struct shortlog *log = opt->value;
+	const char *field;
+
+	if (unset) {
+		log->groups = 0;
+		string_list_clear(&log->trailers, 0);
+	} else if (!strcasecmp(arg, "author"))
+		log->groups |= SHORTLOG_GROUP_AUTHOR;
+	else if (!strcasecmp(arg, "committer"))
+		log->groups |= SHORTLOG_GROUP_COMMITTER;
+	else if (skip_prefix(arg, "trailer:", &field)) {
+		log->groups |= SHORTLOG_GROUP_TRAILER;
+		string_list_append(&log->trailers, field);
+	} else
+		return error(_("unknown group type: %s"), arg);
+
+	return 0;
+}
+
+
 void shortlog_init(struct shortlog *log)
 {
 	memset(log, 0, sizeof(*log));
@@ -251,6 +401,8 @@
 	log->wrap = DEFAULT_WRAPLEN;
 	log->in1 = DEFAULT_INDENT1;
 	log->in2 = DEFAULT_INDENT2;
+	log->trailers.strdup_strings = 1;
+	log->trailers.cmp = strcasecmp;
 }
 
 int cmd_shortlog(int argc, const char **argv, const char *prefix)
@@ -260,8 +412,9 @@
 	int nongit = !startup_info->have_repository;
 
 	const struct option options[] = {
-		OPT_BOOL('c', "committer", &log.committer,
-			 N_("Group by committer rather than author")),
+		OPT_BIT('c', "committer", &log.groups,
+			N_("Group by committer rather than author"),
+			SHORTLOG_GROUP_COMMITTER),
 		OPT_BOOL('n', "numbered", &log.sort_by_number,
 			 N_("sort output according to the number of commits per author")),
 		OPT_BOOL('s', "summary", &log.summary,
@@ -271,6 +424,8 @@
 		OPT_CALLBACK_F('w', NULL, &log, N_("<w>[,<i1>[,<i2>]]"),
 			N_("Linewrap output"), PARSE_OPT_OPTARG,
 			&parse_wrap_args),
+		OPT_CALLBACK(0, "group", &log, N_("field"),
+			N_("Group by field"), parse_group_option),
 		OPT_END(),
 	};
 
@@ -311,6 +466,10 @@
 	log.abbrev = rev.abbrev;
 	log.file = rev.diffopt.file;
 
+	if (!log.groups)
+		log.groups = SHORTLOG_GROUP_AUTHOR;
+	string_list_sort(&log.trailers);
+
 	/* assume HEAD if from a tty */
 	if (!nongit && !rev.pending.nr && isatty(0))
 		add_head_to_pending(&rev);
diff --git a/ci/lib.sh b/ci/lib.sh
index 3eefec5..821e366 100755
--- a/ci/lib.sh
+++ b/ci/lib.sh
@@ -178,6 +178,7 @@
 export DEVELOPER=1
 export DEFAULT_TEST_TARGET=prove
 export GIT_TEST_CLONE_2GB=true
+export SKIP_DASHED_BUILT_INS=YesPlease
 
 case "$jobname" in
 linux-clang|linux-gcc)
diff --git a/combine-diff.c b/combine-diff.c
index 002e0e5..555b812 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -923,7 +923,6 @@
 
 static void show_combined_header(struct combine_diff_path *elem,
 				 int num_parent,
-				 int dense,
 				 struct rev_info *rev,
 				 const char *line_prefix,
 				 int mode_differs,
@@ -939,6 +938,7 @@
 	int added = 0;
 	int deleted = 0;
 	int i;
+	int dense = rev->dense_combined_merges;
 
 	if (rev->loginfo && !rev->no_commit_id)
 		show_log(rev);
@@ -1012,7 +1012,7 @@
 }
 
 static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
-			    int dense, int working_tree_file,
+			    int working_tree_file,
 			    struct rev_info *rev)
 {
 	struct diff_options *opt = &rev->diffopt;
@@ -1145,7 +1145,7 @@
 		}
 	}
 	if (is_binary) {
-		show_combined_header(elem, num_parent, dense, rev,
+		show_combined_header(elem, num_parent, rev,
 				     line_prefix, mode_differs, 0);
 		printf("Binary files differ\n");
 		free(result);
@@ -1200,10 +1200,10 @@
 				     textconv, elem->path, opt->xdl_opts);
 	}
 
-	show_hunks = make_hunks(sline, cnt, num_parent, dense);
+	show_hunks = make_hunks(sline, cnt, num_parent, rev->dense_combined_merges);
 
 	if (show_hunks || mode_differs || working_tree_file) {
-		show_combined_header(elem, num_parent, dense, rev,
+		show_combined_header(elem, num_parent, rev,
 				     line_prefix, mode_differs, 1);
 		dump_sline(sline, line_prefix, cnt, num_parent,
 			   opt->use_color, result_deleted);
@@ -1284,7 +1284,6 @@
  */
 void show_combined_diff(struct combine_diff_path *p,
 		       int num_parent,
-		       int dense,
 		       struct rev_info *rev)
 {
 	struct diff_options *opt = &rev->diffopt;
@@ -1294,7 +1293,7 @@
 				  DIFF_FORMAT_NAME_STATUS))
 		show_raw_diff(p, num_parent, rev);
 	else if (opt->output_format & DIFF_FORMAT_PATCH)
-		show_patch_diff(p, num_parent, dense, 1, rev);
+		show_patch_diff(p, num_parent, 1, rev);
 }
 
 static void free_combined_pair(struct diff_filepair *pair)
@@ -1454,7 +1453,6 @@
 
 void diff_tree_combined(const struct object_id *oid,
 			const struct oid_array *parents,
-			int dense,
 			struct rev_info *rev)
 {
 	struct diff_options *opt = &rev->diffopt;
@@ -1581,8 +1579,7 @@
 				printf("%s%c", diff_line_prefix(opt),
 				       opt->line_termination);
 			for (p = paths; p; p = p->next)
-				show_patch_diff(p, num_parent, dense,
-						0, rev);
+				show_patch_diff(p, num_parent, 0, rev);
 		}
 	}
 
@@ -1600,7 +1597,7 @@
 	clear_pathspec(&diffopts.pathspec);
 }
 
-void diff_tree_combined_merge(const struct commit *commit, int dense,
+void diff_tree_combined_merge(const struct commit *commit,
 			      struct rev_info *rev)
 {
 	struct commit_list *parent = get_saved_parents(rev, commit);
@@ -1610,6 +1607,6 @@
 		oid_array_append(&parents, &parent->item->object.oid);
 		parent = parent->next;
 	}
-	diff_tree_combined(&commit->object.oid, &parents, dense, rev);
+	diff_tree_combined(&commit->object.oid, &parents, rev);
 	oid_array_clear(&parents);
 }
diff --git a/commit-reach.c b/commit-reach.c
index efd5925..50175b1 100644
--- a/commit-reach.c
+++ b/commit-reach.c
@@ -321,7 +321,7 @@
 {
 	struct commit_list *bases;
 	int ret = 0, i;
-	uint32_t generation, min_generation = GENERATION_NUMBER_INFINITY;
+	uint32_t generation, max_generation = GENERATION_NUMBER_ZERO;
 
 	if (repo_parse_commit(r, commit))
 		return ret;
@@ -330,12 +330,12 @@
 			return ret;
 
 		generation = commit_graph_generation(reference[i]);
-		if (generation < min_generation)
-			min_generation = generation;
+		if (generation > max_generation)
+			max_generation = generation;
 	}
 
 	generation = commit_graph_generation(commit);
-	if (generation > min_generation)
+	if (generation > max_generation)
 		return ret;
 
 	bases = paint_down_to_common(r, commit,
diff --git a/compat/bswap.h b/compat/bswap.h
index e4e2573..c0bb744 100644
--- a/compat/bswap.h
+++ b/compat/bswap.h
@@ -145,28 +145,6 @@
 
 #endif
 
-/*
- * Performance might be improved if the CPU architecture is OK with
- * unaligned 32-bit loads and a fast ntohl() is available.
- * Otherwise fall back to byte loads and shifts which is portable,
- * and is faster on architectures with memory alignment issues.
- */
-
-#if !defined(NO_UNALIGNED_LOADS) && ( \
-    defined(__i386__) || defined(__x86_64__) || \
-    defined(_M_IX86) || defined(_M_X64) || \
-    defined(__ppc__) || defined(__ppc64__) || \
-    defined(__powerpc__) || defined(__powerpc64__) || \
-    defined(__s390__) || defined(__s390x__))
-
-#define get_be16(p)	ntohs(*(unsigned short *)(p))
-#define get_be32(p)	ntohl(*(unsigned int *)(p))
-#define get_be64(p)	ntohll(*(uint64_t *)(p))
-#define put_be32(p, v)	do { *(unsigned int *)(p) = htonl(v); } while (0)
-#define put_be64(p, v)	do { *(uint64_t *)(p) = htonll(v); } while (0)
-
-#else
-
 static inline uint16_t get_be16(const void *ptr)
 {
 	const unsigned char *p = ptr;
@@ -212,6 +190,4 @@
 	p[7] = value >>  0;
 }
 
-#endif
-
 #endif /* COMPAT_BSWAP_H */
diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt
index 5007f17..df539a4 100644
--- a/contrib/buildsystems/CMakeLists.txt
+++ b/contrib/buildsystems/CMakeLists.txt
@@ -4,17 +4,25 @@
 
 #[[
 
-Instructions to run CMake:
+Instructions how to use this in Visual Studio:
 
-cmake `relative-path-to-CMakeLists.txt` -DCMAKE_BUILD_TYPE=Release
-Eg.
-From the root of git source tree
-	`cmake contrib/buildsystems/ `
-This will build the git binaries at the root
+Open the worktree as a folder. Visual Studio 2019 and later will detect
+the CMake configuration automatically and set everything up for you,
+ready to build. You can then run the tests in `t/` via a regular Git Bash.
 
-For out of source builds, say build in 'git/git-build/'
-	`mkdir git-build;cd git-build; cmake ../contrib/buildsystems/`
-This will build the git binaries in git-build directory
+Note: Visual Studio also has the option of opening `CMakeLists.txt`
+directly; Using this option, Visual Studio will not find the source code,
+though, therefore the `File>Open>Folder...` option is preferred.
+
+Instructions to run CMake manually:
+
+    mkdir -p contrib/buildsystems/out
+    cd contrib/buildsystems/out
+    cmake ../ -DCMAKE_BUILD_TYPE=Release
+
+This will build the git binaries in contrib/buildsystems/out
+directory (our top-level .gitignore file knows to ignore contents of
+this directory).
 
 Possible build configurations(-DCMAKE_BUILD_TYPE) with corresponding
 compiler flags
@@ -40,8 +48,19 @@
 
 #set the source directory to root of git
 set(CMAKE_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
+if(WIN32)
+	set(VCPKG_DIR "${CMAKE_SOURCE_DIR}/compat/vcbuild/vcpkg")
+	if(MSVC AND NOT EXISTS ${VCPKG_DIR})
+		message("Initializing vcpkg and building the Git's dependencies (this will take a while...)")
+		execute_process(COMMAND ${CMAKE_SOURCE_DIR}/compat/vcbuild/vcpkg_install.bat)
+	endif()
+	list(APPEND CMAKE_PREFIX_PATH "${VCPKG_DIR}/installed/x64-windows")
 
-find_program(SH_EXE sh)
+	# In the vcpkg edition, we need this to be able to link to libcurl
+	set(CURL_NO_CURL_CMAKE ON)
+endif()
+
+find_program(SH_EXE sh PATHS "C:/Program Files/Git/bin")
 if(NOT SH_EXE)
 	message(FATAL_ERROR "sh: shell interpreter was not found in your path, please install one."
 			"On Windows, you can get it as part of 'Git for Windows' install at https://gitforwindows.org/")
@@ -145,7 +164,11 @@
 
 find_program(MSGFMT_EXE msgfmt)
 if(NOT MSGFMT_EXE)
-	message(WARNING "Text Translations won't be build")
+	set(MSGFMT_EXE ${CMAKE_SOURCE_DIR}/compat/vcbuild/vcpkg/downloads/tools/msys2/msys64/usr/bin/msgfmt.exe)
+	if(NOT EXISTS ${MSGFMT_EXE})
+		message(WARNING "Text Translations won't be built")
+		unset(MSGFMT_EXE)
+	endif()
 endif()
 
 #Force all visual studio outputs to CMAKE_BINARY_DIR
@@ -606,6 +629,8 @@
 		target_link_options(common-main PUBLIC -municode -Wl,-nxcompat -Wl,-dynamicbase -Wl,-entry:wmainCRTStartup -Wl,invalidcontinue.obj)
 	elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
 		target_link_options(common-main PUBLIC /IGNORE:4217 /IGNORE:4049 /NOLOGO /ENTRY:wmainCRTStartup /SUBSYSTEM:CONSOLE invalidcontinue.obj)
+	else()
+		message(FATAL_ERROR "Unhandled compiler: ${CMAKE_C_COMPILER_ID}")
 	endif()
 elseif(UNIX)
 	target_link_libraries(common-main pthread rt)
@@ -928,6 +953,9 @@
 file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_GETTEXT='${NO_GETTEXT}'\n")
 file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "RUNTIME_PREFIX='${RUNTIME_PREFIX}'\n")
 file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_PYTHON='${NO_PYTHON}'\n")
+if(WIN32)
+	file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "PATH=\"$PATH:$TEST_DIRECTORY/../compat/vcbuild/vcpkg/installed/x64-windows/bin\"\n")
+endif()
 
 #Make the tests work when building out of the source tree
 get_filename_component(CACHE_PATH ${CMAKE_CURRENT_LIST_DIR}/../../CMakeCache.txt ABSOLUTE)
@@ -938,7 +966,7 @@
 	file(WRITE ${CMAKE_BINARY_DIR}/CTestCustom.cmake
 		"file(STRINGS ${CMAKE_SOURCE_DIR}/t/test-lib.sh GIT_BUILD_DIR_REPL REGEX \"GIT_BUILD_DIR=(.*)\")\n"
 		"file(STRINGS ${CMAKE_SOURCE_DIR}/t/test-lib.sh content NEWLINE_CONSUME)\n"
-		"string(REPLACE \"\${GIT_BUILD_DIR_REPL}\" \"GIT_BUILD_DIR=\\\"$TEST_DIRECTORY\\\"/../${BUILD_DIR_RELATIVE}\" content \"\${content}\")\n"
+		"string(REPLACE \"\${GIT_BUILD_DIR_REPL}\" \"GIT_BUILD_DIR=\\\"$TEST_DIRECTORY/../${BUILD_DIR_RELATIVE}\\\"\" content \"\${content}\")\n"
 		"file(WRITE ${CMAKE_SOURCE_DIR}/t/test-lib.sh \${content})")
 	#misc copies
 	file(COPY ${CMAKE_SOURCE_DIR}/t/chainlint.sed DESTINATION ${CMAKE_BINARY_DIR}/t/)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 8be4a03..0a96ad8 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1508,6 +1508,22 @@
 {
 	__git_has_doubledash && return
 
+	local dwim_opt="$(__git_checkout_default_dwim_mode)"
+
+	case "$prev" in
+	-b|-B|--orphan)
+		# Complete local branches (and DWIM branch
+		# remote branch names) for an option argument
+		# specifying a new branch name. This is for
+		# convenience, assuming new branches are
+		# possibly based on pre-existing branch names.
+		__git_complete_refs $dwim_opt --mode="heads"
+		return
+		;;
+	*)
+		;;
+	esac
+
 	case "$cur" in
 	--conflict=*)
 		__gitcomp "diff3 merge" "" "${cur##--conflict=}"
@@ -1516,23 +1532,6 @@
 		__gitcomp_builtin checkout
 		;;
 	*)
-		local dwim_opt="$(__git_checkout_default_dwim_mode)"
-		local prevword prevword="${words[cword-1]}"
-
-		case "$prevword" in
-			-b|-B|--orphan)
-				# Complete local branches (and DWIM branch
-				# remote branch names) for an option argument
-				# specifying a new branch name. This is for
-				# convenience, assuming new branches are
-				# possibly based on pre-existing branch names.
-				__git_complete_refs $dwim_opt --mode="heads"
-				return
-				;;
-			*)
-				;;
-		esac
-
 		# At this point, we've already handled special completion for
 		# the arguments to -b/-B, and --orphan. There are 3 main
 		# things left we can possibly complete:
@@ -2392,6 +2391,22 @@
 
 _git_switch ()
 {
+	local dwim_opt="$(__git_checkout_default_dwim_mode)"
+
+	case "$prev" in
+	-c|-C|--orphan)
+		# Complete local branches (and DWIM branch
+		# remote branch names) for an option argument
+		# specifying a new branch name. This is for
+		# convenience, assuming new branches are
+		# possibly based on pre-existing branch names.
+		__git_complete_refs $dwim_opt --mode="heads"
+		return
+		;;
+	*)
+		;;
+	esac
+
 	case "$cur" in
 	--conflict=*)
 		__gitcomp "diff3 merge" "" "${cur##--conflict=}"
@@ -2400,23 +2415,6 @@
 		__gitcomp_builtin switch
 		;;
 	*)
-		local dwim_opt="$(__git_checkout_default_dwim_mode)"
-		local prevword prevword="${words[cword-1]}"
-
-		case "$prevword" in
-			-c|-C|--orphan)
-				# Complete local branches (and DWIM branch
-				# remote branch names) for an option argument
-				# specifying a new branch name. This is for
-				# convenience, assuming new branches are
-				# possibly based on pre-existing branch names.
-				__git_complete_refs $dwim_opt --mode="heads"
-				return
-				;;
-			*)
-				;;
-		esac
-
 		# Unlike in git checkout, git switch --orphan does not take
 		# a start point. Thus we really have nothing to complete after
 		# the branch name.
@@ -2843,6 +2841,13 @@
 
 _git_restore ()
 {
+	case "$prev" in
+	-s)
+		__git_complete_refs
+		return
+		;;
+	esac
+
 	case "$cur" in
 	--conflict=*)
 		__gitcomp "diff3 merge" "" "${cur##--conflict=}"
diff --git a/contrib/mw-to-git/git-mw.perl b/contrib/mw-to-git/git-mw.perl
index 28df3ee..eb52a53 100755
--- a/contrib/mw-to-git/git-mw.perl
+++ b/contrib/mw-to-git/git-mw.perl
@@ -6,7 +6,7 @@
 # License: GPL v2 or later
 
 # Set of tools for git repo with a mediawiki remote.
-# Documentation & bugtracker: https://github.com/moy/Git-Mediawiki/
+# Documentation & bugtracker: https://github.com/Git-Mediawiki/Git-Mediawiki
 
 use strict;
 use warnings;
diff --git a/contrib/mw-to-git/git-remote-mediawiki.perl b/contrib/mw-to-git/git-remote-mediawiki.perl
index d8ff2e6..a562441 100755
--- a/contrib/mw-to-git/git-remote-mediawiki.perl
+++ b/contrib/mw-to-git/git-remote-mediawiki.perl
@@ -9,7 +9,7 @@
 # License: GPL v2 or later
 
 # Gateway between Git and MediaWiki.
-# Documentation & bugtracker: https://github.com/moy/Git-Mediawiki/
+# Documentation & bugtracker: https://github.com/Git-Mediawiki/Git-Mediawiki
 
 use strict;
 use MediaWiki::API;
@@ -56,38 +56,38 @@
 
 # Accept both space-separated and multiple keys in config file.
 # Spaces should be written as _ anyway because we'll use chomp.
-my @tracked_pages = split(/[ \n]/, run_git("config --get-all remote.${remotename}.pages"));
+my @tracked_pages = split(/[ \n]/, run_git_quoted(["config", "--get-all", "remote.${remotename}.pages"]));
 chomp(@tracked_pages);
 
 # Just like @tracked_pages, but for MediaWiki categories.
-my @tracked_categories = split(/[ \n]/, run_git("config --get-all remote.${remotename}.categories"));
+my @tracked_categories = split(/[ \n]/, run_git_quoted(["config", "--get-all", "remote.${remotename}.categories"]));
 chomp(@tracked_categories);
 
 # Just like @tracked_categories, but for MediaWiki namespaces.
-my @tracked_namespaces = split(/[ \n]/, run_git("config --get-all remote.${remotename}.namespaces"));
+my @tracked_namespaces = split(/[ \n]/, run_git_quoted(["config", "--get-all", "remote.${remotename}.namespaces"]));
 for (@tracked_namespaces) { s/_/ /g; }
 chomp(@tracked_namespaces);
 
 # Import media files on pull
-my $import_media = run_git("config --get --bool remote.${remotename}.mediaimport");
+my $import_media = run_git_quoted(["config", "--get", "--bool", "remote.${remotename}.mediaimport"]);
 chomp($import_media);
 $import_media = ($import_media eq 'true');
 
 # Export media files on push
-my $export_media = run_git("config --get --bool remote.${remotename}.mediaexport");
+my $export_media = run_git_quoted(["config", "--get", "--bool", "remote.${remotename}.mediaexport"]);
 chomp($export_media);
 $export_media = !($export_media eq 'false');
 
-my $wiki_login = run_git("config --get remote.${remotename}.mwLogin");
+my $wiki_login = run_git_quoted(["config", "--get", "remote.${remotename}.mwLogin"]);
 # Note: mwPassword is discouraged. Use the credential system instead.
-my $wiki_passwd = run_git("config --get remote.${remotename}.mwPassword");
-my $wiki_domain = run_git("config --get remote.${remotename}.mwDomain");
+my $wiki_passwd = run_git_quoted(["config", "--get", "remote.${remotename}.mwPassword"]);
+my $wiki_domain = run_git_quoted(["config", "--get", "remote.${remotename}.mwDomain"]);
 chomp($wiki_login);
 chomp($wiki_passwd);
 chomp($wiki_domain);
 
 # Import only last revisions (both for clone and fetch)
-my $shallow_import = run_git("config --get --bool remote.${remotename}.shallow");
+my $shallow_import = run_git_quoted(["config", "--get", "--bool", "remote.${remotename}.shallow"]);
 chomp($shallow_import);
 $shallow_import = ($shallow_import eq 'true');
 
@@ -97,9 +97,9 @@
 # Possible values:
 # - by_rev: perform one query per new revision on the remote wiki
 # - by_page: query each tracked page for new revision
-my $fetch_strategy = run_git("config --get remote.${remotename}.fetchStrategy");
+my $fetch_strategy = run_git_quoted(["config", "--get", "remote.${remotename}.fetchStrategy"]);
 if (!$fetch_strategy) {
-	$fetch_strategy = run_git('config --get mediawiki.fetchStrategy');
+	$fetch_strategy = run_git_quoted(["config", "--get", "mediawiki.fetchStrategy"]);
 }
 chomp($fetch_strategy);
 if (!$fetch_strategy) {
@@ -123,9 +123,9 @@
 # will get the history with information lost). If the import is
 # deterministic, this means everybody gets the same sha1 for each
 # MediaWiki revision.
-my $dumb_push = run_git("config --get --bool remote.${remotename}.dumbPush");
+my $dumb_push = run_git_quoted(["config", "--get", "--bool", "remote.${remotename}.dumbPush"]);
 if (!$dumb_push) {
-	$dumb_push = run_git('config --get --bool mediawiki.dumbPush');
+	$dumb_push = run_git_quoted(["config", "--get", "--bool", "mediawiki.dumbPush"]);
 }
 chomp($dumb_push);
 $dumb_push = ($dumb_push eq 'true');
@@ -369,12 +369,14 @@
 	return %pages;
 }
 
-# usage: $out = run_git("command args");
-#        $out = run_git("command args", "raw"); # don't interpret output as UTF-8.
-sub run_git {
+# usage: $out = run_git_quoted(["command", "args", ...]);
+#        $out = run_git_quoted(["command", "args", ...], "raw"); # don't interpret output as UTF-8.
+#        $out = run_git_quoted_nostderr(["command", "args", ...]); # discard stderr
+#        $out = run_git_quoted_nostderr(["command", "args", ...], "raw"); # ditto but raw instead of UTF-8 as above
+sub _run_git {
 	my $args = shift;
 	my $encoding = (shift || 'encoding(UTF-8)');
-	open(my $git, "-|:${encoding}", "git ${args}")
+	open(my $git, "-|:${encoding}", @$args)
 	    or die "Unable to fork: $!\n";
 	my $res = do {
 		local $/ = undef;
@@ -385,6 +387,13 @@
 	return $res;
 }
 
+sub run_git_quoted {
+    _run_git(["git", @{$_[0]}], $_[1]);
+}
+
+sub run_git_quoted_nostderr {
+    _run_git(['sh', '-c', 'git "$@" 2>/dev/null', '--', @{$_[0]}], $_[1]);
+}
 
 sub get_all_mediafiles {
 	my $pages = shift;
@@ -511,8 +520,9 @@
 }
 
 sub get_last_local_revision {
-	# Get note regarding last mediawiki revision
-	my $note = run_git("notes --ref=${remotename}/mediawiki show refs/mediawiki/${remotename}/master 2>/dev/null");
+	# Get note regarding last mediawiki revision.
+	my $note = run_git_quoted_nostderr(["notes", "--ref=${remotename}/mediawiki",
+					    "show", "refs/mediawiki/${remotename}/master"]);
 	my @note_info = split(/ /, $note);
 
 	my $lastrevision_number;
@@ -807,7 +817,10 @@
 sub mw_import {
 	# multiple import commands can follow each other.
 	my @refs = (shift, get_more_refs('import'));
+	my $processedRefs;
 	foreach my $ref (@refs) {
+		next if $processedRefs->{$ref}; # skip duplicates: "import refs/heads/master" being issued twice; TODO: why?
+		$processedRefs->{$ref} = 1;
 		mw_import_ref($ref);
 	}
 	print {*STDOUT} "done\n";
@@ -970,7 +983,7 @@
 }
 
 sub error_non_fast_forward {
-	my $advice = run_git('config --bool advice.pushNonFastForward');
+	my $advice = run_git_quoted(["config", "--bool", "advice.pushNonFastForward"]);
 	chomp($advice);
 	if ($advice ne 'false') {
 		# Native git-push would show this after the summary.
@@ -1014,7 +1027,7 @@
 		}
 	} else {
 		# Don't let perl try to interpret file content as UTF-8 => use "raw"
-		my $content = run_git("cat-file blob ${new_sha1}", 'raw');
+		my $content = run_git_quoted(["cat-file", "blob", $new_sha1], 'raw');
 		if ($content ne EMPTY) {
 			$mediawiki = connect_maybe($mediawiki, $remotename, $url);
 			$mediawiki->{config}->{upload_url} =
@@ -1084,7 +1097,7 @@
 			# with this content instead:
 			$file_content = DELETED_CONTENT;
 		} else {
-			$file_content = run_git("cat-file blob ${new_sha1}");
+			$file_content = run_git_quoted(["cat-file", "blob", $new_sha1]);
 		}
 
 		$mediawiki = connect_maybe($mediawiki, $remotename, $url);
@@ -1174,10 +1187,10 @@
 	my $mw_revision = $last_remote_revid;
 
 	# Get sha1 of commit pointed by local HEAD
-	my $HEAD_sha1 = run_git("rev-parse ${local} 2>/dev/null");
+	my $HEAD_sha1 = run_git_quoted_nostderr(["rev-parse", $local]);
 	chomp($HEAD_sha1);
 	# Get sha1 of commit pointed by remotes/$remotename/master
-	my $remoteorigin_sha1 = run_git("rev-parse refs/remotes/${remotename}/master 2>/dev/null");
+	my $remoteorigin_sha1 = run_git_quoted_nostderr(["rev-parse", "refs/remotes/${remotename}/master"]);
 	chomp($remoteorigin_sha1);
 
 	if ($last_local_revid > 0 &&
@@ -1197,7 +1210,7 @@
 		my $parsed_sha1 = $remoteorigin_sha1;
 		# Find a path from last MediaWiki commit to pushed commit
 		print {*STDERR} "Computing path from local to remote ...\n";
-		my @local_ancestry = split(/\n/, run_git("rev-list --boundary --parents ${local} ^${parsed_sha1}"));
+		my @local_ancestry = split(/\n/, run_git_quoted(["rev-list", "--boundary", "--parents", $local, "^${parsed_sha1}"]));
 		my %local_ancestry;
 		foreach my $line (@local_ancestry) {
 			if (my ($child, $parents) = $line =~ /^-?([a-f0-9]+) ([a-f0-9 ]+)/) {
@@ -1221,7 +1234,7 @@
 		# No remote mediawiki revision. Export the whole
 		# history (linearized with --first-parent)
 		print {*STDERR} "Warning: no common ancestor, pushing complete history\n";
-		my $history = run_git("rev-list --first-parent --children ${local}");
+		my $history = run_git_quoted(["rev-list", "--first-parent", "--children", $local]);
 		my @history = split(/\n/, $history);
 		@history = @history[1..$#history];
 		foreach my $line (reverse @history) {
@@ -1233,12 +1246,12 @@
 	foreach my $commit_info_split (@commit_pairs) {
 		my $sha1_child = @{$commit_info_split}[0];
 		my $sha1_commit = @{$commit_info_split}[1];
-		my $diff_infos = run_git("diff-tree -r --raw -z ${sha1_child} ${sha1_commit}");
+		my $diff_infos = run_git_quoted(["diff-tree", "-r", "--raw", "-z", $sha1_child, $sha1_commit]);
 		# TODO: we could detect rename, and encode them with a #redirect on the wiki.
 		# TODO: for now, it's just a delete+add
 		my @diff_info_list = split(/\0/, $diff_infos);
 		# Keep the subject line of the commit message as mediawiki comment for the revision
-		my $commit_msg = run_git(qq(log --no-walk --format="%s" ${sha1_commit}));
+		my $commit_msg = run_git_quoted(["log", "--no-walk", '--format="%s"', $sha1_commit]);
 		chomp($commit_msg);
 		# Push every blob
 		while (@diff_info_list) {
@@ -1263,7 +1276,10 @@
 			}
 		}
 		if (!$dumb_push) {
-			run_git(qq(notes --ref=${remotename}/mediawiki add -f -m "mediawiki_revision: ${mw_revision}" ${sha1_commit}));
+			run_git_quoted(["notes", "--ref=${remotename}/mediawiki",
+					"add", "-f", "-m",
+					"mediawiki_revision: ${mw_revision}",
+					$sha1_commit]);
 		}
 	}
 
@@ -1304,7 +1320,7 @@
 		# already cached. Namespaces are stored in form:
 		# "Name_of_namespace:Id_namespace", ex.: "File:6".
 		my @temp = split(/\n/,
-				 run_git("config --get-all remote.${remotename}.namespaceCache"));
+				 run_git_quoted(["config", "--get-all", "remote.${remotename}.namespaceCache"]));
 		chomp(@temp);
 		foreach my $ns (@temp) {
 			my ($n, $id) = split(/:/, $ns);
@@ -1358,7 +1374,7 @@
 
 	# Store explicitly requested namespaces on disk
 	if (!exists $cached_mw_namespace_id{$name}) {
-		run_git(qq(config --add remote.${remotename}.namespaceCache "${name}:${store_id}"));
+		run_git_quoted(["config", "--add", "remote.${remotename}.namespaceCache", "${name}:${store_id}"]);
 		$cached_mw_namespace_id{$name} = 1;
 	}
 	return $id;
diff --git a/contrib/mw-to-git/git-remote-mediawiki.txt b/contrib/mw-to-git/git-remote-mediawiki.txt
index 23b7ef9..5da825f 100644
--- a/contrib/mw-to-git/git-remote-mediawiki.txt
+++ b/contrib/mw-to-git/git-remote-mediawiki.txt
@@ -4,4 +4,4 @@
 repository thanks to remote-helpers.
 
 For more information, visit the wiki at
-https://github.com/moy/Git-Mediawiki/wiki
+https://github.com/Git-Mediawiki/Git-Mediawiki
diff --git a/contrib/mw-to-git/t/.gitignore b/contrib/mw-to-git/t/.gitignore
index a7a40b4..2b8dc30 100644
--- a/contrib/mw-to-git/t/.gitignore
+++ b/contrib/mw-to-git/t/.gitignore
@@ -1,4 +1,4 @@
 WEB/
-wiki/
+mediawiki/
 trash directory.t*/
 test-results/
diff --git a/contrib/mw-to-git/t/README b/contrib/mw-to-git/t/README
index 2ee34be..72c4889 100644
--- a/contrib/mw-to-git/t/README
+++ b/contrib/mw-to-git/t/README
@@ -14,11 +14,11 @@
 adapted for another distribution):
 
 * lighttpd
-* php5
-* php5-cgi
-* php5-cli
-* php5-curl
-* php5-sqlite
+* php
+* php-cgi
+* php-cli
+* php-curl
+* php-sqlite
 
 Principles and Technical Choices
 --------------------------------
diff --git a/contrib/mw-to-git/t/install-wiki/.gitignore b/contrib/mw-to-git/t/install-wiki/.gitignore
deleted file mode 100644
index b5a2a44..0000000
--- a/contrib/mw-to-git/t/install-wiki/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-wikidb.sqlite
diff --git a/contrib/mw-to-git/t/install-wiki/LocalSettings.php b/contrib/mw-to-git/t/install-wiki/LocalSettings.php
deleted file mode 100644
index 745e47e..0000000
--- a/contrib/mw-to-git/t/install-wiki/LocalSettings.php
+++ /dev/null
@@ -1,129 +0,0 @@
-<?php
-# This file was automatically generated by the MediaWiki 1.19.0
-# installer. If you make manual changes, please keep track in case you
-# need to recreate them later.
-#
-# See includes/DefaultSettings.php for all configurable settings
-# and their default values, but don't forget to make changes in _this_
-# file, not there.
-#
-# Further documentation for configuration settings may be found at:
-# http://www.mediawiki.org/wiki/Manual:Configuration_settings
-
-# Protect against web entry
-if ( !defined( 'MEDIAWIKI' ) ) {
-	exit;
-}
-
-## Uncomment this to disable output compression
-# $wgDisableOutputCompression = true;
-
-$wgSitename      = "Git-MediaWiki-Test";
-$wgMetaNamespace = "Git-MediaWiki-Test";
-
-## The URL base path to the directory containing the wiki;
-## defaults for all runtime URL paths are based off of this.
-## For more information on customizing the URLs please see:
-## http://www.mediawiki.org/wiki/Manual:Short_URL
-$wgScriptPath       = "@WG_SCRIPT_PATH@";
-$wgScriptExtension  = ".php";
-
-## The protocol and server name to use in fully-qualified URLs
-$wgServer           = "@WG_SERVER@";
-
-## The relative URL path to the skins directory
-$wgStylePath        = "$wgScriptPath/skins";
-
-## The relative URL path to the logo.  Make sure you change this from the default,
-## or else you'll overwrite your logo when you upgrade!
-$wgLogo             = "$wgStylePath/common/images/wiki.png";
-
-## UPO means: this is also a user preference option
-
-$wgEnableEmail      = true;
-$wgEnableUserEmail  = true; # UPO
-
-$wgEmergencyContact = "apache@localhost";
-$wgPasswordSender   = "apache@localhost";
-
-$wgEnotifUserTalk      = false; # UPO
-$wgEnotifWatchlist     = false; # UPO
-$wgEmailAuthentication = true;
-
-## Database settings
-$wgDBtype           = "sqlite";
-$wgDBserver         = "";
-$wgDBname           = "@WG_SQLITE_DATAFILE@";
-$wgDBuser           = "";
-$wgDBpassword       = "";
-
-# SQLite-specific settings
-$wgSQLiteDataDir    = "@WG_SQLITE_DATADIR@";
-
-
-## Shared memory settings
-$wgMainCacheType    = CACHE_NONE;
-$wgMemCachedServers = array();
-
-## To enable image uploads, make sure the 'images' directory
-## is writable, then set this to true:
-$wgEnableUploads  = true;
-$wgUseImageMagick = true;
-$wgImageMagickConvertCommand ="@CONVERT@";
-$wgFileExtensions[] = 'txt';
-
-# InstantCommons allows wiki to use images from http://commons.wikimedia.org
-$wgUseInstantCommons  = false;
-
-## If you use ImageMagick (or any other shell command) on a
-## Linux server, this will need to be set to the name of an
-## available UTF-8 locale
-$wgShellLocale = "en_US.utf8";
-
-## If you want to use image uploads under safe mode,
-## create the directories images/archive, images/thumb and
-## images/temp, and make them all writable. Then uncomment
-## this, if it's not already uncommented:
-#$wgHashedUploadDirectory = false;
-
-## Set $wgCacheDirectory to a writable directory on the web server
-## to make your wiki go slightly faster. The directory should not
-## be publicly accessible from the web.
-#$wgCacheDirectory = "$IP/cache";
-
-# Site language code, should be one of the list in ./languages/Names.php
-$wgLanguageCode = "en";
-
-$wgSecretKey = "1c912bfe3519fb70f5dc523ecc698111cd43d81a11c585b3eefb28f29c2699b7";
-#$wgSecretKey = "@SECRETKEY@";
-
-
-# Site upgrade key. Must be set to a string (default provided) to turn on the
-# web installer while LocalSettings.php is in place
-$wgUpgradeKey = "ddae7dc87cd0a645";
-
-## Default skin: you can change the default skin. Use the internal symbolic
-## names, ie 'standard', 'nostalgia', 'cologneblue', 'monobook', 'vector':
-$wgDefaultSkin = "vector";
-
-## For attaching licensing metadata to pages, and displaying an
-## appropriate copyright notice / icon. GNU Free Documentation
-## License and Creative Commons licenses are supported so far.
-$wgRightsPage = ""; # Set to the title of a wiki page that describes your license/copyright
-$wgRightsUrl  = "";
-$wgRightsText = "";
-$wgRightsIcon = "";
-
-# Path to the GNU diff3 utility. Used for conflict resolution.
-$wgDiff3 = "/usr/bin/diff3";
-
-# Query string length limit for ResourceLoader. You should only set this if
-# your web server has a query string length limit (then set it to that limit),
-# or if you have suhosin.get.max_value_length set in php.ini (then set it to
-# that value)
-$wgResourceLoaderMaxQueryLength = -1;
-
-
-
-# End of automatically generated settings.
-# Add more configuration options below.
diff --git a/contrib/mw-to-git/t/install-wiki/db_install.php b/contrib/mw-to-git/t/install-wiki/db_install.php
deleted file mode 100644
index b033849..0000000
--- a/contrib/mw-to-git/t/install-wiki/db_install.php
+++ /dev/null
@@ -1,120 +0,0 @@
-<?php
-/**
- * This script generates a SQLite database for a MediaWiki version 1.19.0
- * You must specify the login of the admin (argument 1) and its
- * password (argument 2) and the folder where the database file
- * is located (absolute path in argument 3).
- * It is used by the script install-wiki.sh in order to make easy the
- * installation of a MediaWiki.
- *
- * In order to generate a SQLite database file, MediaWiki ask the user
- * to submit some forms in its web browser. This script simulates this
- * behavior though the functions <get> and <submit>
- *
- */
-$argc = $_SERVER['argc'];
-$argv = $_SERVER['argv'];
-
-$login = $argv[2];
-$pass = $argv[3];
-$tmp = $argv[4];
-$port = $argv[5];
-
-$url = 'http://localhost:'.$port.'/wiki/mw-config/index.php';
-$db_dir = urlencode($tmp);
-$tmp_cookie = tempnam($tmp, "COOKIE_");
-/*
- * Fetches a page with cURL.
- */
-function get($page_name = "") {
-	$curl = curl_init();
-	$page_name_add = "";
-	if ($page_name != "") {
-		$page_name_add = '?page='.$page_name;
-	}
-	$url = $GLOBALS['url'].$page_name_add;
-	$tmp_cookie = $GLOBALS['tmp_cookie'];
-	curl_setopt($curl, CURLOPT_COOKIEJAR, $tmp_cookie);
-	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
-	curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
-	curl_setopt($curl, CURLOPT_COOKIEFILE, $tmp_cookie);
-	curl_setopt($curl, CURLOPT_HEADER, true);
-	curl_setopt($curl, CURLOPT_URL, $url);
-
-	$page = curl_exec($curl);
-	if (!$page) {
-		die("Could not get page: $url\n");
-	}
-	curl_close($curl);
-	return $page;
-}
-
-/*
- * Submits a form with cURL.
- */
-function submit($page_name, $option = "") {
-	$curl = curl_init();
-	$datapost = 'submit-continue=Continue+%E2%86%92';
-	if ($option != "") {
-		$datapost = $option.'&'.$datapost;
-	}
-	$url = $GLOBALS['url'].'?page='.$page_name;
-	$tmp_cookie = $GLOBALS['tmp_cookie'];
-	curl_setopt($curl, CURLOPT_URL, $url);
-	curl_setopt($curl, CURLOPT_POST, true);
-	curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
-	curl_setopt($curl, CURLOPT_POSTFIELDS, $datapost);
-	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
-	curl_setopt($curl, CURLOPT_COOKIEJAR, $tmp_cookie);
-	curl_setopt($curl, CURLOPT_COOKIEFILE, $tmp_cookie);
-
-	$page = curl_exec($curl);
-	if (!$page) {
-		die("Could not get page: $url\n");
-	}
-	curl_close($curl);
-	return "$page";
-}
-
-/*
- * Here starts this script: simulates the behavior of the user
- * submitting forms to generates the database file.
- * Note this simulation was made for the MediaWiki version 1.19.0,
- * we can't assume it works with other versions.
- *
- */
-
-$page = get();
-if (!preg_match('/input type="hidden" value="([0-9]+)" name="LanguageRequestTime"/',
-		$page, $matches)) {
-	echo "Unexpected content for page downloaded:\n";
-	echo "$page";
-	die;
-};
-$timestamp = $matches[1];
-$language = "LanguageRequestTime=$timestamp&uselang=en&ContLang=en";
-$page = submit('Language', $language);
-
-submit('Welcome');
-
-$db_config = 'DBType=sqlite';
-$db_config = $db_config.'&sqlite_wgSQLiteDataDir='.$db_dir;
-$db_config = $db_config.'&sqlite_wgDBname='.$argv[1];
-submit('DBConnect', $db_config);
-
-$wiki_config = 'config_wgSitename=TEST';
-$wiki_config = $wiki_config.'&config__NamespaceType=site-name';
-$wiki_config = $wiki_config.'&config_wgMetaNamespace=MyWiki';
-$wiki_config = $wiki_config.'&config__AdminName='.$login;
-
-$wiki_config = $wiki_config.'&config__AdminPassword='.$pass;
-$wiki_config = $wiki_config.'&config__AdminPassword2='.$pass;
-
-$wiki_config = $wiki_config.'&wiki__configEmail=email%40email.org';
-$wiki_config = $wiki_config.'&config__SkipOptional=skip';
-submit('Name', $wiki_config);
-submit('Install');
-submit('Install');
-
-unlink($tmp_cookie);
-?>
diff --git a/contrib/mw-to-git/t/t9360-mw-to-git-clone.sh b/contrib/mw-to-git/t/t9360-mw-to-git-clone.sh
index 9106833..4c39bda 100755
--- a/contrib/mw-to-git/t/t9360-mw-to-git-clone.sh
+++ b/contrib/mw-to-git/t/t9360-mw-to-git-clone.sh
@@ -28,7 +28,7 @@
 		git log --format=%s HEAD^..HEAD >log.tmp
 	) &&
 	echo "this must be the same" >msg.tmp &&
-	diff -b mw_dir_1/log.tmp msg.tmp
+	test_cmp msg.tmp mw_dir_1/log.tmp
 '
 
 
@@ -50,8 +50,8 @@
 	echo "this must be the same" >>msgDaddy.tmp &&
 	echo "identical too" >msgDj.tmp &&
 	echo "identical" >>msgDj.tmp &&
-	diff -b mw_dir_2/logDaddy.tmp msgDaddy.tmp &&
-	diff -b mw_dir_2/logDj.tmp msgDj.tmp
+	test_cmp msgDaddy.tmp mw_dir_2/logDaddy.tmp &&
+	test_cmp msgDj.tmp mw_dir_2/logDj.tmp
 '
 
 
@@ -135,7 +135,7 @@
 		cd mw_dir_8 &&
 		echo "this log must stay" >msg.tmp &&
 		git log --format=%s >log.tmp &&
-		diff -b msg.tmp log.tmp
+		test_cmp msg.tmp log.tmp
 	) &&
 	wiki_check_content mw_dir_8/Namnam.mw Namnam
 '
diff --git a/contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh b/contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh
index 3ff3a09..6187ec6 100755
--- a/contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh
+++ b/contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh
@@ -27,12 +27,12 @@
 
 # Don't bother with permissions, be administrator by default
 test_expect_success 'setup config' '
-	git config --global remote.origin.mwLogin WikiAdmin &&
-	git config --global remote.origin.mwPassword AdminPass &&
+	git config --global remote.origin.mwLogin "$WIKI_ADMIN" &&
+	git config --global remote.origin.mwPassword "$WIKI_PASSW" &&
 	test_might_fail git config --global --unset remote.origin.mediaImport
 '
 
-test_expect_success 'git push can upload media (File:) files' '
+test_expect_failure 'git push can upload media (File:) files' '
 	wiki_reset &&
 	git clone mediawiki::'"$WIKI_URL"' mw_dir &&
 	(
@@ -48,13 +48,14 @@
 	)
 '
 
-test_expect_success 'git clone works on previously created wiki with media files' '
+test_expect_failure 'git clone works on previously created wiki with media files' '
 	test_when_finished "rm -rf mw_dir mw_dir_clone" &&
 	git clone -c remote.origin.mediaimport=true \
 		mediawiki::'"$WIKI_URL"' mw_dir_clone &&
 	test_cmp mw_dir_clone/Foo.txt mw_dir/Foo.txt &&
 	(cd mw_dir_clone && git checkout HEAD^) &&
 	(cd mw_dir && git checkout HEAD^) &&
+	test_path_is_file mw_dir_clone/Foo.txt &&
 	test_cmp mw_dir_clone/Foo.txt mw_dir/Foo.txt
 '
 
diff --git a/contrib/mw-to-git/t/test-gitmw-lib.sh b/contrib/mw-to-git/t/test-gitmw-lib.sh
index 3948a00..64e46c1 100755
--- a/contrib/mw-to-git/t/test-gitmw-lib.sh
+++ b/contrib/mw-to-git/t/test-gitmw-lib.sh
@@ -13,7 +13,8 @@
 
 . ./test.config
 
-WIKI_URL=http://"$SERVER_ADDR:$PORT/$WIKI_DIR_NAME"
+WIKI_BASE_URL=http://$SERVER_ADDR:$PORT
+WIKI_URL=$WIKI_BASE_URL/$WIKI_DIR_NAME
 CURR_DIR=$(pwd)
 TEST_OUTPUT_DIRECTORY=$(pwd)
 TEST_DIRECTORY="$CURR_DIR"/../../../t
@@ -65,7 +66,7 @@
 	GIT_EXEC_PATH=$(cd "$(dirname "$0")" && cd "../.." && pwd)
 	PATH="$GIT_EXEC_PATH"'/bin-wrapper:'"$PATH"
 
-	if [ ! -d "$WIKI_DIR_INST/$WIKI_DIR_NAME" ];
+	if ! test -d "$WIKI_DIR_INST/$WIKI_DIR_NAME"
 	then
 		skip_all='skipping gateway git-mw tests, no mediawiki found'
 		test_done
@@ -291,27 +292,59 @@
 	test -f "$WEB_TMP/pid" && kill $(cat "$WEB_TMP/pid")
 }
 
-# Create the SQLite database of the MediaWiki. If the database file already
-# exists, it will be deleted.
-# This script should be runned from the directory where $FILES_FOLDER is
-# located.
-create_db () {
-	rm -f "$TMP/$DB_FILE"
+wiki_delete_db () {
+	rm -rf \
+	   "$FILES_FOLDER_DB"/* || error "Couldn't delete $FILES_FOLDER_DB/"
+}
 
-	echo "Generating the SQLite database file. It can take some time ..."
-	# Run the php script to generate the SQLite database file
-	# with cURL calls.
-	php "$FILES_FOLDER/$DB_INSTALL_SCRIPT" $(basename "$DB_FILE" .sqlite) \
-		"$WIKI_ADMIN" "$WIKI_PASSW" "$TMP" "$PORT"
+wiki_delete_db_backup () {
+	rm -rf \
+	   "$FILES_FOLDER_POST_INSTALL_DB"/* || error "Couldn't delete $FILES_FOLDER_POST_INSTALL_DB/"
+}
 
-	if [ ! -f "$TMP/$DB_FILE" ] ; then
-		error "Can't create database file $TMP/$DB_FILE. Try to run ./install-wiki.sh delete first."
+# Install MediaWiki using its install.php script. If the database file
+# already exists, it will be deleted.
+install_mediawiki () {
+
+	localsettings="$WIKI_DIR_INST/$WIKI_DIR_NAME/LocalSettings.php"
+	if test -f "$localsettings"
+	then
+		error "We already installed the wiki, since $localsettings exists" \
+		      "perhaps you wanted to run 'delete' first?"
 	fi
 
-	# Copy the generated database file into the directory the
-	# user indicated.
-	cp "$TMP/$DB_FILE" "$FILES_FOLDER" ||
-		error "Unable to copy $TMP/$DB_FILE to $FILES_FOLDER"
+	wiki_delete_db
+	wiki_delete_db_backup
+	mkdir \
+		"$FILES_FOLDER_DB/" \
+		"$FILES_FOLDER_POST_INSTALL_DB/"
+
+	install_script="$WIKI_DIR_INST/$WIKI_DIR_NAME/maintenance/install.php"
+	echo "Installing MediaWiki using $install_script. This may take some time ..."
+
+	php "$WIKI_DIR_INST/$WIKI_DIR_NAME/maintenance/install.php" \
+	    --server $WIKI_BASE_URL \
+	    --scriptpath /wiki \
+	    --lang en \
+	    --dbtype sqlite \
+	    --dbpath $PWD/$FILES_FOLDER_DB/ \
+	    --pass "$WIKI_PASSW" \
+	    Git-MediaWiki-Test \
+	    "$WIKI_ADMIN" ||
+		error "Couldn't run $install_script, see errors above. Try to run ./install-wiki.sh delete first."
+	cat <<-'EOF' >>$localsettings
+# Custom settings added by test-gitmw-lib.sh
+#
+# Uploading text files is needed for
+# t9363-mw-to-git-export-import.sh
+$wgEnableUploads = true;
+$wgFileExtensions[] = 'txt';
+EOF
+
+	# Copy the initially generated database file into our backup
+	# folder
+	cp -R "$FILES_FOLDER_DB/"* "$FILES_FOLDER_POST_INSTALL_DB/" ||
+		error "Unable to copy $FILES_FOLDER_DB/* to $FILES_FOLDER_POST_INSTALL_DB/*"
 }
 
 # Install a wiki in your web server directory.
@@ -320,30 +353,33 @@
 		start_lighttpd
 	fi
 
-	SERVER_ADDR=$SERVER_ADDR:$PORT
 	# In this part, we change directory to $TMP in order to download,
 	# unpack and copy the files of MediaWiki
 	(
 	mkdir -p "$WIKI_DIR_INST/$WIKI_DIR_NAME"
-	if [ ! -d "$WIKI_DIR_INST/$WIKI_DIR_NAME" ] ; then
+	if ! test -d "$WIKI_DIR_INST/$WIKI_DIR_NAME"
+	then
 		error "Folder $WIKI_DIR_INST/$WIKI_DIR_NAME doesn't exist.
 		Please create it and launch the script again."
 	fi
 
-	# Fetch MediaWiki's archive if not already present in the TMP directory
+	# Fetch MediaWiki's archive if not already present in the
+	# download directory
+	mkdir -p "$FILES_FOLDER_DOWNLOAD"
 	MW_FILENAME="mediawiki-$MW_VERSION_MAJOR.$MW_VERSION_MINOR.tar.gz"
-	cd "$TMP"
-	if [ ! -f $MW_FILENAME ] ; then
+	cd "$FILES_FOLDER_DOWNLOAD"
+	if ! test -f $MW_FILENAME
+	then
 		echo "Downloading $MW_VERSION_MAJOR.$MW_VERSION_MINOR sources ..."
 		wget "http://download.wikimedia.org/mediawiki/$MW_VERSION_MAJOR/$MW_FILENAME" ||
 			error "Unable to download "\
 			"http://download.wikimedia.org/mediawiki/$MW_VERSION_MAJOR/"\
 			"$MW_FILENAME. "\
 			"Please fix your connection and launch the script again."
-		echo "$MW_FILENAME downloaded in $(pwd). "\
-			"You can delete it later if you want."
+		echo "$MW_FILENAME downloaded in $(pwd)/;" \
+		     "you can delete it later if you want."
 	else
-		echo "Reusing existing $MW_FILENAME downloaded in $(pwd)."
+		echo "Reusing existing $MW_FILENAME downloaded in $(pwd)/"
 	fi
 	archive_abs_path=$(pwd)/$MW_FILENAME
 	cd "$WIKI_DIR_INST/$WIKI_DIR_NAME/" ||
@@ -352,48 +388,12 @@
 		error "Unable to extract WikiMedia's files from $archive_abs_path to "\
 			"$WIKI_DIR_INST/$WIKI_DIR_NAME"
 	) || exit 1
+	echo Extracted in "$WIKI_DIR_INST/$WIKI_DIR_NAME"
 
-	create_db
-
-	# Copy the generic LocalSettings.php in the web server's directory
-	# And modify parameters according to the ones set at the top
-	# of this script.
-	# Note that LocalSettings.php is never modified.
-	if [ ! -f "$FILES_FOLDER/LocalSettings.php" ] ; then
-		error "Can't find $FILES_FOLDER/LocalSettings.php " \
-			"in the current folder. "\
-		"Please run the script inside its folder."
-	fi
-	cp "$FILES_FOLDER/LocalSettings.php" \
-		"$FILES_FOLDER/LocalSettings-tmp.php" ||
-		error "Unable to copy $FILES_FOLDER/LocalSettings.php " \
-		"to $FILES_FOLDER/LocalSettings-tmp.php"
-
-	# Parse and set the LocalSettings file of the user according to the
-	# CONFIGURATION VARIABLES section at the beginning of this script
-	file_swap="$FILES_FOLDER/LocalSettings-swap.php"
-	sed "s,@WG_SCRIPT_PATH@,/$WIKI_DIR_NAME," \
-		"$FILES_FOLDER/LocalSettings-tmp.php" > "$file_swap"
-	mv "$file_swap" "$FILES_FOLDER/LocalSettings-tmp.php"
-	sed "s,@WG_SERVER@,http://$SERVER_ADDR," \
-		"$FILES_FOLDER/LocalSettings-tmp.php" > "$file_swap"
-	mv "$file_swap" "$FILES_FOLDER/LocalSettings-tmp.php"
-	sed "s,@WG_SQLITE_DATADIR@,$TMP," \
-		"$FILES_FOLDER/LocalSettings-tmp.php" > "$file_swap"
-	mv "$file_swap" "$FILES_FOLDER/LocalSettings-tmp.php"
-	sed "s,@WG_SQLITE_DATAFILE@,$( basename $DB_FILE .sqlite)," \
-		"$FILES_FOLDER/LocalSettings-tmp.php" > "$file_swap"
-	mv "$file_swap" "$FILES_FOLDER/LocalSettings-tmp.php"
-
-	mv "$FILES_FOLDER/LocalSettings-tmp.php" \
-		"$WIKI_DIR_INST/$WIKI_DIR_NAME/LocalSettings.php" ||
-		error "Unable to move $FILES_FOLDER/LocalSettings-tmp.php" \
-		"in $WIKI_DIR_INST/$WIKI_DIR_NAME"
-	echo "File $FILES_FOLDER/LocalSettings.php is set in" \
-		" $WIKI_DIR_INST/$WIKI_DIR_NAME"
+	install_mediawiki
 
 	echo "Your wiki has been installed. You can check it at
-		http://$SERVER_ADDR/$WIKI_DIR_NAME"
+		$WIKI_URL"
 }
 
 # Reset the database of the wiki and the password of the admin
@@ -401,12 +401,18 @@
 # Warning: This function must be called only in a subdirectory of t/ directory
 wiki_reset () {
 	# Copy initial database of the wiki
-	if [ ! -f "../$FILES_FOLDER/$DB_FILE" ] ; then
-		error "Can't find ../$FILES_FOLDER/$DB_FILE in the current folder."
+	if ! test -d "../$FILES_FOLDER_DB"
+	then
+		error "No wiki database at ../$FILES_FOLDER_DB, not installed yet?"
 	fi
-	cp "../$FILES_FOLDER/$DB_FILE" "$TMP" ||
-		error "Can't copy ../$FILES_FOLDER/$DB_FILE in $TMP"
-	echo "File $FILES_FOLDER/$DB_FILE is set in $TMP"
+	if ! test -d "../$FILES_FOLDER_POST_INSTALL_DB"
+	then
+		error "No wiki backup database at ../$FILES_FOLDER_POST_INSTALL_DB, failed installation?"
+	fi
+	wiki_delete_db
+	cp -R "../$FILES_FOLDER_POST_INSTALL_DB/"* "../$FILES_FOLDER_DB/" ||
+		error "Can't copy ../$FILES_FOLDER_POST_INSTALL_DB/* to ../$FILES_FOLDER_DB/*"
+	echo "File $FILES_FOLDER_DB/* has been reset"
 }
 
 # Delete the wiki created in the web server's directory and all its content
@@ -420,13 +426,7 @@
 		rm -rf "$WIKI_DIR_INST/$WIKI_DIR_NAME" ||
 			error "Wiki's directory $WIKI_DIR_INST/" \
 			"$WIKI_DIR_NAME could not be deleted"
-		# Delete the wiki's SQLite database.
-		rm -f "$TMP/$DB_FILE" ||
-			error "Database $TMP/$DB_FILE could not be deleted."
 	fi
-
-	# Delete the wiki's SQLite database
-	rm -f "$TMP/$DB_FILE" || error "Database $TMP/$DB_FILE could not be deleted."
-	rm -f "$FILES_FOLDER/$DB_FILE"
-	rm -rf "$TMP/mediawiki-$MW_VERSION_MAJOR.$MW_VERSION_MINOR.tar.gz"
+	wiki_delete_db
+	wiki_delete_db_backup
 }
diff --git a/contrib/mw-to-git/t/test-gitmw.pl b/contrib/mw-to-git/t/test-gitmw.pl
index 0ff7625..c5d687f 100755
--- a/contrib/mw-to-git/t/test-gitmw.pl
+++ b/contrib/mw-to-git/t/test-gitmw.pl
@@ -24,9 +24,7 @@
 
 use MediaWiki::API;
 use Getopt::Long;
-use encoding 'utf8';
 use DateTime::Format::ISO8601;
-use open ':encoding(utf8)';
 use constant SLASH_REPLACEMENT => "%2F";
 
 #Parsing of the config file
@@ -87,7 +85,7 @@
 	# Replace spaces by underscore in the page name
 	$pagename =~ s/ /_/g;
 	$pagename =~ s/\//%2F/g;
-	open(my $file, ">$destdir/$pagename.mw");
+	open(my $file, ">:encoding(UTF-8)", "$destdir/$pagename.mw");
 	print $file "$content";
 	close ($file);
 
@@ -172,7 +170,7 @@
 				cmlimit => 500 },
 		)
 		|| die $mw->{error}->{code}.": ".$mw->{error}->{details};
-		open(my $file, ">all.txt");
+		open(my $file, ">:encoding(UTF-8)", "all.txt");
 		foreach my $page (@{$mw_pages}) {
 			print $file "$page->{title}\n";
 		}
@@ -185,7 +183,7 @@
 				aplimit => 500,
 			})
 		|| die $mw->{error}->{code}.": ".$mw->{error}->{details};
-		open(my $file, ">all.txt");
+		open(my $file, ">:encoding(UTF-8)", "all.txt");
 		foreach my $page (@{$mw_pages}) {
 			print $file "$page->{title}\n";
 		}
@@ -214,12 +212,12 @@
 
 wiki_login($wiki_admin, $wiki_admin_pass);
 
-my %functions_to_call = qw(
-	upload_file    wiki_upload_file
-	get_page       wiki_getpage
-	delete_page    wiki_delete_page
-	edit_page      wiki_editpage
-	getallpagename wiki_getallpagename
+my %functions_to_call = (
+	upload_file    => \&wiki_upload_file,
+	get_page       => \&wiki_getpage,
+	delete_page    => \&wiki_delete_page,
+	edit_page      => \&wiki_editpage,
+	getallpagename => \&wiki_getallpagename,
 );
 die "$0 ERROR: wrong argument" unless exists $functions_to_call{$fct_to_call};
-&{$functions_to_call{$fct_to_call}}(@ARGV);
+$functions_to_call{$fct_to_call}->(map { utf8::decode($_); $_ } @ARGV);
diff --git a/contrib/mw-to-git/t/test.config b/contrib/mw-to-git/t/test.config
index 5ba0684..ed10b3e 100644
--- a/contrib/mw-to-git/t/test.config
+++ b/contrib/mw-to-git/t/test.config
@@ -3,15 +3,11 @@
 
 # Login and password of the wiki's admin
 WIKI_ADMIN=WikiAdmin
-WIKI_PASSW=AdminPass
+WIKI_PASSW=AdminPass1
 
 # Address of the web server
 SERVER_ADDR=localhost
 
-# SQLite database of the wiki, named DB_FILE, is located in TMP
-TMP=/tmp
-DB_FILE=wikidb.sqlite
-
 # If LIGHTTPD is not set to true, the script will use the default
 # web server running in WIKI_DIR_INST.
 WIKI_DIR_INST=/var/www
@@ -28,10 +24,17 @@
 WEB_TMP=$WEB/tmp
 WEB_WWW=$WEB/www
 
+# Where our configuration for the wiki is located
+FILES_FOLDER=mediawiki
+FILES_FOLDER_DOWNLOAD=$FILES_FOLDER/download
+FILES_FOLDER_DB=$FILES_FOLDER/db
+FILES_FOLDER_POST_INSTALL_DB=$FILES_FOLDER/post-install-db
+
 # The variables below are used by the script to install a wiki.
 # You should not modify these unless you are modifying the script itself.
-# tested versions: 1.19.X -> 1.21.1
-MW_VERSION_MAJOR=1.21
-MW_VERSION_MINOR=1
-FILES_FOLDER=install-wiki
-DB_INSTALL_SCRIPT=db_install.php
+# tested versions: 1.19.X -> 1.21.1 -> 1.34.2
+#
+# See https://www.mediawiki.org/wiki/Download for what the latest
+# version is.
+MW_VERSION_MAJOR=1.34
+MW_VERSION_MINOR=2
diff --git a/diff-lib.c b/diff-lib.c
index 346fdcf..f95c6de 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -177,9 +177,7 @@
 			i--;
 
 			if (revs->combine_merges && num_compare_stages == 2) {
-				show_combined_diff(dpath, 2,
-						   revs->dense_combined_merges,
-						   revs);
+				show_combined_diff(dpath, 2, revs);
 				free(dpath);
 				continue;
 			}
@@ -361,7 +359,7 @@
 		p->parent[1].status = DIFF_STATUS_MODIFIED;
 		p->parent[1].mode = old_entry->ce_mode;
 		oidcpy(&p->parent[1].oid, &old_entry->oid);
-		show_combined_diff(p, 2, revs->dense_combined_merges, revs);
+		show_combined_diff(p, 2, revs);
 		free(p);
 		return 0;
 	}
diff --git a/diff.h b/diff.h
index 3de3432..11de52e 100644
--- a/diff.h
+++ b/diff.h
@@ -452,11 +452,11 @@
 		st_mult(sizeof(struct combine_diff_parent), (n)))
 
 void show_combined_diff(struct combine_diff_path *elem, int num_parent,
-			int dense, struct rev_info *);
+			struct rev_info *);
 
-void diff_tree_combined(const struct object_id *oid, const struct oid_array *parents, int dense, struct rev_info *rev);
+void diff_tree_combined(const struct object_id *oid, const struct oid_array *parents, struct rev_info *rev);
 
-void diff_tree_combined_merge(const struct commit *commit, int dense, struct rev_info *rev);
+void diff_tree_combined_merge(const struct commit *commit, struct rev_info *rev);
 
 void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b);
 
diff --git a/git-bisect.sh b/git-bisect.sh
index 2f60fef..ea7e684 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -49,27 +49,6 @@
 	fi
 }
 
-bisect_autostart() {
-	test -s "$GIT_DIR/BISECT_START" || {
-		gettextln "You need to start by \"git bisect start\"" >&2
-		if test -t 0
-		then
-			# TRANSLATORS: Make sure to include [Y] and [n] in your
-			# translation. The program will only accept English input
-			# at this point.
-			gettext "Do you want me to do it for you [Y/n]? " >&2
-			read yesno
-			case "$yesno" in
-			[Nn]*)
-				exit ;;
-			esac
-			bisect_start
-		else
-			exit 1
-		fi
-	}
-}
-
 bisect_start() {
 	git bisect--helper --bisect-start $@ || exit
 
@@ -86,8 +65,7 @@
 	#
 	# Check if we can proceed to the next bisect state.
 	#
-	get_terms
-	bisect_auto_next
+	git bisect--helper --bisect-auto-next || exit
 
 	trap '-' 0
 }
@@ -108,7 +86,7 @@
 }
 
 bisect_state() {
-	bisect_autostart
+	git bisect--helper --bisect-autostart || exit
 	state=$1
 	git bisect--helper --check-and-set-terms $state $TERM_GOOD $TERM_BAD || exit
 	get_terms
@@ -140,45 +118,7 @@
 	*)
 		usage ;;
 	esac
-	bisect_auto_next
-}
-
-bisect_auto_next() {
-	git bisect--helper --bisect-next-check $TERM_GOOD $TERM_BAD && bisect_next || :
-}
-
-bisect_next() {
-	case "$#" in 0) ;; *) usage ;; esac
-	bisect_autostart
-	git bisect--helper --bisect-next-check $TERM_GOOD $TERM_BAD $TERM_GOOD|| exit
-
-	# Perform all bisection computation, display and checkout
-	git bisect--helper --next-all
-	res=$?
-
-	# Check if we should exit because bisection is finished
-	if test $res -eq 10
-	then
-		bad_rev=$(git show-ref --hash --verify refs/bisect/$TERM_BAD)
-		bad_commit=$(git show-branch $bad_rev)
-		echo "# first $TERM_BAD commit: $bad_commit" >>"$GIT_DIR/BISECT_LOG"
-		exit 0
-	elif test $res -eq 2
-	then
-		echo "# only skipped commits left to test" >>"$GIT_DIR/BISECT_LOG"
-		good_revs=$(git for-each-ref --format="%(objectname)" "refs/bisect/$TERM_GOOD-*")
-		for skipped in $(git rev-list refs/bisect/$TERM_BAD --not $good_revs)
-		do
-			skipped_commit=$(git show-branch $skipped)
-			echo "# possible first $TERM_BAD commit: $skipped_commit" >>"$GIT_DIR/BISECT_LOG"
-		done
-		exit $res
-	fi
-
-	# Check for an error in the bisection process
-	test $res -ne 0 && exit $res
-
-	return 0
+	git bisect--helper --bisect-auto-next
 }
 
 bisect_visualize() {
@@ -234,7 +174,7 @@
 		esac
 	done <"$file"
 	IFS="$oIFS"
-	bisect_auto_next
+	git bisect--helper --bisect-auto-next || exit
 }
 
 bisect_run () {
@@ -331,7 +271,7 @@
 		bisect_skip "$@" ;;
 	next)
 		# Not sure we want "next" at the UI level anymore.
-		bisect_next "$@" ;;
+		git bisect--helper --bisect-next "$@" || exit ;;
 	visualize|view)
 		bisect_visualize "$@" ;;
 	reset)
diff --git a/gitk-git/gitk b/gitk-git/gitk
index abe4805..23d9dd1 100755
--- a/gitk-git/gitk
+++ b/gitk-git/gitk
@@ -11,14 +11,14 @@
 
 proc hasworktree {} {
     return [expr {[exec git rev-parse --is-bare-repository] == "false" &&
-		  [exec git rev-parse --is-inside-git-dir] == "false"}]
+                  [exec git rev-parse --is-inside-git-dir] == "false"}]
 }
 
 proc reponame {} {
     global gitdir
     set n [file normalize $gitdir]
     if {[string match "*/.git" $n]} {
-	set n [string range $n 0 end-5]
+        set n [string range $n 0 end-5]
     }
     return [file tail $n]
 }
@@ -26,7 +26,7 @@
 proc gitworktree {} {
     variable _gitworktree
     if {[info exists _gitworktree]} {
-	return $_gitworktree
+        return $_gitworktree
     }
     # v1.7.0 introduced --show-toplevel to return the canonical work-tree
     if {[catch {set _gitworktree [exec git rev-parse --show-toplevel]}]} {
@@ -34,10 +34,9 @@
         # cdup to obtain a relative path to the top of the worktree. If
         # run from the top, the ./ prefix ensures normalize expands pwd.
         if {[catch { set _gitworktree $env(GIT_WORK_TREE) }]} {
-	    catch {set _gitworktree [exec git config --get core.worktree]}
-	    if {$_gitworktree eq ""} {
-		set _gitworktree [file normalize ./[exec git rev-parse --show-cdup]]
-	    }
+            if {[catch {set _gitworktree [exec git config --get core.worktree]}]} {
+                set _gitworktree [file normalize ./[exec git rev-parse --show-cdup]]
+            }
         }
     }
     return $_gitworktree
@@ -54,7 +53,7 @@
     set script $args
     if {[info exists isonrunq($script)]} return
     if {$runq eq {} && ![info exists currunq]} {
-	after idle dorunq
+        after idle dorunq
     }
     lappend runq [list {} $script]
     set isonrunq($script) 1
@@ -69,7 +68,7 @@
 
     fileevent $fd readable {}
     if {$runq eq {} && ![info exists currunq]} {
-	after idle dorunq
+        after idle dorunq
     }
     lappend runq [list $fd $script]
 }
@@ -78,11 +77,11 @@
     global runq
 
     for {set i 0} {$i < [llength $runq]} {} {
-	if {[lindex $runq $i 0] eq $fd} {
-	    set runq [lreplace $runq $i $i]
-	} else {
-	    incr i
-	}
+        if {[lindex $runq $i 0] eq $fd} {
+            set runq [lreplace $runq $i $i]
+        } else {
+            incr i
+        }
     }
 }
 
@@ -92,30 +91,30 @@
     set tstart [clock clicks -milliseconds]
     set t0 $tstart
     while {[llength $runq] > 0} {
-	set fd [lindex $runq 0 0]
-	set script [lindex $runq 0 1]
-	set currunq [lindex $runq 0]
-	set runq [lrange $runq 1 end]
-	set repeat [eval $script]
-	unset currunq
-	set t1 [clock clicks -milliseconds]
-	set t [expr {$t1 - $t0}]
-	if {$repeat ne {} && $repeat} {
-	    if {$fd eq {} || $repeat == 2} {
-		# script returns 1 if it wants to be readded
-		# file readers return 2 if they could do more straight away
-		lappend runq [list $fd $script]
-	    } else {
-		fileevent $fd readable [list filereadable $fd $script]
-	    }
-	} elseif {$fd eq {}} {
-	    unset isonrunq($script)
-	}
-	set t0 $t1
-	if {$t1 - $tstart >= 80} break
+        set fd [lindex $runq 0 0]
+        set script [lindex $runq 0 1]
+        set currunq [lindex $runq 0]
+        set runq [lrange $runq 1 end]
+        set repeat [eval $script]
+        unset currunq
+        set t1 [clock clicks -milliseconds]
+        set t [expr {$t1 - $t0}]
+        if {$repeat ne {} && $repeat} {
+            if {$fd eq {} || $repeat == 2} {
+                # script returns 1 if it wants to be readded
+                # file readers return 2 if they could do more straight away
+                lappend runq [list $fd $script]
+            } else {
+                fileevent $fd readable [list filereadable $fd $script]
+            }
+        } elseif {$fd eq {}} {
+            unset isonrunq($script)
+        }
+        set t0 $t1
+        if {$t1 - $tstart >= 80} break
     }
     if {$runq ne {}} {
-	after idle dorunq
+        after idle dorunq
     }
 }
 
@@ -135,20 +134,20 @@
     set mlist {}
     set nr_unmerged 0
     if {[catch {
-	set fd [open "| git ls-files -u" r]
+        set fd [open "| git ls-files -u" r]
     } err]} {
-	show_error {} . "[mc "Couldn't get list of unmerged files:"] $err"
-	exit 1
+        show_error {} . "[mc "Couldn't get list of unmerged files:"] $err"
+        exit 1
     }
     while {[gets $fd line] >= 0} {
-	set i [string first "\t" $line]
-	if {$i < 0} continue
-	set fname [string range $line [expr {$i+1}] end]
-	if {[lsearch -exact $mlist $fname] >= 0} continue
-	incr nr_unmerged
-	if {$files eq {} || [path_filter $files $fname]} {
-	    lappend mlist $fname
-	}
+        set i [string first "\t" $line]
+        if {$i < 0} continue
+        set fname [string range $line [expr {$i+1}] end]
+        if {[lsearch -exact $mlist $fname] >= 0} continue
+        incr nr_unmerged
+        if {$files eq {} || [path_filter $files $fname]} {
+            lappend mlist $fname
+        }
     }
     catch {close $fd}
     return $mlist
@@ -171,115 +170,115 @@
     set filtered 0
     set i -1
     foreach arg $arglist {
-	incr i
-	if {$nextisval} {
-	    lappend glflags $arg
-	    set nextisval 0
-	    continue
-	}
-	switch -glob -- $arg {
-	    "-d" -
-	    "--date-order" {
-		set vdatemode($n) 1
-		# remove from origargs in case we hit an unknown option
-		set origargs [lreplace $origargs $i $i]
-		incr i -1
-	    }
-	    "-[puabwcrRBMC]" -
-	    "--no-renames" - "--full-index" - "--binary" - "--abbrev=*" -
-	    "--find-copies-harder" - "-l*" - "--ext-diff" - "--no-ext-diff" -
-	    "--src-prefix=*" - "--dst-prefix=*" - "--no-prefix" -
-	    "-O*" - "--text" - "--full-diff" - "--ignore-space-at-eol" -
-	    "--ignore-space-change" - "-U*" - "--unified=*" {
-		# These request or affect diff output, which we don't want.
-		# Some could be used to set our defaults for diff display.
-		lappend diffargs $arg
-	    }
-	    "--raw" - "--patch-with-raw" - "--patch-with-stat" -
-	    "--name-only" - "--name-status" - "--color" -
-	    "--log-size" - "--pretty=*" - "--decorate" - "--abbrev-commit" -
-	    "--cc" - "-z" - "--header" - "--parents" - "--boundary" -
-	    "--no-color" - "-g" - "--walk-reflogs" - "--no-walk" -
-	    "--timestamp" - "relative-date" - "--date=*" - "--stdin" -
-	    "--objects" - "--objects-edge" - "--reverse" {
-		# These cause our parsing of git log's output to fail, or else
-		# they're options we want to set ourselves, so ignore them.
-	    }
-	    "--color-words*" - "--word-diff=color" {
-		# These trigger a word diff in the console interface,
-		# so help the user by enabling our own support
-		if {[package vcompare $git_version "1.7.2"] >= 0} {
-		    set worddiff [mc "Color words"]
-		}
-	    }
-	    "--word-diff*" {
-		if {[package vcompare $git_version "1.7.2"] >= 0} {
-		    set worddiff [mc "Markup words"]
-		}
-	    }
-	    "--stat=*" - "--numstat" - "--shortstat" - "--summary" -
-	    "--check" - "--exit-code" - "--quiet" - "--topo-order" -
-	    "--full-history" - "--dense" - "--sparse" -
-	    "--follow" - "--left-right" - "--encoding=*" {
-		# These are harmless, and some are even useful
-		lappend glflags $arg
-	    }
-	    "--diff-filter=*" - "--no-merges" - "--unpacked" -
-	    "--max-count=*" - "--skip=*" - "--since=*" - "--after=*" -
-	    "--until=*" - "--before=*" - "--max-age=*" - "--min-age=*" -
-	    "--author=*" - "--committer=*" - "--grep=*" - "-[iE]" -
-	    "--remove-empty" - "--first-parent" - "--cherry-pick" -
-	    "-S*" - "-G*" - "--pickaxe-all" - "--pickaxe-regex" -
-	    "--simplify-by-decoration" {
-		# These mean that we get a subset of the commits
-		set filtered 1
-		lappend glflags $arg
-	    }
-	    "-L*" {
-		# Line-log with 'stuck' argument (unstuck form is
-		# not supported)
-		set filtered 1
-		set vinlinediff($n) 1
-		set allknown 0
-		lappend glflags $arg
-	    }
-	    "-n" {
-		# This appears to be the only one that has a value as a
-		# separate word following it
-		set filtered 1
-		set nextisval 1
-		lappend glflags $arg
-	    }
-	    "--not" - "--all" {
-		lappend revargs $arg
-	    }
-	    "--merge" {
-		set vmergeonly($n) 1
-		# git rev-parse doesn't understand --merge
-		lappend revargs --gitk-symmetric-diff-marker MERGE_HEAD...HEAD
-	    }
-	    "--no-replace-objects" {
-		set env(GIT_NO_REPLACE_OBJECTS) "1"
-	    }
-	    "-*" {
-		# Other flag arguments including -<n>
-		if {[string is digit -strict [string range $arg 1 end]]} {
-		    set filtered 1
-		} else {
-		    # a flag argument that we don't recognize;
-		    # that means we can't optimize
-		    set allknown 0
-		}
-		lappend glflags $arg
-	    }
-	    default {
-		# Non-flag arguments specify commits or ranges of commits
-		if {[string match "*...*" $arg]} {
-		    lappend revargs --gitk-symmetric-diff-marker
-		}
-		lappend revargs $arg
-	    }
-	}
+        incr i
+        if {$nextisval} {
+            lappend glflags $arg
+            set nextisval 0
+            continue
+        }
+        switch -glob -- $arg {
+            "-d" -
+            "--date-order" {
+                set vdatemode($n) 1
+                # remove from origargs in case we hit an unknown option
+                set origargs [lreplace $origargs $i $i]
+                incr i -1
+            }
+            "-[puabwcrRBMC]" -
+            "--no-renames" - "--full-index" - "--binary" - "--abbrev=*" -
+            "--find-copies-harder" - "-l*" - "--ext-diff" - "--no-ext-diff" -
+            "--src-prefix=*" - "--dst-prefix=*" - "--no-prefix" -
+            "-O*" - "--text" - "--full-diff" - "--ignore-space-at-eol" -
+            "--ignore-space-change" - "-U*" - "--unified=*" {
+                # These request or affect diff output, which we don't want.
+                # Some could be used to set our defaults for diff display.
+                lappend diffargs $arg
+            }
+            "--raw" - "--patch-with-raw" - "--patch-with-stat" -
+            "--name-only" - "--name-status" - "--color" -
+            "--log-size" - "--pretty=*" - "--decorate" - "--abbrev-commit" -
+            "--cc" - "-z" - "--header" - "--parents" - "--boundary" -
+            "--no-color" - "-g" - "--walk-reflogs" - "--no-walk" -
+            "--timestamp" - "relative-date" - "--date=*" - "--stdin" -
+            "--objects" - "--objects-edge" - "--reverse" {
+                # These cause our parsing of git log's output to fail, or else
+                # they're options we want to set ourselves, so ignore them.
+            }
+            "--color-words*" - "--word-diff=color" {
+                # These trigger a word diff in the console interface,
+                # so help the user by enabling our own support
+                if {[package vcompare $git_version "1.7.2"] >= 0} {
+                    set worddiff [mc "Color words"]
+                }
+            }
+            "--word-diff*" {
+                if {[package vcompare $git_version "1.7.2"] >= 0} {
+                    set worddiff [mc "Markup words"]
+                }
+            }
+            "--stat=*" - "--numstat" - "--shortstat" - "--summary" -
+            "--check" - "--exit-code" - "--quiet" - "--topo-order" -
+            "--full-history" - "--dense" - "--sparse" -
+            "--follow" - "--left-right" - "--encoding=*" {
+                # These are harmless, and some are even useful
+                lappend glflags $arg
+            }
+            "--diff-filter=*" - "--no-merges" - "--unpacked" -
+            "--max-count=*" - "--skip=*" - "--since=*" - "--after=*" -
+            "--until=*" - "--before=*" - "--max-age=*" - "--min-age=*" -
+            "--author=*" - "--committer=*" - "--grep=*" - "-[iE]" -
+            "--remove-empty" - "--first-parent" - "--cherry-pick" -
+            "-S*" - "-G*" - "--pickaxe-all" - "--pickaxe-regex" -
+            "--simplify-by-decoration" {
+                # These mean that we get a subset of the commits
+                set filtered 1
+                lappend glflags $arg
+            }
+            "-L*" {
+                # Line-log with 'stuck' argument (unstuck form is
+                # not supported)
+                set filtered 1
+                set vinlinediff($n) 1
+                set allknown 0
+                lappend glflags $arg
+            }
+            "-n" {
+                # This appears to be the only one that has a value as a
+                # separate word following it
+                set filtered 1
+                set nextisval 1
+                lappend glflags $arg
+            }
+            "--not" - "--all" {
+                lappend revargs $arg
+            }
+            "--merge" {
+                set vmergeonly($n) 1
+                # git rev-parse doesn't understand --merge
+                lappend revargs --gitk-symmetric-diff-marker MERGE_HEAD...HEAD
+            }
+            "--no-replace-objects" {
+                set env(GIT_NO_REPLACE_OBJECTS) "1"
+            }
+            "-*" {
+                # Other flag arguments including -<n>
+                if {[string is digit -strict [string range $arg 1 end]]} {
+                    set filtered 1
+                } else {
+                    # a flag argument that we don't recognize;
+                    # that means we can't optimize
+                    set allknown 0
+                }
+                lappend glflags $arg
+            }
+            default {
+                # Non-flag arguments specify commits or ranges of commits
+                if {[string match "*...*" $arg]} {
+                    lappend revargs --gitk-symmetric-diff-marker
+                }
+                lappend revargs $arg
+            }
+        }
     }
     set vdflags($n) $diffargs
     set vflags($n) $glflags
@@ -293,61 +292,61 @@
     global vposids vnegids
 
     if {$revs eq {}} {
-	set revs HEAD
+        set revs HEAD
     } elseif {[lsearch -exact $revs --all] >= 0} {
-	lappend revs HEAD
+        lappend revs HEAD
     }
     if {[catch {set ids [eval exec git rev-parse $revs]} err]} {
-	# we get stdout followed by stderr in $err
-	# for an unknown rev, git rev-parse echoes it and then errors out
-	set errlines [split $err "\n"]
-	set badrev {}
-	for {set l 0} {$l < [llength $errlines]} {incr l} {
-	    set line [lindex $errlines $l]
-	    if {!([string length $line] == 40 && [string is xdigit $line])} {
-		if {[string match "fatal:*" $line]} {
-		    if {[string match "fatal: ambiguous argument*" $line]
-			&& $badrev ne {}} {
-			if {[llength $badrev] == 1} {
-			    set err "unknown revision $badrev"
-			} else {
-			    set err "unknown revisions: [join $badrev ", "]"
-			}
-		    } else {
-			set err [join [lrange $errlines $l end] "\n"]
-		    }
-		    break
-		}
-		lappend badrev $line
-	    }
-	}
-	error_popup "[mc "Error parsing revisions:"] $err"
-	return {}
+        # we get stdout followed by stderr in $err
+        # for an unknown rev, git rev-parse echoes it and then errors out
+        set errlines [split $err "\n"]
+        set badrev {}
+        for {set l 0} {$l < [llength $errlines]} {incr l} {
+            set line [lindex $errlines $l]
+            if {!([string length $line] == 40 && [string is xdigit $line])} {
+                if {[string match "fatal:*" $line]} {
+                    if {[string match "fatal: ambiguous argument*" $line]
+                        && $badrev ne {}} {
+                        if {[llength $badrev] == 1} {
+                            set err "unknown revision $badrev"
+                        } else {
+                            set err "unknown revisions: [join $badrev ", "]"
+                        }
+                    } else {
+                        set err [join [lrange $errlines $l end] "\n"]
+                    }
+                    break
+                }
+                lappend badrev $line
+            }
+        }
+        error_popup "[mc "Error parsing revisions:"] $err"
+        return {}
     }
     set ret {}
     set pos {}
     set neg {}
     set sdm 0
     foreach id [split $ids "\n"] {
-	if {$id eq "--gitk-symmetric-diff-marker"} {
-	    set sdm 4
-	} elseif {[string match "^*" $id]} {
-	    if {$sdm != 1} {
-		lappend ret $id
-		if {$sdm == 3} {
-		    set sdm 0
-		}
-	    }
-	    lappend neg [string range $id 1 end]
-	} else {
-	    if {$sdm != 2} {
-		lappend ret $id
-	    } else {
-		lset ret end $id...[lindex $ret end]
-	    }
-	    lappend pos $id
-	}
-	incr sdm -1
+        if {$id eq "--gitk-symmetric-diff-marker"} {
+            set sdm 4
+        } elseif {[string match "^*" $id]} {
+            if {$sdm != 1} {
+                lappend ret $id
+                if {$sdm == 3} {
+                    set sdm 0
+                }
+            }
+            lappend neg [string range $id 1 end]
+        } else {
+            if {$sdm != 2} {
+                lappend ret $id
+            } else {
+                lset ret end $id...[lindex $ret end]
+            }
+            lappend pos $id
+        }
+        incr sdm -1
     }
     set vposids($view) $pos
     set vnegids($view) $neg
@@ -374,63 +373,63 @@
 
     set args $viewargs($view)
     if {$viewargscmd($view) ne {}} {
-	if {[catch {
-	    set str [exec sh -c $viewargscmd($view)]
-	} err]} {
-	    error_popup "[mc "Error executing --argscmd command:"] $err"
-	    return 0
-	}
-	set args [concat $args [split $str "\n"]]
+        if {[catch {
+            set str [exec sh -c $viewargscmd($view)]
+        } err]} {
+            error_popup "[mc "Error executing --argscmd command:"] $err"
+            return 0
+        }
+        set args [concat $args [split $str "\n"]]
     }
     set vcanopt($view) [parseviewargs $view $args]
 
     set files $viewfiles($view)
     if {$vmergeonly($view)} {
-	set files [unmerged_files $files]
-	if {$files eq {}} {
-	    global nr_unmerged
-	    if {$nr_unmerged == 0} {
-		error_popup [mc "No files selected: --merge specified but\
-			     no files are unmerged."]
-	    } else {
-		error_popup [mc "No files selected: --merge specified but\
-			     no unmerged files are within file limit."]
-	    }
-	    return 0
-	}
+        set files [unmerged_files $files]
+        if {$files eq {}} {
+            global nr_unmerged
+            if {$nr_unmerged == 0} {
+                error_popup [mc "No files selected: --merge specified but\
+                             no files are unmerged."]
+            } else {
+                error_popup [mc "No files selected: --merge specified but\
+                             no unmerged files are within file limit."]
+            }
+            return 0
+        }
     }
     set vfilelimit($view) $files
 
     if {$vcanopt($view)} {
-	set revs [parseviewrevs $view $vrevs($view)]
-	if {$revs eq {}} {
-	    return 0
-	}
-	set args [concat $vflags($view) $revs]
+        set revs [parseviewrevs $view $vrevs($view)]
+        if {$revs eq {}} {
+            return 0
+        }
+        set args [concat $vflags($view) $revs]
     } else {
-	set args $vorigargs($view)
+        set args $vorigargs($view)
     }
 
     if {[catch {
-	set fd [open [concat | git log --no-color -z --pretty=raw $show_notes \
-			--parents --boundary $args "--" $files] r]
+        set fd [open [concat | git log --no-color -z --pretty=raw $show_notes \
+                        --parents --boundary $args "--" $files] r]
     } err]} {
-	error_popup "[mc "Error executing git log:"] $err"
-	return 0
+        error_popup "[mc "Error executing git log:"] $err"
+        return 0
     }
     set i [reg_instance $fd]
     set viewinstances($view) [list $i]
     set viewmainheadid($view) $mainheadid
     set viewmainheadid_orig($view) $mainheadid
     if {$files ne {} && $mainheadid ne {}} {
-	get_viewmainhead $view
+        get_viewmainhead $view
     }
     if {$showlocalchanges && $viewmainheadid($view) ne {}} {
-	interestedin $viewmainheadid($view) dodiffindex
+        interestedin $viewmainheadid($view) dodiffindex
     }
     fconfigure $fd -blocking 0 -translation lf -eofchar {}
     if {$tclencoding != {}} {
-	fconfigure $fd -encoding $tclencoding
+        fconfigure $fd -encoding $tclencoding
     }
     filerun $fd [list getcommitlines $fd $i $view 0]
     nowbusy $view [mc "Reading"]
@@ -444,13 +443,13 @@
 
     set fd $commfd($inst)
     catch {
-	set pid [pid $fd]
+        set pid [pid $fd]
 
-	if {$::tcl_platform(platform) eq {windows}} {
-	    exec taskkill /pid $pid
-	} else {
-	    exec kill $pid
-	}
+        if {$::tcl_platform(platform) eq {windows}} {
+            exec taskkill /pid $pid
+        } else {
+            exec kill $pid
+        }
     }
     catch {close $fd}
     nukefile $fd
@@ -462,7 +461,7 @@
     global commfd
 
     foreach inst [array names commfd] {
-	stop_instance $inst
+        stop_instance $inst
     }
 }
 
@@ -470,7 +469,7 @@
     global viewinstances
 
     foreach inst $viewinstances($view) {
-	stop_instance $inst
+        stop_instance $inst
     }
     set viewinstances($view) {}
 }
@@ -479,11 +478,11 @@
     global pending_select mainheadid selectheadid
 
     if {$selid ne {}} {
-	set pending_select $selid
+        set pending_select $selid
     } elseif {$selectheadid ne {}} {
-	set pending_select $selectheadid
+        set pending_select $selectheadid
     } else {
-	set pending_select $mainheadid
+        set pending_select $mainheadid
     }
 }
 
@@ -492,11 +491,11 @@
 
     initlayout
     if {[start_rev_list $curview]} {
-	reset_pending_select $selid
-	show_status [mc "Reading commits..."]
-	set need_redisplay 1
+        reset_pending_select $selid
+        show_status [mc "Reading commits..."]
+        set need_redisplay 1
     } else {
-	show_status [mc "No commits selected"]
+        show_status [mc "No commits selected"]
     }
 }
 
@@ -513,67 +512,67 @@
     rereadrefs
     set view $curview
     if {$mainheadid ne $viewmainheadid_orig($view)} {
-	if {$showlocalchanges} {
-	    dohidelocalchanges
-	}
-	set viewmainheadid($view) $mainheadid
-	set viewmainheadid_orig($view) $mainheadid
-	if {$vfilelimit($view) ne {}} {
-	    get_viewmainhead $view
-	}
+        if {$showlocalchanges} {
+            dohidelocalchanges
+        }
+        set viewmainheadid($view) $mainheadid
+        set viewmainheadid_orig($view) $mainheadid
+        if {$vfilelimit($view) ne {}} {
+            get_viewmainhead $view
+        }
     }
     if {$showlocalchanges} {
-	doshowlocalchanges
+        doshowlocalchanges
     }
     if {$vcanopt($view)} {
-	set oldpos $vposids($view)
-	set oldneg $vnegids($view)
-	set revs [parseviewrevs $view $vrevs($view)]
-	if {$revs eq {}} {
-	    return
-	}
-	# note: getting the delta when negative refs change is hard,
-	# and could require multiple git log invocations, so in that
-	# case we ask git log for all the commits (not just the delta)
-	if {$oldneg eq $vnegids($view)} {
-	    set newrevs {}
-	    set npos 0
-	    # take out positive refs that we asked for before or
-	    # that we have already seen
-	    foreach rev $revs {
-		if {[string length $rev] == 40} {
-		    if {[lsearch -exact $oldpos $rev] < 0
-			&& ![info exists varcid($view,$rev)]} {
-			lappend newrevs $rev
-			incr npos
-		    }
-		} else {
-		    lappend $newrevs $rev
-		}
-	    }
-	    if {$npos == 0} return
-	    set revs $newrevs
-	    set vposids($view) [lsort -unique [concat $oldpos $vposids($view)]]
-	}
-	set args [concat $vflags($view) $revs --not $oldpos]
+        set oldpos $vposids($view)
+        set oldneg $vnegids($view)
+        set revs [parseviewrevs $view $vrevs($view)]
+        if {$revs eq {}} {
+            return
+        }
+        # note: getting the delta when negative refs change is hard,
+        # and could require multiple git log invocations, so in that
+        # case we ask git log for all the commits (not just the delta)
+        if {$oldneg eq $vnegids($view)} {
+            set newrevs {}
+            set npos 0
+            # take out positive refs that we asked for before or
+            # that we have already seen
+            foreach rev $revs {
+                if {[string length $rev] == 40} {
+                    if {[lsearch -exact $oldpos $rev] < 0
+                        && ![info exists varcid($view,$rev)]} {
+                        lappend newrevs $rev
+                        incr npos
+                    }
+                } else {
+                    lappend $newrevs $rev
+                }
+            }
+            if {$npos == 0} return
+            set revs $newrevs
+            set vposids($view) [lsort -unique [concat $oldpos $vposids($view)]]
+        }
+        set args [concat $vflags($view) $revs --not $oldpos]
     } else {
-	set args $vorigargs($view)
+        set args $vorigargs($view)
     }
     if {[catch {
-	set fd [open [concat | git log --no-color -z --pretty=raw $show_notes \
-			--parents --boundary $args "--" $vfilelimit($view)] r]
+        set fd [open [concat | git log --no-color -z --pretty=raw $show_notes \
+                        --parents --boundary $args "--" $vfilelimit($view)] r]
     } err]} {
-	error_popup "[mc "Error executing git log:"] $err"
-	return
+        error_popup "[mc "Error executing git log:"] $err"
+        return
     }
     if {$viewactive($view) == 0} {
-	set startmsecs [clock clicks -milliseconds]
+        set startmsecs [clock clicks -milliseconds]
     }
     set i [reg_instance $fd]
     lappend viewinstances($view) $i
     fconfigure $fd -blocking 0 -translation lf -eofchar {}
     if {$tclencoding != {}} {
-	fconfigure $fd -encoding $tclencoding
+        fconfigure $fd -encoding $tclencoding
     }
     filerun $fd [list getcommitlines $fd $i $view 1]
     incr viewactive($view)
@@ -581,7 +580,7 @@
     reset_pending_select {}
     nowbusy $view [mc "Reading"]
     if {$showneartags} {
-	getallcommits
+        getallcommits
     }
 }
 
@@ -592,11 +591,11 @@
 
     set selid {}
     if {$selectedline ne {}} {
-	set selid $currentid
+        set selid $currentid
     }
 
     if {!$viewcomplete($curview)} {
-	stop_rev_list $curview
+        stop_rev_list $curview
     }
     resetvarcs $curview
     set selectedline {}
@@ -606,7 +605,7 @@
     readrefs
     changedrefs
     if {$showneartags} {
-	getallcommits
+        getallcommits
     }
     clear_display
     unset -nocomplain commitinfo
@@ -622,11 +621,11 @@
 # sorts as a string in numerical order
 proc strrep {n} {
     if {$n < 16} {
-	return [format "%x" $n]
+        return [format "%x" $n]
     } elseif {$n < 256} {
-	return [format "x%.2x" $n]
+        return [format "x%.2x" $n]
     } elseif {$n < 65536} {
-	return [format "y%.4x" $n]
+        return [format "y%.4x" $n]
     }
     return [format "z%.8x" $n]
 }
@@ -657,22 +656,22 @@
     global vshortids
 
     foreach vid [array names varcid $view,*] {
-	unset varcid($vid)
-	unset children($vid)
-	unset parents($vid)
+        unset varcid($vid)
+        unset children($vid)
+        unset parents($vid)
     }
     foreach vid [array names vshortids $view,*] {
-	unset vshortids($vid)
+        unset vshortids($vid)
     }
     # some commits might have children but haven't been seen yet
     foreach vid [array names children $view,*] {
-	unset children($vid)
+        unset children($vid)
     }
     foreach va [array names varccommits $view,*] {
-	unset varccommits($va)
+        unset varccommits($va)
     }
     foreach vd [array names vseedcount $view,*] {
-	unset vseedcount($vd)
+        unset vseedcount($vd)
     }
     unset -nocomplain ordertok
 }
@@ -684,8 +683,8 @@
     set ret {}
     set a [lindex $vdownptr($v) 0]
     while {$a != 0} {
-	lappend ret [lindex $varcstart($v) $a]
-	set a [lindex $vleftptr($v) $a]
+        lappend ret [lindex $varcstart($v) $a]
+        set a [lindex $vleftptr($v) $a]
     }
     return $ret
 }
@@ -698,60 +697,60 @@
     set a [llength $varctok($view)]
     set vid $view,$id
     if {[llength $children($vid)] == 0 || $vdatemode($view)} {
-	if {![info exists commitinfo($id)]} {
-	    parsecommit $id $commitdata($id) 1
-	}
-	set cdate [lindex [lindex $commitinfo($id) 4] 0]
-	if {![string is integer -strict $cdate]} {
-	    set cdate 0
-	}
-	if {![info exists vseedcount($view,$cdate)]} {
-	    set vseedcount($view,$cdate) -1
-	}
-	set c [incr vseedcount($view,$cdate)]
-	set cdate [expr {$cdate ^ 0xffffffff}]
-	set tok "s[strrep $cdate][strrep $c]"
+        if {![info exists commitinfo($id)]} {
+            parsecommit $id $commitdata($id) 1
+        }
+        set cdate [lindex [lindex $commitinfo($id) 4] 0]
+        if {![string is integer -strict $cdate]} {
+            set cdate 0
+        }
+        if {![info exists vseedcount($view,$cdate)]} {
+            set vseedcount($view,$cdate) -1
+        }
+        set c [incr vseedcount($view,$cdate)]
+        set cdate [expr {$cdate ^ 0xffffffff}]
+        set tok "s[strrep $cdate][strrep $c]"
     } else {
-	set tok {}
+        set tok {}
     }
     set ka 0
     if {[llength $children($vid)] > 0} {
-	set kid [lindex $children($vid) end]
-	set k $varcid($view,$kid)
-	if {[string compare [lindex $varctok($view) $k] $tok] > 0} {
-	    set ki $kid
-	    set ka $k
-	    set tok [lindex $varctok($view) $k]
-	}
+        set kid [lindex $children($vid) end]
+        set k $varcid($view,$kid)
+        if {[string compare [lindex $varctok($view) $k] $tok] > 0} {
+            set ki $kid
+            set ka $k
+            set tok [lindex $varctok($view) $k]
+        }
     }
     if {$ka != 0} {
-	set i [lsearch -exact $parents($view,$ki) $id]
-	set j [expr {[llength $parents($view,$ki)] - 1 - $i}]
-	append tok [strrep $j]
+        set i [lsearch -exact $parents($view,$ki) $id]
+        set j [expr {[llength $parents($view,$ki)] - 1 - $i}]
+        append tok [strrep $j]
     }
     set c [lindex $vlastins($view) $ka]
     if {$c == 0 || [string compare $tok [lindex $varctok($view) $c]] < 0} {
-	set c $ka
-	set b [lindex $vdownptr($view) $ka]
+        set c $ka
+        set b [lindex $vdownptr($view) $ka]
     } else {
-	set b [lindex $vleftptr($view) $c]
+        set b [lindex $vleftptr($view) $c]
     }
     while {$b != 0 && [string compare $tok [lindex $varctok($view) $b]] >= 0} {
-	set c $b
-	set b [lindex $vleftptr($view) $c]
+        set c $b
+        set b [lindex $vleftptr($view) $c]
     }
     if {$c == $ka} {
-	lset vdownptr($view) $ka $a
-	lappend vbackptr($view) 0
+        lset vdownptr($view) $ka $a
+        lappend vbackptr($view) 0
     } else {
-	lset vleftptr($view) $c $a
-	lappend vbackptr($view) $c
+        lset vleftptr($view) $c $a
+        lappend vbackptr($view) $c
     }
     lset vlastins($view) $ka $a
     lappend vupptr($view) $ka
     lappend vleftptr($view) $b
     if {$b != 0} {
-	lset vbackptr($view) $b $a
+        lset vbackptr($view) $b $a
     }
     lappend varctok($view) $tok
     lappend varcstart($view) $id
@@ -782,7 +781,7 @@
     set varccommits($v,$na) [lrange $ac $i end]
     lappend varcstart($v) $p
     foreach id $varccommits($v,$na) {
-	set varcid($v,$id) $na
+        set varcid($v,$id) $na
     }
     lappend vdownptr($v) [lindex $vdownptr($v) $oa]
     lappend vlastins($v) [lindex $vlastins($v) $oa]
@@ -792,10 +791,10 @@
     lappend vleftptr($v) 0
     lappend vbackptr($v) 0
     for {set b [lindex $vdownptr($v) $na]} {$b != 0} {set b [lindex $vleftptr($v) $b]} {
-	lset vupptr($v) $b $na
+        lset vupptr($v) $b $na
     }
     if {[string compare $otok $vtokmod($v)] <= 0} {
-	modify_arc $v $oa
+        modify_arc $v $oa
     }
 }
 
@@ -809,120 +808,120 @@
     set kidchanged($a) 1
     set ntot 0
     while {$a != 0} {
-	if {[info exists isrelated($a)]} {
-	    lappend todo $a
-	    set id [lindex $varccommits($v,$a) end]
-	    foreach p $parents($v,$id) {
-		if {[info exists varcid($v,$p)]} {
-		    set isrelated($varcid($v,$p)) 1
-		}
-	    }
-	}
-	incr ntot
-	set b [lindex $vdownptr($v) $a]
-	if {$b == 0} {
-	    while {$a != 0} {
-		set b [lindex $vleftptr($v) $a]
-		if {$b != 0} break
-		set a [lindex $vupptr($v) $a]
-	    }
-	}
-	set a $b
+        if {[info exists isrelated($a)]} {
+            lappend todo $a
+            set id [lindex $varccommits($v,$a) end]
+            foreach p $parents($v,$id) {
+                if {[info exists varcid($v,$p)]} {
+                    set isrelated($varcid($v,$p)) 1
+                }
+            }
+        }
+        incr ntot
+        set b [lindex $vdownptr($v) $a]
+        if {$b == 0} {
+            while {$a != 0} {
+                set b [lindex $vleftptr($v) $a]
+                if {$b != 0} break
+                set a [lindex $vupptr($v) $a]
+            }
+        }
+        set a $b
     }
     foreach a $todo {
-	if {![info exists kidchanged($a)]} continue
-	set id [lindex $varcstart($v) $a]
-	if {[llength $children($v,$id)] > 1} {
-	    set children($v,$id) [lsort -command [list vtokcmp $v] \
-				      $children($v,$id)]
-	}
-	set oldtok [lindex $varctok($v) $a]
-	if {!$vdatemode($v)} {
-	    set tok {}
-	} else {
-	    set tok $oldtok
-	}
-	set ka 0
-	set kid [last_real_child $v,$id]
-	if {$kid ne {}} {
-	    set k $varcid($v,$kid)
-	    if {[string compare [lindex $varctok($v) $k] $tok] > 0} {
-		set ki $kid
-		set ka $k
-		set tok [lindex $varctok($v) $k]
-	    }
-	}
-	if {$ka != 0} {
-	    set i [lsearch -exact $parents($v,$ki) $id]
-	    set j [expr {[llength $parents($v,$ki)] - 1 - $i}]
-	    append tok [strrep $j]
-	}
-	if {$tok eq $oldtok} {
-	    continue
-	}
-	set id [lindex $varccommits($v,$a) end]
-	foreach p $parents($v,$id) {
-	    if {[info exists varcid($v,$p)]} {
-		set kidchanged($varcid($v,$p)) 1
-	    } else {
-		set sortkids($p) 1
-	    }
-	}
-	lset varctok($v) $a $tok
-	set b [lindex $vupptr($v) $a]
-	if {$b != $ka} {
-	    if {[string compare [lindex $varctok($v) $ka] $vtokmod($v)] < 0} {
-		modify_arc $v $ka
-	    }
-	    if {[string compare [lindex $varctok($v) $b] $vtokmod($v)] < 0} {
-		modify_arc $v $b
-	    }
-	    set c [lindex $vbackptr($v) $a]
-	    set d [lindex $vleftptr($v) $a]
-	    if {$c == 0} {
-		lset vdownptr($v) $b $d
-	    } else {
-		lset vleftptr($v) $c $d
-	    }
-	    if {$d != 0} {
-		lset vbackptr($v) $d $c
-	    }
-	    if {[lindex $vlastins($v) $b] == $a} {
-		lset vlastins($v) $b $c
-	    }
-	    lset vupptr($v) $a $ka
-	    set c [lindex $vlastins($v) $ka]
-	    if {$c == 0 || \
-		    [string compare $tok [lindex $varctok($v) $c]] < 0} {
-		set c $ka
-		set b [lindex $vdownptr($v) $ka]
-	    } else {
-		set b [lindex $vleftptr($v) $c]
-	    }
-	    while {$b != 0 && \
-		      [string compare $tok [lindex $varctok($v) $b]] >= 0} {
-		set c $b
-		set b [lindex $vleftptr($v) $c]
-	    }
-	    if {$c == $ka} {
- 		lset vdownptr($v) $ka $a
-		lset vbackptr($v) $a 0
-	    } else {
-		lset vleftptr($v) $c $a
-		lset vbackptr($v) $a $c
-	    }
-	    lset vleftptr($v) $a $b
-	    if {$b != 0} {
-		lset vbackptr($v) $b $a
-	    }
-	    lset vlastins($v) $ka $a
-	}
+        if {![info exists kidchanged($a)]} continue
+        set id [lindex $varcstart($v) $a]
+        if {[llength $children($v,$id)] > 1} {
+            set children($v,$id) [lsort -command [list vtokcmp $v] \
+                                      $children($v,$id)]
+        }
+        set oldtok [lindex $varctok($v) $a]
+        if {!$vdatemode($v)} {
+            set tok {}
+        } else {
+            set tok $oldtok
+        }
+        set ka 0
+        set kid [last_real_child $v,$id]
+        if {$kid ne {}} {
+            set k $varcid($v,$kid)
+            if {[string compare [lindex $varctok($v) $k] $tok] > 0} {
+                set ki $kid
+                set ka $k
+                set tok [lindex $varctok($v) $k]
+            }
+        }
+        if {$ka != 0} {
+            set i [lsearch -exact $parents($v,$ki) $id]
+            set j [expr {[llength $parents($v,$ki)] - 1 - $i}]
+            append tok [strrep $j]
+        }
+        if {$tok eq $oldtok} {
+            continue
+        }
+        set id [lindex $varccommits($v,$a) end]
+        foreach p $parents($v,$id) {
+            if {[info exists varcid($v,$p)]} {
+                set kidchanged($varcid($v,$p)) 1
+            } else {
+                set sortkids($p) 1
+            }
+        }
+        lset varctok($v) $a $tok
+        set b [lindex $vupptr($v) $a]
+        if {$b != $ka} {
+            if {[string compare [lindex $varctok($v) $ka] $vtokmod($v)] < 0} {
+                modify_arc $v $ka
+            }
+            if {[string compare [lindex $varctok($v) $b] $vtokmod($v)] < 0} {
+                modify_arc $v $b
+            }
+            set c [lindex $vbackptr($v) $a]
+            set d [lindex $vleftptr($v) $a]
+            if {$c == 0} {
+                lset vdownptr($v) $b $d
+            } else {
+                lset vleftptr($v) $c $d
+            }
+            if {$d != 0} {
+                lset vbackptr($v) $d $c
+            }
+            if {[lindex $vlastins($v) $b] == $a} {
+                lset vlastins($v) $b $c
+            }
+            lset vupptr($v) $a $ka
+            set c [lindex $vlastins($v) $ka]
+            if {$c == 0 || \
+                    [string compare $tok [lindex $varctok($v) $c]] < 0} {
+                set c $ka
+                set b [lindex $vdownptr($v) $ka]
+            } else {
+                set b [lindex $vleftptr($v) $c]
+            }
+            while {$b != 0 && \
+                      [string compare $tok [lindex $varctok($v) $b]] >= 0} {
+                set c $b
+                set b [lindex $vleftptr($v) $c]
+            }
+            if {$c == $ka} {
+                lset vdownptr($v) $ka $a
+                lset vbackptr($v) $a 0
+            } else {
+                lset vleftptr($v) $c $a
+                lset vbackptr($v) $a $c
+            }
+            lset vleftptr($v) $a $b
+            if {$b != 0} {
+                lset vbackptr($v) $b $a
+            }
+            lset vlastins($v) $ka $a
+        }
     }
     foreach id [array names sortkids] {
-	if {[llength $children($v,$id)] > 1} {
-	    set children($v,$id) [lsort -command [list vtokcmp $v] \
-				      $children($v,$id)]
-	}
+        if {[llength $children($v,$id)] > 1} {
+            set children($v,$id) [lsort -command [list vtokcmp $v] \
+                                      $children($v,$id)]
+        }
     }
     set t2 [clock clicks -milliseconds]
     #puts "renumbervarc did [llength $todo] of $ntot arcs in [expr {$t2-$t1}]ms"
@@ -936,14 +935,14 @@
 
     set pa $varcid($v,$p)
     if {$p ne [lindex $varcstart($v) $pa]} {
-	splitvarc $p $v
-	set pa $varcid($v,$p)
+        splitvarc $p $v
+        set pa $varcid($v,$p)
     }
     # seeds always need to be renumbered
     if {[lindex $vupptr($v) $pa] == 0 ||
-	[string compare [lindex $varctok($v) $a] \
-	     [lindex $varctok($v) $pa]] > 0} {
-	renumbervarc $pa $v
+        [string compare [lindex $varctok($v) $a] \
+             [lindex $varctok($v) $pa]] > 0} {
+        renumbervarc $pa $v
     }
 }
 
@@ -961,24 +960,24 @@
     set varcid($vid) $a
     lappend vshortids($v,[string range $id 0 3]) $id
     if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} {
-	modify_arc $v $a
+        modify_arc $v $a
     }
     lappend varccommits($v,$a) $id
     set vp $v,$p
     if {[llength [lappend children($vp) $id]] > 1} {
-	set children($vp) [lsort -command [list vtokcmp $v] $children($vp)]
-	unset -nocomplain ordertok
+        set children($vp) [lsort -command [list vtokcmp $v] $children($vp)]
+        unset -nocomplain ordertok
     }
     fix_reversal $p $a $v
     incr commitidx($v)
     if {$v == $curview} {
-	set numcommits $commitidx($v)
-	setcanvscroll
-	if {[info exists targetid]} {
-	    if {![comes_before $targetid $p]} {
-		incr targetrow
-	    }
-	}
+        set numcommits $commitidx($v)
+        setcanvscroll
+        if {[info exists targetid]} {
+            if {![comes_before $targetid $p]} {
+                incr targetrow
+            }
+        }
     }
 }
 
@@ -990,8 +989,8 @@
     set a $varcid($v,$p)
     set i [lsearch -exact $varccommits($v,$a) $p]
     if {$i < 0} {
-	puts "oops: insertfakerow can't find [shortids $p] on arc $a"
-	return
+        puts "oops: insertfakerow can't find [shortids $p] on arc $a"
+        return
     }
     set children($v,$id) {}
     set parents($v,$id) [list $p]
@@ -1003,9 +1002,9 @@
     set varccommits($v,$a) [linsert $varccommits($v,$a) $i $id]
     modify_arc $v $a $i
     if {[info exists targetid]} {
-	if {![comes_before $targetid $p]} {
-	    incr targetrow
-	}
+        if {![comes_before $targetid $p]} {
+            incr targetrow
+        }
     }
     setcanvscroll
     drawvisible
@@ -1018,15 +1017,15 @@
 
     set v $curview
     if {[llength $parents($v,$id)] != 1} {
-	puts "oops: removefakerow [shortids $id] has [llength $parents($v,$id)] parents"
-	return
+        puts "oops: removefakerow [shortids $id] has [llength $parents($v,$id)] parents"
+        return
     }
     set p [lindex $parents($v,$id) 0]
     set a $varcid($v,$id)
     set i [lsearch -exact $varccommits($v,$a) $id]
     if {$i < 0} {
-	puts "oops: removefakerow can't find [shortids $id] on arc $a"
-	return
+        puts "oops: removefakerow can't find [shortids $id] on arc $a"
+        return
     }
     unset varcid($v,$id)
     set varccommits($v,$a) [lreplace $varccommits($v,$a) $i $i]
@@ -1036,15 +1035,15 @@
     set numcommits [incr commitidx($v) -1]
     set j [lsearch -exact $children($v,$p) $id]
     if {$j >= 0} {
-	set children($v,$p) [lreplace $children($v,$p) $j $j]
+        set children($v,$p) [lreplace $children($v,$p) $j $j]
     }
     modify_arc $v $a $i
     if {[info exist currentid] && $id eq $currentid} {
-	unset currentid
-	set selectedline {}
+        unset currentid
+        set selectedline {}
     }
     if {[info exists targetid] && $targetid eq $id} {
-	set targetid $p
+        set targetid $p
     }
     setcanvscroll
     drawvisible
@@ -1055,9 +1054,9 @@
 
     set kids {}
     foreach id $children($vp) {
-	if {$id ne $nullid && $id ne $nullid2} {
-	    lappend kids $id
-	}
+        if {$id ne $nullid && $id ne $nullid2} {
+            lappend kids $id
+        }
     }
     return $kids
 }
@@ -1066,9 +1065,9 @@
     global children nullid nullid2
 
     foreach id $children($vp) {
-	if {$id ne $nullid && $id ne $nullid2} {
-	    return $id
-	}
+        if {$id ne $nullid && $id ne $nullid2} {
+            return $id
+        }
     }
     return {}
 }
@@ -1078,10 +1077,10 @@
 
     set kids $children($vp)
     for {set i [llength $kids]} {[incr i -1] >= 0} {} {
-	set id [lindex $kids $i]
-	if {$id ne $nullid && $id ne $nullid2} {
-	    return $id
-	}
+        set id [lindex $kids $i]
+        if {$id ne $nullid && $id ne $nullid2} {
+            return $id
+        }
     }
     return {}
 }
@@ -1090,7 +1089,7 @@
     global varctok varcid
 
     return [string compare [lindex $varctok($v) $varcid($v,$a)] \
-		[lindex $varctok($v) $varcid($v,$b)]]
+                [lindex $varctok($v) $varcid($v,$b)]]
 }
 
 # This assumes that if lim is not given, the caller has checked that
@@ -1099,29 +1098,29 @@
     global varctok vtokmod varcmod varcrow vupptr curview vrowmod varccommits
 
     if {$lim ne {}} {
-	set c [string compare [lindex $varctok($v) $a] $vtokmod($v)]
-	if {$c > 0} return
-	if {$c == 0} {
-	    set r [lindex $varcrow($v) $a]
-	    if {$r ne {} && $vrowmod($v) <= $r + $lim} return
-	}
+        set c [string compare [lindex $varctok($v) $a] $vtokmod($v)]
+        if {$c > 0} return
+        if {$c == 0} {
+            set r [lindex $varcrow($v) $a]
+            if {$r ne {} && $vrowmod($v) <= $r + $lim} return
+        }
     }
     set vtokmod($v) [lindex $varctok($v) $a]
     set varcmod($v) $a
     if {$v == $curview} {
-	while {$a != 0 && [lindex $varcrow($v) $a] eq {}} {
-	    set a [lindex $vupptr($v) $a]
-	    set lim {}
-	}
-	set r 0
-	if {$a != 0} {
-	    if {$lim eq {}} {
-		set lim [llength $varccommits($v,$a)]
-	    }
-	    set r [expr {[lindex $varcrow($v) $a] + $lim}]
-	}
-	set vrowmod($v) $r
-	undolayout $r
+        while {$a != 0 && [lindex $varcrow($v) $a] eq {}} {
+            set a [lindex $vupptr($v) $a]
+            set lim {}
+        }
+        set r 0
+        if {$a != 0} {
+            if {$lim eq {}} {
+                set lim [llength $varccommits($v,$a)]
+            }
+            set r [expr {[lindex $varcrow($v) $a] + $lim}]
+        }
+        set vrowmod($v) $r
+        undolayout $r
     }
 }
 
@@ -1133,62 +1132,62 @@
 
     if {$vrowmod($v) == $commitidx($v)} return
     if {$v == $curview} {
-	if {[llength $displayorder] > $vrowmod($v)} {
-	    set displayorder [lrange $displayorder 0 [expr {$vrowmod($v) - 1}]]
-	    set parentlist [lrange $parentlist 0 [expr {$vrowmod($v) - 1}]]
-	}
-	unset -nocomplain cached_commitrow
+        if {[llength $displayorder] > $vrowmod($v)} {
+            set displayorder [lrange $displayorder 0 [expr {$vrowmod($v) - 1}]]
+            set parentlist [lrange $parentlist 0 [expr {$vrowmod($v) - 1}]]
+        }
+        unset -nocomplain cached_commitrow
     }
     set narctot [expr {[llength $varctok($v)] - 1}]
     set a $varcmod($v)
     while {$a != 0 && [lindex $varcix($v) $a] eq {}} {
-	# go up the tree until we find something that has a row number,
-	# or we get to a seed
-	set a [lindex $vupptr($v) $a]
+        # go up the tree until we find something that has a row number,
+        # or we get to a seed
+        set a [lindex $vupptr($v) $a]
     }
     if {$a == 0} {
-	set a [lindex $vdownptr($v) 0]
-	if {$a == 0} return
-	set vrownum($v) {0}
-	set varcorder($v) [list $a]
-	lset varcix($v) $a 0
-	lset varcrow($v) $a 0
-	set arcn 0
-	set row 0
+        set a [lindex $vdownptr($v) 0]
+        if {$a == 0} return
+        set vrownum($v) {0}
+        set varcorder($v) [list $a]
+        lset varcix($v) $a 0
+        lset varcrow($v) $a 0
+        set arcn 0
+        set row 0
     } else {
-	set arcn [lindex $varcix($v) $a]
-	if {[llength $vrownum($v)] > $arcn + 1} {
-	    set vrownum($v) [lrange $vrownum($v) 0 $arcn]
-	    set varcorder($v) [lrange $varcorder($v) 0 $arcn]
-	}
-	set row [lindex $varcrow($v) $a]
+        set arcn [lindex $varcix($v) $a]
+        if {[llength $vrownum($v)] > $arcn + 1} {
+            set vrownum($v) [lrange $vrownum($v) 0 $arcn]
+            set varcorder($v) [lrange $varcorder($v) 0 $arcn]
+        }
+        set row [lindex $varcrow($v) $a]
     }
     while {1} {
-	set p $a
-	incr row [llength $varccommits($v,$a)]
-	# go down if possible
-	set b [lindex $vdownptr($v) $a]
-	if {$b == 0} {
-	    # if not, go left, or go up until we can go left
-	    while {$a != 0} {
-		set b [lindex $vleftptr($v) $a]
-		if {$b != 0} break
-		set a [lindex $vupptr($v) $a]
-	    }
-	    if {$a == 0} break
-	}
-	set a $b
-	incr arcn
-	lappend vrownum($v) $row
-	lappend varcorder($v) $a
-	lset varcix($v) $a $arcn
-	lset varcrow($v) $a $row
+        set p $a
+        incr row [llength $varccommits($v,$a)]
+        # go down if possible
+        set b [lindex $vdownptr($v) $a]
+        if {$b == 0} {
+            # if not, go left, or go up until we can go left
+            while {$a != 0} {
+                set b [lindex $vleftptr($v) $a]
+                if {$b != 0} break
+                set a [lindex $vupptr($v) $a]
+            }
+            if {$a == 0} break
+        }
+        set a $b
+        incr arcn
+        lappend vrownum($v) $row
+        lappend varcorder($v) $a
+        lset varcix($v) $a $arcn
+        lset varcrow($v) $a $row
     }
     set vtokmod($v) [lindex $varctok($v) $p]
     set varcmod($v) $p
     set vrowmod($v) $row
     if {[info exists currentid]} {
-	set selectedline [rowofcommit $currentid]
+        set selectedline [rowofcommit $currentid]
     }
 }
 
@@ -1206,20 +1205,20 @@
 
     set v $curview
     if {![info exists varcid($v,$id)]} {
-	puts "oops rowofcommit no arc for [shortids $id]"
-	return {}
+        puts "oops rowofcommit no arc for [shortids $id]"
+        return {}
     }
     set a $varcid($v,$id)
     if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] >= 0} {
-	update_arcrows $v
+        update_arcrows $v
     }
     if {[info exists cached_commitrow($id)]} {
-	return $cached_commitrow($id)
+        return $cached_commitrow($id)
     }
     set i [lsearch -exact $varccommits($v,$a) $id]
     if {$i < 0} {
-	puts "oops didn't find commit [shortids $id] in arc $a"
-	return {}
+        puts "oops didn't find commit [shortids $id] in arc $a"
+        return {}
     }
     incr i [lindex $varcrow($v) $a]
     set cached_commitrow($id) $i
@@ -1232,32 +1231,32 @@
 
     set v $curview
     if {$a eq $b || ![info exists varcid($v,$a)] || \
-	    ![info exists varcid($v,$b)]} {
-	return 0
+            ![info exists varcid($v,$b)]} {
+        return 0
     }
     if {$varcid($v,$a) != $varcid($v,$b)} {
-	return [expr {[string compare [lindex $varctok($v) $varcid($v,$a)] \
-			   [lindex $varctok($v) $varcid($v,$b)]] < 0}]
+        return [expr {[string compare [lindex $varctok($v) $varcid($v,$a)] \
+                           [lindex $varctok($v) $varcid($v,$b)]] < 0}]
     }
     return [expr {[rowofcommit $a] < [rowofcommit $b]}]
 }
 
 proc bsearch {l elt} {
     if {[llength $l] == 0 || $elt <= [lindex $l 0]} {
-	return 0
+        return 0
     }
     set lo 0
     set hi [llength $l]
     while {$hi - $lo > 1} {
-	set mid [expr {int(($lo + $hi) / 2)}]
-	set t [lindex $l $mid]
-	if {$elt < $t} {
-	    set hi $mid
-	} elseif {$elt > $t} {
-	    set lo $mid
-	} else {
-	    return $mid
-	}
+        set mid [expr {int(($lo + $hi) / 2)}]
+        set t [lindex $l $mid]
+        if {$elt < $t} {
+            set hi $mid
+        } elseif {$elt > $t} {
+            set lo $mid
+        } else {
+            return $mid
+        }
     }
     return $lo
 }
@@ -1269,37 +1268,37 @@
     global d_valid_start d_valid_end
 
     if {$end > $vrowmod($curview)} {
-	update_arcrows $curview
+        update_arcrows $curview
     }
     set ai [bsearch $vrownum($curview) $start]
     set start [lindex $vrownum($curview) $ai]
     set narc [llength $vrownum($curview)]
     for {set r $start} {$ai < $narc && $r < $end} {incr ai} {
-	set a [lindex $varcorder($curview) $ai]
-	set l [llength $displayorder]
-	set al [llength $varccommits($curview,$a)]
-	if {$l < $r + $al} {
-	    if {$l < $r} {
-		set pad [ntimes [expr {$r - $l}] {}]
-		set displayorder [concat $displayorder $pad]
-		set parentlist [concat $parentlist $pad]
-	    } elseif {$l > $r} {
-		set displayorder [lrange $displayorder 0 [expr {$r - 1}]]
-		set parentlist [lrange $parentlist 0 [expr {$r - 1}]]
-	    }
-	    foreach id $varccommits($curview,$a) {
-		lappend displayorder $id
-		lappend parentlist $parents($curview,$id)
-	    }
-	} elseif {[lindex $displayorder [expr {$r + $al - 1}]] eq {}} {
-	    set i $r
-	    foreach id $varccommits($curview,$a) {
-		lset displayorder $i $id
-		lset parentlist $i $parents($curview,$id)
-		incr i
-	    }
-	}
-	incr r $al
+        set a [lindex $varcorder($curview) $ai]
+        set l [llength $displayorder]
+        set al [llength $varccommits($curview,$a)]
+        if {$l < $r + $al} {
+            if {$l < $r} {
+                set pad [ntimes [expr {$r - $l}] {}]
+                set displayorder [concat $displayorder $pad]
+                set parentlist [concat $parentlist $pad]
+            } elseif {$l > $r} {
+                set displayorder [lrange $displayorder 0 [expr {$r - 1}]]
+                set parentlist [lrange $parentlist 0 [expr {$r - 1}]]
+            }
+            foreach id $varccommits($curview,$a) {
+                lappend displayorder $id
+                lappend parentlist $parents($curview,$id)
+            }
+        } elseif {[lindex $displayorder [expr {$r + $al - 1}]] eq {}} {
+            set i $r
+            foreach id $varccommits($curview,$a) {
+                lset displayorder $i $id
+                lset parentlist $i $parents($curview,$id)
+                incr i
+            }
+        }
+        incr r $al
     }
 }
 
@@ -1308,8 +1307,8 @@
 
     set id [lindex $displayorder $row]
     if {$id eq {}} {
-	make_disporder $row [expr {$row + 1}]
-	set id [lindex $displayorder $row]
+        make_disporder $row [expr {$row + 1}]
+        set id [lindex $displayorder $row]
     }
     return $id
 }
@@ -1322,35 +1321,35 @@
     set scripts {}
     set narcs [llength $varctok($v)]
     for {set a 1} {$a < $narcs} {incr a} {
-	set id [lindex $varccommits($v,$a) end]
-	foreach p $parents($v,$id) {
-	    if {[info exists varcid($v,$p)]} continue
-	    # add p as a new commit
-	    incr missing_parents
-	    set cmitlisted($v,$p) 0
-	    set parents($v,$p) {}
-	    if {[llength $children($v,$p)] == 1 &&
-		[llength $parents($v,$id)] == 1} {
-		set b $a
-	    } else {
-		set b [newvarc $v $p]
-	    }
-	    set varcid($v,$p) $b
-	    if {[string compare [lindex $varctok($v) $b] $vtokmod($v)] < 0} {
-		modify_arc $v $b
-	    }
-	    lappend varccommits($v,$b) $p
-	    incr commitidx($v)
-	    if {$v == $curview} {
-		set numcommits $commitidx($v)
-	    }
-	    set scripts [check_interest $p $scripts]
-	}
+        set id [lindex $varccommits($v,$a) end]
+        foreach p $parents($v,$id) {
+            if {[info exists varcid($v,$p)]} continue
+            # add p as a new commit
+            incr missing_parents
+            set cmitlisted($v,$p) 0
+            set parents($v,$p) {}
+            if {[llength $children($v,$p)] == 1 &&
+                [llength $parents($v,$id)] == 1} {
+                set b $a
+            } else {
+                set b [newvarc $v $p]
+            }
+            set varcid($v,$p) $b
+            if {[string compare [lindex $varctok($v) $b] $vtokmod($v)] < 0} {
+                modify_arc $v $b
+            }
+            lappend varccommits($v,$b) $p
+            incr commitidx($v)
+            if {$v == $curview} {
+                set numcommits $commitidx($v)
+            }
+            set scripts [check_interest $p $scripts]
+        }
     }
     if {$missing_parents > 0} {
-	foreach s $scripts {
-	    eval $s
-	}
+        foreach s $scripts {
+            eval $s
+        }
     }
 }
 
@@ -1360,23 +1359,23 @@
     global children parents varcid varctok vtokmod varccommits
 
     foreach ch $children($v,$id) {
-	# make $rwid be $ch's parent in place of $id
-	set i [lsearch -exact $parents($v,$ch) $id]
-	if {$i < 0} {
-	    puts "oops rewrite_commit didn't find $id in parent list for $ch"
-	}
-	set parents($v,$ch) [lreplace $parents($v,$ch) $i $i $rwid]
-	# add $ch to $rwid's children and sort the list if necessary
-	if {[llength [lappend children($v,$rwid) $ch]] > 1} {
-	    set children($v,$rwid) [lsort -command [list vtokcmp $v] \
-					$children($v,$rwid)]
-	}
-	# fix the graph after joining $id to $rwid
-	set a $varcid($v,$ch)
-	fix_reversal $rwid $a $v
-	# parentlist is wrong for the last element of arc $a
-	# even if displayorder is right, hence the 3rd arg here
-	modify_arc $v $a [expr {[llength $varccommits($v,$a)] - 1}]
+        # make $rwid be $ch's parent in place of $id
+        set i [lsearch -exact $parents($v,$ch) $id]
+        if {$i < 0} {
+            puts "oops rewrite_commit didn't find $id in parent list for $ch"
+        }
+        set parents($v,$ch) [lreplace $parents($v,$ch) $i $i $rwid]
+        # add $ch to $rwid's children and sort the list if necessary
+        if {[llength [lappend children($v,$rwid) $ch]] > 1} {
+            set children($v,$rwid) [lsort -command [list vtokcmp $v] \
+                                        $children($v,$rwid)]
+        }
+        # fix the graph after joining $id to $rwid
+        set a $varcid($v,$ch)
+        fix_reversal $rwid $a $v
+        # parentlist is wrong for the last element of arc $a
+        # even if displayorder is right, hence the 3rd arg here
+        modify_arc $v $a [expr {[llength $varccommits($v,$a)] - 1}]
     }
 }
 
@@ -1396,19 +1395,19 @@
 
     set prefix [string range $id 0 3]
     if {[info exists commitinterest($prefix)]} {
-	set newlist {}
-	foreach {i script} $commitinterest($prefix) {
-	    if {[string match "$i*" $id]} {
-		lappend scripts [string map [list "%I" $id "%P" $i] $script]
-	    } else {
-		lappend newlist $i $script
-	    }
-	}
-	if {$newlist ne {}} {
-	    set commitinterest($prefix) $newlist
-	} else {
-	    unset commitinterest($prefix)
-	}
+        set newlist {}
+        foreach {i script} $commitinterest($prefix) {
+            if {[string match "$i*" $id]} {
+                lappend scripts [string map [list "%I" $id "%P" $i] $script]
+            } else {
+                lappend newlist $i $script
+            }
+        }
+        if {$newlist ne {}} {
+            set commitinterest($prefix) $newlist
+        } else {
+            unset commitinterest($prefix)
+        }
     }
     return $scripts
 }
@@ -1423,192 +1422,192 @@
     set stuff [read $fd 500000]
     # git log doesn't terminate the last commit with a null...
     if {$stuff == {} && $leftover($inst) ne {} && [eof $fd]} {
-	set stuff "\0"
+        set stuff "\0"
     }
     if {$stuff == {}} {
-	if {![eof $fd]} {
-	    return 1
-	}
-	global commfd viewcomplete viewactive viewname
-	global viewinstances
-	unset commfd($inst)
-	set i [lsearch -exact $viewinstances($view) $inst]
-	if {$i >= 0} {
-	    set viewinstances($view) [lreplace $viewinstances($view) $i $i]
-	}
-	# set it blocking so we wait for the process to terminate
-	fconfigure $fd -blocking 1
-	if {[catch {close $fd} err]} {
-	    set fv {}
-	    if {$view != $curview} {
-		set fv " for the \"$viewname($view)\" view"
-	    }
-	    if {[string range $err 0 4] == "usage"} {
-		set err "Gitk: error reading commits$fv:\
-			bad arguments to git log."
-		if {$viewname($view) eq [mc "Command line"]} {
-		    append err \
-			"  (Note: arguments to gitk are passed to git log\
-			 to allow selection of commits to be displayed.)"
-		}
-	    } else {
-		set err "Error reading commits$fv: $err"
-	    }
-	    error_popup $err
-	}
-	if {[incr viewactive($view) -1] <= 0} {
-	    set viewcomplete($view) 1
-	    # Check if we have seen any ids listed as parents that haven't
-	    # appeared in the list
-	    closevarcs $view
-	    notbusy $view
-	}
-	if {$view == $curview} {
-	    run chewcommits
-	}
-	return 0
+        if {![eof $fd]} {
+            return 1
+        }
+        global commfd viewcomplete viewactive viewname
+        global viewinstances
+        unset commfd($inst)
+        set i [lsearch -exact $viewinstances($view) $inst]
+        if {$i >= 0} {
+            set viewinstances($view) [lreplace $viewinstances($view) $i $i]
+        }
+        # set it blocking so we wait for the process to terminate
+        fconfigure $fd -blocking 1
+        if {[catch {close $fd} err]} {
+            set fv {}
+            if {$view != $curview} {
+                set fv " for the \"$viewname($view)\" view"
+            }
+            if {[string range $err 0 4] == "usage"} {
+                set err "Gitk: error reading commits$fv:\
+                        bad arguments to git log."
+                if {$viewname($view) eq [mc "Command line"]} {
+                    append err \
+                        "  (Note: arguments to gitk are passed to git log\
+                         to allow selection of commits to be displayed.)"
+                }
+            } else {
+                set err "Error reading commits$fv: $err"
+            }
+            error_popup $err
+        }
+        if {[incr viewactive($view) -1] <= 0} {
+            set viewcomplete($view) 1
+            # Check if we have seen any ids listed as parents that haven't
+            # appeared in the list
+            closevarcs $view
+            notbusy $view
+        }
+        if {$view == $curview} {
+            run chewcommits
+        }
+        return 0
     }
     set start 0
     set gotsome 0
     set scripts {}
     while 1 {
-	set i [string first "\0" $stuff $start]
-	if {$i < 0} {
-	    append leftover($inst) [string range $stuff $start end]
-	    break
-	}
-	if {$start == 0} {
-	    set cmit $leftover($inst)
-	    append cmit [string range $stuff 0 [expr {$i - 1}]]
-	    set leftover($inst) {}
-	} else {
-	    set cmit [string range $stuff $start [expr {$i - 1}]]
-	}
-	set start [expr {$i + 1}]
-	set j [string first "\n" $cmit]
-	set ok 0
-	set listed 1
-	if {$j >= 0 && [string match "commit *" $cmit]} {
-	    set ids [string range $cmit 7 [expr {$j - 1}]]
-	    if {[string match {[-^<>]*} $ids]} {
-		switch -- [string index $ids 0] {
-		    "-" {set listed 0}
-		    "^" {set listed 2}
-		    "<" {set listed 3}
-		    ">" {set listed 4}
-		}
-		set ids [string range $ids 1 end]
-	    }
-	    set ok 1
-	    foreach id $ids {
-		if {[string length $id] != 40} {
-		    set ok 0
-		    break
-		}
-	    }
-	}
-	if {!$ok} {
-	    set shortcmit $cmit
-	    if {[string length $shortcmit] > 80} {
-		set shortcmit "[string range $shortcmit 0 80]..."
-	    }
-	    error_popup "[mc "Can't parse git log output:"] {$shortcmit}"
-	    exit 1
-	}
-	set id [lindex $ids 0]
-	set vid $view,$id
+        set i [string first "\0" $stuff $start]
+        if {$i < 0} {
+            append leftover($inst) [string range $stuff $start end]
+            break
+        }
+        if {$start == 0} {
+            set cmit $leftover($inst)
+            append cmit [string range $stuff 0 [expr {$i - 1}]]
+            set leftover($inst) {}
+        } else {
+            set cmit [string range $stuff $start [expr {$i - 1}]]
+        }
+        set start [expr {$i + 1}]
+        set j [string first "\n" $cmit]
+        set ok 0
+        set listed 1
+        if {$j >= 0 && [string match "commit *" $cmit]} {
+            set ids [string range $cmit 7 [expr {$j - 1}]]
+            if {[string match {[-^<>]*} $ids]} {
+                switch -- [string index $ids 0] {
+                    "-" {set listed 0}
+                    "^" {set listed 2}
+                    "<" {set listed 3}
+                    ">" {set listed 4}
+                }
+                set ids [string range $ids 1 end]
+            }
+            set ok 1
+            foreach id $ids {
+                if {[string length $id] != 40} {
+                    set ok 0
+                    break
+                }
+            }
+        }
+        if {!$ok} {
+            set shortcmit $cmit
+            if {[string length $shortcmit] > 80} {
+                set shortcmit "[string range $shortcmit 0 80]..."
+            }
+            error_popup "[mc "Can't parse git log output:"] {$shortcmit}"
+            exit 1
+        }
+        set id [lindex $ids 0]
+        set vid $view,$id
 
-	lappend vshortids($view,[string range $id 0 3]) $id
+        lappend vshortids($view,[string range $id 0 3]) $id
 
-	if {!$listed && $updating && ![info exists varcid($vid)] &&
-	    $vfilelimit($view) ne {}} {
-	    # git log doesn't rewrite parents for unlisted commits
-	    # when doing path limiting, so work around that here
-	    # by working out the rewritten parent with git rev-list
-	    # and if we already know about it, using the rewritten
-	    # parent as a substitute parent for $id's children.
-	    if {![catch {
-		set rwid [exec git rev-list --first-parent --max-count=1 \
-			      $id -- $vfilelimit($view)]
-	    }]} {
-		if {$rwid ne {} && [info exists varcid($view,$rwid)]} {
-		    # use $rwid in place of $id
-		    rewrite_commit $view $id $rwid
-		    continue
-		}
-	    }
-	}
+        if {!$listed && $updating && ![info exists varcid($vid)] &&
+            $vfilelimit($view) ne {}} {
+            # git log doesn't rewrite parents for unlisted commits
+            # when doing path limiting, so work around that here
+            # by working out the rewritten parent with git rev-list
+            # and if we already know about it, using the rewritten
+            # parent as a substitute parent for $id's children.
+            if {![catch {
+                set rwid [exec git rev-list --first-parent --max-count=1 \
+                              $id -- $vfilelimit($view)]
+            }]} {
+                if {$rwid ne {} && [info exists varcid($view,$rwid)]} {
+                    # use $rwid in place of $id
+                    rewrite_commit $view $id $rwid
+                    continue
+                }
+            }
+        }
 
-	set a 0
-	if {[info exists varcid($vid)]} {
-	    if {$cmitlisted($vid) || !$listed} continue
-	    set a $varcid($vid)
-	}
-	if {$listed} {
-	    set olds [lrange $ids 1 end]
-	} else {
-	    set olds {}
-	}
-	set commitdata($id) [string range $cmit [expr {$j + 1}] end]
-	set cmitlisted($vid) $listed
-	set parents($vid) $olds
-	if {![info exists children($vid)]} {
-	    set children($vid) {}
-	} elseif {$a == 0 && [llength $children($vid)] == 1} {
-	    set k [lindex $children($vid) 0]
-	    if {[llength $parents($view,$k)] == 1 &&
-		(!$vdatemode($view) ||
-		 $varcid($view,$k) == [llength $varctok($view)] - 1)} {
-		set a $varcid($view,$k)
-	    }
-	}
-	if {$a == 0} {
-	    # new arc
-	    set a [newvarc $view $id]
-	}
-	if {[string compare [lindex $varctok($view) $a] $vtokmod($view)] < 0} {
-	    modify_arc $view $a
-	}
-	if {![info exists varcid($vid)]} {
-	    set varcid($vid) $a
-	    lappend varccommits($view,$a) $id
-	    incr commitidx($view)
-	}
+        set a 0
+        if {[info exists varcid($vid)]} {
+            if {$cmitlisted($vid) || !$listed} continue
+            set a $varcid($vid)
+        }
+        if {$listed} {
+            set olds [lrange $ids 1 end]
+        } else {
+            set olds {}
+        }
+        set commitdata($id) [string range $cmit [expr {$j + 1}] end]
+        set cmitlisted($vid) $listed
+        set parents($vid) $olds
+        if {![info exists children($vid)]} {
+            set children($vid) {}
+        } elseif {$a == 0 && [llength $children($vid)] == 1} {
+            set k [lindex $children($vid) 0]
+            if {[llength $parents($view,$k)] == 1 &&
+                (!$vdatemode($view) ||
+                 $varcid($view,$k) == [llength $varctok($view)] - 1)} {
+                set a $varcid($view,$k)
+            }
+        }
+        if {$a == 0} {
+            # new arc
+            set a [newvarc $view $id]
+        }
+        if {[string compare [lindex $varctok($view) $a] $vtokmod($view)] < 0} {
+            modify_arc $view $a
+        }
+        if {![info exists varcid($vid)]} {
+            set varcid($vid) $a
+            lappend varccommits($view,$a) $id
+            incr commitidx($view)
+        }
 
-	set i 0
-	foreach p $olds {
-	    if {$i == 0 || [lsearch -exact $olds $p] >= $i} {
-		set vp $view,$p
-		if {[llength [lappend children($vp) $id]] > 1 &&
-		    [vtokcmp $view [lindex $children($vp) end-1] $id] > 0} {
-		    set children($vp) [lsort -command [list vtokcmp $view] \
-					   $children($vp)]
-		    unset -nocomplain ordertok
-		}
-		if {[info exists varcid($view,$p)]} {
-		    fix_reversal $p $a $view
-		}
-	    }
-	    incr i
-	}
+        set i 0
+        foreach p $olds {
+            if {$i == 0 || [lsearch -exact $olds $p] >= $i} {
+                set vp $view,$p
+                if {[llength [lappend children($vp) $id]] > 1 &&
+                    [vtokcmp $view [lindex $children($vp) end-1] $id] > 0} {
+                    set children($vp) [lsort -command [list vtokcmp $view] \
+                                           $children($vp)]
+                    unset -nocomplain ordertok
+                }
+                if {[info exists varcid($view,$p)]} {
+                    fix_reversal $p $a $view
+                }
+            }
+            incr i
+        }
 
-	set scripts [check_interest $id $scripts]
-	set gotsome 1
+        set scripts [check_interest $id $scripts]
+        set gotsome 1
     }
     if {$gotsome} {
-	global numcommits hlview
+        global numcommits hlview
 
-	if {$view == $curview} {
-	    set numcommits $commitidx($view)
-	    run chewcommits
-	}
-	if {[info exists hlview] && $view == $hlview} {
-	    # we never actually get here...
-	    run vhighlightmore
-	}
-	foreach s $scripts {
-	    eval $s
-	}
+        if {$view == $curview} {
+            set numcommits $commitidx($view)
+            run chewcommits
+        }
+        if {[info exists hlview] && $view == $hlview} {
+            # we never actually get here...
+            run vhighlightmore
+        }
+        foreach s $scripts {
+            eval $s
+        }
     }
     return 2
 }
@@ -1619,28 +1618,28 @@
 
     layoutmore
     if {$viewcomplete($curview)} {
-	global commitidx varctok
-	global numcommits startmsecs
+        global commitidx varctok
+        global numcommits startmsecs
 
-	if {[info exists pending_select]} {
-	    update
-	    reset_pending_select {}
+        if {[info exists pending_select]} {
+            update
+            reset_pending_select {}
 
-	    if {[commitinview $pending_select $curview]} {
-		selectline [rowofcommit $pending_select] 1
-	    } else {
-		set row [first_real_row]
-		selectline $row 1
-	    }
-	}
-	if {$commitidx($curview) > 0} {
-	    #set ms [expr {[clock clicks -milliseconds] - $startmsecs}]
-	    #puts "overall $ms ms for $numcommits commits"
-	    #puts "[llength $varctok($view)] arcs, $commitidx($view) commits"
-	} else {
-	    show_status [mc "No commits selected"]
-	}
-	notbusy layout
+            if {[commitinview $pending_select $curview]} {
+                selectline [rowofcommit $pending_select] 1
+            } else {
+                set row [first_real_row]
+                selectline $row 1
+            }
+        }
+        if {$commitidx($curview) > 0} {
+            #set ms [expr {[clock clicks -milliseconds] - $startmsecs}]
+            #puts "overall $ms ms for $numcommits commits"
+            #puts "[llength $varctok($view)] arcs, $commitidx($view) commits"
+        } else {
+            show_status [mc "No commits selected"]
+        }
+        notbusy layout
     }
     return 0
 }
@@ -1653,7 +1652,7 @@
     # Read the results using i18n.logoutputencoding
     fconfigure $fd -translation lf -eofchar {}
     if {$tclencoding != {}} {
-	fconfigure $fd -encoding $tclencoding
+        fconfigure $fd -encoding $tclencoding
     }
     set contents [read $fd]
     close $fd
@@ -1680,44 +1679,44 @@
     set comdate {}
     set hdrend [string first "\n\n" $contents]
     if {$hdrend < 0} {
-	# should never happen...
-	set hdrend [string length $contents]
+        # should never happen...
+        set hdrend [string length $contents]
     }
     set header [string range $contents 0 [expr {$hdrend - 1}]]
     set comment [string range $contents [expr {$hdrend + 2}] end]
     foreach line [split $header "\n"] {
-	set line [split $line " "]
-	set tag [lindex $line 0]
-	if {$tag == "author"} {
-	    set audate [lrange $line end-1 end]
-	    set auname [join [lrange $line 1 end-2] " "]
-	} elseif {$tag == "committer"} {
-	    set comdate [lrange $line end-1 end]
-	    set comname [join [lrange $line 1 end-2] " "]
-	}
+        set line [split $line " "]
+        set tag [lindex $line 0]
+        if {$tag == "author"} {
+            set audate [lrange $line end-1 end]
+            set auname [join [lrange $line 1 end-2] " "]
+        } elseif {$tag == "committer"} {
+            set comdate [lrange $line end-1 end]
+            set comname [join [lrange $line 1 end-2] " "]
+        }
     }
     set headline {}
     # take the first non-blank line of the comment as the headline
     set headline [string trimleft $comment]
     set i [string first "\n" $headline]
     if {$i >= 0} {
-	set headline [string range $headline 0 $i]
+        set headline [string range $headline 0 $i]
     }
     set headline [string trimright $headline]
     set i [string first "\r" $headline]
     if {$i >= 0} {
-	set headline [string trimright [string range $headline 0 $i]]
+        set headline [string trimright [string range $headline 0 $i]]
     }
     if {!$listed} {
-	# git log indents the comment by 4 spaces;
-	# if we got this via git cat-file, add the indentation
-	set newcomment {}
-	foreach line [split $comment "\n"] {
-	    append newcomment "    "
-	    append newcomment $line
-	    append newcomment "\n"
-	}
-	set comment $newcomment
+        # git log indents the comment by 4 spaces;
+        # if we got this via git cat-file, add the indentation
+        set newcomment {}
+        foreach line [split $comment "\n"] {
+            append newcomment "    "
+            append newcomment $line
+            append newcomment "\n"
+        }
+        set comment $newcomment
     }
     set hasnote [string first "\nNotes:\n" $contents]
     set diff ""
@@ -1726,23 +1725,23 @@
     # diff.
     set i [string first "\n\ndiff" $comment]
     if {$i >= 0} {
-	set diff [string range $comment $i+1 end]
-	set comment [string range $comment 0 $i-1]
+        set diff [string range $comment $i+1 end]
+        set comment [string range $comment 0 $i-1]
     }
     set commitinfo($id) [list $headline $auname $audate \
-			     $comname $comdate $comment $hasnote $diff]
+                             $comname $comdate $comment $hasnote $diff]
 }
 
 proc getcommit {id} {
     global commitdata commitinfo
 
     if {[info exists commitdata($id)]} {
-	parsecommit $id $commitdata($id) 1
+        parsecommit $id $commitdata($id) 1
     } else {
-	readcommit $id
-	if {![info exists commitinfo($id)]} {
-	    set commitinfo($id) [list [mc "No commit information available"]]
-	}
+        readcommit $id
+        if {![info exists commitinfo($id)]} {
+            set commitinfo($id) [list [mc "No commit information available"]]
+        }
     }
     return 1
 }
@@ -1755,22 +1754,22 @@
 
     set ids {}
     if {[string length $prefix] >= 4} {
-	set vshortid $curview,[string range $prefix 0 3]
-	if {[info exists vshortids($vshortid)]} {
-	    foreach id $vshortids($vshortid) {
-		if {[string match "$prefix*" $id]} {
-		    if {[lsearch -exact $ids $id] < 0} {
-			lappend ids $id
-			if {[llength $ids] >= 2} break
-		    }
-		}
-	    }
-	}
+        set vshortid $curview,[string range $prefix 0 3]
+        if {[info exists vshortids($vshortid)]} {
+            foreach id $vshortids($vshortid) {
+                if {[string match "$prefix*" $id]} {
+                    if {[lsearch -exact $ids $id] < 0} {
+                        lappend ids $id
+                        if {[llength $ids] >= 2} break
+                    }
+                }
+            }
+        }
     } else {
-	foreach match [array names varcid "$curview,$prefix*"] {
-	    lappend ids [lindex [split $match ","] 1]
-	    if {[llength $ids] >= 2} break
-	}
+        foreach match [array names varcid "$curview,$prefix*"] {
+            lappend ids [lindex [split $match ","] 1]
+            if {[llength $ids] >= 2} break
+        }
     }
     return $ids
 }
@@ -1780,57 +1779,61 @@
     global otherrefids idotherrefs mainhead mainheadid
     global selecthead selectheadid
     global hideremotes
+    global tclencoding
 
     foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
-	unset -nocomplain $v
+        unset -nocomplain $v
     }
     set refd [open [list | git show-ref -d] r]
+    if {$tclencoding != {}} {
+        fconfigure $refd -encoding $tclencoding
+    }
     while {[gets $refd line] >= 0} {
-	if {[string index $line 40] ne " "} continue
-	set id [string range $line 0 39]
-	set ref [string range $line 41 end]
-	if {![string match "refs/*" $ref]} continue
-	set name [string range $ref 5 end]
-	if {[string match "remotes/*" $name]} {
-	    if {![string match "*/HEAD" $name] && !$hideremotes} {
-		set headids($name) $id
-		lappend idheads($id) $name
-	    }
-	} elseif {[string match "heads/*" $name]} {
-	    set name [string range $name 6 end]
-	    set headids($name) $id
-	    lappend idheads($id) $name
-	} elseif {[string match "tags/*" $name]} {
-	    # this lets refs/tags/foo^{} overwrite refs/tags/foo,
-	    # which is what we want since the former is the commit ID
-	    set name [string range $name 5 end]
-	    if {[string match "*^{}" $name]} {
-		set name [string range $name 0 end-3]
-	    } else {
-		set tagobjid($name) $id
-	    }
-	    set tagids($name) $id
-	    lappend idtags($id) $name
-	} else {
-	    set otherrefids($name) $id
-	    lappend idotherrefs($id) $name
-	}
+        if {[string index $line 40] ne " "} continue
+        set id [string range $line 0 39]
+        set ref [string range $line 41 end]
+        if {![string match "refs/*" $ref]} continue
+        set name [string range $ref 5 end]
+        if {[string match "remotes/*" $name]} {
+            if {![string match "*/HEAD" $name] && !$hideremotes} {
+                set headids($name) $id
+                lappend idheads($id) $name
+            }
+        } elseif {[string match "heads/*" $name]} {
+            set name [string range $name 6 end]
+            set headids($name) $id
+            lappend idheads($id) $name
+        } elseif {[string match "tags/*" $name]} {
+            # this lets refs/tags/foo^{} overwrite refs/tags/foo,
+            # which is what we want since the former is the commit ID
+            set name [string range $name 5 end]
+            if {[string match "*^{}" $name]} {
+                set name [string range $name 0 end-3]
+            } else {
+                set tagobjid($name) $id
+            }
+            set tagids($name) $id
+            lappend idtags($id) $name
+        } else {
+            set otherrefids($name) $id
+            lappend idotherrefs($id) $name
+        }
     }
     catch {close $refd}
     set mainhead {}
     set mainheadid {}
     catch {
-	set mainheadid [exec git rev-parse HEAD]
-	set thehead [exec git symbolic-ref HEAD]
-	if {[string match "refs/heads/*" $thehead]} {
-	    set mainhead [string range $thehead 11 end]
-	}
+        set mainheadid [exec git rev-parse HEAD]
+        set thehead [exec git symbolic-ref HEAD]
+        if {[string match "refs/heads/*" $thehead]} {
+            set mainhead [string range $thehead 11 end]
+        }
     }
     set selectheadid {}
     if {$selecthead ne {}} {
-	catch {
-	    set selectheadid [exec git rev-parse --verify $selecthead]
-	}
+        catch {
+            set selectheadid [exec git rev-parse --verify $selecthead]
+        }
     }
 }
 
@@ -1839,10 +1842,10 @@
     global nullid nullid2 numcommits
 
     for {set row 0} {$row < $numcommits} {incr row} {
-	set id [commitonrow $row]
-	if {$id ne $nullid && $id ne $nullid2} {
-	    break
-	}
+        set id [commitonrow $row]
+        if {$id ne $nullid && $id ne $nullid2} {
+            break
+        }
     }
     return $row
 }
@@ -1861,12 +1864,12 @@
     global headids idheads
 
     if {$idheads($id) eq $name} {
-	unset idheads($id)
+        unset idheads($id)
     } else {
-	set i [lsearch -exact $idheads($id) $name]
-	if {$i >= 0} {
-	    set idheads($id) [lreplace $idheads($id) $i $i]
-	}
+        set i [lsearch -exact $idheads($id) $name]
+        if {$i >= 0} {
+            set idheads($id) [lreplace $idheads($id) $i $i]
+        }
     }
     unset headids($name)
 }
@@ -1894,7 +1897,7 @@
     # Windows fails to place transient windows normally, so
     # schedule a callback to center them on the parent.
     if {[tk windowingsystem] eq {win32}} {
-	after idle [list tk::PlaceWindow $window widget $origin]
+        after idle [list tk::PlaceWindow $window widget $origin]
     }
 }
 
@@ -1994,41 +1997,41 @@
 proc makemenu {m items} {
     menu $m
     if {[tk windowingsystem] eq {aqua}} {
-	set Meta1 Cmd
+        set Meta1 Cmd
     } else {
-	set Meta1 Ctrl
+        set Meta1 Ctrl
     }
     foreach i $items {
-	set name [mc [lindex $i 1]]
-	set type [lindex $i 2]
-	set thing [lindex $i 3]
-	set params [list $type]
-	if {$name ne {}} {
-	    set u [string first "&" [string map {&& x} $name]]
-	    lappend params -label [string map {&& & & {}} $name]
-	    if {$u >= 0} {
-		lappend params -underline $u
-	    }
-	}
-	switch -- $type {
-	    "cascade" {
-		set submenu [string tolower [string map {& ""} [lindex $i 1]]]
-		lappend params -menu $m.$submenu
-	    }
-	    "command" {
-		lappend params -command $thing
-	    }
-	    "radiobutton" {
-		lappend params -variable [lindex $thing 0] \
-		    -value [lindex $thing 1]
-	    }
-	}
-	set tail [lrange $i 4 end]
-	regsub -all {\yMeta1\y} $tail $Meta1 tail
-	eval $m add $params $tail
-	if {$type eq "cascade"} {
-	    makemenu $m.$submenu $thing
-	}
+        set name [mc [lindex $i 1]]
+        set type [lindex $i 2]
+        set thing [lindex $i 3]
+        set params [list $type]
+        if {$name ne {}} {
+            set u [string first "&" [string map {&& x} $name]]
+            lappend params -label [string map {&& & & {}} $name]
+            if {$u >= 0} {
+                lappend params -underline $u
+            }
+        }
+        switch -- $type {
+            "cascade" {
+                set submenu [string tolower [string map {& ""} [lindex $i 1]]]
+                lappend params -menu $m.$submenu
+            }
+            "command" {
+                lappend params -command $thing
+            }
+            "radiobutton" {
+                lappend params -variable [lindex $thing 0] \
+                    -value [lindex $thing 1]
+            }
+        }
+        set tail [lrange $i 4 end]
+        regsub -all {\yMeta1\y} $tail $Meta1 tail
+        eval $m add $params $tail
+        if {$type eq "cascade"} {
+            makemenu $m.$submenu $thing
+        }
     }
 }
 
@@ -2048,12 +2051,12 @@
             set cx [string length $label]
             if {$cx > $width} {set width $cx}
         }
-	set gm [ttk::combobox $w -width $width -state readonly\
-		    -textvariable $varname -values $args \
-		    -exportselection false]
-	bind $gm <<ComboboxSelected>> [list $gm selection clear]
+        set gm [ttk::combobox $w -width $width -state readonly\
+                    -textvariable $varname -values $args \
+                    -exportselection false]
+        bind $gm <<ComboboxSelected>> [list $gm selection clear]
     } else {
-	set gm [eval [linsert $args 0 tk_optionMenu $w $varname]]
+        set gm [eval [linsert $args 0 tk_optionMenu $w $varname]]
     }
     return $gm
 }
@@ -2069,7 +2072,7 @@
     global rowctxmenu fakerowmenu mergemax wrapcomment
     global highlight_files gdttype
     global searchstring sstring
-    global bgcolor fgcolor bglist fglist diffcolors selectbgcolor
+    global bgcolor fgcolor bglist fglist diffcolors diffbgcolors selectbgcolor
     global uifgcolor uifgdisabledcolor
     global filesepbgcolor filesepfgcolor
     global mergecolors foundbgcolor currentsearchhitbgcolor
@@ -2083,49 +2086,49 @@
     # The "mc" arguments here are purely so that xgettext
     # sees the following string as needing to be translated
     set file {
-	mc "&File" cascade {
-	    {mc "&Update" command updatecommits -accelerator F5}
-	    {mc "&Reload" command reloadcommits -accelerator Shift-F5}
-	    {mc "Reread re&ferences" command rereadrefs}
-	    {mc "&List references" command showrefs -accelerator F2}
-	    {xx "" separator}
-	    {mc "Start git &gui" command {exec git gui &}}
-	    {xx "" separator}
-	    {mc "&Quit" command doquit -accelerator Meta1-Q}
-	}}
+        mc "&File" cascade {
+            {mc "&Update" command updatecommits -accelerator F5}
+            {mc "&Reload" command reloadcommits -accelerator Shift-F5}
+            {mc "Reread re&ferences" command rereadrefs}
+            {mc "&List references" command showrefs -accelerator F2}
+            {xx "" separator}
+            {mc "Start git &gui" command {exec git gui &}}
+            {xx "" separator}
+            {mc "&Quit" command doquit -accelerator Meta1-Q}
+        }}
     set edit {
-	mc "&Edit" cascade {
-	    {mc "&Preferences" command doprefs}
-	}}
+        mc "&Edit" cascade {
+            {mc "&Preferences" command doprefs}
+        }}
     set view {
-	mc "&View" cascade {
-	    {mc "&New view..." command {newview 0} -accelerator Shift-F4}
-	    {mc "&Edit view..." command editview -state disabled -accelerator F4}
-	    {mc "&Delete view" command delview -state disabled}
-	    {xx "" separator}
-	    {mc "&All files" radiobutton {selectedview 0} -command {showview 0}}
-	}}
+        mc "&View" cascade {
+            {mc "&New view..." command {newview 0} -accelerator Shift-F4}
+            {mc "&Edit view..." command editview -state disabled -accelerator F4}
+            {mc "&Delete view" command delview -state disabled}
+            {xx "" separator}
+            {mc "&All files" radiobutton {selectedview 0} -command {showview 0}}
+        }}
     if {[tk windowingsystem] ne "aqua"} {
-	set help {
-	mc "&Help" cascade {
-	    {mc "&About gitk" command about}
-	    {mc "&Key bindings" command keys}
-	}}
-	set bar [list $file $edit $view $help]
+        set help {
+        mc "&Help" cascade {
+            {mc "&About gitk" command about}
+            {mc "&Key bindings" command keys}
+        }}
+        set bar [list $file $edit $view $help]
     } else {
-	proc ::tk::mac::ShowPreferences {} {doprefs}
-	proc ::tk::mac::Quit {} {doquit}
-	lset file end [lreplace [lindex $file end] end-1 end]
-	set apple {
-	xx "&Apple" cascade {
-	    {mc "&About gitk" command about}
-	    {xx "" separator}
-	}}
-	set help {
-	mc "&Help" cascade {
-	    {mc "&Key bindings" command keys}
-	}}
-	set bar [list $apple $file $view $help]
+        proc ::tk::mac::ShowPreferences {} {doprefs}
+        proc ::tk::mac::Quit {} {doquit}
+        lset file end [lreplace [lindex $file end] end-1 end]
+        set apple {
+        xx "&Apple" cascade {
+            {mc "&About gitk" command about}
+            {xx "" separator}
+        }}
+        set help {
+        mc "&Help" cascade {
+            {mc "&Key bindings" command keys}
+        }}
+        set bar [list $apple $file $view $help]
     }
     makemenu .bar $bar
     . configure -menu .bar
@@ -2153,36 +2156,36 @@
     ${NS}::frame .tf.histframe
     ${NS}::panedwindow .tf.histframe.pwclist -orient horizontal
     if {!$use_ttk} {
-	.tf.histframe.pwclist configure -sashpad 0 -handlesize 4
+        .tf.histframe.pwclist configure -sashpad 0 -handlesize 4
     }
 
     # create three canvases
     set cscroll .tf.histframe.csb
     set canv .tf.histframe.pwclist.canv
     canvas $canv \
-	-selectbackground $selectbgcolor \
-	-background $bgcolor -bd 0 \
-	-yscrollincr $linespc -yscrollcommand "scrollcanv $cscroll"
+        -selectbackground $selectbgcolor \
+        -background $bgcolor -bd 0 \
+        -yscrollincr $linespc -yscrollcommand "scrollcanv $cscroll"
     .tf.histframe.pwclist add $canv
     set canv2 .tf.histframe.pwclist.canv2
     canvas $canv2 \
-	-selectbackground $selectbgcolor \
-	-background $bgcolor -bd 0 -yscrollincr $linespc
+        -selectbackground $selectbgcolor \
+        -background $bgcolor -bd 0 -yscrollincr $linespc
     .tf.histframe.pwclist add $canv2
     set canv3 .tf.histframe.pwclist.canv3
     canvas $canv3 \
-	-selectbackground $selectbgcolor \
-	-background $bgcolor -bd 0 -yscrollincr $linespc
+        -selectbackground $selectbgcolor \
+        -background $bgcolor -bd 0 -yscrollincr $linespc
     .tf.histframe.pwclist add $canv3
     if {$use_ttk} {
-	bind .tf.histframe.pwclist <Map> {
-	    bind %W <Map> {}
-	    .tf.histframe.pwclist sashpos 1 [lindex $::geometry(pwsash1) 0]
-	    .tf.histframe.pwclist sashpos 0 [lindex $::geometry(pwsash0) 0]
-	}
+        bind .tf.histframe.pwclist <Map> {
+            bind %W <Map> {}
+            .tf.histframe.pwclist sashpos 1 [lindex $::geometry(pwsash1) 0]
+            .tf.histframe.pwclist sashpos 0 [lindex $::geometry(pwsash0) 0]
+        }
     } else {
-	eval .tf.histframe.pwclist sash place 0 $geometry(pwsash0)
-	eval .tf.histframe.pwclist sash place 1 $geometry(pwsash1)
+        eval .tf.histframe.pwclist sash place 0 $geometry(pwsash0)
+        eval .tf.histframe.pwclist sash place 1 $geometry(pwsash1)
     }
 
     # a scroll bar to rule them
@@ -2201,7 +2204,7 @@
     set entries $sha1entry
     set sha1but .tf.bar.sha1label
     button $sha1but -text "[mc "SHA1 ID:"] " -state disabled -relief flat \
-	-command gotocommit -width 8
+        -command gotocommit -width 8
     $sha1but conf -disabledforeground [$sha1but cget -foreground]
     pack .tf.bar.sha1label -side left
     ${NS}::entry $sha1entry -width 40 -font textfont -textvariable sha1string
@@ -2209,20 +2212,20 @@
     pack $sha1entry -side left -pady 2
 
     set bm_left_data {
-	#define left_width 16
-	#define left_height 16
-	static unsigned char left_bits[] = {
-	0x00, 0x00, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00,
-	0x0e, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x0e, 0x00, 0x1c, 0x00,
-	0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01};
+        #define left_width 16
+        #define left_height 16
+        static unsigned char left_bits[] = {
+        0x00, 0x00, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00,
+        0x0e, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x0e, 0x00, 0x1c, 0x00,
+        0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01};
     }
     set bm_right_data {
-	#define right_width 16
-	#define right_height 16
-	static unsigned char right_bits[] = {
-	0x00, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c,
-	0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c,
-	0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01};
+        #define right_width 16
+        #define right_height 16
+        static unsigned char right_bits[] = {
+        0x00, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c,
+        0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c,
+        0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01};
     }
     image create bitmap bm-left -data $bm_left_data -foreground $uifgcolor
     image create bitmap bm-left-gray -data $bm_left_data -foreground $uifgdisabledcolor
@@ -2231,28 +2234,28 @@
 
     ${NS}::button .tf.bar.leftbut -command goback -state disabled -width 26
     if {$use_ttk} {
-	.tf.bar.leftbut configure -image [list bm-left disabled bm-left-gray]
+        .tf.bar.leftbut configure -image [list bm-left disabled bm-left-gray]
     } else {
-	.tf.bar.leftbut configure -image bm-left
+        .tf.bar.leftbut configure -image bm-left
     }
     pack .tf.bar.leftbut -side left -fill y
     ${NS}::button .tf.bar.rightbut -command goforw -state disabled -width 26
     if {$use_ttk} {
-	.tf.bar.rightbut configure -image [list bm-right disabled bm-right-gray]
+        .tf.bar.rightbut configure -image [list bm-right disabled bm-right-gray]
     } else {
-	.tf.bar.rightbut configure -image bm-right
+        .tf.bar.rightbut configure -image bm-right
     }
     pack .tf.bar.rightbut -side left -fill y
 
     ${NS}::label .tf.bar.rowlabel -text [mc "Row"]
     set rownumsel {}
     ${NS}::label .tf.bar.rownum -width 7 -textvariable rownumsel \
-	-relief sunken -anchor e
+        -relief sunken -anchor e
     ${NS}::label .tf.bar.rowlabel2 -text "/"
     ${NS}::label .tf.bar.numcommits -width 7 -textvariable numcommits \
-	-relief sunken -anchor e
+        -relief sunken -anchor e
     pack .tf.bar.rowlabel .tf.bar.rownum .tf.bar.rowlabel2 .tf.bar.numcommits \
-	-side left
+        -side left
     if {!$use_ttk} {
         foreach w {rownum numcommits} {.tf.bar.$w configure -font textfont}
     }
@@ -2264,14 +2267,14 @@
     ${NS}::label $statusw -width 15 -relief sunken
     pack $statusw -side left -padx 5
     if {$use_ttk} {
-	set progresscanv [ttk::progressbar .tf.bar.progress]
+        set progresscanv [ttk::progressbar .tf.bar.progress]
     } else {
-	set h [expr {[font metrics uifont -linespace] + 2}]
-	set progresscanv .tf.bar.progress
-	canvas $progresscanv -relief sunken -height $h -borderwidth 2
-	set progressitem [$progresscanv create rect -1 0 0 $h -fill "#00ff00"]
-	set fprogitem [$progresscanv create rect -1 0 0 $h -fill yellow]
-	set rprogitem [$progresscanv create rect -1 0 0 $h -fill red]
+        set h [expr {[font metrics uifont -linespace] + 2}]
+        set progresscanv .tf.bar.progress
+        canvas $progresscanv -relief sunken -height $h -borderwidth 2
+        set progressitem [$progresscanv create rect -1 0 0 $h -fill "#00ff00"]
+        set fprogitem [$progresscanv create rect -1 0 0 $h -fill yellow]
+        set rprogitem [$progresscanv create rect -1 0 0 $h -fill red]
     }
     pack $progresscanv -side right -expand 1 -fill x -padx {0 2}
     set progresscoords {0 0}
@@ -2285,26 +2288,26 @@
     ${NS}::label .tf.lbar.flabel -text "[mc "Find"] "
 
     set bm_down_data {
-	#define down_width 16
-	#define down_height 16
-	static unsigned char down_bits[] = {
-	0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
-	0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
-	0x87, 0xe1, 0x8e, 0x71, 0x9c, 0x39, 0xb8, 0x1d,
-	0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01};
+        #define down_width 16
+        #define down_height 16
+        static unsigned char down_bits[] = {
+        0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
+        0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
+        0x87, 0xe1, 0x8e, 0x71, 0x9c, 0x39, 0xb8, 0x1d,
+        0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01};
     }
     image create bitmap bm-down -data $bm_down_data -foreground $uifgcolor
     ${NS}::button .tf.lbar.fnext -width 26 -command {dofind 1 1}
     .tf.lbar.fnext configure -image bm-down
 
     set bm_up_data {
-	#define up_width 16
-	#define up_height 16
-	static unsigned char up_bits[] = {
-	0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
-	0xb8, 0x1d, 0x9c, 0x39, 0x8e, 0x71, 0x87, 0xe1,
-	0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
-	0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01};
+        #define up_width 16
+        #define up_height 16
+        static unsigned char up_bits[] = {
+        0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
+        0xb8, 0x1d, 0x9c, 0x39, 0x8e, 0x71, 0x87, 0xe1,
+        0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
+        0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01};
     }
     image create bitmap bm-up -data $bm_up_data -foreground $uifgcolor
     ${NS}::button .tf.lbar.fprev -width 26 -command {dofind -1 1}
@@ -2313,13 +2316,13 @@
     ${NS}::label .tf.lbar.flab2 -text " [mc "commit"] "
 
     pack .tf.lbar.flabel .tf.lbar.fnext .tf.lbar.fprev .tf.lbar.flab2 \
-	-side left -fill y
+        -side left -fill y
     set gdttype [mc "containing:"]
     set gm [makedroplist .tf.lbar.gdttype gdttype \
-		[mc "containing:"] \
-		[mc "touching paths:"] \
-		[mc "adding/removing string:"] \
-		[mc "changing lines matching:"]]
+                [mc "containing:"] \
+                [mc "touching paths:"] \
+                [mc "adding/removing string:"] \
+                [mc "changing lines matching:"]]
     trace add variable gdttype write gdttype_change
     pack .tf.lbar.gdttype -side left -fill y
 
@@ -2330,11 +2333,11 @@
     trace add variable findstring write find_change
     set findtype [mc "Exact"]
     set findtypemenu [makedroplist .tf.lbar.findtype \
-			  findtype [mc "Exact"] [mc "IgnCase"] [mc "Regexp"]]
+                          findtype [mc "Exact"] [mc "IgnCase"] [mc "Regexp"]]
     trace add variable findtype write findcom_change
     set findloc [mc "All fields"]
     makedroplist .tf.lbar.findloc findloc [mc "All fields"] [mc "Headline"] \
-	[mc "Comments"] [mc "Author"] [mc "Committer"]
+        [mc "Comments"] [mc "Author"] [mc "Committer"]
     trace add variable findloc write find_change
     pack .tf.lbar.findloc -side right
     pack .tf.lbar.findtype -side right
@@ -2346,8 +2349,8 @@
     pack .tf.histframe -fill both -side top -expand 1
     .ctop add .tf
     if {!$use_ttk} {
-	.ctop paneconfigure .tf -height $geometry(topheight)
-	.ctop paneconfigure .tf -width $geometry(topwidth)
+        .ctop paneconfigure .tf -height $geometry(topheight)
+        .ctop paneconfigure .tf -width $geometry(topwidth)
     }
 
     # now build up the bottom
@@ -2357,9 +2360,9 @@
     # if we know window height, then that will set the lower text height, otherwise
     # we set lower text height which will drive window height
     if {[info exists geometry(main)]} {
-	${NS}::frame .bleft -width $geometry(botwidth)
+        ${NS}::frame .bleft -width $geometry(botwidth)
     } else {
-	${NS}::frame .bleft -width $geometry(botwidth) -height $geometry(botheight)
+        ${NS}::frame .bleft -width $geometry(botwidth) -height $geometry(botheight)
     }
     ${NS}::frame .bleft.top
     ${NS}::frame .bleft.mid
@@ -2377,41 +2380,41 @@
     trace add variable searchstring write incrsearch
     pack $sstring -side left -expand 1 -fill x
     ${NS}::radiobutton .bleft.mid.diff -text [mc "Diff"] \
-	-command changediffdisp -variable diffelide -value {0 0}
+        -command changediffdisp -variable diffelide -value {0 0}
     ${NS}::radiobutton .bleft.mid.old -text [mc "Old version"] \
-	-command changediffdisp -variable diffelide -value {0 1}
+        -command changediffdisp -variable diffelide -value {0 1}
     ${NS}::radiobutton .bleft.mid.new -text [mc "New version"] \
-	-command changediffdisp -variable diffelide -value {1 0}
+        -command changediffdisp -variable diffelide -value {1 0}
 
     ${NS}::label .bleft.mid.labeldiffcontext -text "      [mc "Lines of context"]: "
     pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new -side left -ipadx $wgap
     spinbox .bleft.mid.diffcontext -width 5 \
-	-from 0 -increment 1 -to 10000000 \
-	-validate all -validatecommand "diffcontextvalidate %P" \
-	-textvariable diffcontextstring
+        -from 0 -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.labeldiffcontext .bleft.mid.diffcontext -side left -ipadx $wgap
     ${NS}::checkbutton .bleft.mid.ignspace -text [mc "Ignore space change"] \
-	-command changeignorespace -variable ignorespace
+        -command changeignorespace -variable ignorespace
     pack .bleft.mid.ignspace -side left -padx 5
 
     set worddiff [mc "Line diff"]
     if {[package vcompare $git_version "1.7.2"] >= 0} {
-	makedroplist .bleft.mid.worddiff worddiff [mc "Line diff"] \
-	    [mc "Markup words"] [mc "Color words"]
-	trace add variable worddiff write changeworddiff
-	pack .bleft.mid.worddiff -side left -padx 5
+        makedroplist .bleft.mid.worddiff worddiff [mc "Line diff"] \
+            [mc "Markup words"] [mc "Color words"]
+        trace add variable worddiff write changeworddiff
+        pack .bleft.mid.worddiff -side left -padx 5
     }
 
     set ctext .bleft.bottom.ctext
     text $ctext -background $bgcolor -foreground $fgcolor \
-	-state disabled -undo 0 -font textfont \
-	-yscrollcommand scrolltext -wrap none \
-	-xscrollcommand ".bleft.bottom.sbhorizontal set"
+        -state disabled -undo 0 -font textfont \
+        -yscrollcommand scrolltext -wrap none \
+        -xscrollcommand ".bleft.bottom.sbhorizontal set"
     if {$have_tk85} {
-	$ctext conf -tabstyle wordprocessor
+        $ctext conf -tabstyle wordprocessor
     }
     ${NS}::scrollbar .bleft.bottom.sb -command "$ctext yview"
     ${NS}::scrollbar .bleft.bottom.sbhorizontal -command "$ctext xview" -orient h
@@ -2430,7 +2433,9 @@
     $ctext tag conf filesep -font textfontbold -fore $filesepfgcolor -back $filesepbgcolor
     $ctext tag conf hunksep -fore [lindex $diffcolors 2]
     $ctext tag conf d0 -fore [lindex $diffcolors 0]
+    $ctext tag conf d0 -back [lindex $diffbgcolors 0]
     $ctext tag conf dresult -fore [lindex $diffcolors 1]
+    $ctext tag conf dresult -back [lindex $diffbgcolors 1]
     $ctext tag conf m0 -fore [lindex $mergecolors 0]
     $ctext tag conf m1 -fore [lindex $mergecolors 1]
     $ctext tag conf m2 -fore [lindex $mergecolors 2]
@@ -2455,38 +2460,44 @@
     $ctext tag conf currentsearchhit -back $currentsearchhitbgcolor
     $ctext tag conf wwrap -wrap word -lmargin2 1c
     $ctext tag conf bold -font textfontbold
+    # set these to the lowest priority:
+    $ctext tag lower currentsearchhit
+    $ctext tag lower found
+    $ctext tag lower filesep
+    $ctext tag lower dresult
+    $ctext tag lower d0
 
     .pwbottom add .bleft
     if {!$use_ttk} {
-	.pwbottom paneconfigure .bleft -width $geometry(botwidth)
+        .pwbottom paneconfigure .bleft -width $geometry(botwidth)
     }
 
     # lower right
     ${NS}::frame .bright
     ${NS}::frame .bright.mode
     ${NS}::radiobutton .bright.mode.patch -text [mc "Patch"] \
-	-command reselectline -variable cmitmode -value "patch"
+        -command reselectline -variable cmitmode -value "patch"
     ${NS}::radiobutton .bright.mode.tree -text [mc "Tree"] \
-	-command reselectline -variable cmitmode -value "tree"
+        -command reselectline -variable cmitmode -value "tree"
     grid .bright.mode.patch .bright.mode.tree -sticky ew
     pack .bright.mode -side top -fill x
     set cflist .bright.cfiles
     set indent [font measure mainfont "nn"]
     text $cflist \
-	-selectbackground $selectbgcolor \
-	-background $bgcolor -foreground $fgcolor \
-	-font mainfont \
-	-tabs [list $indent [expr {2 * $indent}]] \
-	-yscrollcommand ".bright.sb set" \
-	-cursor [. cget -cursor] \
-	-spacing1 1 -spacing3 1
+        -selectbackground $selectbgcolor \
+        -background $bgcolor -foreground $fgcolor \
+        -font mainfont \
+        -tabs [list $indent [expr {2 * $indent}]] \
+        -yscrollcommand ".bright.sb set" \
+        -cursor [. cget -cursor] \
+        -spacing1 1 -spacing3 1
     lappend bglist $cflist
     lappend fglist $cflist
     ${NS}::scrollbar .bright.sb -command "$cflist yview"
     pack .bright.sb -side right -fill y
     pack $cflist -side left -fill both -expand 1
     $cflist tag configure highlight \
-	-background [$cflist cget -selectbackground]
+        -background [$cflist cget -selectbackground]
     $cflist tag configure bold -font mainfontbold
 
     .pwbottom add .bright
@@ -2494,15 +2505,15 @@
 
     # restore window width & height if known
     if {[info exists geometry(main)]} {
-	if {[scan $geometry(main) "%dx%d" w h] >= 2} {
-	    if {$w > [winfo screenwidth .]} {
-		set w [winfo screenwidth .]
-	    }
-	    if {$h > [winfo screenheight .]} {
-		set h [winfo screenheight .]
-	    }
-	    wm geometry . "${w}x$h"
-	}
+        if {[scan $geometry(main) "%dx%d" w h] >= 2} {
+            if {$w > [winfo screenwidth .]} {
+                set w [winfo screenwidth .]
+            }
+            if {$h > [winfo screenheight .]} {
+                set h [winfo screenheight .]
+            }
+            wm geometry . "${w}x$h"
+        }
     }
 
     if {[info exists geometry(state)] && $geometry(state) eq "zoomed"} {
@@ -2526,25 +2537,25 @@
             bind %W <Map> {}
             %W sashpos 0 $::geometry(botwidth)
         }
+        bind .pwbottom <Configure> {resizecdetpanes %W %w}
     }
 
-    bind .pwbottom <Configure> {resizecdetpanes %W %w}
     pack .ctop -fill both -expand 1
     bindall <1> {selcanvline %W %x %y}
     #bindall <B1-Motion> {selcanvline %W %x %y}
     if {[tk windowingsystem] == "win32"} {
-	bind . <MouseWheel> { windows_mousewheel_redirector %W %X %Y %D }
-	bind $ctext <MouseWheel> { windows_mousewheel_redirector %W %X %Y %D ; break }
+        bind . <MouseWheel> { windows_mousewheel_redirector %W %X %Y %D }
+        bind $ctext <MouseWheel> { windows_mousewheel_redirector %W %X %Y %D ; break }
     } else {
-	bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
-	bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
-	bind $ctext <Button> {
-	    if {"%b" eq 6} {
-		$ctext xview scroll -5 units
-	    } elseif {"%b" eq 7} {
-		$ctext xview scroll 5 units
-	    }
-	}
+        bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
+        bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
+        bind $ctext <Button> {
+            if {"%b" eq 6} {
+                $ctext xview scroll -5 units
+            } elseif {"%b" eq 7} {
+                $ctext xview scroll 5 units
+            }
+        }
         if {[tk windowingsystem] eq "aqua"} {
             bindall <MouseWheel> {
                 set delta [expr {- (%D)}]
@@ -2627,7 +2638,7 @@
     bind $ctext <Button-1> {focus %W}
     bind $ctext <<Selection>> rehighlight_search_results
     for {set i 1} {$i < 10} {incr i} {
-	bind . <$M1B-Key-$i> [list go_to_parent $i]
+        bind . <$M1B-Key-$i> [list go_to_parent $i]
     }
 
     set maincursor [. cget -cursor]
@@ -2636,60 +2647,60 @@
 
     set rowctxmenu .rowctxmenu
     makemenu $rowctxmenu {
-	{mc "Diff this -> selected" command {diffvssel 0}}
-	{mc "Diff selected -> this" command {diffvssel 1}}
-	{mc "Make patch" command mkpatch}
-	{mc "Create tag" command mktag}
-	{mc "Copy commit summary" command copysummary}
-	{mc "Write commit to file" command writecommit}
-	{mc "Create new branch" command mkbranch}
-	{mc "Cherry-pick this commit" command cherrypick}
-	{mc "Reset HEAD branch to here" command resethead}
-	{mc "Mark this commit" command markhere}
-	{mc "Return to mark" command gotomark}
-	{mc "Find descendant of this and mark" command find_common_desc}
-	{mc "Compare with marked commit" command compare_commits}
-	{mc "Diff this -> marked commit" command {diffvsmark 0}}
-	{mc "Diff marked commit -> this" command {diffvsmark 1}}
-	{mc "Revert this commit" command revert}
+        {mc "Diff this -> selected" command {diffvssel 0}}
+        {mc "Diff selected -> this" command {diffvssel 1}}
+        {mc "Make patch" command mkpatch}
+        {mc "Create tag" command mktag}
+        {mc "Copy commit reference" command copyreference}
+        {mc "Write commit to file" command writecommit}
+        {mc "Create new branch" command mkbranch}
+        {mc "Cherry-pick this commit" command cherrypick}
+        {mc "Reset HEAD branch to here" command resethead}
+        {mc "Mark this commit" command markhere}
+        {mc "Return to mark" command gotomark}
+        {mc "Find descendant of this and mark" command find_common_desc}
+        {mc "Compare with marked commit" command compare_commits}
+        {mc "Diff this -> marked commit" command {diffvsmark 0}}
+        {mc "Diff marked commit -> this" command {diffvsmark 1}}
+        {mc "Revert this commit" command revert}
     }
     $rowctxmenu configure -tearoff 0
 
     set fakerowmenu .fakerowmenu
     makemenu $fakerowmenu {
-	{mc "Diff this -> selected" command {diffvssel 0}}
-	{mc "Diff selected -> this" command {diffvssel 1}}
-	{mc "Make patch" command mkpatch}
-	{mc "Diff this -> marked commit" command {diffvsmark 0}}
-	{mc "Diff marked commit -> this" command {diffvsmark 1}}
+        {mc "Diff this -> selected" command {diffvssel 0}}
+        {mc "Diff selected -> this" command {diffvssel 1}}
+        {mc "Make patch" command mkpatch}
+        {mc "Diff this -> marked commit" command {diffvsmark 0}}
+        {mc "Diff marked commit -> this" command {diffvsmark 1}}
     }
     $fakerowmenu configure -tearoff 0
 
     set headctxmenu .headctxmenu
     makemenu $headctxmenu {
-	{mc "Check out this branch" command cobranch}
-	{mc "Rename this branch" command mvbranch}
-	{mc "Remove this branch" command rmbranch}
-	{mc "Copy branch name" command {clipboard clear; clipboard append $headmenuhead}}
+        {mc "Check out this branch" command cobranch}
+        {mc "Rename this branch" command mvbranch}
+        {mc "Remove this branch" command rmbranch}
+        {mc "Copy branch name" command {clipboard clear; clipboard append $headmenuhead}}
     }
     $headctxmenu configure -tearoff 0
 
     global flist_menu
     set flist_menu .flistctxmenu
     makemenu $flist_menu {
-	{mc "Highlight this too" command {flist_hl 0}}
-	{mc "Highlight this only" command {flist_hl 1}}
-	{mc "External diff" command {external_diff}}
-	{mc "Blame parent commit" command {external_blame 1}}
-	{mc "Copy path" command {clipboard clear; clipboard append $flist_menu_file}}
+        {mc "Highlight this too" command {flist_hl 0}}
+        {mc "Highlight this only" command {flist_hl 1}}
+        {mc "External diff" command {external_diff}}
+        {mc "Blame parent commit" command {external_blame 1}}
+        {mc "Copy path" command {clipboard clear; clipboard append $flist_menu_file}}
     }
     $flist_menu configure -tearoff 0
 
     global diff_menu
     set diff_menu .diffctxmenu
     makemenu $diff_menu {
-	{mc "Show origin of this line" command show_line_source}
-	{mc "Run git gui blame on this line" command {external_blame_diff}}
+        {mc "Show origin of this line" command show_line_source}
+        {mc "Run git gui blame on this line" command {external_blame_diff}}
     }
     $diff_menu configure -tearoff 0
 }
@@ -2701,14 +2712,14 @@
     global canv canv2 canv3
     set w [winfo containing -displayof $W $X $Y]
     if {$w ne ""} {
-	set u [expr {$D < 0 ? 5 : -5}]
-	if {$w == $canv || $w == $canv2 || $w == $canv3} {
-	    allcanvs yview scroll $u units
-	} else {
-	    catch {
-		$w yview scroll $u units
-	    }
-	}
+        set u [expr {$D < 0 ? 5 : -5}]
+        if {$w == $canv || $w == $canv2 || $w == $canv3} {
+            allcanvs yview scroll $u units
+        } else {
+            catch {
+                $w yview scroll $u units
+            }
+        }
     }
 }
 
@@ -2717,9 +2728,9 @@
     global selectedline rownumsel
 
     if {$selectedline eq {}} {
-	set rownumsel {}
+        set rownumsel {}
     } else {
-	set rownumsel [expr {$selectedline + 1}]
+        set rownumsel [expr {$selectedline + 1}]
     }
 }
 
@@ -2728,11 +2739,11 @@
 proc canvscan {op w x y} {
     global canv canv2 canv3
     foreach c [list $canv $canv2 $canv3] {
-	if {$c == $w} {
-	    $c scan $op $x $y
-	} else {
-	    $c scan $op 0 $y
-	}
+        if {$c == $w} {
+            $c scan $op $x $y
+        } else {
+            $c scan $op 0 $y
+        }
     }
 }
 
@@ -2750,10 +2761,10 @@
     bind . $ev $script
     set escript [bind Entry $ev]
     if {$escript == {}} {
-	set escript [bind Entry <Key>]
+        set escript [bind Entry <Key>]
     }
     foreach e $entries {
-	bind $e $ev "$escript; break"
+        bind $e $ev "$escript; break"
     }
 }
 
@@ -2767,7 +2778,7 @@
 proc click {w} {
     global ctext entries
     foreach e [concat $entries $ctext] {
-	if {$w == $e} return
+        if {$w == $e} return
     }
     focus .
 }
@@ -2779,8 +2790,8 @@
     global rprogitem rprogcoord use_ttk
 
     if {$use_ttk} {
-	$progresscanv configure -value [expr {int($fprogcoord * 100)}]
-	return
+        $progresscanv configure -value [expr {int($fprogcoord * 100)}]
+        return
     }
 
     set w [expr {[winfo width $progresscanv] - 4}]
@@ -2792,11 +2803,11 @@
     $progresscanv coords $rprogitem 0 0 [expr {$w * $rprogcoord}] $h
     set now [clock clicks -milliseconds]
     if {$now >= $lastprogupdate + 100} {
-	set progupdatepending 0
-	update
+        set progupdatepending 0
+        update
     } elseif {!$progupdatepending} {
-	set progupdatepending 1
-	after [expr {$lastprogupdate + 100 - $now}] doprogupdate
+        set progupdatepending 1
+        after [expr {$lastprogupdate + 100 - $now}] doprogupdate
     }
 }
 
@@ -2804,9 +2815,9 @@
     global lastprogupdate progupdatepending
 
     if {$progupdatepending} {
-	set progupdatepending 0
-	set lastprogupdate [clock clicks -milliseconds]
-	update
+        set progupdatepending 0
+        set lastprogupdate [clock clicks -milliseconds]
+        update
     }
 }
 
@@ -2814,14 +2825,14 @@
     global config_file_tmp
 
     if {[file exists $config_file_tmp]} {
-	incr tries_left -1
-	if {$tries_left > 0} {
-	    after 100 [list config_check_tmp_exists $tries_left]
-	} else {
-	    error_popup "There appears to be a stale $config_file_tmp\
+        incr tries_left -1
+        if {$tries_left > 0} {
+            after 100 [list config_check_tmp_exists $tries_left]
+        } else {
+            error_popup "There appears to be a stale $config_file_tmp\
  file, which will prevent gitk from saving its configuration on exit.\
  Please remove it if it is not being used by any existing gitk process."
-	}
+        }
     }
 }
 
@@ -2838,9 +2849,9 @@
 
     upvar #0 $name var
     if {$op eq "write" &&
-	(![info exists config_variable_original($name)] ||
-	 $config_variable_original($name) ne $var)} {
-	set config_variable_changed($name) 1
+        (![info exists config_variable_original($name)] ||
+         $config_variable_original($name) ne $var)} {
+        set config_variable_changed($name) 1
     }
 }
 
@@ -2862,151 +2873,158 @@
     if {![winfo viewable .]} return
     set remove_tmp 0
     if {[catch {
-	set try_count 0
-	while {[catch {set f [open $config_file_tmp {WRONLY CREAT EXCL}]}]} {
-	    if {[incr try_count] > 50} {
-		error "Unable to write config file: $config_file_tmp exists"
-	    }
-	    after 100
-	}
-	set remove_tmp 1
-	if {$::tcl_platform(platform) eq {windows}} {
-	    file attributes $config_file_tmp -hidden true
-	}
-	if {[file exists $config_file]} {
-	    source $config_file
-	}
-	foreach var_name $config_variables {
-	    upvar #0 $var_name var
-	    upvar 0 $var_name old_var
-	    if {!$config_variable_changed($var_name) && [info exists old_var]} {
-		puts $f [list set $var_name $old_var]
-	    } else {
-		puts $f [list set $var_name $var]
-	    }
-	}
+        set try_count 0
+        while {[catch {set f [open $config_file_tmp {WRONLY CREAT EXCL}]}]} {
+            if {[incr try_count] > 50} {
+                error "Unable to write config file: $config_file_tmp exists"
+            }
+            after 100
+        }
+        set remove_tmp 1
+        if {$::tcl_platform(platform) eq {windows}} {
+            file attributes $config_file_tmp -hidden true
+        }
+        if {[file exists $config_file]} {
+            source $config_file
+        }
+        foreach var_name $config_variables {
+            upvar #0 $var_name var
+            upvar 0 $var_name old_var
+            if {!$config_variable_changed($var_name) && [info exists old_var]} {
+                puts $f [list set $var_name $old_var]
+            } else {
+                puts $f [list set $var_name $var]
+            }
+        }
 
-	puts $f "set geometry(main) [wm geometry .]"
-	puts $f "set geometry(state) [wm state .]"
-	puts $f "set geometry(topwidth) [winfo width .tf]"
-	puts $f "set geometry(topheight) [winfo height .tf]"
-	if {$current_use_ttk} {
-	    puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sashpos 0] 1\""
-	    puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sashpos 1] 1\""
-	} else {
-	    puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sash coord 0]\""
-	    puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sash coord 1]\""
-	}
-	puts $f "set geometry(botwidth) [winfo width .bleft]"
-	puts $f "set geometry(botheight) [winfo height .bleft]"
+        puts $f "set geometry(main) [wm geometry .]"
+        puts $f "set geometry(state) [wm state .]"
+        puts $f "set geometry(topwidth) [winfo width .tf]"
+        puts $f "set geometry(topheight) [winfo height .tf]"
+        if {$current_use_ttk} {
+            puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sashpos 0] 1\""
+            puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sashpos 1] 1\""
+        } else {
+            puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sash coord 0]\""
+            puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sash coord 1]\""
+        }
+        puts $f "set geometry(botwidth) [winfo width .bleft]"
+        puts $f "set geometry(botheight) [winfo height .bleft]"
 
-	array set view_save {}
-	array set views {}
-	if {![info exists permviews]} { set permviews {} }
-	foreach view $permviews {
-	    set view_save([lindex $view 0]) 1
-	    set views([lindex $view 0]) $view
-	}
-	puts -nonewline $f "set permviews {"
-	for {set v 1} {$v < $current_nextviewnum} {incr v} {
-	    if {$viewchanged($v)} {
-		if {$current_viewperm($v)} {
-		    set views($current_viewname($v)) [list $current_viewname($v) $current_viewfiles($v) $current_viewargs($v) $current_viewargscmd($v)]
-		} else {
-		    set view_save($current_viewname($v)) 0
-		}
-	    }
-	}
-	# write old and updated view to their places and append remaining to the end
-	foreach view $permviews {
-	    set view_name [lindex $view 0]
-	    if {$view_save($view_name)} {
-		puts $f "{$views($view_name)}"
-	    }
-	    unset views($view_name)
-	}
-	foreach view_name [array names views] {
-	    puts $f "{$views($view_name)}"
-	}
-	puts $f "}"
-	close $f
-	file rename -force $config_file_tmp $config_file
-	set remove_tmp 0
+        array set view_save {}
+        array set views {}
+        if {![info exists permviews]} { set permviews {} }
+        foreach view $permviews {
+            set view_save([lindex $view 0]) 1
+            set views([lindex $view 0]) $view
+        }
+        puts -nonewline $f "set permviews {"
+        for {set v 1} {$v < $current_nextviewnum} {incr v} {
+            if {$viewchanged($v)} {
+                if {$current_viewperm($v)} {
+                    set views($current_viewname($v)) [list $current_viewname($v) $current_viewfiles($v) $current_viewargs($v) $current_viewargscmd($v)]
+                } else {
+                    set view_save($current_viewname($v)) 0
+                }
+            }
+        }
+        # write old and updated view to their places and append remaining to the end
+        foreach view $permviews {
+            set view_name [lindex $view 0]
+            if {$view_save($view_name)} {
+                puts $f "{$views($view_name)}"
+            }
+            unset views($view_name)
+        }
+        foreach view_name [array names views] {
+            puts $f "{$views($view_name)}"
+        }
+        puts $f "}"
+        close $f
+        file rename -force $config_file_tmp $config_file
+        set remove_tmp 0
     } err]} {
         puts "Error saving config: $err"
     }
     if {$remove_tmp} {
-	file delete -force $config_file_tmp
+        file delete -force $config_file_tmp
     }
     set stuffsaved 1
 }
 
 proc resizeclistpanes {win w} {
-    global oldwidth use_ttk
+    global oldwidth oldsash use_ttk
     if {[info exists oldwidth($win)]} {
-	if {$use_ttk} {
-	    set s0 [$win sashpos 0]
-	    set s1 [$win sashpos 1]
-	} else {
-	    set s0 [$win sash coord 0]
-	    set s1 [$win sash coord 1]
-	}
-	if {$w < 60} {
-	    set sash0 [expr {int($w/2 - 2)}]
-	    set sash1 [expr {int($w*5/6 - 2)}]
-	} else {
-	    set factor [expr {1.0 * $w / $oldwidth($win)}]
-	    set sash0 [expr {int($factor * [lindex $s0 0])}]
-	    set sash1 [expr {int($factor * [lindex $s1 0])}]
-	    if {$sash0 < 30} {
-		set sash0 30
-	    }
-	    if {$sash1 < $sash0 + 20} {
-		set sash1 [expr {$sash0 + 20}]
-	    }
-	    if {$sash1 > $w - 10} {
-		set sash1 [expr {$w - 10}]
-		if {$sash0 > $sash1 - 20} {
-		    set sash0 [expr {$sash1 - 20}]
-		}
-	    }
-	}
-	if {$use_ttk} {
-	    $win sashpos 0 $sash0
-	    $win sashpos 1 $sash1
-	} else {
-	    $win sash place 0 $sash0 [lindex $s0 1]
-	    $win sash place 1 $sash1 [lindex $s1 1]
-	}
+	if {[info exists oldsash($win)]} {
+	    set s0 [lindex $oldsash($win) 0]
+	    set s1 [lindex $oldsash($win) 1]
+        } elseif {$use_ttk} {
+            set s0 [$win sashpos 0]
+            set s1 [$win sashpos 1]
+        } else {
+            set s0 [$win sash coord 0]
+            set s1 [$win sash coord 1]
+        }
+        if {$w < 60} {
+            set sash0 [expr {int($w/2 - 2)}]
+            set sash1 [expr {int($w*5/6 - 2)}]
+        } else {
+            set factor [expr {1.0 * $w / $oldwidth($win)}]
+            set sash0 [expr {int($factor * [lindex $s0 0])}]
+            set sash1 [expr {int($factor * [lindex $s1 0])}]
+            if {$sash0 < 30} {
+                set sash0 30
+            }
+            if {$sash1 < $sash0 + 20} {
+                set sash1 [expr {$sash0 + 20}]
+            }
+            if {$sash1 > $w - 10} {
+                set sash1 [expr {$w - 10}]
+                if {$sash0 > $sash1 - 20} {
+                    set sash0 [expr {$sash1 - 20}]
+                }
+            }
+        }
+        if {$use_ttk} {
+            $win sashpos 0 $sash0
+            $win sashpos 1 $sash1
+        } else {
+            $win sash place 0 $sash0 [lindex $s0 1]
+            $win sash place 1 $sash1 [lindex $s1 1]
+        }
+	set oldsash($win) [list $sash0 $sash1]
     }
     set oldwidth($win) $w
 }
 
 proc resizecdetpanes {win w} {
-    global oldwidth use_ttk
+    global oldwidth oldsash use_ttk
     if {[info exists oldwidth($win)]} {
-	if {$use_ttk} {
-	    set s0 [$win sashpos 0]
-	} else {
-	    set s0 [$win sash coord 0]
-	}
-	if {$w < 60} {
-	    set sash0 [expr {int($w*3/4 - 2)}]
-	} else {
-	    set factor [expr {1.0 * $w / $oldwidth($win)}]
-	    set sash0 [expr {int($factor * [lindex $s0 0])}]
-	    if {$sash0 < 45} {
-		set sash0 45
-	    }
-	    if {$sash0 > $w - 15} {
-		set sash0 [expr {$w - 15}]
-	    }
-	}
-	if {$use_ttk} {
-	    $win sashpos 0 $sash0
-	} else {
-	    $win sash place 0 $sash0 [lindex $s0 1]
-	}
+	if {[info exists oldsash($win)]} {
+	    set s0 $oldsash($win)
+        } elseif {$use_ttk} {
+            set s0 [$win sashpos 0]
+        } else {
+            set s0 [$win sash coord 0]
+        }
+        if {$w < 60} {
+            set sash0 [expr {int($w*3/4 - 2)}]
+        } else {
+            set factor [expr {1.0 * $w / $oldwidth($win)}]
+            set sash0 [expr {int($factor * [lindex $s0 0])}]
+            if {$sash0 < 45} {
+                set sash0 45
+            }
+            if {$sash0 > $w - 15} {
+                set sash0 [expr {$w - 15}]
+            }
+        }
+        if {$use_ttk} {
+            $win sashpos 0 $sash0
+        } else {
+            $win sash place 0 $sash0 [lindex $s0 1]
+        }
+	set oldsash($win) $sash0
     }
     set oldwidth($win) $w
 }
@@ -3029,8 +3047,8 @@
     global bgcolor NS
     set w .about
     if {[winfo exists $w]} {
-	raise $w
-	return
+        raise $w
+        return
     }
     ttk_toplevel $w
     wm title $w [mc "About gitk"]
@@ -3041,7 +3059,7 @@
 Copyright \u00a9 2005-2016 Paul Mackerras
 
 Use and redistribute under the terms of the GNU General Public License"] \
-	    -justify center -aspect 400 -border 2 -bg $bgcolor -relief groove
+            -justify center -aspect 400 -border 2 -bg $bgcolor -relief groove
     pack $w.m -side top -fill x -padx 2 -pady 2
     ${NS}::button $w.ok -text [mc "Close"] -command "destroy $w" -default active
     pack $w.ok -side bottom
@@ -3055,13 +3073,13 @@
     global bgcolor NS
     set w .keys
     if {[winfo exists $w]} {
-	raise $w
-	return
+        raise $w
+        return
     }
     if {[tk windowingsystem] eq {aqua}} {
-	set M1T Cmd
+        set M1T Cmd
     } else {
-	set M1T Ctrl
+        set M1T Ctrl
     }
     ttk_toplevel $w
     wm title $w [mc "Gitk key bindings"]
@@ -3108,7 +3126,7 @@
 [mc "<%s-minus>	Decrease font size" $M1T]
 [mc "<F5>		Update"]
 " \
-	    -justify left -bg $bgcolor -border 2 -relief groove
+            -justify left -bg $bgcolor -border 2 -relief groove
     pack $w.m -side top -fill both -padx 2 -pady 2
     ${NS}::button $w.ok -text [mc "Close"] -command "destroy $w" -default active
     bind $w <Key-Escape> [list destroy $w]
@@ -3135,68 +3153,68 @@
     set treecontents() {}
     $w conf -state normal
     foreach f $l {
-	while {[string range $f 0 $prefixend] ne $prefix} {
-	    if {$lev <= $openlevs} {
-		$w mark set e:$treeindex($prefix) "end -1c"
-		$w mark gravity e:$treeindex($prefix) left
-	    }
-	    set treeheight($prefix) $ht
-	    incr ht [lindex $htstack end]
-	    set htstack [lreplace $htstack end end]
-	    set prefixend [lindex $prefendstack end]
-	    set prefendstack [lreplace $prefendstack end end]
-	    set prefix [string range $prefix 0 $prefixend]
-	    incr lev -1
-	}
-	set tail [string range $f [expr {$prefixend+1}] end]
-	while {[set slash [string first "/" $tail]] >= 0} {
-	    lappend htstack $ht
-	    set ht 0
-	    lappend prefendstack $prefixend
-	    incr prefixend [expr {$slash + 1}]
-	    set d [string range $tail 0 $slash]
-	    lappend treecontents($prefix) $d
-	    set oldprefix $prefix
-	    append prefix $d
-	    set treecontents($prefix) {}
-	    set treeindex($prefix) [incr ix]
-	    set treeparent($prefix) $oldprefix
-	    set tail [string range $tail [expr {$slash+1}] end]
-	    if {$lev <= $openlevs} {
-		set ht 1
-		set treediropen($prefix) [expr {$lev < $openlevs}]
-		set bm [expr {$lev == $openlevs? "tri-rt": "tri-dn"}]
-		$w mark set d:$ix "end -1c"
-		$w mark gravity d:$ix left
-		set str "\n"
-		for {set i 0} {$i < $lev} {incr i} {append str "\t"}
-		$w insert end $str
-		$w image create end -align center -image $bm -padx 1 \
-		    -name a:$ix
-		$w insert end $d [highlight_tag $prefix]
-		$w mark set s:$ix "end -1c"
-		$w mark gravity s:$ix left
-	    }
-	    incr lev
-	}
-	if {$tail ne {}} {
-	    if {$lev <= $openlevs} {
-		incr ht
-		set str "\n"
-		for {set i 0} {$i < $lev} {incr i} {append str "\t"}
-		$w insert end $str
-		$w insert end $tail [highlight_tag $f]
-	    }
-	    lappend treecontents($prefix) $tail
-	}
+        while {[string range $f 0 $prefixend] ne $prefix} {
+            if {$lev <= $openlevs} {
+                $w mark set e:$treeindex($prefix) "end -1c"
+                $w mark gravity e:$treeindex($prefix) left
+            }
+            set treeheight($prefix) $ht
+            incr ht [lindex $htstack end]
+            set htstack [lreplace $htstack end end]
+            set prefixend [lindex $prefendstack end]
+            set prefendstack [lreplace $prefendstack end end]
+            set prefix [string range $prefix 0 $prefixend]
+            incr lev -1
+        }
+        set tail [string range $f [expr {$prefixend+1}] end]
+        while {[set slash [string first "/" $tail]] >= 0} {
+            lappend htstack $ht
+            set ht 0
+            lappend prefendstack $prefixend
+            incr prefixend [expr {$slash + 1}]
+            set d [string range $tail 0 $slash]
+            lappend treecontents($prefix) $d
+            set oldprefix $prefix
+            append prefix $d
+            set treecontents($prefix) {}
+            set treeindex($prefix) [incr ix]
+            set treeparent($prefix) $oldprefix
+            set tail [string range $tail [expr {$slash+1}] end]
+            if {$lev <= $openlevs} {
+                set ht 1
+                set treediropen($prefix) [expr {$lev < $openlevs}]
+                set bm [expr {$lev == $openlevs? "tri-rt": "tri-dn"}]
+                $w mark set d:$ix "end -1c"
+                $w mark gravity d:$ix left
+                set str "\n"
+                for {set i 0} {$i < $lev} {incr i} {append str "\t"}
+                $w insert end $str
+                $w image create end -align center -image $bm -padx 1 \
+                    -name a:$ix
+                $w insert end $d [highlight_tag $prefix]
+                $w mark set s:$ix "end -1c"
+                $w mark gravity s:$ix left
+            }
+            incr lev
+        }
+        if {$tail ne {}} {
+            if {$lev <= $openlevs} {
+                incr ht
+                set str "\n"
+                for {set i 0} {$i < $lev} {incr i} {append str "\t"}
+                $w insert end $str
+                $w insert end $tail [highlight_tag $f]
+            }
+            lappend treecontents($prefix) $tail
+        }
     }
     while {$htstack ne {}} {
-	set treeheight($prefix) $ht
-	incr ht [lindex $htstack end]
-	set htstack [lreplace $htstack end end]
-	set prefixend [lindex $prefendstack end]
-	set prefendstack [lreplace $prefendstack end end]
-	set prefix [string range $prefix 0 $prefixend]
+        set treeheight($prefix) $ht
+        incr ht [lindex $htstack end]
+        set htstack [lreplace $htstack end end]
+        set prefixend [lindex $prefendstack end]
+        set prefendstack [lreplace $prefendstack end end]
+        set prefix [string range $prefix 0 $prefixend]
     }
     $w conf -state disabled
 }
@@ -3207,21 +3225,21 @@
     set y 2
     set prefix {}
     while {1} {
-	foreach e $treecontents($prefix) {
-	    if {$y == $l} {
-		return "$prefix$e"
-	    }
-	    set n 1
-	    if {[string index $e end] eq "/"} {
-		set n $treeheight($prefix$e)
-		if {$y + $n > $l} {
-		    append prefix $e
-		    incr y
-		    break
-		}
-	    }
-	    incr y $n
-	}
+        foreach e $treecontents($prefix) {
+            if {$y == $l} {
+                return "$prefix$e"
+            }
+            set n 1
+            if {[string index $e end] eq "/"} {
+                set n $treeheight($prefix$e)
+                if {$y + $n > $l} {
+                    append prefix $e
+                    incr y
+                    break
+                }
+            }
+            incr y $n
+        }
     }
 }
 
@@ -3229,14 +3247,14 @@
     global treeheight treecontents cflist
 
     foreach e $treecontents($prefix) {
-	set path $prefix$e
-	if {[highlight_tag $path] ne {}} {
-	    $cflist tag add bold $y.0 "$y.0 lineend"
-	}
-	incr y
-	if {[string index $e end] eq "/" && $treeheight($path) > 1} {
-	    set y [highlight_tree $y $path]
-	}
+        set path $prefix$e
+        if {[highlight_tag $path] ne {}} {
+            $cflist tag add bold $y.0 "$y.0 lineend"
+        }
+        incr y
+        if {[string index $e end] eq "/" && $treeheight($path) > 1} {
+            set y [highlight_tree $y $path]
+        }
     }
     return $y
 }
@@ -3252,8 +3270,8 @@
     $w conf -state disabled
     set n [expr {1 - $treeheight($dir)}]
     while {$dir ne {}} {
-	incr treeheight($dir) $n
-	set dir $treeparent($dir)
+        incr treeheight($dir) $n
+        set dir $treeparent($dir)
     }
 }
 
@@ -3269,28 +3287,28 @@
     set str "\n"
     set n [llength $treecontents($dir)]
     for {set x $dir} {$x ne {}} {set x $treeparent($x)} {
-	incr lev
-	append str "\t"
-	incr treeheight($x) $n
+        incr lev
+        append str "\t"
+        incr treeheight($x) $n
     }
     foreach e $treecontents($dir) {
-	set de $dir$e
-	if {[string index $e end] eq "/"} {
-	    set iy $treeindex($de)
-	    $w mark set d:$iy e:$ix
-	    $w mark gravity d:$iy left
-	    $w insert e:$ix $str
-	    set treediropen($de) 0
-	    $w image create e:$ix -align center -image tri-rt -padx 1 \
-		-name a:$iy
-	    $w insert e:$ix $e [highlight_tag $de]
-	    $w mark set s:$iy e:$ix
-	    $w mark gravity s:$iy left
-	    set treeheight($de) 1
-	} else {
-	    $w insert e:$ix $str
-	    $w insert e:$ix $e [highlight_tag $de]
-	}
+        set de $dir$e
+        if {[string index $e end] eq "/"} {
+            set iy $treeindex($de)
+            $w mark set d:$iy e:$ix
+            $w mark gravity d:$iy left
+            $w insert e:$ix $str
+            set treediropen($de) 0
+            $w image create e:$ix -align center -image tri-rt -padx 1 \
+                -name a:$iy
+            $w insert e:$ix $e [highlight_tag $de]
+            $w mark set s:$iy e:$ix
+            $w mark gravity s:$iy left
+            set treeheight($de) 1
+        } else {
+            $w insert e:$ix $str
+            $w insert e:$ix $e [highlight_tag $de]
+        }
     }
     $w mark gravity e:$ix right
     $w conf -state disabled
@@ -3299,13 +3317,13 @@
     set ht [$w cget -height]
     set l [lindex [split [$w index s:$ix] .] 0]
     if {$l < $top} {
-	$w yview $l.0
+        $w yview $l.0
     } elseif {$l + $n + 1 > $top + $ht} {
-	set top [expr {$l + $n + 2 - $ht}]
-	if {$l < $top} {
-	    set top $l
-	}
-	$w yview $top.0
+        set top [expr {$l + $n + 2 - $ht}]
+        if {$l < $top} {
+            set top $l
+        }
+        $w yview $top.0
     }
 }
 
@@ -3319,16 +3337,16 @@
     $cflist tag add highlight $l.0 "$l.0 lineend"
     set cflist_top $l
     if {$l == 1} {
-	$ctext yview 1.0
-	return
+        $ctext yview 1.0
+        return
     }
     set e [linetoelt $l]
     if {[string index $e end] ne "/"} {
-	showfile $e
+        showfile $e
     } elseif {$treediropen($e)} {
-	treeclosedir $w $e
+        treeclosedir $w $e
     } else {
-	treeopendir $w $e
+        treeopendir $w $e
     }
 }
 
@@ -3337,10 +3355,10 @@
 
     treeview $cflist $treefilelist($id) 0
     if {$jump_to_here ne {}} {
-	set f [lindex $jump_to_here 0]
-	if {[lsearch -exact $treefilelist($id) $f] >= 0} {
-	    showfile $f
-	}
+        set f [lindex $jump_to_here 0]
+        if {[lsearch -exact $treefilelist($id) $f] >= 0} {
+            showfile $f
+        }
     }
 }
 
@@ -3415,11 +3433,11 @@
     $cflist conf -state normal
     $cflist delete 0.0 end
     if {$first ne {}} {
-	$cflist insert end $first
-	set cflist_top 1
-	$cflist tag add highlight 1.0 "1.0 lineend"
+        $cflist insert end $first
+        set cflist_top 1
+        $cflist tag add highlight 1.0 "1.0 lineend"
     } else {
-	unset -nocomplain cflist_top
+        unset -nocomplain cflist_top
     }
     $cflist conf -state disabled
     set difffilestart {}
@@ -3429,9 +3447,9 @@
     global highlight_paths
 
     foreach p $highlight_paths {
-	if {[string match $p $f]} {
-	    return "bold"
-	}
+        if {[string match $p $f]} {
+            return "bold"
+        }
     }
     return {}
 }
@@ -3441,15 +3459,15 @@
 
     $cflist conf -state normal
     if {$cmitmode ne "tree"} {
-	set end [lindex [split [$cflist index end] .] 0]
-	for {set l 2} {$l < $end} {incr l} {
-	    set line [$cflist get $l.0 "$l.0 lineend"]
-	    if {[highlight_tag $line] ne {}} {
-		$cflist tag add bold $l.0 "$l.0 lineend"
-	    }
-	}
+        set end [lindex [split [$cflist index end] .] 0]
+        for {set l 2} {$l < $end} {incr l} {
+            set line [$cflist get $l.0 "$l.0 lineend"]
+            if {[highlight_tag $line] ne {}} {
+                $cflist tag add bold $l.0 "$l.0 lineend"
+            }
+        }
     } else {
-	highlight_tree 2 {}
+        highlight_tree 2 {}
     }
     $cflist conf -state disabled
 }
@@ -3467,8 +3485,8 @@
 
     $cflist conf -state normal
     foreach f $fl {
-	$cflist insert end "\n"
-	$cflist insert end $f [highlight_tag $f]
+        $cflist insert end "\n"
+        $cflist insert end $f [highlight_tag $f]
     }
     $cflist conf -state disabled
 }
@@ -3483,9 +3501,9 @@
     $cflist tag add highlight $l.0 "$l.0 lineend"
     set cflist_top $l
     if {$l == 1} {
-	$ctext yview 1.0
+        $ctext yview 1.0
     } else {
-	catch {$ctext yview [lindex $difffilestart [expr {$l - 2}]]}
+        catch {$ctext yview [lindex $difffilestart [expr {$l - 2}]]}
     }
     suppress_highlighting_file_for_current_scrollpos
 }
@@ -3498,15 +3516,15 @@
     set l [lindex [split [$w index "@$x,$y"] "."] 0]
     if {$l <= 1} return
     if {$cmitmode eq "tree"} {
-	set e [linetoelt $l]
-	if {[string index $e end] eq "/"} return
+        set e [linetoelt $l]
+        if {[string index $e end] eq "/"} return
     } else {
-	set e [lindex $treediffs($diffids) [expr {$l-2}]]
+        set e [lindex $treediffs($diffids) [expr {$l-2}]]
     }
     set flist_menu_file $e
     set xdiffstate "normal"
     if {$cmitmode eq "tree"} {
-	set xdiffstate "disabled"
+        set xdiffstate "disabled"
     }
     # Disable "External diff" item in tree mode
     $flist_menu entryconf 2 -state $xdiffstate
@@ -3535,7 +3553,7 @@
     set diff_menu_line [lindex $diff_menu_txtpos 0]
     # don't pop up the menu on hunk-separator or file-separator lines
     if {[lsearch -glob [$ctext tag names $diff_menu_line.0] "*sep"] >= 0} {
-	return
+        return
     }
     stopfinding
     set f [find_ctext_fileinfo $diff_menu_line]
@@ -3550,9 +3568,9 @@
 
     set x [shellquote $flist_menu_file]
     if {$only || $findstring eq {} || $gdttype ne [mc "touching paths:"]} {
-	set findstring $x
+        set findstring $x
     } else {
-	append findstring " " $x
+        append findstring " " $x
     }
     set gdttype [mc "touching paths:"]
 }
@@ -3561,29 +3579,29 @@
     global diffnum gitktmpdir gitdir env
 
     if {![info exists gitktmpdir]} {
-	if {[info exists env(GITK_TMPDIR)]} {
-	    set tmpdir $env(GITK_TMPDIR)
-	} elseif {[info exists env(TMPDIR)]} {
-	    set tmpdir $env(TMPDIR)
-	} else {
-	    set tmpdir $gitdir
-	}
-	set gitktmpformat [file join $tmpdir ".gitk-tmp.XXXXXX"]
-	if {[catch {set gitktmpdir [exec mktemp -d $gitktmpformat]}]} {
-	    set gitktmpdir [file join $gitdir [format ".gitk-tmp.%s" [pid]]]
-	}
-	if {[catch {file mkdir $gitktmpdir} err]} {
-	    error_popup "[mc "Error creating temporary directory %s:" $gitktmpdir] $err"
-	    unset gitktmpdir
-	    return {}
-	}
-	set diffnum 0
+        if {[info exists env(GITK_TMPDIR)]} {
+            set tmpdir $env(GITK_TMPDIR)
+        } elseif {[info exists env(TMPDIR)]} {
+            set tmpdir $env(TMPDIR)
+        } else {
+            set tmpdir $gitdir
+        }
+        set gitktmpformat [file join $tmpdir ".gitk-tmp.XXXXXX"]
+        if {[catch {set gitktmpdir [exec mktemp -d $gitktmpformat]}]} {
+            set gitktmpdir [file join $gitdir [format ".gitk-tmp.%s" [pid]]]
+        }
+        if {[catch {file mkdir $gitktmpdir} err]} {
+            error_popup "[mc "Error creating temporary directory %s:" $gitktmpdir] $err"
+            unset gitktmpdir
+            return {}
+        }
+        set diffnum 0
     }
     incr diffnum
     set diffdir [file join $gitktmpdir $diffnum]
     if {[catch {file mkdir $diffdir} err]} {
-	error_popup "[mc "Error creating temporary directory %s:" $diffdir] $err"
-	return {}
+        error_popup "[mc "Error creating temporary directory %s:" $diffdir] $err"
+        return {}
     }
     return $diffdir
 }
@@ -3592,11 +3610,11 @@
     global nullfile
 
     if {[catch {exec git show $filename -- > $output} err]} {
-	if {[string match "fatal: bad revision *" $err]} {
-	    return $nullfile
-	}
-	error_popup "[mc "Error getting \"%s\" from %s:" $filename $what] $err"
-	return {}
+        if {[string match "fatal: bad revision *" $err]} {
+            return $nullfile
+        }
+        error_popup "[mc "Error getting \"%s\" from %s:" $filename $what] $err"
+        return {}
     }
     return $output
 }
@@ -3607,10 +3625,10 @@
 
     if {$diffid == $nullid} {
         set difffile [file join $worktree $filename]
-	if {[file exists $difffile]} {
-	    return $difffile
-	}
-	return $nullfile
+        if {[file exists $difffile]} {
+            return $difffile
+        }
+        return $nullfile
     }
     if {$diffid == $nullid2} {
         set difffile [file join $diffdir "\[index\] [file tail $filename]"]
@@ -3618,7 +3636,7 @@
     }
     set difffile [file join $diffdir "\[$diffid\] [file tail $filename]"]
     return [save_file_from_commit $diffid:$filename $difffile \
-	       "revision $diffid"]
+               "revision $diffid"]
 }
 
 proc external_diff {} {
@@ -3675,18 +3693,18 @@
 
     set s_line [$ctext get $s_lix "$s_lix + 1 lines"]
     if {![regexp {^@@@*(( -\d+(,\d+)?)+) \+(\d+)(,\d+)? @@} $s_line \
-	    s_line old_specs osz osz1 new_line nsz]} {
-	return
+            s_line old_specs osz osz1 new_line nsz]} {
+        return
     }
 
     # base lines for the parents
     set base_lines [list $new_line]
     foreach old_spec [lrange [split $old_specs " "] 1 end] {
-	if {![regexp -- {-(\d+)(,\d+)?} $old_spec \
-	        old_spec old_line osz]} {
-	    return
-	}
-	lappend base_lines $old_line
+        if {![regexp -- {-(\d+)(,\d+)?} $old_spec \
+                old_spec old_line osz]} {
+            return
+        }
+        lappend base_lines $old_line
     }
 
     # Now scan the lines to determine offset within the hunk
@@ -3697,38 +3715,38 @@
     # Determine if the line is removed
     set chunk [$ctext get $line.0 "$line.1 + $max_parent chars"]
     if {[string match {[-+ ]*} $chunk]} {
-	set removed_idx [string first "-" $chunk]
-	# Choose a parent index
-	if {$removed_idx >= 0} {
-	    set parent $removed_idx
-	} else {
-	    set unchanged_idx [string first " " $chunk]
-	    if {$unchanged_idx >= 0} {
-		set parent $unchanged_idx
-	    } else {
-		# blame the current commit
-		set parent -1
-	    }
-	}
-	# then count other lines that belong to it
-	for {set i $line} {[incr i -1] > $s_lno} {} {
-	    set chunk [$ctext get $i.0 "$i.1 + $max_parent chars"]
-	    # Determine if the line is removed
-	    set removed_idx [string first "-" $chunk]
-	    if {$parent >= 0} {
-		set code [string index $chunk $parent]
-		if {$code eq "-" || ($removed_idx < 0 && $code ne "+")} {
-		    incr dline
-		}
-	    } else {
-		if {$removed_idx < 0} {
-		    incr dline
-		}
-	    }
-	}
-	incr parent
+        set removed_idx [string first "-" $chunk]
+        # Choose a parent index
+        if {$removed_idx >= 0} {
+            set parent $removed_idx
+        } else {
+            set unchanged_idx [string first " " $chunk]
+            if {$unchanged_idx >= 0} {
+                set parent $unchanged_idx
+            } else {
+                # blame the current commit
+                set parent -1
+            }
+        }
+        # then count other lines that belong to it
+        for {set i $line} {[incr i -1] > $s_lno} {} {
+            set chunk [$ctext get $i.0 "$i.1 + $max_parent chars"]
+            # Determine if the line is removed
+            set removed_idx [string first "-" $chunk]
+            if {$parent >= 0} {
+                set code [string index $chunk $parent]
+                if {$code eq "-" || ($removed_idx < 0 && $code ne "+")} {
+                    incr dline
+                }
+            } else {
+                if {$removed_idx < 0} {
+                    incr dline
+                }
+            }
+        }
+        incr parent
     } else {
-	set parent 0
+        set parent 0
     }
 
     incr dline [lindex $base_lines $parent]
@@ -3741,17 +3759,17 @@
     global diff_menu_filebase flist_menu_file
 
     if {$cmitmode eq "tree"} {
-	set parent_idx 0
-	set line [expr {$diff_menu_line - $diff_menu_filebase}]
+        set parent_idx 0
+        set line [expr {$diff_menu_line - $diff_menu_filebase}]
     } else {
-	set hinfo [find_hunk_blamespec $diff_menu_filebase $diff_menu_line]
-	if {$hinfo ne {}} {
-	    set parent_idx [lindex $hinfo 0]
-	    set line [lindex $hinfo 1]
-	} else {
-	    set parent_idx 0
-	    set line 0
-	}
+        set hinfo [find_hunk_blamespec $diff_menu_filebase $diff_menu_line]
+        if {$hinfo ne {}} {
+            set parent_idx [lindex $hinfo 0]
+            set line [lindex $hinfo 1]
+        } else {
+            set parent_idx 0
+            set line 0
+        }
     }
 
     external_blame $parent_idx $line
@@ -3762,12 +3780,12 @@
 proc index_sha1 {fname} {
     set f [open [list | git ls-files -s $fname] r]
     while {[gets $f line] >= 0} {
-	set info [lindex [split $line "\t"] 0]
-	set stage [lindex $info 2]
-	if {$stage eq "0" || $stage eq "2"} {
-	    close $f
-	    return [lindex $info 1]
-	}
+        set info [lindex [split $line "\t"] 0]
+        set stage [lindex $info 2]
+        if {$stage eq "0" || $stage eq "2"} {
+            close $f
+            return [lindex $info 1]
+        }
     }
     close $f
     return {}
@@ -3776,7 +3794,7 @@
 # Turn an absolute path into one relative to the current directory
 proc make_relative {f} {
     if {[file pathtype $f] eq "relative"} {
-	return $f
+        return $f
     }
     set elts [file split $f]
     set here [file split [pwd]]
@@ -3784,12 +3802,12 @@
     set hi 0
     set res {}
     foreach d $here {
-	if {$ei < $hi || $ei >= [llength $elts] || [lindex $elts $ei] ne $d} {
-	    lappend res ".."
-	} else {
-	    incr ei
-	}
-	incr hi
+        if {$ei < $hi || $ei >= [llength $elts] || [lindex $elts $ei] ne $d} {
+            lappend res ".."
+        } else {
+            incr ei
+        }
+        incr hi
     }
     set elts [concat $res [lrange $elts $ei end]]
     return [eval file join $elts]
@@ -3801,19 +3819,19 @@
     global parentlist selectedline currentid
 
     if {$parent_idx > 0} {
-	set base_commit [lindex $parentlist $selectedline [expr {$parent_idx-1}]]
+        set base_commit [lindex $parentlist $selectedline [expr {$parent_idx-1}]]
     } else {
-	set base_commit $currentid
+        set base_commit $currentid
     }
 
     if {$base_commit eq {} || $base_commit eq $nullid || $base_commit eq $nullid2} {
-	error_popup [mc "No such commit"]
-	return
+        error_popup [mc "No such commit"]
+        return
     }
 
     set cmdline [list git gui blame]
     if {$line ne {} && $line > 1} {
-	lappend cmdline "--line=$line"
+        lappend cmdline "--line=$line"
     }
     set f [file join $cdup $flist_menu_file]
     # Unfortunately it seems git gui blame doesn't like
@@ -3821,7 +3839,7 @@
     set f [make_relative $f]
     lappend cmdline $base_commit $f
     if {[catch {eval exec $cmdline &} err]} {
-	error_popup "[mc "git gui blame: command failed:"] $err"
+        error_popup "[mc "git gui blame: command failed:"] $err"
     }
 }
 
@@ -3832,61 +3850,61 @@
 
     set from_index {}
     if {$cmitmode eq "tree"} {
-	set id $currentid
-	set line [expr {$diff_menu_line - $diff_menu_filebase}]
+        set id $currentid
+        set line [expr {$diff_menu_line - $diff_menu_filebase}]
     } else {
-	set h [find_hunk_blamespec $diff_menu_filebase $diff_menu_line]
-	if {$h eq {}} return
-	set pi [lindex $h 0]
-	if {$pi == 0} {
-	    mark_ctext_line $diff_menu_line
-	    return
-	}
-	incr pi -1
-	if {$currentid eq $nullid} {
-	    if {$pi > 0} {
-		# must be a merge in progress...
-		if {[catch {
-		    # get the last line from .git/MERGE_HEAD
-		    set f [open [file join $gitdir MERGE_HEAD] r]
-		    set id [lindex [split [read $f] "\n"] end-1]
-		    close $f
-		} err]} {
-		    error_popup [mc "Couldn't read merge head: %s" $err]
-		    return
-		}
-	    } elseif {$parents($curview,$currentid) eq $nullid2} {
-		# need to do the blame from the index
-		if {[catch {
-		    set from_index [index_sha1 $flist_menu_file]
-		} err]} {
-		    error_popup [mc "Error reading index: %s" $err]
-		    return
-		}
-	    } else {
-		set id $parents($curview,$currentid)
-	    }
-	} else {
-	    set id [lindex $parents($curview,$currentid) $pi]
-	}
-	set line [lindex $h 1]
+        set h [find_hunk_blamespec $diff_menu_filebase $diff_menu_line]
+        if {$h eq {}} return
+        set pi [lindex $h 0]
+        if {$pi == 0} {
+            mark_ctext_line $diff_menu_line
+            return
+        }
+        incr pi -1
+        if {$currentid eq $nullid} {
+            if {$pi > 0} {
+                # must be a merge in progress...
+                if {[catch {
+                    # get the last line from .git/MERGE_HEAD
+                    set f [open [file join $gitdir MERGE_HEAD] r]
+                    set id [lindex [split [read $f] "\n"] end-1]
+                    close $f
+                } err]} {
+                    error_popup [mc "Couldn't read merge head: %s" $err]
+                    return
+                }
+            } elseif {$parents($curview,$currentid) eq $nullid2} {
+                # need to do the blame from the index
+                if {[catch {
+                    set from_index [index_sha1 $flist_menu_file]
+                } err]} {
+                    error_popup [mc "Error reading index: %s" $err]
+                    return
+                }
+            } else {
+                set id $parents($curview,$currentid)
+            }
+        } else {
+            set id [lindex $parents($curview,$currentid) $pi]
+        }
+        set line [lindex $h 1]
     }
     set blameargs {}
     if {$from_index ne {}} {
-	lappend blameargs | git cat-file blob $from_index
+        lappend blameargs | git cat-file blob $from_index
     }
     lappend blameargs | git blame -p -L$line,+1
     if {$from_index ne {}} {
-	lappend blameargs --contents -
+        lappend blameargs --contents -
     } else {
-	lappend blameargs $id
+        lappend blameargs $id
     }
     lappend blameargs -- [file join $cdup $flist_menu_file]
     if {[catch {
-	set f [open $blameargs r]
+        set f [open $blameargs r]
     } err]} {
-	error_popup [mc "Couldn't start git blame: %s" $err]
-	return
+        error_popup [mc "Couldn't start git blame: %s" $err]
+        return
     }
     nowbusy blaming [mc "Searching"]
     fconfigure $f -blocking 0
@@ -3900,9 +3918,9 @@
     global blameinst
 
     if {[info exists blameinst]} {
-	stop_instance $blameinst
-	unset blameinst
-	notbusy blaming
+        stop_instance $blameinst
+        unset blameinst
+        notbusy blaming
     }
 }
 
@@ -3910,18 +3928,18 @@
     global blamestuff curview commfd blameinst nullid nullid2
 
     while {[gets $fd line] >= 0} {
-	lappend blamestuff($inst) $line
+        lappend blamestuff($inst) $line
     }
     if {![eof $fd]} {
-	return 1
+        return 1
     }
     unset commfd($inst)
     unset blameinst
     notbusy blaming
     fconfigure $fd -blocking 1
     if {[catch {close $fd} err]} {
-	error_popup [mc "Error running git blame: %s" $err]
-	return 0
+        error_popup [mc "Error running git blame: %s" $err]
+        return 0
     }
 
     set fname {}
@@ -3929,30 +3947,30 @@
     set id [lindex $line 0]
     set lnum [lindex $line 1]
     if {[string length $id] == 40 && [string is xdigit $id] &&
-	[string is digit -strict $lnum]} {
-	# look for "filename" line
-	foreach l $blamestuff($inst) {
-	    if {[string match "filename *" $l]} {
-		set fname [string range $l 9 end]
-		break
-	    }
-	}
+        [string is digit -strict $lnum]} {
+        # look for "filename" line
+        foreach l $blamestuff($inst) {
+            if {[string match "filename *" $l]} {
+                set fname [string range $l 9 end]
+                break
+            }
+        }
     }
     if {$fname ne {}} {
-	# all looks good, select it
-	if {$id eq $nullid} {
-	    # blame uses all-zeroes to mean not committed,
-	    # which would mean a change in the index
-	    set id $nullid2
-	}
-	if {[commitinview $id $curview]} {
-	    selectline [rowofcommit $id] 1 [list $fname $lnum] 1
-	} else {
-	    error_popup [mc "That line comes from commit %s, \
-			     which is not in this view" [shortids $id]]
-	}
+        # all looks good, select it
+        if {$id eq $nullid} {
+            # blame uses all-zeroes to mean not committed,
+            # which would mean a change in the index
+            set id $nullid2
+        }
+        if {[commitinview $id $curview]} {
+            selectline [rowofcommit $id] 1 [list $fname $lnum] 1
+        } else {
+            error_popup [mc "That line comes from commit %s, \
+                             which is not in this view" [shortids $id]]
+        }
     } else {
-	puts "oops couldn't parse git blame output"
+        puts "oops couldn't parse git blame output"
     }
     return 0
 }
@@ -3961,11 +3979,11 @@
 proc delete_at_eof {f dir} {
     while {[gets $f line] >= 0} {}
     if {[eof $f]} {
-	if {[catch {close $f} err]} {
-	    error_popup "[mc "External diff viewer failed:"] $err"
-	}
-	file delete -force $dir
-	return 0
+        if {[catch {close $f} err]} {
+            error_popup "[mc "External diff viewer failed:"] $err"
+        }
+        file delete -force $dir
+        return 0
     }
     return 1
 }
@@ -3974,13 +3992,13 @@
 
 proc shellquote {str} {
     if {![string match "*\['\"\\ \t]*" $str]} {
-	return $str
+        return $str
     }
     if {![string match "*\['\"\\]*" $str]} {
-	return "\"$str\""
+        return "\"$str\""
     }
     if {![string match "*'*" $str]} {
-	return "'$str'"
+        return "'$str'"
     }
     return "\"[string map {\" \\\" \\ \\\\} $str]\""
 }
@@ -3988,10 +4006,10 @@
 proc shellarglist {l} {
     set str {}
     foreach a $l {
-	if {$str ne {}} {
-	    append str " "
-	}
-	append str [shellquote $a]
+        if {$str ne {}} {
+            append str " "
+        }
+        append str [shellquote $a]
     }
     return $str
 }
@@ -4000,52 +4018,52 @@
     set ret {}
     set used -1
     while {1} {
-	incr used
-	if {![regexp -start $used -indices "\['\"\\\\ \t]" $str first]} {
-	    append ret [string range $str $used end]
-	    set used [string length $str]
-	    break
-	}
-	set first [lindex $first 0]
-	set ch [string index $str $first]
-	if {$first > $used} {
-	    append ret [string range $str $used [expr {$first - 1}]]
-	    set used $first
-	}
-	if {$ch eq " " || $ch eq "\t"} break
-	incr used
-	if {$ch eq "'"} {
-	    set first [string first "'" $str $used]
-	    if {$first < 0} {
-		error "unmatched single-quote"
-	    }
-	    append ret [string range $str $used [expr {$first - 1}]]
-	    set used $first
-	    continue
-	}
-	if {$ch eq "\\"} {
-	    if {$used >= [string length $str]} {
-		error "trailing backslash"
-	    }
-	    append ret [string index $str $used]
-	    continue
-	}
-	# here ch == "\""
-	while {1} {
-	    if {![regexp -start $used -indices "\[\"\\\\]" $str first]} {
-		error "unmatched double-quote"
-	    }
-	    set first [lindex $first 0]
-	    set ch [string index $str $first]
-	    if {$first > $used} {
-		append ret [string range $str $used [expr {$first - 1}]]
-		set used $first
-	    }
-	    if {$ch eq "\""} break
-	    incr used
-	    append ret [string index $str $used]
-	    incr used
-	}
+        incr used
+        if {![regexp -start $used -indices "\['\"\\\\ \t]" $str first]} {
+            append ret [string range $str $used end]
+            set used [string length $str]
+            break
+        }
+        set first [lindex $first 0]
+        set ch [string index $str $first]
+        if {$first > $used} {
+            append ret [string range $str $used [expr {$first - 1}]]
+            set used $first
+        }
+        if {$ch eq " " || $ch eq "\t"} break
+        incr used
+        if {$ch eq "'"} {
+            set first [string first "'" $str $used]
+            if {$first < 0} {
+                error "unmatched single-quote"
+            }
+            append ret [string range $str $used [expr {$first - 1}]]
+            set used $first
+            continue
+        }
+        if {$ch eq "\\"} {
+            if {$used >= [string length $str]} {
+                error "trailing backslash"
+            }
+            append ret [string index $str $used]
+            continue
+        }
+        # here ch == "\""
+        while {1} {
+            if {![regexp -start $used -indices "\[\"\\\\]" $str first]} {
+                error "unmatched double-quote"
+            }
+            set first [lindex $first 0]
+            set ch [string index $str $first]
+            if {$first > $used} {
+                append ret [string range $str $used [expr {$first - 1}]]
+                set used $first
+            }
+            if {$ch eq "\""} break
+            incr used
+            append ret [string index $str $used]
+            incr used
+        }
     }
     return [list $used $ret]
 }
@@ -4053,13 +4071,13 @@
 proc shellsplit {str} {
     set l {}
     while {1} {
-	set str [string trimleft $str]
-	if {$str eq {}} break
-	set dq [shelldequote $str]
-	set n [lindex $dq 0]
-	set word [lindex $dq 1]
-	set str [string range $str $n end]
-	lappend l $word
+        set str [string trimleft $str]
+        if {$str eq {}} break
+        set dq [shelldequote $str]
+        set n [lindex $dq 0]
+        set word [lindex $dq 1]
+        set str [string range $str $n end]
+        lappend l $word
     }
     return $l
 }
@@ -4068,11 +4086,11 @@
     global appname curview viewname vrevs
     set rev [mc "All files"]
     if {$curview ne 0} {
-	if {$viewname($curview) eq [mc "Command line"]} {
-	    set rev [string map {"--gitk-symmetric-diff-marker" "--merge"} $vrevs($curview)]
-	} else {
-	    set rev $viewname($curview)
-	}
+        if {$viewname($curview) eq [mc "Command line"]} {
+            set rev [string map {"--gitk-symmetric-diff-marker" "--merge"} $vrevs($curview)]
+        } else {
+            set rev $viewname($curview)
+        }
     }
     wm title . "[reponame]: $rev - $appname"
 }
@@ -4086,8 +4104,8 @@
     set newishighlight $ishighlight
     set top .gitkview
     if {[winfo exists $top]} {
-	raise $top
-	return
+        raise $top
+        return
     }
     decode_view_opts $nextviewnum $revtreeargs
     set newviewname($nextviewnum) "[mc "View"] $nextviewnum"
@@ -4136,29 +4154,29 @@
 
     set rargs [list]
     foreach opt $known_view_options {
-	set patterns [lindex $opt 3]
-	if {$patterns eq {}} continue
-	set pattern [lindex $patterns 0]
+        set patterns [lindex $opt 3]
+        if {$patterns eq {}} continue
+        set pattern [lindex $patterns 0]
 
-	if {[lindex $opt 1] eq "b"} {
-	    set val $newviewopts($n,[lindex $opt 0])
-	    if {$val} {
-		lappend rargs $pattern
-	    }
-	} elseif {[regexp {^r(\d+)$} [lindex $opt 1] type value]} {
-	    regexp {^(.*_)} [lindex $opt 0] uselessvar button_id
-	    set val $newviewopts($n,$button_id)
-	    if {$val eq $value} {
-		lappend rargs $pattern
-	    }
-	} else {
-	    set val $newviewopts($n,[lindex $opt 0])
-	    set val [string trim $val]
-	    if {$val ne {}} {
-		set pfix [string range $pattern 0 end-1]
-		lappend rargs $pfix$val
-	    }
-	}
+        if {[lindex $opt 1] eq "b"} {
+            set val $newviewopts($n,[lindex $opt 0])
+            if {$val} {
+                lappend rargs $pattern
+            }
+        } elseif {[regexp {^r(\d+)$} [lindex $opt 1] type value]} {
+            regexp {^(.*_)} [lindex $opt 0] uselessvar button_id
+            set val $newviewopts($n,$button_id)
+            if {$val eq $value} {
+                lappend rargs $pattern
+            }
+        } else {
+            set val $newviewopts($n,[lindex $opt 0])
+            set val [string trim $val]
+            if {$val ne {}} {
+                set pfix [string range $pattern 0 end-1]
+                lappend rargs $pfix$val
+            }
+        }
     }
     set rargs [concat $rargs [shellsplit $newviewopts($n,refs)]]
     return [concat $rargs [shellsplit $newviewopts($n,args)]]
@@ -4169,59 +4187,59 @@
     global known_view_options newviewopts
 
     foreach opt $known_view_options {
-	set id [lindex $opt 0]
-	if {[lindex $opt 1] eq "b"} {
-	    # Checkboxes
-	    set val 0
+        set id [lindex $opt 0]
+        if {[lindex $opt 1] eq "b"} {
+            # Checkboxes
+            set val 0
         } elseif {[regexp {^r(\d+)$} [lindex $opt 1]]} {
-	    # Radiobuttons
-	    regexp {^(.*_)} $id uselessvar id
-	    set val 0
-	} else {
-	    # Text fields
-	    set val {}
-	}
-	set newviewopts($n,$id) $val
+            # Radiobuttons
+            regexp {^(.*_)} $id uselessvar id
+            set val 0
+        } else {
+            # Text fields
+            set val {}
+        }
+        set newviewopts($n,$id) $val
     }
     set oargs [list]
     set refargs [list]
     foreach arg $view_args {
-	if {[regexp -- {^-([0-9]+)$} $arg arg cnt]
-	    && ![info exists found(limit)]} {
-	    set newviewopts($n,limit) $cnt
-	    set found(limit) 1
-	    continue
-	}
-	catch { unset val }
-	foreach opt $known_view_options {
-	    set id [lindex $opt 0]
-	    if {[info exists found($id)]} continue
-	    foreach pattern [lindex $opt 3] {
-		if {![string match $pattern $arg]} continue
-		if {[lindex $opt 1] eq "b"} {
-		    # Check buttons
-		    set val 1
-		} elseif {[regexp {^r(\d+)$} [lindex $opt 1] match num]} {
-		    # Radio buttons
-		    regexp {^(.*_)} $id uselessvar id
-		    set val $num
-		} else {
-		    # Text input fields
-		    set size [string length $pattern]
-		    set val [string range $arg [expr {$size-1}] end]
-		}
-		set newviewopts($n,$id) $val
-		set found($id) 1
-		break
-	    }
-	    if {[info exists val]} break
-	}
-	if {[info exists val]} continue
-	if {[regexp {^-} $arg]} {
-	    lappend oargs $arg
-	} else {
-	    lappend refargs $arg
-	}
+        if {[regexp -- {^-([0-9]+)$} $arg arg cnt]
+            && ![info exists found(limit)]} {
+            set newviewopts($n,limit) $cnt
+            set found(limit) 1
+            continue
+        }
+        catch { unset val }
+        foreach opt $known_view_options {
+            set id [lindex $opt 0]
+            if {[info exists found($id)]} continue
+            foreach pattern [lindex $opt 3] {
+                if {![string match $pattern $arg]} continue
+                if {[lindex $opt 1] eq "b"} {
+                    # Check buttons
+                    set val 1
+                } elseif {[regexp {^r(\d+)$} [lindex $opt 1] match num]} {
+                    # Radio buttons
+                    regexp {^(.*_)} $id uselessvar id
+                    set val $num
+                } else {
+                    # Text input fields
+                    set size [string length $pattern]
+                    set val [string range $arg [expr {$size-1}] end]
+                }
+                set newviewopts($n,$id) $val
+                set found($id) 1
+                break
+            }
+            if {[info exists val]} break
+        }
+        if {[info exists val]} continue
+        if {[regexp {^-} $arg]} {
+            lappend oargs $arg
+        } else {
+            lappend refargs $arg
+        }
     }
     set newviewopts($n,refs) [shellarglist $refargs]
     set newviewopts($n,args) [shellarglist $oargs]
@@ -4231,9 +4249,9 @@
     global curview
 
     if {$curview > 0} {
-	editview
+        editview
     } else {
-	newview 0
+        newview 0
     }
 }
 
@@ -4244,8 +4262,8 @@
 
     set top .gitkvedit-$curview
     if {[winfo exists $top]} {
-	raise $top
-	return
+        raise $top
+        return
     }
     decode_view_opts $curview $viewargs($curview)
     set newviewname($curview)      $viewname($curview)
@@ -4275,66 +4293,66 @@
     set cexpand 0
     set cnt 0
     foreach opt $known_view_options {
-	set id [lindex $opt 0]
-	set type [lindex $opt 1]
-	set flags [lindex $opt 2]
-	set title [eval [lindex $opt 4]]
-	set lxpad 0
+        set id [lindex $opt 0]
+        set type [lindex $opt 1]
+        set flags [lindex $opt 2]
+        set title [eval [lindex $opt 4]]
+        set lxpad 0
 
-	if {$flags eq "+" || $flags eq "*"} {
-	    set cframe $top.fr$cnt
-	    incr cnt
-	    ${NS}::frame $cframe
-	    pack $cframe -in $top -fill x -pady 3 -padx 3
-	    set cexpand [expr {$flags eq "*"}]
+        if {$flags eq "+" || $flags eq "*"} {
+            set cframe $top.fr$cnt
+            incr cnt
+            ${NS}::frame $cframe
+            pack $cframe -in $top -fill x -pady 3 -padx 3
+            set cexpand [expr {$flags eq "*"}]
         } elseif {$flags eq ".." || $flags eq "*."} {
-	    set cframe $top.fr$cnt
-	    incr cnt
-	    ${NS}::frame $cframe
-	    pack $cframe -in $top -fill x -pady 3 -padx [list 15 3]
-	    set cexpand [expr {$flags eq "*."}]
-	} else {
-	    set lxpad 5
-	}
+            set cframe $top.fr$cnt
+            incr cnt
+            ${NS}::frame $cframe
+            pack $cframe -in $top -fill x -pady 3 -padx [list 15 3]
+            set cexpand [expr {$flags eq "*."}]
+        } else {
+            set lxpad 5
+        }
 
-	if {$type eq "l"} {
+        if {$type eq "l"} {
             ${NS}::label $cframe.l_$id -text $title
             pack $cframe.l_$id -in $cframe -side left -pady [list 3 0] -anchor w
-	} elseif {$type eq "b"} {
-	    ${NS}::checkbutton $cframe.c_$id -text $title -variable newviewopts($n,$id)
-	    pack $cframe.c_$id -in $cframe -side left \
-		-padx [list $lxpad 0] -expand $cexpand -anchor w
-	} elseif {[regexp {^r(\d+)$} $type type sz]} {
-	    regexp {^(.*_)} $id uselessvar button_id
-	    ${NS}::radiobutton $cframe.c_$id -text $title -variable newviewopts($n,$button_id) -value $sz
-	    pack $cframe.c_$id -in $cframe -side left \
-		-padx [list $lxpad 0] -expand $cexpand -anchor w
-	} elseif {[regexp {^t(\d+)$} $type type sz]} {
-	    ${NS}::label $cframe.l_$id -text $title
-	    ${NS}::entry $cframe.e_$id -width $sz -background $bgcolor \
-		-textvariable newviewopts($n,$id)
-	    pack $cframe.l_$id -in $cframe -side left -padx [list $lxpad 0]
-	    pack $cframe.e_$id -in $cframe -side left -expand 1 -fill x
-	} elseif {[regexp {^t(\d+)=$} $type type sz]} {
-	    ${NS}::label $cframe.l_$id -text $title
-	    ${NS}::entry $cframe.e_$id -width $sz -background $bgcolor \
-		-textvariable newviewopts($n,$id)
-	    pack $cframe.l_$id -in $cframe -side top -pady [list 3 0] -anchor w
-	    pack $cframe.e_$id -in $cframe -side top -fill x
-	} elseif {$type eq "path"} {
-	    ${NS}::label $top.l -text $title
-	    pack $top.l -in $top -side top -pady [list 3 0] -anchor w -padx 3
-	    text $top.t -width 40 -height 5 -background $bgcolor
-	    if {[info exists viewfiles($n)]} {
-		foreach f $viewfiles($n) {
-		    $top.t insert end $f
-		    $top.t insert end "\n"
-		}
-		$top.t delete {end - 1c} end
-		$top.t mark set insert 0.0
-	    }
-	    pack $top.t -in $top -side top -pady [list 0 5] -fill both -expand 1 -padx 3
-	}
+        } elseif {$type eq "b"} {
+            ${NS}::checkbutton $cframe.c_$id -text $title -variable newviewopts($n,$id)
+            pack $cframe.c_$id -in $cframe -side left \
+                -padx [list $lxpad 0] -expand $cexpand -anchor w
+        } elseif {[regexp {^r(\d+)$} $type type sz]} {
+            regexp {^(.*_)} $id uselessvar button_id
+            ${NS}::radiobutton $cframe.c_$id -text $title -variable newviewopts($n,$button_id) -value $sz
+            pack $cframe.c_$id -in $cframe -side left \
+                -padx [list $lxpad 0] -expand $cexpand -anchor w
+        } elseif {[regexp {^t(\d+)$} $type type sz]} {
+            ${NS}::label $cframe.l_$id -text $title
+            ${NS}::entry $cframe.e_$id -width $sz -background $bgcolor \
+                -textvariable newviewopts($n,$id)
+            pack $cframe.l_$id -in $cframe -side left -padx [list $lxpad 0]
+            pack $cframe.e_$id -in $cframe -side left -expand 1 -fill x
+        } elseif {[regexp {^t(\d+)=$} $type type sz]} {
+            ${NS}::label $cframe.l_$id -text $title
+            ${NS}::entry $cframe.e_$id -width $sz -background $bgcolor \
+                -textvariable newviewopts($n,$id)
+            pack $cframe.l_$id -in $cframe -side top -pady [list 3 0] -anchor w
+            pack $cframe.e_$id -in $cframe -side top -fill x
+        } elseif {$type eq "path"} {
+            ${NS}::label $top.l -text $title
+            pack $top.l -in $top -side top -pady [list 3 0] -anchor w -padx 3
+            text $top.t -width 40 -height 5 -background $bgcolor
+            if {[info exists viewfiles($n)]} {
+                foreach f $viewfiles($n) {
+                    $top.t insert end $f
+                    $top.t insert end "\n"
+                }
+                $top.t delete {end - 1c} end
+                $top.t mark set insert 0.0
+            }
+            pack $top.t -in $top -side top -pady [list 0 5] -fill both -expand 1 -padx 3
+        }
     }
 
     ${NS}::frame $top.buts
@@ -4355,10 +4373,10 @@
 proc doviewmenu {m first cmd op argv} {
     set nmenu [$m index end]
     for {set i $first} {$i <= $nmenu} {incr i} {
-	if {[$m entrycget $i -command] eq $cmd} {
-	    eval $m $op $i $argv
-	    break
-	}
+        if {[$m entrycget $i -command] eq $cmd} {
+            eval $m $op $i $argv
+            break
+        }
     }
 }
 
@@ -4375,53 +4393,53 @@
     global viewargs viewargscmd newviewopts viewhlmenu
 
     if {[catch {
-	set newargs [encode_view_opts $n]
+        set newargs [encode_view_opts $n]
     } err]} {
-	error_popup "[mc "Error in commit selection arguments:"] $err" $top
-	return
+        error_popup "[mc "Error in commit selection arguments:"] $err" $top
+        return
     }
     set files {}
     foreach f [split [$top.t get 0.0 end] "\n"] {
-	set ft [string trim $f]
-	if {$ft ne {}} {
-	    lappend files $ft
-	}
+        set ft [string trim $f]
+        if {$ft ne {}} {
+            lappend files $ft
+        }
     }
     if {![info exists viewfiles($n)]} {
-	# creating a new view
-	incr nextviewnum
-	set viewname($n) $newviewname($n)
-	set viewperm($n) $newviewopts($n,perm)
-	set viewchanged($n) 1
-	set viewfiles($n) $files
-	set viewargs($n) $newargs
-	set viewargscmd($n) $newviewopts($n,cmd)
-	addviewmenu $n
-	if {!$newishighlight} {
-	    run showview $n
-	} else {
-	    run addvhighlight $n
-	}
+        # creating a new view
+        incr nextviewnum
+        set viewname($n) $newviewname($n)
+        set viewperm($n) $newviewopts($n,perm)
+        set viewchanged($n) 1
+        set viewfiles($n) $files
+        set viewargs($n) $newargs
+        set viewargscmd($n) $newviewopts($n,cmd)
+        addviewmenu $n
+        if {!$newishighlight} {
+            run showview $n
+        } else {
+            run addvhighlight $n
+        }
     } else {
-	# editing an existing view
-	set viewperm($n) $newviewopts($n,perm)
-	set viewchanged($n) 1
-	if {$newviewname($n) ne $viewname($n)} {
-	    set viewname($n) $newviewname($n)
-	    doviewmenu .bar.view 5 [list showview $n] \
-		entryconf [list -label $viewname($n)]
-	    # doviewmenu $viewhlmenu 1 [list addvhighlight $n] \
-		# entryconf [list -label $viewname($n) -value $viewname($n)]
-	}
-	if {$files ne $viewfiles($n) || $newargs ne $viewargs($n) || \
-		$newviewopts($n,cmd) ne $viewargscmd($n)} {
-	    set viewfiles($n) $files
-	    set viewargs($n) $newargs
-	    set viewargscmd($n) $newviewopts($n,cmd)
-	    if {$curview == $n} {
-		run reloadcommits
-	    }
-	}
+        # editing an existing view
+        set viewperm($n) $newviewopts($n,perm)
+        set viewchanged($n) 1
+        if {$newviewname($n) ne $viewname($n)} {
+            set viewname($n) $newviewname($n)
+            doviewmenu .bar.view 5 [list showview $n] \
+                entryconf [list -label $viewname($n)]
+            # doviewmenu $viewhlmenu 1 [list addvhighlight $n] \
+                # entryconf [list -label $viewname($n) -value $viewname($n)]
+        }
+        if {$files ne $viewfiles($n) || $newargs ne $viewargs($n) || \
+                $newviewopts($n,cmd) ne $viewargscmd($n)} {
+            set viewfiles($n) $files
+            set viewargs($n) $newargs
+            set viewargscmd($n) $newviewopts($n,cmd)
+            if {$curview == $n} {
+                run reloadcommits
+            }
+        }
     }
     if {$apply} return
     catch {destroy $top}
@@ -4432,8 +4450,8 @@
 
     if {$curview == 0} return
     if {[info exists hlview] && $hlview == $curview} {
-	set selectedhlview [mc "None"]
-	unset hlview
+        set selectedhlview [mc "None"]
+        unset hlview
     }
     allviewmenus $curview delete
     set viewperm($curview) 0
@@ -4445,7 +4463,7 @@
     global viewname viewhlmenu
 
     .bar.view add radiobutton -label $viewname($n) \
-	-command [list showview $n] -variable selectedview -value $n
+        -command [list showview $n] -variable selectedview -value $n
     #$viewhlmenu add radiobutton -label $viewname($n) \
     #	-command [list addvhighlight $n] -variable selectedhlview
 }
@@ -4470,22 +4488,22 @@
     set ybot [expr {[lindex $span 1] * $ymax}]
     set yscreen [expr {($ybot - $ytop) / 2}]
     if {$selectedline ne {}} {
-	set selid $currentid
-	set y [yc $selectedline]
-	if {$ytop < $y && $y < $ybot} {
-	    set yscreen [expr {$y - $ytop}]
-	}
+        set selid $currentid
+        set y [yc $selectedline]
+        if {$ytop < $y && $y < $ybot} {
+            set yscreen [expr {$y - $ytop}]
+        }
     } elseif {[info exists pending_select]} {
-	set selid $pending_select
-	unset pending_select
+        set selid $pending_select
+        unset pending_select
     }
     unselectline
     normalline
     unset -nocomplain treediffs
     clear_display
     if {[info exists hlview] && $hlview == $n} {
-	unset hlview
-	set selectedhlview [mc "None"]
+        unset hlview
+        set selectedhlview [mc "None"]
     }
     unset -nocomplain commitinterest
     unset -nocomplain cached_commitrow
@@ -4498,8 +4516,8 @@
 
     run refill_reflist
     if {![info exists viewcomplete($n)]} {
-	getcommits $selid
-	return
+        getcommits $selid
+        return
     }
 
     set displayorder {}
@@ -4519,39 +4537,39 @@
     set yf 0
     set row {}
     if {$selid ne {} && [commitinview $selid $n]} {
-	set row [rowofcommit $selid]
-	# try to get the selected row in the same position on the screen
-	set ymax [lindex [$canv cget -scrollregion] 3]
-	set ytop [expr {[yc $row] - $yscreen}]
-	if {$ytop < 0} {
-	    set ytop 0
-	}
-	set yf [expr {$ytop * 1.0 / $ymax}]
+        set row [rowofcommit $selid]
+        # try to get the selected row in the same position on the screen
+        set ymax [lindex [$canv cget -scrollregion] 3]
+        set ytop [expr {[yc $row] - $yscreen}]
+        if {$ytop < 0} {
+            set ytop 0
+        }
+        set yf [expr {$ytop * 1.0 / $ymax}]
     }
     allcanvs yview moveto $yf
     drawvisible
     if {$row ne {}} {
-	selectline $row 0
+        selectline $row 0
     } elseif {!$viewcomplete($n)} {
-	reset_pending_select $selid
+        reset_pending_select $selid
     } else {
-	reset_pending_select {}
+        reset_pending_select {}
 
-	if {[commitinview $pending_select $curview]} {
-	    selectline [rowofcommit $pending_select] 1
-	} else {
-	    set row [first_real_row]
-	    if {$row < $numcommits} {
-		selectline $row 0
-	    }
-	}
+        if {[commitinview $pending_select $curview]} {
+            selectline [rowofcommit $pending_select] 1
+        } else {
+            set row [first_real_row]
+            if {$row < $numcommits} {
+                selectline $row 0
+            }
+        }
     }
     if {!$viewcomplete($n)} {
-	if {$numcommits == 0} {
-	    show_status [mc "Reading commits..."]
-	}
+        if {$numcommits == 0} {
+            show_status [mc "Reading commits..."]
+        }
     } elseif {$numcommits == 0} {
-	show_status [mc "No commits selected"]
+        show_status [mc "No commits selected"]
     }
     set_window_title
 }
@@ -4562,16 +4580,16 @@
     global vhighlights fhighlights nhighlights rhighlights
 
     if {[info exists nhighlights($id)] && $nhighlights($id) > 0} {
-	return $nhighlights($id)
+        return $nhighlights($id)
     }
     if {[info exists vhighlights($id)] && $vhighlights($id) > 0} {
-	return $vhighlights($id)
+        return $vhighlights($id)
     }
     if {[info exists fhighlights($id)] && $fhighlights($id) > 0} {
-	return $fhighlights($id)
+        return $fhighlights($id)
     }
     if {[info exists rhighlights($id)] && $rhighlights($id) > 0} {
-	return $rhighlights($id)
+        return $rhighlights($id)
     }
     return 0
 }
@@ -4584,14 +4602,14 @@
     lappend boldids $id
     $canv itemconf $linehtag($id) -font $font
     if {[info exists currentid] && $id eq $currentid} {
-	$canv delete secsel
-	set t [eval $canv create rect [$canv bbox $linehtag($id)] \
-		   -outline {{}} -tags secsel \
-		   -fill [$canv cget -selectbackground]]
-	$canv lower $t
+        $canv delete secsel
+        set t [eval $canv create rect [$canv bbox $linehtag($id)] \
+                   -outline {{}} -tags secsel \
+                   -fill [$canv cget -selectbackground]]
+        $canv lower $t
     }
     if {[info exists markedid] && $id eq $markedid} {
-	make_idmark $id
+        make_idmark $id
     }
 }
 
@@ -4602,11 +4620,11 @@
     lappend boldnameids $id
     $canv2 itemconf $linentag($id) -font $font
     if {[info exists currentid] && $id eq $currentid} {
-	$canv2 delete secsel
-	set t [eval $canv2 create rect [$canv2 bbox $linentag($id)] \
-		   -outline {{}} -tags secsel \
-		   -fill [$canv2 cget -selectbackground]]
-	$canv2 lower $t
+        $canv2 delete secsel
+        set t [eval $canv2 create rect [$canv2 bbox $linentag($id)] \
+                   -outline {{}} -tags secsel \
+                   -fill [$canv2 cget -selectbackground]]
+        $canv2 lower $t
     }
 }
 
@@ -4615,11 +4633,11 @@
 
     set stillbold {}
     foreach id $boldids {
-	if {![ishighlighted $id]} {
-	    bolden $id mainfont
-	} else {
-	    lappend stillbold $id
-	}
+        if {![ishighlighted $id]} {
+            bolden $id mainfont
+        } else {
+            lappend stillbold $id
+        }
     }
     set boldids $stillbold
 }
@@ -4628,15 +4646,15 @@
     global hlview viewcomplete curview vhl_done commitidx
 
     if {[info exists hlview]} {
-	delvhighlight
+        delvhighlight
     }
     set hlview $n
     if {$n != $curview && ![info exists viewcomplete($n)]} {
-	start_rev_list $n
+        start_rev_list $n
     }
     set vhl_done $commitidx($hlview)
     if {$vhl_done > 0} {
-	drawvisible
+        drawvisible
     }
 }
 
@@ -4657,16 +4675,16 @@
     set r0 [lindex $vr 0]
     set r1 [lindex $vr 1]
     for {set i $vhl_done} {$i < $max} {incr i} {
-	set id [commitonrow $i $hlview]
-	if {[commitinview $id $curview]} {
-	    set row [rowofcommit $id]
-	    if {$r0 <= $row && $row <= $r1} {
-		if {![highlighted $row]} {
-		    bolden $id mainfontbold
-		}
-		set vhighlights($id) 1
-	    }
-	}
+        set id [commitonrow $i $hlview]
+        if {[commitinview $id $curview]} {
+            set row [rowofcommit $id]
+            if {$r0 <= $row && $row <= $r1} {
+                if {![highlighted $row]} {
+                    bolden $id mainfontbold
+                }
+                set vhighlights($id) 1
+            }
+        }
     }
     set vhl_done $max
     return 0
@@ -4676,12 +4694,12 @@
     global hlview vhighlights iddrawn
 
     if {[commitinview $id $hlview]} {
-	if {[info exists iddrawn($id)] && ![ishighlighted $id]} {
-	    bolden $id mainfontbold
-	}
-	set vhighlights($id) 1
+        if {[info exists iddrawn($id)] && ![ishighlighted $id]} {
+            bolden $id mainfontbold
+        }
+        set vhighlights($id) 1
     } else {
-	set vhighlights($id) 0
+        set vhighlights($id) 0
     }
 }
 
@@ -4690,18 +4708,18 @@
     global highlight_paths
 
     if {[info exists filehighlight]} {
-	# delete previous highlights
-	catch {close $filehighlight}
-	unset filehighlight
-	unset -nocomplain fhighlights
-	unbolden
-	unhighlight_filelist
+        # delete previous highlights
+        catch {close $filehighlight}
+        unset filehighlight
+        unset -nocomplain fhighlights
+        unbolden
+        unhighlight_filelist
     }
     set highlight_paths {}
     after cancel do_file_hl $fh_serial
     incr fh_serial
     if {$highlight_files ne {}} {
-	after 300 do_file_hl $fh_serial
+        after 300 do_file_hl $fh_serial
     }
 }
 
@@ -4710,21 +4728,21 @@
 
     stopfinding
     if {$findstring ne {}} {
-	if {$gdttype eq [mc "containing:"]} {
-	    if {$highlight_files ne {}} {
-		set highlight_files {}
-		hfiles_change
-	    }
-	    findcom_change
-	} else {
-	    if {$findpattern ne {}} {
-		set findpattern {}
-		findcom_change
-	    }
-	    set highlight_files $findstring
-	    hfiles_change
-	}
-	drawvisible
+        if {$gdttype eq [mc "containing:"]} {
+            if {$highlight_files ne {}} {
+                set highlight_files {}
+                hfiles_change
+            }
+            findcom_change
+        } else {
+            if {$findpattern ne {}} {
+                set findpattern {}
+                findcom_change
+            }
+            set highlight_files $findstring
+            hfiles_change
+        }
+        drawvisible
     }
     # enable/disable findtype/findloc menus too
 }
@@ -4734,12 +4752,12 @@
 
     stopfinding
     if {$gdttype eq [mc "containing:"]} {
-	findcom_change
+        findcom_change
     } else {
-	if {$highlight_files ne $findstring} {
-	    set highlight_files $findstring
-	    hfiles_change
-	}
+        if {$highlight_files ne $findstring} {
+            set highlight_files $findstring
+            hfiles_change
+        }
     }
     drawvisible
 }
@@ -4751,33 +4769,33 @@
     stopfinding
     # delete previous highlights, if any
     foreach id $boldnameids {
-	bolden_name $id mainfont
+        bolden_name $id mainfont
     }
     set boldnameids {}
     unset -nocomplain nhighlights
     unbolden
     unmarkmatches
     if {$gdttype ne [mc "containing:"] || $findstring eq {}} {
-	set findpattern {}
+        set findpattern {}
     } elseif {$findtype eq [mc "Regexp"]} {
-	set findpattern $findstring
+        set findpattern $findstring
     } else {
-	set e [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} \
-		   $findstring]
-	set findpattern "*$e*"
+        set e [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} \
+                   $findstring]
+        set findpattern "*$e*"
     }
 }
 
 proc makepatterns {l} {
     set ret {}
     foreach e $l {
-	set ee [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} $e]
-	if {[string index $ee end] eq "/"} {
-	    lappend ret "$ee*"
-	} else {
-	    lappend ret $ee
-	    lappend ret "$ee/*"
-	}
+        set ee [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} $e]
+        if {[string index $ee end] eq "/"} {
+            lappend ret "$ee*"
+        } else {
+            lappend ret $ee
+            lappend ret "$ee/*"
+        }
     }
     return $ret
 }
@@ -4787,26 +4805,26 @@
     global cdup findtype
 
     if {$gdttype eq [mc "touching paths:"]} {
-	# If "exact" match then convert backslashes to forward slashes.
-	# Most useful to support Windows-flavoured file paths.
-	if {$findtype eq [mc "Exact"]} {
-	    set highlight_files [string map {"\\" "/"} $highlight_files]
-	}
-	if {[catch {set paths [shellsplit $highlight_files]}]} return
-	set highlight_paths [makepatterns $paths]
-	highlight_filelist
-	set relative_paths {}
-	foreach path $paths {
-	    lappend relative_paths [file join $cdup $path]
-	}
-	set gdtargs [concat -- $relative_paths]
+        # If "exact" match then convert backslashes to forward slashes.
+        # Most useful to support Windows-flavoured file paths.
+        if {$findtype eq [mc "Exact"]} {
+            set highlight_files [string map {"\\" "/"} $highlight_files]
+        }
+        if {[catch {set paths [shellsplit $highlight_files]}]} return
+        set highlight_paths [makepatterns $paths]
+        highlight_filelist
+        set relative_paths {}
+        foreach path $paths {
+            lappend relative_paths [file join $cdup $path]
+        }
+        set gdtargs [concat -- $relative_paths]
     } elseif {$gdttype eq [mc "adding/removing string:"]} {
-	set gdtargs [list "-S$highlight_files"]
+        set gdtargs [list "-S$highlight_files"]
     } elseif {$gdttype eq [mc "changing lines matching:"]} {
-	set gdtargs [list "-G$highlight_files"]
+        set gdtargs [list "-G$highlight_files"]
     } else {
-	# must be "containing:", i.e. we're searching commit info
-	return
+        # must be "containing:", i.e. we're searching commit info
+        return
     }
     set cmd [concat | git diff-tree -r -s --stdin $gdtargs]
     set filehighlight [open $cmd r+]
@@ -4821,9 +4839,9 @@
     global filehighlight fhl_list
 
     if {[info exists filehighlight]} {
-	lappend fhl_list {}
-	puts $filehighlight ""
-	flush $filehighlight
+        lappend fhl_list {}
+        puts $filehighlight ""
+        flush $filehighlight
     }
 }
 
@@ -4840,34 +4858,34 @@
     global fhl_list find_dirn
 
     if {![info exists filehighlight]} {
-	return 0
+        return 0
     }
     set nr 0
     while {[incr nr] <= 100 && [gets $filehighlight line] >= 0} {
-	set line [string trim $line]
-	set i [lsearch -exact $fhl_list $line]
-	if {$i < 0} continue
-	for {set j 0} {$j < $i} {incr j} {
-	    set id [lindex $fhl_list $j]
-	    set fhighlights($id) 0
-	}
-	set fhl_list [lrange $fhl_list [expr {$i+1}] end]
-	if {$line eq {}} continue
-	if {![commitinview $line $curview]} continue
-	if {[info exists iddrawn($line)] && ![ishighlighted $line]} {
-	    bolden $line mainfontbold
-	}
-	set fhighlights($line) 1
+        set line [string trim $line]
+        set i [lsearch -exact $fhl_list $line]
+        if {$i < 0} continue
+        for {set j 0} {$j < $i} {incr j} {
+            set id [lindex $fhl_list $j]
+            set fhighlights($id) 0
+        }
+        set fhl_list [lrange $fhl_list [expr {$i+1}] end]
+        if {$line eq {}} continue
+        if {![commitinview $line $curview]} continue
+        if {[info exists iddrawn($line)] && ![ishighlighted $line]} {
+            bolden $line mainfontbold
+        }
+        set fhighlights($line) 1
     }
     if {[eof $filehighlight]} {
-	# strange...
-	puts "oops, git diff-tree died"
-	catch {close $filehighlight}
-	unset filehighlight
-	return 0
+        # strange...
+        puts "oops, git diff-tree died"
+        catch {close $filehighlight}
+        unset filehighlight
+        return 0
     }
     if {[info exists find_dirn]} {
-	run findmore
+        run findmore
     }
     return 1
 }
@@ -4876,11 +4894,11 @@
     global findtype findpattern
 
     if {$findtype eq [mc "Regexp"]} {
-	return [regexp $findpattern $f]
+        return [regexp $findpattern $f]
     } elseif {$findtype eq [mc "IgnCase"]} {
-	return [string match -nocase $findpattern $f]
+        return [string match -nocase $findpattern $f]
     } else {
-	return [string match $findpattern $f]
+        return [string match $findpattern $f]
     }
 }
 
@@ -4890,32 +4908,32 @@
     global markingmatches
 
     if {![info exists commitinfo($id)]} {
-	getcommit $id
+        getcommit $id
     }
     set info $commitinfo($id)
     set isbold 0
     set fldtypes [list [mc Headline] [mc Author] "" [mc Committer] "" [mc Comments]]
     foreach f $info ty $fldtypes {
-	if {$ty eq ""} continue
-	if {($findloc eq [mc "All fields"] || $findloc eq $ty) &&
-	    [doesmatch $f]} {
-	    if {$ty eq [mc "Author"]} {
-		set isbold 2
-		break
-	    }
-	    set isbold 1
-	}
+        if {$ty eq ""} continue
+        if {($findloc eq [mc "All fields"] || $findloc eq $ty) &&
+            [doesmatch $f]} {
+            if {$ty eq [mc "Author"]} {
+                set isbold 2
+                break
+            }
+            set isbold 1
+        }
     }
     if {$isbold && [info exists iddrawn($id)]} {
-	if {![ishighlighted $id]} {
-	    bolden $id mainfontbold
-	    if {$isbold > 1} {
-		bolden_name $id mainfontbold
-	    }
-	}
-	if {$markingmatches} {
-	    markrowmatches $row $id
-	}
+        if {![ishighlighted $id]} {
+            bolden $id mainfontbold
+            if {$isbold > 1} {
+                bolden_name $id mainfontbold
+            }
+        }
+        if {$markingmatches} {
+            markrowmatches $row $id
+        }
     }
     set nhighlights($id) $isbold
 }
@@ -4928,18 +4946,18 @@
     $canv delete match$row
     $canv2 delete match$row
     if {$findloc eq [mc "All fields"] || $findloc eq [mc "Headline"]} {
-	set m [findmatches $headline]
-	if {$m ne {}} {
-	    markmatches $canv $row $headline $linehtag($id) $m \
-		[$canv itemcget $linehtag($id) -font] $row
-	}
+        set m [findmatches $headline]
+        if {$m ne {}} {
+            markmatches $canv $row $headline $linehtag($id) $m \
+                [$canv itemcget $linehtag($id) -font] $row
+        }
     }
     if {$findloc eq [mc "All fields"] || $findloc eq [mc "Author"]} {
-	set m [findmatches $author]
-	if {$m ne {}} {
-	    markmatches $canv2 $row $author $linentag($id) $m \
-		[$canv2 itemcget $linentag($id) -font] $row
-	}
+        set m [findmatches $author]
+        if {$m ne {}} {
+            markmatches $canv2 $row $author $linentag($id) $m \
+                [$canv2 itemcget $linentag($id) -font] $row
+        }
     }
 }
 
@@ -4948,7 +4966,7 @@
 
     rhighlight_none
     if {$highlight_related ne [mc "None"]} {
-	run drawvisible
+        run drawvisible
     }
 }
 
@@ -4962,8 +4980,8 @@
     unset -nocomplain ancestor
     set anc_todo [list $a]
     if {$highlight_related ne [mc "None"]} {
-	rhighlight_none
-	run drawvisible
+        rhighlight_none
+        run drawvisible
     }
 }
 
@@ -4983,24 +5001,24 @@
     set leftover {}
     set done 0
     for {set i 0} {$i < [llength $todo]} {incr i} {
-	set do [lindex $todo $i]
-	if {[rowofcommit $do] < $la} {
-	    lappend leftover $do
-	    continue
-	}
-	foreach nk $children($v,$do) {
-	    if {![info exists descendent($nk)]} {
-		set descendent($nk) 1
-		lappend todo $nk
-		if {$nk eq $a} {
-		    set done 1
-		}
-	    }
-	}
-	if {$done} {
-	    set desc_todo [concat $leftover [lrange $todo [expr {$i+1}] end]]
-	    return
-	}
+        set do [lindex $todo $i]
+        if {[rowofcommit $do] < $la} {
+            lappend leftover $do
+            continue
+        }
+        foreach nk $children($v,$do) {
+            if {![info exists descendent($nk)]} {
+                set descendent($nk) 1
+                lappend todo $nk
+                if {$nk eq $a} {
+                    set done 1
+                }
+            }
+        }
+        if {$done} {
+            set desc_todo [concat $leftover [lrange $todo [expr {$i+1}] end]]
+            return
+        }
     }
     set descendent($a) 0
     set desc_todo $leftover
@@ -5015,24 +5033,24 @@
     set leftover {}
     set done 0
     for {set i 0} {$i < [llength $todo]} {incr i} {
-	set do [lindex $todo $i]
-	if {![commitinview $do $v] || [rowofcommit $do] > $la} {
-	    lappend leftover $do
-	    continue
-	}
-	foreach np $parents($v,$do) {
-	    if {![info exists ancestor($np)]} {
-		set ancestor($np) 1
-		lappend todo $np
-		if {$np eq $a} {
-		    set done 1
-		}
-	    }
-	}
-	if {$done} {
-	    set anc_todo [concat $leftover [lrange $todo [expr {$i+1}] end]]
-	    return
-	}
+        set do [lindex $todo $i]
+        if {![commitinview $do $v] || [rowofcommit $do] > $la} {
+            lappend leftover $do
+            continue
+        }
+        foreach np $parents($v,$do) {
+            if {![info exists ancestor($np)]} {
+                set ancestor($np) 1
+                lappend todo $np
+                if {$np eq $a} {
+                    set done 1
+                }
+            }
+        }
+        if {$done} {
+            set anc_todo [concat $leftover [lrange $todo [expr {$i+1}] end]]
+            return
+        }
     }
     set ancestor($a) 0
     set anc_todo $leftover
@@ -5045,26 +5063,26 @@
     if {$selectedline eq {}} return
     set isbold 0
     if {$highlight_related eq [mc "Descendant"] ||
-	$highlight_related eq [mc "Not descendant"]} {
-	if {![info exists descendent($id)]} {
-	    is_descendent $id
-	}
-	if {$descendent($id) == ($highlight_related eq [mc "Descendant"])} {
-	    set isbold 1
-	}
+        $highlight_related eq [mc "Not descendant"]} {
+        if {![info exists descendent($id)]} {
+            is_descendent $id
+        }
+        if {$descendent($id) == ($highlight_related eq [mc "Descendant"])} {
+            set isbold 1
+        }
     } 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 [mc "Ancestor"])} {
-	    set isbold 1
-	}
+              $highlight_related eq [mc "Not ancestor"]} {
+        if {![info exists ancestor($id)]} {
+            is_ancestor $id
+        }
+        if {$ancestor($id) == ($highlight_related eq [mc "Ancestor"])} {
+            set isbold 1
+        }
     }
     if {[info exists iddrawn($id)]} {
-	if {$isbold && ![ishighlighted $id]} {
-	    bolden $id mainfontbold
-	}
+        if {$isbold && ![ishighlighted $id]} {
+            bolden $id mainfontbold
+        }
     }
     set rhighlights($id) $isbold
 }
@@ -5074,13 +5092,13 @@
 proc shortids {ids} {
     set res {}
     foreach id $ids {
-	if {[llength $id] > 1} {
-	    lappend res [shortids $id]
-	} elseif {[regexp {^[0-9a-f]{40}$} $id]} {
-	    lappend res [string range $id 0 7]
-	} else {
-	    lappend res $id
-	}
+        if {[llength $id] > 1} {
+            lappend res [shortids $id]
+        } elseif {[regexp {^[0-9a-f]{40}$} $id]} {
+            lappend res [string range $id 0 7]
+        } else {
+            lappend res $id
+        }
     }
     return $res
 }
@@ -5089,10 +5107,10 @@
     set ret {}
     set o [list $o]
     for {set mask 1} {$mask <= $n} {incr mask $mask} {
-	if {($n & $mask) != 0} {
-	    set ret [concat $ret $o]
-	}
-	set o [concat $o $o]
+        if {($n & $mask) != 0} {
+            set ret [concat $ret $o]
+        }
+        set o [concat $o $o]
     }
     return $ret
 }
@@ -5102,41 +5120,41 @@
     global nullid nullid2
 
     if {[info exists ordertok($id)]} {
-	return $ordertok($id)
+        return $ordertok($id)
     }
     set origid $id
     set todo {}
     while {1} {
-	if {[info exists varcid($curview,$id)]} {
-	    set a $varcid($curview,$id)
-	    set p [lindex $varcstart($curview) $a]
-	} else {
-	    set p [lindex $children($curview,$id) 0]
-	}
-	if {[info exists ordertok($p)]} {
-	    set tok $ordertok($p)
-	    break
-	}
-	set id [first_real_child $curview,$p]
-	if {$id eq {}} {
-	    # it's a root
-	    set tok [lindex $varctok($curview) $varcid($curview,$p)]
-	    break
-	}
-	if {[llength $parents($curview,$id)] == 1} {
-	    lappend todo [list $p {}]
-	} else {
-	    set j [lsearch -exact $parents($curview,$id) $p]
-	    if {$j < 0} {
-		puts "oops didn't find [shortids $p] in parents of [shortids $id]"
-	    }
-	    lappend todo [list $p [strrep $j]]
-	}
+        if {[info exists varcid($curview,$id)]} {
+            set a $varcid($curview,$id)
+            set p [lindex $varcstart($curview) $a]
+        } else {
+            set p [lindex $children($curview,$id) 0]
+        }
+        if {[info exists ordertok($p)]} {
+            set tok $ordertok($p)
+            break
+        }
+        set id [first_real_child $curview,$p]
+        if {$id eq {}} {
+            # it's a root
+            set tok [lindex $varctok($curview) $varcid($curview,$p)]
+            break
+        }
+        if {[llength $parents($curview,$id)] == 1} {
+            lappend todo [list $p {}]
+        } else {
+            set j [lsearch -exact $parents($curview,$id) $p]
+            if {$j < 0} {
+                puts "oops didn't find [shortids $p] in parents of [shortids $id]"
+            }
+            lappend todo [list $p [strrep $j]]
+        }
     }
     for {set i [llength $todo]} {[incr i -1] >= 0} {} {
-	set p [lindex $todo $i 0]
-	append tok [lindex $todo $i 1]
-	set ordertok($p) $tok
+        set p [lindex $todo $i 0]
+        append tok [lindex $todo $i 1]
+        set ordertok($p) $tok
     }
     set ordertok($origid) $tok
     return $tok
@@ -5147,19 +5165,19 @@
 proc idcol {idlist id {i 0}} {
     set t [ordertoken $id]
     if {$i < 0} {
-	set i 0
+        set i 0
     }
     if {$i >= [llength $idlist] || $t < [ordertoken [lindex $idlist $i]]} {
-	if {$i > [llength $idlist]} {
-	    set i [llength $idlist]
-	}
-	while {[incr i -1] >= 0 && $t < [ordertoken [lindex $idlist $i]]} {}
-	incr i
+        if {$i > [llength $idlist]} {
+            set i [llength $idlist]
+        }
+        while {[incr i -1] >= 0 && $t < [ordertoken [lindex $idlist $i]]} {}
+        incr i
     } else {
-	if {$t > [ordertoken [lindex $idlist $i]]} {
-	    while {[incr i] < [llength $idlist] &&
-		   $t >= [ordertoken [lindex $idlist $i]]} {}
-	}
+        if {$t > [ordertoken [lindex $idlist $i]]} {
+            while {[incr i] < [llength $idlist] &&
+                   $t >= [ordertoken [lindex $idlist $i]]} {}
+        }
     }
     return $i
 }
@@ -5204,12 +5222,12 @@
     set y0 [expr {int([lindex $f 0] * $ymax)}]
     set r0 [expr {int(($y0 - 3) / $linespc) - 1}]
     if {$r0 < 0} {
-	set r0 0
+        set r0 0
     }
     set y1 [expr {int([lindex $f 1] * $ymax)}]
     set r1 [expr {int(($y1 - 3) / $linespc) + 1}]
     if {$r1 >= $numcommits} {
-	set r1 [expr {$numcommits - 1}]
+        set r1 [expr {$numcommits - 1}]
     }
     return [list $r0 $r1]
 }
@@ -5220,13 +5238,13 @@
     global lastscrollset lastscrollrows
 
     if {$lastscrollrows < 100 || $viewcomplete($curview) ||
-	[clock clicks -milliseconds] - $lastscrollset > 500} {
-	setcanvscroll
+        [clock clicks -milliseconds] - $lastscrollset > 500} {
+        setcanvscroll
     }
     if {[info exists pending_select] &&
-	[commitinview $pending_select $curview]} {
-	update
-	selectline [rowofcommit $pending_select] 1
+        [commitinview $pending_select $curview]} {
+        update
+        selectline [rowofcommit $pending_select] 1
     }
     drawvisible
 }
@@ -5238,13 +5256,13 @@
     global viewmainheadid vfilelimit viewinstances mainheadid
 
     catch {
-	set rfd [open [concat | git rev-list -1 $mainheadid \
-			   -- $vfilelimit($view)] r]
-	set j [reg_instance $rfd]
-	lappend viewinstances($view) $j
-	fconfigure $rfd -blocking 0
-	filerun $rfd [list getviewhead $rfd $j $view]
-	set viewmainheadid($curview) {}
+        set rfd [open [concat | git rev-list -1 $mainheadid \
+                           -- $vfilelimit($view)] r]
+        set j [reg_instance $rfd]
+        lappend viewinstances($view) $j
+        fconfigure $rfd -blocking 0
+        filerun $rfd [list getviewhead $rfd $j $view]
+        set viewmainheadid($curview) {}
     }
 }
 
@@ -5254,21 +5272,21 @@
 
     set id {}
     if {[gets $fd line] < 0} {
-	if {![eof $fd]} {
-	    return 1
-	}
+        if {![eof $fd]} {
+            return 1
+        }
     } elseif {[string length $line] == 40 && [string is xdigit $line]} {
-	set id $line
+        set id $line
     }
     set viewmainheadid($view) $id
     close $fd
     unset commfd($inst)
     set i [lsearch -exact $viewinstances($view) $inst]
     if {$i >= 0} {
-	set viewinstances($view) [lreplace $viewinstances($view) $i $i]
+        set viewinstances($view) [lreplace $viewinstances($view) $i $i]
     }
     if {$showlocalchanges && $id ne {} && $view == $curview} {
-	doshowlocalchanges
+        doshowlocalchanges
     }
     return 0
 }
@@ -5278,9 +5296,9 @@
 
     if {$viewmainheadid($curview) eq {}} return
     if {[commitinview $viewmainheadid($curview) $curview]} {
-	dodiffindex
+        dodiffindex
     } else {
-	interestedin $viewmainheadid($curview) dodiffindex
+        interestedin $viewmainheadid($curview) dodiffindex
     }
 }
 
@@ -5288,10 +5306,10 @@
     global nullid nullid2 lserial curview
 
     if {[commitinview $nullid $curview]} {
-	removefakerow $nullid
+        removefakerow $nullid
     }
     if {[commitinview $nullid2 $curview]} {
-	removefakerow $nullid2
+        removefakerow $nullid2
     }
     incr lserial
 }
@@ -5304,12 +5322,12 @@
     if {!$showlocalchanges || !$hasworktree} return
     incr lserial
     if {[package vcompare $git_version "1.7.2"] >= 0} {
-	set cmd "|git diff-index --cached --ignore-submodules=dirty HEAD"
+        set cmd "|git diff-index --cached --ignore-submodules=dirty HEAD"
     } else {
-	set cmd "|git diff-index --cached HEAD"
+        set cmd "|git diff-index --cached HEAD"
     }
     if {$vfilelimit($curview) ne {}} {
-	set cmd [concat $cmd -- $vfilelimit($curview)]
+        set cmd [concat $cmd -- $vfilelimit($curview)]
     }
     set fd [open $cmd r]
     fconfigure $fd -blocking 0
@@ -5323,22 +5341,22 @@
 
     set isdiff 1
     if {[gets $fd line] < 0} {
-	if {![eof $fd]} {
-	    return 1
-	}
-	set isdiff 0
+        if {![eof $fd]} {
+            return 1
+        }
+        set isdiff 0
     }
     # we only need to see one line and we don't really care what it says...
     stop_instance $inst
 
     if {$serial != $lserial} {
-	return 0
+        return 0
     }
 
     # now see if there are any local changes not checked in to the index
     set cmd "|git diff-files"
     if {$vfilelimit($curview) ne {}} {
-	set cmd [concat $cmd -- $vfilelimit($curview)]
+        set cmd [concat $cmd -- $vfilelimit($curview)]
     }
     set fd [open $cmd r]
     fconfigure $fd -blocking 0
@@ -5346,19 +5364,19 @@
     filerun $fd [list readdifffiles $fd $serial $i]
 
     if {$isdiff && ![commitinview $nullid2 $curview]} {
-	# add the line for the changes in the index to the graph
-	set hl [mc "Local changes checked in to index but not committed"]
-	set commitinfo($nullid2) [list  $hl {} {} {} {} "    $hl\n"]
-	set commitdata($nullid2) "\n    $hl\n"
-	if {[commitinview $nullid $curview]} {
-	    removefakerow $nullid
-	}
-	insertfakerow $nullid2 $viewmainheadid($curview)
+        # add the line for the changes in the index to the graph
+        set hl [mc "Local changes checked in to index but not committed"]
+        set commitinfo($nullid2) [list  $hl {} {} {} {} "    $hl\n"]
+        set commitdata($nullid2) "\n    $hl\n"
+        if {[commitinview $nullid $curview]} {
+            removefakerow $nullid
+        }
+        insertfakerow $nullid2 $viewmainheadid($curview)
     } elseif {!$isdiff && [commitinview $nullid2 $curview]} {
-	if {[commitinview $nullid $curview]} {
-	    removefakerow $nullid
-	}
-	removefakerow $nullid2
+        if {[commitinview $nullid $curview]} {
+            removefakerow $nullid
+        }
+        removefakerow $nullid2
     }
     return 0
 }
@@ -5369,31 +5387,31 @@
 
     set isdiff 1
     if {[gets $fd line] < 0} {
-	if {![eof $fd]} {
-	    return 1
-	}
-	set isdiff 0
+        if {![eof $fd]} {
+            return 1
+        }
+        set isdiff 0
     }
     # we only need to see one line and we don't really care what it says...
     stop_instance $inst
 
     if {$serial != $lserial} {
-	return 0
+        return 0
     }
 
     if {$isdiff && ![commitinview $nullid $curview]} {
-	# add the line for the local diff to the graph
-	set hl [mc "Local uncommitted changes, not checked in to index"]
-	set commitinfo($nullid) [list  $hl {} {} {} {} "    $hl\n"]
-	set commitdata($nullid) "\n    $hl\n"
-	if {[commitinview $nullid2 $curview]} {
-	    set p $nullid2
-	} else {
-	    set p $viewmainheadid($curview)
-	}
-	insertfakerow $nullid $p
+        # add the line for the local diff to the graph
+        set hl [mc "Local uncommitted changes, not checked in to index"]
+        set commitinfo($nullid) [list  $hl {} {} {} {} "    $hl\n"]
+        set commitdata($nullid) "\n    $hl\n"
+        if {[commitinview $nullid2 $curview]} {
+            set p $nullid2
+        } else {
+            set p $viewmainheadid($curview)
+        }
+        insertfakerow $nullid $p
     } elseif {!$isdiff && [commitinview $nullid $curview]} {
-	removefakerow $nullid
+        removefakerow $nullid
     }
     return 0
 }
@@ -5402,17 +5420,17 @@
     global curview children
 
     if {[info exists children($curview,$id)]} {
-	foreach kid $children($curview,$id) {
-	    if {![commitinview $kid $curview]} {
-		return -1
-	    }
-	    if {[rowofcommit $kid] > $row} {
-		return [rowofcommit $kid]
-	    }
-	}
+        foreach kid $children($curview,$id) {
+            if {![commitinview $kid $curview]} {
+                return -1
+            }
+            if {[rowofcommit $kid] > $row} {
+                return [rowofcommit $kid]
+            }
+        }
     }
     if {[commitinview $id $curview]} {
-	return [rowofcommit $id]
+        return [rowofcommit $id]
     }
     return -1
 }
@@ -5422,12 +5440,12 @@
 
     set ret -1
     if {[info exists children($curview,$id)]} {
-	foreach kid $children($curview,$id) {
-	    if {![commitinview $kid $curview]} break
-	    if {[rowofcommit $kid] < $row} {
-		set ret [rowofcommit $kid]
-	    }
-	}
+        foreach kid $children($curview,$id) {
+            if {![commitinview $kid $curview]} break
+            if {[rowofcommit $kid] < $row} {
+                set ret [rowofcommit $kid]
+            }
+        }
     }
     return $ret
 }
@@ -5438,70 +5456,70 @@
 
     set r [expr {$row - $mingaplen - $downarrowlen - 1}]
     if {$r < 0} {
-	set r 0
+        set r 0
     }
     set ra [expr {$row - $downarrowlen}]
     if {$ra < 0} {
-	set ra 0
+        set ra 0
     }
     set rb [expr {$row + $uparrowlen}]
     if {$rb > $commitidx($curview)} {
-	set rb $commitidx($curview)
+        set rb $commitidx($curview)
     }
     make_disporder $r [expr {$rb + 1}]
     set ids {}
     for {} {$r < $ra} {incr r} {
-	set nextid [lindex $displayorder [expr {$r + 1}]]
-	foreach p [lindex $parentlist $r] {
-	    if {$p eq $nextid} continue
-	    set rn [nextuse $p $r]
-	    if {$rn >= $row &&
-		$rn <= $r + $downarrowlen + $mingaplen + $uparrowlen} {
-		lappend ids [list [ordertoken $p] $p]
-	    }
-	}
+        set nextid [lindex $displayorder [expr {$r + 1}]]
+        foreach p [lindex $parentlist $r] {
+            if {$p eq $nextid} continue
+            set rn [nextuse $p $r]
+            if {$rn >= $row &&
+                $rn <= $r + $downarrowlen + $mingaplen + $uparrowlen} {
+                lappend ids [list [ordertoken $p] $p]
+            }
+        }
     }
     for {} {$r < $row} {incr r} {
-	set nextid [lindex $displayorder [expr {$r + 1}]]
-	foreach p [lindex $parentlist $r] {
-	    if {$p eq $nextid} continue
-	    set rn [nextuse $p $r]
-	    if {$rn < 0 || $rn >= $row} {
-		lappend ids [list [ordertoken $p] $p]
-	    }
-	}
+        set nextid [lindex $displayorder [expr {$r + 1}]]
+        foreach p [lindex $parentlist $r] {
+            if {$p eq $nextid} continue
+            set rn [nextuse $p $r]
+            if {$rn < 0 || $rn >= $row} {
+                lappend ids [list [ordertoken $p] $p]
+            }
+        }
     }
     set id [lindex $displayorder $row]
     lappend ids [list [ordertoken $id] $id]
     while {$r < $rb} {
-	foreach p [lindex $parentlist $r] {
-	    set firstkid [lindex $children($curview,$p) 0]
-	    if {[rowofcommit $firstkid] < $row} {
-		lappend ids [list [ordertoken $p] $p]
-	    }
-	}
-	incr r
-	set id [lindex $displayorder $r]
-	if {$id ne {}} {
-	    set firstkid [lindex $children($curview,$id) 0]
-	    if {$firstkid ne {} && [rowofcommit $firstkid] < $row} {
-		lappend ids [list [ordertoken $id] $id]
-	    }
-	}
+        foreach p [lindex $parentlist $r] {
+            set firstkid [lindex $children($curview,$p) 0]
+            if {[rowofcommit $firstkid] < $row} {
+                lappend ids [list [ordertoken $p] $p]
+            }
+        }
+        incr r
+        set id [lindex $displayorder $r]
+        if {$id ne {}} {
+            set firstkid [lindex $children($curview,$id) 0]
+            if {$firstkid ne {} && [rowofcommit $firstkid] < $row} {
+                lappend ids [list [ordertoken $id] $id]
+            }
+        }
     }
     set idlist {}
     foreach idx [lsort -unique $ids] {
-	lappend idlist [lindex $idx 1]
+        lappend idlist [lindex $idx 1]
     }
     return $idlist
 }
 
 proc rowsequal {a b} {
     while {[set i [lsearch -exact $a {}]] >= 0} {
-	set a [lreplace $a $i $i]
+        set a [lreplace $a $i $i]
     }
     while {[set i [lsearch -exact $b {}]] >= 0} {
-	set b [lreplace $b $i $i]
+        set b [lreplace $b $i $i]
     }
     return [expr {$a eq $b}]
 }
@@ -5510,20 +5528,20 @@
     global rowidlist uparrowlen downarrowlen mingaplen
 
     for {set r $rend} {1} {set r $rstart} {
-	set rstart [prevuse $id $r]
-	if {$rstart < 0} return
-	if {$rstart < $row} break
+        set rstart [prevuse $id $r]
+        if {$rstart < 0} return
+        if {$rstart < $row} break
     }
     if {$rstart + $uparrowlen + $mingaplen + $downarrowlen < $rend} {
-	set rstart [expr {$rend - $uparrowlen - 1}]
+        set rstart [expr {$rend - $uparrowlen - 1}]
     }
     for {set r $rstart} {[incr r] <= $row} {} {
-	set idlist [lindex $rowidlist $r]
-	if {$idlist ne {} && [lsearch -exact $idlist $id] < 0} {
-	    set col [idcol $idlist $id $col]
-	    lset rowidlist $r [linsert $idlist $col $id]
-	    changedrow $r
-	}
+        set idlist [lindex $rowidlist $r]
+        if {$idlist ne {} && [lsearch -exact $idlist $id] < 0} {
+            set col [idcol $idlist $id $col]
+            lset rowidlist $r [linsert $idlist $col $id]
+            changedrow $r
+        }
     }
 }
 
@@ -5536,100 +5554,100 @@
     make_disporder [expr {$row - 1}] [expr {$endrow + $uparrowlen}]
     set idlist {}
     if {$row > 0} {
-	set rm1 [expr {$row - 1}]
-	foreach id [lindex $rowidlist $rm1] {
-	    if {$id ne {}} {
-		lappend idlist $id
-	    }
-	}
-	set final [lindex $rowfinal $rm1]
+        set rm1 [expr {$row - 1}]
+        foreach id [lindex $rowidlist $rm1] {
+            if {$id ne {}} {
+                lappend idlist $id
+            }
+        }
+        set final [lindex $rowfinal $rm1]
     }
     for {} {$row < $endrow} {incr row} {
-	set rm1 [expr {$row - 1}]
-	if {$rm1 < 0 || $idlist eq {}} {
-	    set idlist [make_idlist $row]
-	    set final 1
-	} else {
-	    set id [lindex $displayorder $rm1]
-	    set col [lsearch -exact $idlist $id]
-	    set idlist [lreplace $idlist $col $col]
-	    foreach p [lindex $parentlist $rm1] {
-		if {[lsearch -exact $idlist $p] < 0} {
-		    set col [idcol $idlist $p $col]
-		    set idlist [linsert $idlist $col $p]
-		    # if not the first child, we have to insert a line going up
-		    if {$id ne [lindex $children($curview,$p) 0]} {
-			makeupline $p $rm1 $row $col
-		    }
-		}
-	    }
-	    set id [lindex $displayorder $row]
-	    if {$row > $downarrowlen} {
-		set termrow [expr {$row - $downarrowlen - 1}]
-		foreach p [lindex $parentlist $termrow] {
-		    set i [lsearch -exact $idlist $p]
-		    if {$i < 0} continue
-		    set nr [nextuse $p $termrow]
-		    if {$nr < 0 || $nr >= $row + $mingaplen + $uparrowlen} {
-			set idlist [lreplace $idlist $i $i]
-		    }
-		}
-	    }
-	    set col [lsearch -exact $idlist $id]
-	    if {$col < 0} {
-		set col [idcol $idlist $id]
-		set idlist [linsert $idlist $col $id]
-		if {$children($curview,$id) ne {}} {
-		    makeupline $id $rm1 $row $col
-		}
-	    }
-	    set r [expr {$row + $uparrowlen - 1}]
-	    if {$r < $commitidx($curview)} {
-		set x $col
-		foreach p [lindex $parentlist $r] {
-		    if {[lsearch -exact $idlist $p] >= 0} continue
-		    set fk [lindex $children($curview,$p) 0]
-		    if {[rowofcommit $fk] < $row} {
-			set x [idcol $idlist $p $x]
-			set idlist [linsert $idlist $x $p]
-		    }
-		}
-		if {[incr r] < $commitidx($curview)} {
-		    set p [lindex $displayorder $r]
-		    if {[lsearch -exact $idlist $p] < 0} {
-			set fk [lindex $children($curview,$p) 0]
-			if {$fk ne {} && [rowofcommit $fk] < $row} {
-			    set x [idcol $idlist $p $x]
-			    set idlist [linsert $idlist $x $p]
-			}
-		    }
-		}
-	    }
-	}
-	if {$final && !$viewcomplete($curview) &&
-	    $row + $uparrowlen + $mingaplen + $downarrowlen
-		>= $commitidx($curview)} {
-	    set final 0
-	}
-	set l [llength $rowidlist]
-	if {$row == $l} {
-	    lappend rowidlist $idlist
-	    lappend rowisopt 0
-	    lappend rowfinal $final
-	} elseif {$row < $l} {
-	    if {![rowsequal $idlist [lindex $rowidlist $row]]} {
-		lset rowidlist $row $idlist
-		changedrow $row
-	    }
-	    lset rowfinal $row $final
-	} else {
-	    set pad [ntimes [expr {$row - $l}] {}]
-	    set rowidlist [concat $rowidlist $pad]
-	    lappend rowidlist $idlist
-	    set rowfinal [concat $rowfinal $pad]
-	    lappend rowfinal $final
-	    set rowisopt [concat $rowisopt [ntimes [expr {$row - $l + 1}] 0]]
-	}
+        set rm1 [expr {$row - 1}]
+        if {$rm1 < 0 || $idlist eq {}} {
+            set idlist [make_idlist $row]
+            set final 1
+        } else {
+            set id [lindex $displayorder $rm1]
+            set col [lsearch -exact $idlist $id]
+            set idlist [lreplace $idlist $col $col]
+            foreach p [lindex $parentlist $rm1] {
+                if {[lsearch -exact $idlist $p] < 0} {
+                    set col [idcol $idlist $p $col]
+                    set idlist [linsert $idlist $col $p]
+                    # if not the first child, we have to insert a line going up
+                    if {$id ne [lindex $children($curview,$p) 0]} {
+                        makeupline $p $rm1 $row $col
+                    }
+                }
+            }
+            set id [lindex $displayorder $row]
+            if {$row > $downarrowlen} {
+                set termrow [expr {$row - $downarrowlen - 1}]
+                foreach p [lindex $parentlist $termrow] {
+                    set i [lsearch -exact $idlist $p]
+                    if {$i < 0} continue
+                    set nr [nextuse $p $termrow]
+                    if {$nr < 0 || $nr >= $row + $mingaplen + $uparrowlen} {
+                        set idlist [lreplace $idlist $i $i]
+                    }
+                }
+            }
+            set col [lsearch -exact $idlist $id]
+            if {$col < 0} {
+                set col [idcol $idlist $id]
+                set idlist [linsert $idlist $col $id]
+                if {$children($curview,$id) ne {}} {
+                    makeupline $id $rm1 $row $col
+                }
+            }
+            set r [expr {$row + $uparrowlen - 1}]
+            if {$r < $commitidx($curview)} {
+                set x $col
+                foreach p [lindex $parentlist $r] {
+                    if {[lsearch -exact $idlist $p] >= 0} continue
+                    set fk [lindex $children($curview,$p) 0]
+                    if {[rowofcommit $fk] < $row} {
+                        set x [idcol $idlist $p $x]
+                        set idlist [linsert $idlist $x $p]
+                    }
+                }
+                if {[incr r] < $commitidx($curview)} {
+                    set p [lindex $displayorder $r]
+                    if {[lsearch -exact $idlist $p] < 0} {
+                        set fk [lindex $children($curview,$p) 0]
+                        if {$fk ne {} && [rowofcommit $fk] < $row} {
+                            set x [idcol $idlist $p $x]
+                            set idlist [linsert $idlist $x $p]
+                        }
+                    }
+                }
+            }
+        }
+        if {$final && !$viewcomplete($curview) &&
+            $row + $uparrowlen + $mingaplen + $downarrowlen
+                >= $commitidx($curview)} {
+            set final 0
+        }
+        set l [llength $rowidlist]
+        if {$row == $l} {
+            lappend rowidlist $idlist
+            lappend rowisopt 0
+            lappend rowfinal $final
+        } elseif {$row < $l} {
+            if {![rowsequal $idlist [lindex $rowidlist $row]]} {
+                lset rowidlist $row $idlist
+                changedrow $row
+            }
+            lset rowfinal $row $final
+        } else {
+            set pad [ntimes [expr {$row - $l}] {}]
+            set rowidlist [concat $rowidlist $pad]
+            lappend rowidlist $idlist
+            set rowfinal [concat $rowfinal $pad]
+            lappend rowfinal $final
+            set rowisopt [concat $rowisopt [ntimes [expr {$row - $l + 1}] 0]]
+        }
     }
     return $row
 }
@@ -5639,17 +5657,17 @@
 
     set l [llength $rowisopt]
     if {$row < $l} {
-	lset rowisopt $row 0
-	if {$row + 1 < $l} {
-	    lset rowisopt [expr {$row + 1}] 0
-	    if {$row + 2 < $l} {
-		lset rowisopt [expr {$row + 2}] 0
-	    }
-	}
+        lset rowisopt $row 0
+        if {$row + 1 < $l} {
+            lset rowisopt [expr {$row + 1}] 0
+            if {$row + 2 < $l} {
+                lset rowisopt [expr {$row + 2}] 0
+            }
+        }
     }
     set id [lindex $displayorder $row]
     if {[info exists iddrawn($id)]} {
-	set need_redisplay 1
+        set need_redisplay 1
     }
 }
 
@@ -5662,7 +5680,7 @@
     set aft [lrange $idlist $col end]
     set i [lsearch -exact $aft {}]
     if {$i > 0} {
-	set aft [lreplace $aft $i $i]
+        set aft [lreplace $aft $i $i]
     }
     lset rowidlist $row [concat $bef $pad $aft]
     changedrow $row
@@ -5672,123 +5690,123 @@
     global rowidlist rowisopt displayorder curview children
 
     if {$row < 1} {
-	set row 1
+        set row 1
     }
     for {} {$row < $endrow} {incr row; set col 0} {
-	if {[lindex $rowisopt $row]} continue
-	set haspad 0
-	set y0 [expr {$row - 1}]
-	set ym [expr {$row - 2}]
-	set idlist [lindex $rowidlist $row]
-	set previdlist [lindex $rowidlist $y0]
-	if {$idlist eq {} || $previdlist eq {}} continue
-	if {$ym >= 0} {
-	    set pprevidlist [lindex $rowidlist $ym]
-	    if {$pprevidlist eq {}} continue
-	} else {
-	    set pprevidlist {}
-	}
-	set x0 -1
-	set xm -1
-	for {} {$col < [llength $idlist]} {incr col} {
-	    set id [lindex $idlist $col]
-	    if {[lindex $previdlist $col] eq $id} continue
-	    if {$id eq {}} {
-		set haspad 1
-		continue
-	    }
-	    set x0 [lsearch -exact $previdlist $id]
-	    if {$x0 < 0} continue
-	    set z [expr {$x0 - $col}]
-	    set isarrow 0
-	    set z0 {}
-	    if {$ym >= 0} {
-		set xm [lsearch -exact $pprevidlist $id]
-		if {$xm >= 0} {
-		    set z0 [expr {$xm - $x0}]
-		}
-	    }
-	    if {$z0 eq {}} {
-		# if row y0 is the first child of $id then it's not an arrow
-		if {[lindex $children($curview,$id) 0] ne
-		    [lindex $displayorder $y0]} {
-		    set isarrow 1
-		}
-	    }
-	    if {!$isarrow && $id ne [lindex $displayorder $row] &&
-		[lsearch -exact [lindex $rowidlist [expr {$row+1}]] $id] < 0} {
-		set isarrow 1
-	    }
-	    # Looking at lines from this row to the previous row,
-	    # make them go straight up if they end in an arrow on
-	    # the previous row; otherwise make them go straight up
-	    # or at 45 degrees.
-	    if {$z < -1 || ($z < 0 && $isarrow)} {
-		# Line currently goes left too much;
-		# insert pads in the previous row, then optimize it
-		set npad [expr {-1 - $z + $isarrow}]
-		insert_pad $y0 $x0 $npad
-		if {$y0 > 0} {
-		    optimize_rows $y0 $x0 $row
-		}
-		set previdlist [lindex $rowidlist $y0]
-		set x0 [lsearch -exact $previdlist $id]
-		set z [expr {$x0 - $col}]
-		if {$z0 ne {}} {
-		    set pprevidlist [lindex $rowidlist $ym]
-		    set xm [lsearch -exact $pprevidlist $id]
-		    set z0 [expr {$xm - $x0}]
-		}
-	    } elseif {$z > 1 || ($z > 0 && $isarrow)} {
-		# Line currently goes right too much;
-		# insert pads in this line
-		set npad [expr {$z - 1 + $isarrow}]
-		insert_pad $row $col $npad
-		set idlist [lindex $rowidlist $row]
-		incr col $npad
-		set z [expr {$x0 - $col}]
-		set haspad 1
-	    }
-	    if {$z0 eq {} && !$isarrow && $ym >= 0} {
-		# this line links to its first child on row $row-2
-		set id [lindex $displayorder $ym]
-		set xc [lsearch -exact $pprevidlist $id]
-		if {$xc >= 0} {
-		    set z0 [expr {$xc - $x0}]
-		}
-	    }
-	    # avoid lines jigging left then immediately right
-	    if {$z0 ne {} && $z < 0 && $z0 > 0} {
-		insert_pad $y0 $x0 1
-		incr x0
-		optimize_rows $y0 $x0 $row
-		set previdlist [lindex $rowidlist $y0]
-	    }
-	}
-	if {!$haspad} {
-	    # Find the first column that doesn't have a line going right
-	    for {set col [llength $idlist]} {[incr col -1] >= 0} {} {
-		set id [lindex $idlist $col]
-		if {$id eq {}} break
-		set x0 [lsearch -exact $previdlist $id]
-		if {$x0 < 0} {
-		    # check if this is the link to the first child
-		    set kid [lindex $displayorder $y0]
-		    if {[lindex $children($curview,$id) 0] eq $kid} {
-			# it is, work out offset to child
-			set x0 [lsearch -exact $previdlist $kid]
-		    }
-		}
-		if {$x0 <= $col} break
-	    }
-	    # Insert a pad at that column as long as it has a line and
-	    # isn't the last column
-	    if {$x0 >= 0 && [incr col] < [llength $idlist]} {
-		set idlist [linsert $idlist $col {}]
-		lset rowidlist $row $idlist
-		changedrow $row
-	    }
-	}
+        if {[lindex $rowisopt $row]} continue
+        set haspad 0
+        set y0 [expr {$row - 1}]
+        set ym [expr {$row - 2}]
+        set idlist [lindex $rowidlist $row]
+        set previdlist [lindex $rowidlist $y0]
+        if {$idlist eq {} || $previdlist eq {}} continue
+        if {$ym >= 0} {
+            set pprevidlist [lindex $rowidlist $ym]
+            if {$pprevidlist eq {}} continue
+        } else {
+            set pprevidlist {}
+        }
+        set x0 -1
+        set xm -1
+        for {} {$col < [llength $idlist]} {incr col} {
+            set id [lindex $idlist $col]
+            if {[lindex $previdlist $col] eq $id} continue
+            if {$id eq {}} {
+                set haspad 1
+                continue
+            }
+            set x0 [lsearch -exact $previdlist $id]
+            if {$x0 < 0} continue
+            set z [expr {$x0 - $col}]
+            set isarrow 0
+            set z0 {}
+            if {$ym >= 0} {
+                set xm [lsearch -exact $pprevidlist $id]
+                if {$xm >= 0} {
+                    set z0 [expr {$xm - $x0}]
+                }
+            }
+            if {$z0 eq {}} {
+                # if row y0 is the first child of $id then it's not an arrow
+                if {[lindex $children($curview,$id) 0] ne
+                    [lindex $displayorder $y0]} {
+                    set isarrow 1
+                }
+            }
+            if {!$isarrow && $id ne [lindex $displayorder $row] &&
+                [lsearch -exact [lindex $rowidlist [expr {$row+1}]] $id] < 0} {
+                set isarrow 1
+            }
+            # Looking at lines from this row to the previous row,
+            # make them go straight up if they end in an arrow on
+            # the previous row; otherwise make them go straight up
+            # or at 45 degrees.
+            if {$z < -1 || ($z < 0 && $isarrow)} {
+                # Line currently goes left too much;
+                # insert pads in the previous row, then optimize it
+                set npad [expr {-1 - $z + $isarrow}]
+                insert_pad $y0 $x0 $npad
+                if {$y0 > 0} {
+                    optimize_rows $y0 $x0 $row
+                }
+                set previdlist [lindex $rowidlist $y0]
+                set x0 [lsearch -exact $previdlist $id]
+                set z [expr {$x0 - $col}]
+                if {$z0 ne {}} {
+                    set pprevidlist [lindex $rowidlist $ym]
+                    set xm [lsearch -exact $pprevidlist $id]
+                    set z0 [expr {$xm - $x0}]
+                }
+            } elseif {$z > 1 || ($z > 0 && $isarrow)} {
+                # Line currently goes right too much;
+                # insert pads in this line
+                set npad [expr {$z - 1 + $isarrow}]
+                insert_pad $row $col $npad
+                set idlist [lindex $rowidlist $row]
+                incr col $npad
+                set z [expr {$x0 - $col}]
+                set haspad 1
+            }
+            if {$z0 eq {} && !$isarrow && $ym >= 0} {
+                # this line links to its first child on row $row-2
+                set id [lindex $displayorder $ym]
+                set xc [lsearch -exact $pprevidlist $id]
+                if {$xc >= 0} {
+                    set z0 [expr {$xc - $x0}]
+                }
+            }
+            # avoid lines jigging left then immediately right
+            if {$z0 ne {} && $z < 0 && $z0 > 0} {
+                insert_pad $y0 $x0 1
+                incr x0
+                optimize_rows $y0 $x0 $row
+                set previdlist [lindex $rowidlist $y0]
+            }
+        }
+        if {!$haspad} {
+            # Find the first column that doesn't have a line going right
+            for {set col [llength $idlist]} {[incr col -1] >= 0} {} {
+                set id [lindex $idlist $col]
+                if {$id eq {}} break
+                set x0 [lsearch -exact $previdlist $id]
+                if {$x0 < 0} {
+                    # check if this is the link to the first child
+                    set kid [lindex $displayorder $y0]
+                    if {[lindex $children($curview,$id) 0] eq $kid} {
+                        # it is, work out offset to child
+                        set x0 [lsearch -exact $previdlist $kid]
+                    }
+                }
+                if {$x0 <= $col} break
+            }
+            # Insert a pad at that column as long as it has a line and
+            # isn't the last column
+            if {$x0 >= 0 && [incr col] < [llength $idlist]} {
+                set idlist [linsert $idlist $col {}]
+                lset rowidlist $row $idlist
+                changedrow $row
+            }
+        }
     }
 }
 
@@ -5807,7 +5825,7 @@
 
     set wid $lthickness
     if {[info exists thickerline] && $id eq $thickerline} {
-	set wid [expr {2 * $lthickness}]
+        set wid [expr {2 * $lthickness}]
     }
     return $wid
 }
@@ -5818,52 +5836,52 @@
 
     set kids $children($curview,$id)
     if {$kids eq {}} {
-	return {}
+        return {}
     }
     set ret {}
     lappend kids $id
     foreach child $kids {
-	if {![commitinview $child $curview]} break
-	set row [rowofcommit $child]
-	if {![info exists prev]} {
-	    lappend ret [expr {$row + 1}]
-	} else {
-	    if {$row <= $prevrow} {
-		puts "oops children of [shortids $id] out of order [shortids $child] $row <= [shortids $prev] $prevrow"
-	    }
-	    # see if the line extends the whole way from prevrow to row
-	    if {$row > $prevrow + $uparrowlen + $downarrowlen &&
-		[lsearch -exact [lindex $rowidlist \
-			    [expr {int(($row + $prevrow) / 2)}]] $id] < 0} {
-		# it doesn't, see where it ends
-		set r [expr {$prevrow + $downarrowlen}]
-		if {[lsearch -exact [lindex $rowidlist $r] $id] < 0} {
-		    while {[incr r -1] > $prevrow &&
-			   [lsearch -exact [lindex $rowidlist $r] $id] < 0} {}
-		} else {
-		    while {[incr r] <= $row &&
-			   [lsearch -exact [lindex $rowidlist $r] $id] >= 0} {}
-		    incr r -1
-		}
-		lappend ret $r
-		# see where it starts up again
-		set r [expr {$row - $uparrowlen}]
-		if {[lsearch -exact [lindex $rowidlist $r] $id] < 0} {
-		    while {[incr r] < $row &&
-			   [lsearch -exact [lindex $rowidlist $r] $id] < 0} {}
-		} else {
-		    while {[incr r -1] >= $prevrow &&
-			   [lsearch -exact [lindex $rowidlist $r] $id] >= 0} {}
-		    incr r
-		}
-		lappend ret $r
-	    }
-	}
-	if {$child eq $id} {
-	    lappend ret $row
-	}
-	set prev $child
-	set prevrow $row
+        if {![commitinview $child $curview]} break
+        set row [rowofcommit $child]
+        if {![info exists prev]} {
+            lappend ret [expr {$row + 1}]
+        } else {
+            if {$row <= $prevrow} {
+                puts "oops children of [shortids $id] out of order [shortids $child] $row <= [shortids $prev] $prevrow"
+            }
+            # see if the line extends the whole way from prevrow to row
+            if {$row > $prevrow + $uparrowlen + $downarrowlen &&
+                [lsearch -exact [lindex $rowidlist \
+                            [expr {int(($row + $prevrow) / 2)}]] $id] < 0} {
+                # it doesn't, see where it ends
+                set r [expr {$prevrow + $downarrowlen}]
+                if {[lsearch -exact [lindex $rowidlist $r] $id] < 0} {
+                    while {[incr r -1] > $prevrow &&
+                           [lsearch -exact [lindex $rowidlist $r] $id] < 0} {}
+                } else {
+                    while {[incr r] <= $row &&
+                           [lsearch -exact [lindex $rowidlist $r] $id] >= 0} {}
+                    incr r -1
+                }
+                lappend ret $r
+                # see where it starts up again
+                set r [expr {$row - $uparrowlen}]
+                if {[lsearch -exact [lindex $rowidlist $r] $id] < 0} {
+                    while {[incr r] < $row &&
+                           [lsearch -exact [lindex $rowidlist $r] $id] < 0} {}
+                } else {
+                    while {[incr r -1] >= $prevrow &&
+                           [lsearch -exact [lindex $rowidlist $r] $id] >= 0} {}
+                    incr r
+                }
+                lappend ret $r
+            }
+        }
+        if {$child eq $id} {
+            lappend ret $row
+        }
+        set prev $child
+        set prevrow $row
     }
     return $ret
 }
@@ -5876,158 +5894,158 @@
     set le [expr {$row + 1}]
     set arrowhigh 1
     while {1} {
-	set c [lsearch -exact [lindex $rowidlist $le] $id]
-	if {$c < 0} {
-	    incr le -1
-	    break
-	}
-	lappend cols $c
-	set x [lindex $displayorder $le]
-	if {$x eq $id} {
-	    set arrowhigh 0
-	    break
-	}
-	if {[info exists iddrawn($x)] || $le == $endrow} {
-	    set c [lsearch -exact [lindex $rowidlist [expr {$le+1}]] $id]
-	    if {$c >= 0} {
-		lappend cols $c
-		set arrowhigh 0
-	    }
-	    break
-	}
-	incr le
+        set c [lsearch -exact [lindex $rowidlist $le] $id]
+        if {$c < 0} {
+            incr le -1
+            break
+        }
+        lappend cols $c
+        set x [lindex $displayorder $le]
+        if {$x eq $id} {
+            set arrowhigh 0
+            break
+        }
+        if {[info exists iddrawn($x)] || $le == $endrow} {
+            set c [lsearch -exact [lindex $rowidlist [expr {$le+1}]] $id]
+            if {$c >= 0} {
+                lappend cols $c
+                set arrowhigh 0
+            }
+            break
+        }
+        incr le
     }
     if {$le <= $row} {
-	return $row
+        return $row
     }
 
     set lines {}
     set i 0
     set joinhigh 0
     if {[info exists linesegs($id)]} {
-	set lines $linesegs($id)
-	foreach li $lines {
-	    set r0 [lindex $li 0]
-	    if {$r0 > $row} {
-		if {$r0 == $le && [lindex $li 1] - $row <= $maxlinelen} {
-		    set joinhigh 1
-		}
-		break
-	    }
-	    incr i
-	}
+        set lines $linesegs($id)
+        foreach li $lines {
+            set r0 [lindex $li 0]
+            if {$r0 > $row} {
+                if {$r0 == $le && [lindex $li 1] - $row <= $maxlinelen} {
+                    set joinhigh 1
+                }
+                break
+            }
+            incr i
+        }
     }
     set joinlow 0
     if {$i > 0} {
-	set li [lindex $lines [expr {$i-1}]]
-	set r1 [lindex $li 1]
-	if {$r1 == $row && $le - [lindex $li 0] <= $maxlinelen} {
-	    set joinlow 1
-	}
+        set li [lindex $lines [expr {$i-1}]]
+        set r1 [lindex $li 1]
+        if {$r1 == $row && $le - [lindex $li 0] <= $maxlinelen} {
+            set joinlow 1
+        }
     }
 
     set x [lindex $cols [expr {$le - $row}]]
     set xp [lindex $cols [expr {$le - 1 - $row}]]
     set dir [expr {$xp - $x}]
     if {$joinhigh} {
-	set ith [lindex $lines $i 2]
-	set coords [$canv coords $ith]
-	set ah [$canv itemcget $ith -arrow]
-	set arrowhigh [expr {$ah eq "first" || $ah eq "both"}]
-	set x2 [lindex $cols [expr {$le + 1 - $row}]]
-	if {$x2 ne {} && $x - $x2 == $dir} {
-	    set coords [lrange $coords 0 end-2]
-	}
+        set ith [lindex $lines $i 2]
+        set coords [$canv coords $ith]
+        set ah [$canv itemcget $ith -arrow]
+        set arrowhigh [expr {$ah eq "first" || $ah eq "both"}]
+        set x2 [lindex $cols [expr {$le + 1 - $row}]]
+        if {$x2 ne {} && $x - $x2 == $dir} {
+            set coords [lrange $coords 0 end-2]
+        }
     } else {
-	set coords [list [xc $le $x] [yc $le]]
+        set coords [list [xc $le $x] [yc $le]]
     }
     if {$joinlow} {
-	set itl [lindex $lines [expr {$i-1}] 2]
-	set al [$canv itemcget $itl -arrow]
-	set arrowlow [expr {$al eq "last" || $al eq "both"}]
+        set itl [lindex $lines [expr {$i-1}] 2]
+        set al [$canv itemcget $itl -arrow]
+        set arrowlow [expr {$al eq "last" || $al eq "both"}]
     } elseif {$arrowlow} {
-	if {[lsearch -exact [lindex $rowidlist [expr {$row-1}]] $id] >= 0 ||
-	    [lsearch -exact [lindex $parentlist [expr {$row-1}]] $id] >= 0} {
-	    set arrowlow 0
-	}
+        if {[lsearch -exact [lindex $rowidlist [expr {$row-1}]] $id] >= 0 ||
+            [lsearch -exact [lindex $parentlist [expr {$row-1}]] $id] >= 0} {
+            set arrowlow 0
+        }
     }
     set arrow [lindex {none first last both} [expr {$arrowhigh + 2*$arrowlow}]]
     for {set y $le} {[incr y -1] > $row} {} {
-	set x $xp
-	set xp [lindex $cols [expr {$y - 1 - $row}]]
-	set ndir [expr {$xp - $x}]
-	if {$dir != $ndir || $xp < 0} {
-	    lappend coords [xc $y $x] [yc $y]
-	}
-	set dir $ndir
+        set x $xp
+        set xp [lindex $cols [expr {$y - 1 - $row}]]
+        set ndir [expr {$xp - $x}]
+        if {$dir != $ndir || $xp < 0} {
+            lappend coords [xc $y $x] [yc $y]
+        }
+        set dir $ndir
     }
     if {!$joinlow} {
-	if {$xp < 0} {
-	    # join parent line to first child
-	    set ch [lindex $displayorder $row]
-	    set xc [lsearch -exact [lindex $rowidlist $row] $ch]
-	    if {$xc < 0} {
-		puts "oops: drawlineseg: child $ch not on row $row"
-	    } elseif {$xc != $x} {
-		if {($arrowhigh && $le == $row + 1) || $dir == 0} {
-		    set d [expr {int(0.5 * $linespc)}]
-		    set x1 [xc $row $x]
-		    if {$xc < $x} {
-			set x2 [expr {$x1 - $d}]
-		    } else {
-			set x2 [expr {$x1 + $d}]
-		    }
-		    set y2 [yc $row]
-		    set y1 [expr {$y2 + $d}]
-		    lappend coords $x1 $y1 $x2 $y2
-		} elseif {$xc < $x - 1} {
-		    lappend coords [xc $row [expr {$x-1}]] [yc $row]
-		} elseif {$xc > $x + 1} {
-		    lappend coords [xc $row [expr {$x+1}]] [yc $row]
-		}
-		set x $xc
-	    }
-	    lappend coords [xc $row $x] [yc $row]
-	} else {
-	    set xn [xc $row $xp]
-	    set yn [yc $row]
-	    lappend coords $xn $yn
-	}
-	if {!$joinhigh} {
-	    assigncolor $id
-	    set t [$canv create line $coords -width [linewidth $id] \
-		       -fill $colormap($id) -tags lines.$id -arrow $arrow]
-	    $canv lower $t
-	    bindline $t $id
-	    set lines [linsert $lines $i [list $row $le $t]]
-	} else {
-	    $canv coords $ith $coords
-	    if {$arrow ne $ah} {
-		$canv itemconf $ith -arrow $arrow
-	    }
-	    lset lines $i 0 $row
-	}
+        if {$xp < 0} {
+            # join parent line to first child
+            set ch [lindex $displayorder $row]
+            set xc [lsearch -exact [lindex $rowidlist $row] $ch]
+            if {$xc < 0} {
+                puts "oops: drawlineseg: child $ch not on row $row"
+            } elseif {$xc != $x} {
+                if {($arrowhigh && $le == $row + 1) || $dir == 0} {
+                    set d [expr {int(0.5 * $linespc)}]
+                    set x1 [xc $row $x]
+                    if {$xc < $x} {
+                        set x2 [expr {$x1 - $d}]
+                    } else {
+                        set x2 [expr {$x1 + $d}]
+                    }
+                    set y2 [yc $row]
+                    set y1 [expr {$y2 + $d}]
+                    lappend coords $x1 $y1 $x2 $y2
+                } elseif {$xc < $x - 1} {
+                    lappend coords [xc $row [expr {$x-1}]] [yc $row]
+                } elseif {$xc > $x + 1} {
+                    lappend coords [xc $row [expr {$x+1}]] [yc $row]
+                }
+                set x $xc
+            }
+            lappend coords [xc $row $x] [yc $row]
+        } else {
+            set xn [xc $row $xp]
+            set yn [yc $row]
+            lappend coords $xn $yn
+        }
+        if {!$joinhigh} {
+            assigncolor $id
+            set t [$canv create line $coords -width [linewidth $id] \
+                       -fill $colormap($id) -tags lines.$id -arrow $arrow]
+            $canv lower $t
+            bindline $t $id
+            set lines [linsert $lines $i [list $row $le $t]]
+        } else {
+            $canv coords $ith $coords
+            if {$arrow ne $ah} {
+                $canv itemconf $ith -arrow $arrow
+            }
+            lset lines $i 0 $row
+        }
     } else {
-	set xo [lsearch -exact [lindex $rowidlist [expr {$row - 1}]] $id]
-	set ndir [expr {$xo - $xp}]
-	set clow [$canv coords $itl]
-	if {$dir == $ndir} {
-	    set clow [lrange $clow 2 end]
-	}
-	set coords [concat $coords $clow]
-	if {!$joinhigh} {
-	    lset lines [expr {$i-1}] 1 $le
-	} else {
-	    # coalesce two pieces
-	    $canv delete $ith
-	    set b [lindex $lines [expr {$i-1}] 0]
-	    set e [lindex $lines $i 1]
-	    set lines [lreplace $lines [expr {$i-1}] $i [list $b $e $itl]]
-	}
-	$canv coords $itl $coords
-	if {$arrow ne $al} {
-	    $canv itemconf $itl -arrow $arrow
-	}
+        set xo [lsearch -exact [lindex $rowidlist [expr {$row - 1}]] $id]
+        set ndir [expr {$xo - $xp}]
+        set clow [$canv coords $itl]
+        if {$dir == $ndir} {
+            set clow [lrange $clow 2 end]
+        }
+        set coords [concat $coords $clow]
+        if {!$joinhigh} {
+            lset lines [expr {$i-1}] 1 $le
+        } else {
+            # coalesce two pieces
+            $canv delete $ith
+            set b [lindex $lines [expr {$i-1}] 0]
+            set e [lindex $lines $i 1]
+            set lines [lreplace $lines [expr {$i-1}] $i [list $b $e $itl]]
+        }
+        $canv coords $itl $coords
+        if {$arrow ne $al} {
+            $canv itemconf $itl -arrow $arrow
+        }
     }
 
     set linesegs($id) $lines
@@ -6052,54 +6070,54 @@
     # rmx = right-most X coord used
     set rmx 0
     foreach p $olds {
-	set i [lsearch -exact $ids $p]
-	if {$i < 0} {
-	    puts "oops, parent $p of $id not in list"
-	    continue
-	}
-	set x2 [xc $row2 $i]
-	if {$x2 > $rmx} {
-	    set rmx $x2
-	}
-	set j [lsearch -exact $rowids $p]
-	if {$j < 0} {
-	    # drawlineseg will do this one for us
-	    continue
-	}
-	assigncolor $p
-	# should handle duplicated parents here...
-	set coords [list $x $y]
-	if {$i != $col} {
-	    # if attaching to a vertical segment, draw a smaller
-	    # slant for visual distinctness
-	    if {$i == $j} {
-		if {$i < $col} {
-		    lappend coords [expr {$x2 + $d}] $y $x2 $ymid
-		} else {
-		    lappend coords [expr {$x2 - $d}] $y $x2 $ymid
-		}
-	    } elseif {$i < $col && $i < $j} {
-		# segment slants towards us already
-		lappend coords [xc $row $j] $y
-	    } else {
-		if {$i < $col - 1} {
-		    lappend coords [expr {$x2 + $linespc}] $y
-		} elseif {$i > $col + 1} {
-		    lappend coords [expr {$x2 - $linespc}] $y
-		}
-		lappend coords $x2 $y2
-	    }
-	} else {
-	    lappend coords $x2 $y2
-	}
-	set t [$canv create line $coords -width [linewidth $p] \
-		   -fill $colormap($p) -tags lines.$p]
-	$canv lower $t
-	bindline $t $p
+        set i [lsearch -exact $ids $p]
+        if {$i < 0} {
+            puts "oops, parent $p of $id not in list"
+            continue
+        }
+        set x2 [xc $row2 $i]
+        if {$x2 > $rmx} {
+            set rmx $x2
+        }
+        set j [lsearch -exact $rowids $p]
+        if {$j < 0} {
+            # drawlineseg will do this one for us
+            continue
+        }
+        assigncolor $p
+        # should handle duplicated parents here...
+        set coords [list $x $y]
+        if {$i != $col} {
+            # if attaching to a vertical segment, draw a smaller
+            # slant for visual distinctness
+            if {$i == $j} {
+                if {$i < $col} {
+                    lappend coords [expr {$x2 + $d}] $y $x2 $ymid
+                } else {
+                    lappend coords [expr {$x2 - $d}] $y $x2 $ymid
+                }
+            } elseif {$i < $col && $i < $j} {
+                # segment slants towards us already
+                lappend coords [xc $row $j] $y
+            } else {
+                if {$i < $col - 1} {
+                    lappend coords [expr {$x2 + $linespc}] $y
+                } elseif {$i > $col + 1} {
+                    lappend coords [expr {$x2 - $linespc}] $y
+                }
+                lappend coords $x2 $y2
+            }
+        } else {
+            lappend coords $x2 $y2
+        }
+        set t [$canv create line $coords -width [linewidth $p] \
+                   -fill $colormap($p) -tags lines.$p]
+        $canv lower $t
+        bindline $t $p
     }
     if {$rmx > [lindex $idpos($id) 1]} {
-	lset idpos($id) 1 $rmx
-	redrawtags $id
+        lset idpos($id) 1 $rmx
+        redrawtags $id
     }
 }
 
@@ -6122,35 +6140,35 @@
     # listed is 0 for boundary, 1 for normal, 2 for negative, 3 for left, 4 for right
     set listed $cmitlisted($curview,$id)
     if {$id eq $nullid} {
-	set ofill $workingfilescirclecolor
+        set ofill $workingfilescirclecolor
     } elseif {$id eq $nullid2} {
-	set ofill $indexcirclecolor
+        set ofill $indexcirclecolor
     } elseif {$id eq $mainheadid} {
-	set ofill $mainheadcirclecolor
+        set ofill $mainheadcirclecolor
     } else {
-	set ofill [lindex $circlecolors $listed]
+        set ofill [lindex $circlecolors $listed]
     }
     set x [xc $row $col]
     set y [yc $row]
     set orad [expr {$linespc / 3}]
     if {$listed <= 2} {
-	set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \
-		   [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
-		   -fill $ofill -outline $circleoutlinecolor -width 1 -tags circle]
+        set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \
+                   [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
+                   -fill $ofill -outline $circleoutlinecolor -width 1 -tags circle]
     } elseif {$listed == 3} {
-	# triangle pointing left for left-side commits
-	set t [$canv create polygon \
-		   [expr {$x - $orad}] $y \
-		   [expr {$x + $orad - 1}] [expr {$y - $orad}] \
-		   [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
-		   -fill $ofill -outline $circleoutlinecolor -width 1 -tags circle]
+        # triangle pointing left for left-side commits
+        set t [$canv create polygon \
+                   [expr {$x - $orad}] $y \
+                   [expr {$x + $orad - 1}] [expr {$y - $orad}] \
+                   [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
+                   -fill $ofill -outline $circleoutlinecolor -width 1 -tags circle]
     } else {
-	# triangle pointing right for right-side commits
-	set t [$canv create polygon \
-		   [expr {$x + $orad - 1}] $y \
-		   [expr {$x - $orad}] [expr {$y - $orad}] \
-		   [expr {$x - $orad}] [expr {$y + $orad - 1}] \
-		   -fill $ofill -outline $circleoutlinecolor -width 1 -tags circle]
+        # triangle pointing right for right-side commits
+        set t [$canv create polygon \
+                   [expr {$x + $orad - 1}] $y \
+                   [expr {$x - $orad}] [expr {$y - $orad}] \
+                   [expr {$x - $orad}] [expr {$y + $orad - 1}] \
+                   -fill $ofill -outline $circleoutlinecolor -width 1 -tags circle]
     }
     set circleitem($row) $t
     $canv raise $t
@@ -6158,23 +6176,23 @@
     set rmx [llength [lindex $rowidlist $row]]
     set olds [lindex $parentlist $row]
     if {$olds ne {}} {
-	set nextids [lindex $rowidlist [expr {$row + 1}]]
-	foreach p $olds {
-	    set i [lsearch -exact $nextids $p]
-	    if {$i > $rmx} {
-		set rmx $i
-	    }
-	}
+        set nextids [lindex $rowidlist [expr {$row + 1}]]
+        foreach p $olds {
+            set i [lsearch -exact $nextids $p]
+            if {$i > $rmx} {
+                set rmx $i
+            }
+        }
     }
     set xt [xc $row $rmx]
     set rowtextx($row) $xt
     set idpos($id) [list $x $xt $y]
     if {[info exists idtags($id)] || [info exists idheads($id)]
-	|| [info exists idotherrefs($id)]} {
-	set xt [drawtags $id $x $xt $y]
+        || [info exists idotherrefs($id)]} {
+        set xt [drawtags $id $x $xt $y]
     }
     if {[lindex $commitinfo($id) 6] > 0} {
-	set xt [drawnotesign $xt $y]
+        set xt [drawnotesign $xt $y]
     }
     set headline [lindex $commitinfo($id) 0]
     set name [lindex $commitinfo($id) 1]
@@ -6184,30 +6202,30 @@
     set nfont mainfont
     set isbold [ishighlighted $id]
     if {$isbold > 0} {
-	lappend boldids $id
-	set font mainfontbold
-	if {$isbold > 1} {
-	    lappend boldnameids $id
-	    set nfont mainfontbold
-	}
+        lappend boldids $id
+        set font mainfontbold
+        if {$isbold > 1} {
+            lappend boldnameids $id
+            set nfont mainfontbold
+        }
     }
     set linehtag($id) [$canv create text $xt $y -anchor w -fill $fgcolor \
-			   -text $headline -font $font -tags text]
+                           -text $headline -font $font -tags text]
     $canv bind $linehtag($id) $ctxbut "rowmenu %X %Y $id"
     set linentag($id) [$canv2 create text 3 $y -anchor w -fill $fgcolor \
-			   -text $name -font $nfont -tags text]
+                           -text $name -font $nfont -tags text]
     set linedtag($id) [$canv3 create text 3 $y -anchor w -fill $fgcolor \
-			   -text $date -font mainfont -tags text]
+                           -text $date -font mainfont -tags text]
     if {$selectedline == $row} {
-	make_secsel $id
+        make_secsel $id
     }
     if {[info exists markedid] && $markedid eq $id} {
-	make_idmark $id
+        make_idmark $id
     }
     set xr [expr {$xt + [font measure $font $headline]}]
     if {$xr > $canvxmax} {
-	set canvxmax $xr
-	setcanvscroll
+        set canvxmax $xr
+        setcanvscroll
     }
 }
 
@@ -6223,33 +6241,33 @@
 
     set id [lindex $displayorder $row]
     if {[info exists hlview] && ![info exists vhighlights($id)]} {
-	askvhighlight $row $id
+        askvhighlight $row $id
     }
     if {[info exists filehighlight] && ![info exists fhighlights($id)]} {
-	askfilehighlight $row $id
+        askfilehighlight $row $id
     }
     if {$findpattern ne {} && ![info exists nhighlights($id)]} {
-	askfindhighlight $row $id
+        askfindhighlight $row $id
     }
     if {$highlight_related ne [mc "None"] && ![info exists rhighlights($id)]} {
-	askrelhighlight $row $id
+        askrelhighlight $row $id
     }
     if {![info exists iddrawn($id)]} {
-	set col [lsearch -exact [lindex $rowidlist $row] $id]
-	if {$col < 0} {
-	    puts "oops, row $row id $id not in list"
-	    return
-	}
-	if {![info exists commitinfo($id)]} {
-	    getcommit $id
-	}
-	assigncolor $id
-	drawcmittext $id $row $col
-	set iddrawn($id) 1
-	incr nrows_drawn
+        set col [lsearch -exact [lindex $rowidlist $row] $id]
+        if {$col < 0} {
+            puts "oops, row $row id $id not in list"
+            return
+        }
+        if {![info exists commitinfo($id)]} {
+            getcommit $id
+        }
+        assigncolor $id
+        drawcmittext $id $row $col
+        set iddrawn($id) 1
+        incr nrows_drawn
     }
     if {$markingmatches} {
-	markrowmatches $row $id
+        markrowmatches $row $id
     }
 }
 
@@ -6258,78 +6276,78 @@
     global parentlist rowidlist rowfinal uparrowlen downarrowlen nrows_drawn
 
     if {$row < 0} {
-	set row 0
+        set row 0
     }
     if {$endrow eq {}} {
-	set endrow $row
+        set endrow $row
     }
     if {$endrow >= $numcommits} {
-	set endrow [expr {$numcommits - 1}]
+        set endrow [expr {$numcommits - 1}]
     }
 
     set rl1 [expr {$row - $downarrowlen - 3}]
     if {$rl1 < 0} {
-	set rl1 0
+        set rl1 0
     }
     set ro1 [expr {$row - 3}]
     if {$ro1 < 0} {
-	set ro1 0
+        set ro1 0
     }
     set r2 [expr {$endrow + $uparrowlen + 3}]
     if {$r2 > $numcommits} {
-	set r2 $numcommits
+        set r2 $numcommits
     }
     for {set r $rl1} {$r < $r2} {incr r} {
-	if {[lindex $rowidlist $r] ne {} && [lindex $rowfinal $r]} {
-	    if {$rl1 < $r} {
-		layoutrows $rl1 $r
-	    }
-	    set rl1 [expr {$r + 1}]
-	}
+        if {[lindex $rowidlist $r] ne {} && [lindex $rowfinal $r]} {
+            if {$rl1 < $r} {
+                layoutrows $rl1 $r
+            }
+            set rl1 [expr {$r + 1}]
+        }
     }
     if {$rl1 < $r} {
-	layoutrows $rl1 $r
+        layoutrows $rl1 $r
     }
     optimize_rows $ro1 0 $r2
     if {$need_redisplay || $nrows_drawn > 2000} {
-	clear_display
+        clear_display
     }
 
     # make the lines join to already-drawn rows either side
     set r [expr {$row - 1}]
     if {$r < 0 || ![info exists iddrawn([lindex $displayorder $r])]} {
-	set r $row
+        set r $row
     }
     set er [expr {$endrow + 1}]
     if {$er >= $numcommits ||
-	![info exists iddrawn([lindex $displayorder $er])]} {
-	set er $endrow
+        ![info exists iddrawn([lindex $displayorder $er])]} {
+        set er $endrow
     }
     for {} {$r <= $er} {incr r} {
-	set id [lindex $displayorder $r]
-	set wasdrawn [info exists iddrawn($id)]
-	drawcmitrow $r
-	if {$r == $er} break
-	set nextid [lindex $displayorder [expr {$r + 1}]]
-	if {$wasdrawn && [info exists iddrawn($nextid)]} continue
-	drawparentlinks $id $r
+        set id [lindex $displayorder $r]
+        set wasdrawn [info exists iddrawn($id)]
+        drawcmitrow $r
+        if {$r == $er} break
+        set nextid [lindex $displayorder [expr {$r + 1}]]
+        if {$wasdrawn && [info exists iddrawn($nextid)]} continue
+        drawparentlinks $id $r
 
-	set rowids [lindex $rowidlist $r]
-	foreach lid $rowids {
-	    if {$lid eq {}} continue
-	    if {[info exists lineend($lid)] && $lineend($lid) > $r} continue
-	    if {$lid eq $id} {
-		# see if this is the first child of any of its parents
-		foreach p [lindex $parentlist $r] {
-		    if {[lsearch -exact $rowids $p] < 0} {
-			# make this line extend up to the child
-			set lineend($p) [drawlineseg $p $r $er 0]
-		    }
-		}
-	    } else {
-		set lineend($lid) [drawlineseg $lid $r $er 1]
-	    }
-	}
+        set rowids [lindex $rowidlist $r]
+        foreach lid $rowids {
+            if {$lid eq {}} continue
+            if {[info exists lineend($lid)] && $lineend($lid) > $r} continue
+            if {$lid eq $id} {
+                # see if this is the first child of any of its parents
+                foreach p [lindex $parentlist $r] {
+                    if {[lsearch -exact $rowids $p] < 0} {
+                        # make this line extend up to the child
+                        set lineend($p) [drawlineseg $p $r $er 0]
+                    }
+                }
+            } else {
+                set lineend($lid) [drawlineseg $lid $r $er 1]
+            }
+        }
     }
 }
 
@@ -6339,15 +6357,15 @@
 
     set r [expr {$row - ($uparrowlen + $mingaplen + $downarrowlen)}]
     if {$r < 0} {
-	set r 0
+        set r 0
     }
     if {[llength $rowidlist] > $r} {
-	incr r -1
-	set rowidlist [lrange $rowidlist 0 $r]
-	set rowfinal [lrange $rowfinal 0 $r]
-	set rowisopt [lrange $rowisopt 0 $r]
-	set need_redisplay 1
-	run drawvisible
+        incr r -1
+        set rowidlist [lrange $rowidlist 0 $r]
+        set rowfinal [lrange $rowfinal 0 $r]
+        set rowisopt [lrange $rowisopt 0 $r]
+        set need_redisplay 1
+        run drawvisible
     }
 }
 
@@ -6364,44 +6382,44 @@
     set y1 [expr {int($f1 * $ymax)}]
 
     if {[info exists targetid]} {
-	if {[commitinview $targetid $curview]} {
-	    set r [rowofcommit $targetid]
-	    if {$r != $targetrow} {
-		# Fix up the scrollregion and change the scrolling position
-		# now that our target row has moved.
-		set diff [expr {($r - $targetrow) * $linespc}]
-		set targetrow $r
-		setcanvscroll
-		set ymax [lindex [$canv cget -scrollregion] 3]
-		incr y0 $diff
-		incr y1 $diff
-		set f0 [expr {$y0 / $ymax}]
-		set f1 [expr {$y1 / $ymax}]
-		allcanvs yview moveto $f0
-		$cscroll set $f0 $f1
-		set need_redisplay 1
-	    }
-	} else {
-	    unset targetid
-	}
+        if {[commitinview $targetid $curview]} {
+            set r [rowofcommit $targetid]
+            if {$r != $targetrow} {
+                # Fix up the scrollregion and change the scrolling position
+                # now that our target row has moved.
+                set diff [expr {($r - $targetrow) * $linespc}]
+                set targetrow $r
+                setcanvscroll
+                set ymax [lindex [$canv cget -scrollregion] 3]
+                incr y0 $diff
+                incr y1 $diff
+                set f0 [expr {$y0 / $ymax}]
+                set f1 [expr {$y1 / $ymax}]
+                allcanvs yview moveto $f0
+                $cscroll set $f0 $f1
+                set need_redisplay 1
+            }
+        } else {
+            unset targetid
+        }
     }
 
     set row [expr {int(($y0 - 3) / $linespc) - 1}]
     set endrow [expr {int(($y1 - 3) / $linespc) + 1}]
     if {$endrow >= $vrowmod($curview)} {
-	update_arcrows $curview
+        update_arcrows $curview
     }
     if {$selectedline ne {} &&
-	$row <= $selectedline && $selectedline <= $endrow} {
-	set targetrow $selectedline
+        $row <= $selectedline && $selectedline <= $endrow} {
+        set targetrow $selectedline
     } elseif {[info exists targetid]} {
-	set targetrow [expr {int(($row + $endrow) / 2)}]
+        set targetrow [expr {int(($row + $endrow) / 2)}]
     }
     if {[info exists targetrow]} {
-	if {$targetrow >= $numcommits} {
-	    set targetrow [expr {$numcommits - 1}]
-	}
-	set targetid [commitonrow $targetrow]
+        if {$targetrow >= $numcommits} {
+            set targetrow [expr {$numcommits - 1}]
+        }
+        set targetid [commitonrow $targetrow]
     }
     drawcommits $row $endrow
 }
@@ -6433,31 +6451,31 @@
     set cross {}
     set ccross {}
     foreach {s e} [rowranges $id] {
-	if {$e >= $numcommits} {
-	    set e [expr {$numcommits - 1}]
-	}
-	if {$e <= $s} continue
-	for {set row $e} {[incr row -1] >= $s} {} {
-	    set x [lsearch -exact [lindex $rowidlist $row] $id]
-	    if {$x < 0} break
-	    set olds [lindex $parentlist $row]
-	    set kid [lindex $displayorder $row]
-	    set kidx [lsearch -exact [lindex $rowidlist $row] $kid]
-	    if {$kidx < 0} continue
-	    set nextrow [lindex $rowidlist [expr {$row + 1}]]
-	    foreach p $olds {
-		set px [lsearch -exact $nextrow $p]
-		if {$px < 0} continue
-		if {($kidx < $x && $x < $px) || ($px < $x && $x < $kidx)} {
-		    if {[lsearch -exact $ccross $p] >= 0} continue
-		    if {$x == $px + ($kidx < $px? -1: 1)} {
-			lappend ccross $p
-		    } elseif {[lsearch -exact $cross $p] < 0} {
-			lappend cross $p
-		    }
-		}
-	    }
-	}
+        if {$e >= $numcommits} {
+            set e [expr {$numcommits - 1}]
+        }
+        if {$e <= $s} continue
+        for {set row $e} {[incr row -1] >= $s} {} {
+            set x [lsearch -exact [lindex $rowidlist $row] $id]
+            if {$x < 0} break
+            set olds [lindex $parentlist $row]
+            set kid [lindex $displayorder $row]
+            set kidx [lsearch -exact [lindex $rowidlist $row] $kid]
+            if {$kidx < 0} continue
+            set nextrow [lindex $rowidlist [expr {$row + 1}]]
+            foreach p $olds {
+                set px [lsearch -exact $nextrow $p]
+                if {$px < 0} continue
+                if {($kidx < $x && $x < $px) || ($px < $x && $x < $kidx)} {
+                    if {[lsearch -exact $ccross $p] >= 0} continue
+                    if {$x == $px + ($kidx < $px? -1: 1)} {
+                        lappend ccross $p
+                    } elseif {[lsearch -exact $cross $p] < 0} {
+                        lappend cross $p
+                    }
+                }
+            }
+        }
     }
     return [concat $ccross {{}} $cross]
 }
@@ -6469,58 +6487,58 @@
     if {[info exists colormap($id)]} return
     set ncolors [llength $colors]
     if {[info exists children($curview,$id)]} {
-	set kids $children($curview,$id)
+        set kids $children($curview,$id)
     } else {
-	set kids {}
+        set kids {}
     }
     if {[llength $kids] == 1} {
-	set child [lindex $kids 0]
-	if {[info exists colormap($child)]
-	    && [llength $parents($curview,$child)] == 1} {
-	    set colormap($id) $colormap($child)
-	    return
-	}
+        set child [lindex $kids 0]
+        if {[info exists colormap($child)]
+            && [llength $parents($curview,$child)] == 1} {
+            set colormap($id) $colormap($child)
+            return
+        }
     }
     set badcolors {}
     set origbad {}
     foreach x [findcrossings $id] {
-	if {$x eq {}} {
-	    # delimiter between corner crossings and other crossings
-	    if {[llength $badcolors] >= $ncolors - 1} break
-	    set origbad $badcolors
-	}
-	if {[info exists colormap($x)]
-	    && [lsearch -exact $badcolors $colormap($x)] < 0} {
-	    lappend badcolors $colormap($x)
-	}
+        if {$x eq {}} {
+            # delimiter between corner crossings and other crossings
+            if {[llength $badcolors] >= $ncolors - 1} break
+            set origbad $badcolors
+        }
+        if {[info exists colormap($x)]
+            && [lsearch -exact $badcolors $colormap($x)] < 0} {
+            lappend badcolors $colormap($x)
+        }
     }
     if {[llength $badcolors] >= $ncolors} {
-	set badcolors $origbad
+        set badcolors $origbad
     }
     set origbad $badcolors
     if {[llength $badcolors] < $ncolors - 1} {
-	foreach child $kids {
-	    if {[info exists colormap($child)]
-		&& [lsearch -exact $badcolors $colormap($child)] < 0} {
-		lappend badcolors $colormap($child)
-	    }
-	    foreach p $parents($curview,$child) {
-		if {[info exists colormap($p)]
-		    && [lsearch -exact $badcolors $colormap($p)] < 0} {
-		    lappend badcolors $colormap($p)
-		}
-	    }
-	}
-	if {[llength $badcolors] >= $ncolors} {
-	    set badcolors $origbad
-	}
+        foreach child $kids {
+            if {[info exists colormap($child)]
+                && [lsearch -exact $badcolors $colormap($child)] < 0} {
+                lappend badcolors $colormap($child)
+            }
+            foreach p $parents($curview,$child) {
+                if {[info exists colormap($p)]
+                    && [lsearch -exact $badcolors $colormap($p)] < 0} {
+                    lappend badcolors $colormap($p)
+                }
+            }
+        }
+        if {[llength $badcolors] >= $ncolors} {
+            set badcolors $origbad
+        }
     }
     for {set i 0} {$i <= $ncolors} {incr i} {
-	set c [lindex $colors $nextcolor]
-	if {[incr nextcolor] >= $ncolors} {
-	    set nextcolor 0
-	}
-	if {[lsearch -exact $badcolors $c]} break
+        set c [lindex $colors $nextcolor]
+        if {[incr nextcolor] >= $ncolors} {
+            set nextcolor 0
+        }
+        if {[lsearch -exact $badcolors $c]} break
     }
     set colormap($id) $c
 }
@@ -6538,9 +6556,9 @@
     global use_ttk
 
     if {$use_ttk} {
-	set g [.tf.histframe.pwclist sashpos 0]
+        set g [.tf.histframe.pwclist sashpos 0]
     } else {
-	set g [.tf.histframe.pwclist sash coord 0]
+        set g [.tf.histframe.pwclist sash coord 0]
     }
     return [lindex $g 0]
 }
@@ -6548,7 +6566,7 @@
 proc totalwidth {l font extra} {
     set tot 0
     foreach str $l {
-	set tot [expr {$tot + [font measure $font $str] + $extra}]
+        set tot [expr {$tot + [font measure $font $str] + $extra}]
     }
     return $tot
 }
@@ -6572,29 +6590,29 @@
     set extra [expr {$delta + $lthickness + $linespc}]
 
     if {[info exists idtags($id)]} {
-	set marks $idtags($id)
-	set ntags [llength $marks]
-	if {$ntags > $maxtags ||
-	    [totalwidth $marks mainfont $extra] > $maxwidth} {
-	    # show just a single "n tags..." tag
-	    set singletag 1
-	    if {$ntags == 1} {
-		set marks [list "tag..."]
-	    } else {
-		set marks [list [format "%d tags..." $ntags]]
-	    }
-	    set ntags 1
-	}
+        set marks $idtags($id)
+        set ntags [llength $marks]
+        if {$ntags > $maxtags ||
+            [totalwidth $marks mainfont $extra] > $maxwidth} {
+            # show just a single "n tags..." tag
+            set singletag 1
+            if {$ntags == 1} {
+                set marks [list "tag..."]
+            } else {
+                set marks [list [format "%d tags..." $ntags]]
+            }
+            set ntags 1
+        }
     }
     if {[info exists idheads($id)]} {
-	set marks [concat $marks $idheads($id)]
-	set nheads [llength $idheads($id)]
+        set marks [concat $marks $idheads($id)]
+        set nheads [llength $idheads($id)]
     }
     if {[info exists idotherrefs($id)]} {
-	set marks [concat $marks $idotherrefs($id)]
+        set marks [concat $marks $idotherrefs($id)]
     }
     if {$marks eq {}} {
-	return $xt
+        return $xt
     }
 
     set yt [expr {$y1 - 0.5 * $linespc}]
@@ -6603,66 +6621,66 @@
     set wvals {}
     set i -1
     foreach tag $marks {
-	incr i
-	if {$i >= $ntags && $i < $ntags + $nheads && $tag eq $mainhead} {
-	    set wid [font measure mainfontbold $tag]
-	} else {
-	    set wid [font measure mainfont $tag]
-	}
-	lappend xvals $xt
-	lappend wvals $wid
-	set xt [expr {$xt + $wid + $extra}]
+        incr i
+        if {$i >= $ntags && $i < $ntags + $nheads && $tag eq $mainhead} {
+            set wid [font measure mainfontbold $tag]
+        } else {
+            set wid [font measure mainfont $tag]
+        }
+        lappend xvals $xt
+        lappend wvals $wid
+        set xt [expr {$xt + $wid + $extra}]
     }
     set t [$canv create line $x $y1 [lindex $xvals end] $y1 \
-	       -width $lthickness -fill $reflinecolor -tags tag.$id]
+               -width $lthickness -fill $reflinecolor -tags tag.$id]
     $canv lower $t
     foreach tag $marks x $xvals wid $wvals {
-	set tag_quoted [string map {% %%} $tag]
-	set xl [expr {$x + $delta}]
-	set xr [expr {$x + $delta + $wid + $lthickness}]
-	set font mainfont
-	if {[incr ntags -1] >= 0} {
-	    # draw a tag
-	    set t [$canv create polygon $x [expr {$yt + $delta}] $xl $yt \
-		       $xr $yt $xr $yb $xl $yb $x [expr {$yb - $delta}] \
-		       -width 1 -outline $tagoutlinecolor -fill $tagbgcolor \
-		       -tags tag.$id]
-	    if {$singletag} {
-		set tagclick [list showtags $id 1]
-	    } else {
-		set tagclick [list showtag $tag_quoted 1]
-	    }
-	    $canv bind $t <1> $tagclick
-	    set rowtextx([rowofcommit $id]) [expr {$xr + $linespc}]
-	} else {
-	    # draw a head or other ref
-	    if {[incr nheads -1] >= 0} {
-		set col $headbgcolor
-		if {$tag eq $mainhead} {
-		    set font mainfontbold
-		}
-	    } else {
-		set col "#ddddff"
-	    }
-	    set xl [expr {$xl - $delta/2}]
-	    $canv create polygon $x $yt $xr $yt $xr $yb $x $yb \
-		-width 1 -outline black -fill $col -tags tag.$id
-	    if {[regexp {^(remotes/.*/|remotes/)} $tag match remoteprefix]} {
-	        set rwid [font measure mainfont $remoteprefix]
-		set xi [expr {$x + 1}]
-		set yti [expr {$yt + 1}]
-		set xri [expr {$x + $rwid}]
-		$canv create polygon $xi $yti $xri $yti $xri $yb $xi $yb \
-			-width 0 -fill $remotebgcolor -tags tag.$id
-	    }
-	}
-	set t [$canv create text $xl $y1 -anchor w -text $tag -fill $headfgcolor \
-		   -font $font -tags [list tag.$id text]]
-	if {$ntags >= 0} {
-	    $canv bind $t <1> $tagclick
-	} elseif {$nheads >= 0} {
-	    $canv bind $t $ctxbut [list headmenu %X %Y $id $tag_quoted]
-	}
+        set tag_quoted [string map {% %%} $tag]
+        set xl [expr {$x + $delta}]
+        set xr [expr {$x + $delta + $wid + $lthickness}]
+        set font mainfont
+        if {[incr ntags -1] >= 0} {
+            # draw a tag
+            set t [$canv create polygon $x [expr {$yt + $delta}] $xl $yt \
+                       $xr $yt $xr $yb $xl $yb $x [expr {$yb - $delta}] \
+                       -width 1 -outline $tagoutlinecolor -fill $tagbgcolor \
+                       -tags tag.$id]
+            if {$singletag} {
+                set tagclick [list showtags $id 1]
+            } else {
+                set tagclick [list showtag $tag_quoted 1]
+            }
+            $canv bind $t <1> $tagclick
+            set rowtextx([rowofcommit $id]) [expr {$xr + $linespc}]
+        } else {
+            # draw a head or other ref
+            if {[incr nheads -1] >= 0} {
+                set col $headbgcolor
+                if {$tag eq $mainhead} {
+                    set font mainfontbold
+                }
+            } else {
+                set col "#ddddff"
+            }
+            set xl [expr {$xl - $delta/2}]
+            $canv create polygon $x $yt $xr $yt $xr $yb $x $yb \
+                -width 1 -outline black -fill $col -tags tag.$id
+            if {[regexp {^(remotes/.*/|remotes/)} $tag match remoteprefix]} {
+                set rwid [font measure mainfont $remoteprefix]
+                set xi [expr {$x + 1}]
+                set yti [expr {$yt + 1}]
+                set xri [expr {$x + $rwid}]
+                $canv create polygon $xi $yti $xri $yti $xri $yb $xi $yb \
+                        -width 0 -fill $remotebgcolor -tags tag.$id
+            }
+        }
+        set t [$canv create text $xl $y1 -anchor w -text $tag -fill $headfgcolor \
+                   -font $font -tags [list tag.$id text]]
+        if {$ntags >= 0} {
+            $canv bind $t <1> $tagclick
+        } elseif {$nheads >= 0} {
+            $canv bind $t $ctxbut [list headmenu %X %Y $id $tag_quoted]
+        }
     }
     return $xt
 }
@@ -6672,8 +6690,8 @@
 
     set orad [expr {$linespc / 3}]
     set t [$canv create rectangle [expr {$xt - $orad}] [expr {$y - $orad}] \
-	       [expr {$xt + $orad - 1}] [expr {$y + $orad - 1}] \
-	       -fill yellow -outline $fgcolor -width 1 -tags circle]
+               [expr {$xt + $orad - 1}] [expr {$y + $orad - 1}] \
+               -fill yellow -outline $fgcolor -width 1 -tags circle]
     set xt [expr {$xt + $orad * 3}]
     return $xt
 }
@@ -6683,9 +6701,9 @@
 
     set x [expr {$canvx0 + $i * $xspc1($ln)}]
     if {$i > 0 && $i == $level} {
-	set x [expr {$x + 0.5 * ($xspc2 - $xspc1($ln))}]
+        set x [expr {$x + 0.5 * ($xspc2 - $xspc1($ln))}]
     } elseif {$i > $level} {
-	set x [expr {$x + $xspc2 - $xspc1($ln)}]
+        set x [expr {$x + $xspc2 - $xspc1($ln)}]
     }
     return $x
 }
@@ -6696,7 +6714,7 @@
     clear_display
     set_window_title
     $canv create text 3 3 -anchor nw -text $msg -font mainfont \
-	-tags text -fill $fgcolor
+        -tags text -fill $fgcolor
 }
 
 # Don't change the text pane cursor if it is currently the hand cursor,
@@ -6705,7 +6723,7 @@
     global ctext curtextcursor
 
     if {[$ctext cget -cursor] == $curtextcursor} {
-	$ctext config -cursor $c
+        $ctext config -cursor $c
     }
     set curtextcursor $c
 }
@@ -6714,13 +6732,13 @@
     global isbusy busyname statusw
 
     if {[array names isbusy] eq {}} {
-	. config -cursor watch
-	settextcursor watch
+        . config -cursor watch
+        settextcursor watch
     }
     set isbusy($what) 1
     set busyname($what) $name
     if {$name ne {}} {
-	$statusw conf -text $name
+        $statusw conf -text $name
     }
 }
 
@@ -6728,35 +6746,35 @@
     global isbusy maincursor textcursor busyname statusw
 
     catch {
-	unset isbusy($what)
-	if {$busyname($what) ne {} &&
-	    [$statusw cget -text] eq $busyname($what)} {
-	    $statusw conf -text {}
-	}
+        unset isbusy($what)
+        if {$busyname($what) ne {} &&
+            [$statusw cget -text] eq $busyname($what)} {
+            $statusw conf -text {}
+        }
     }
     if {[array names isbusy] eq {}} {
-	. config -cursor $maincursor
-	settextcursor $textcursor
+        . config -cursor $maincursor
+        settextcursor $textcursor
     }
 }
 
 proc findmatches {f} {
     global findtype findstring
     if {$findtype == [mc "Regexp"]} {
-	set matches [regexp -indices -all -inline $findstring $f]
+        set matches [regexp -indices -all -inline $findstring $f]
     } else {
-	set fs $findstring
-	if {$findtype == [mc "IgnCase"]} {
-	    set f [string tolower $f]
-	    set fs [string tolower $fs]
-	}
-	set matches {}
-	set i 0
-	set l [string length $fs]
-	while {[set j [string first $fs $f $i]] >= 0} {
-	    lappend matches [list $j [expr {$j+$l-1}]]
-	    set i [expr {$j + $l}]
-	}
+        set fs $findstring
+        if {$findtype == [mc "IgnCase"]} {
+            set f [string tolower $f]
+            set fs [string tolower $fs]
+        }
+        set matches {}
+        set i 0
+        set l [string length $fs]
+        while {[set j [string first $fs $f $i]] >= 0} {
+            lappend matches [list $j [expr {$j+$l-1}]]
+            set i [expr {$j + $l}]
+        }
     }
     return $matches
 }
@@ -6766,21 +6784,21 @@
     global gdttype filehighlight fh_serial find_dirn findallowwrap
 
     if {[info exists find_dirn]} {
-	if {$find_dirn == $dirn} return
-	stopfinding
+        if {$find_dirn == $dirn} return
+        stopfinding
     }
     focus .
     if {$findstring eq {} || $numcommits == 0} return
     if {$selectedline eq {}} {
-	set findstartline [lindex [visiblerows] [expr {$dirn < 0}]]
+        set findstartline [lindex [visiblerows] [expr {$dirn < 0}]]
     } else {
-	set findstartline $selectedline
+        set findstartline $selectedline
     }
     set findcurline $findstartline
     nowbusy finding [mc "Searching"]
     if {$gdttype ne [mc "containing:"] && ![info exists filehighlight]} {
-	after cancel do_file_hl $fh_serial
-	do_file_hl $fh_serial
+        after cancel do_file_hl $fh_serial
+        do_file_hl $fh_serial
     }
     set find_dirn $dirn
     set findallowwrap $wrap
@@ -6791,11 +6809,11 @@
     global find_dirn findcurline fprogcoord
 
     if {[info exists find_dirn]} {
-	unset find_dirn
-	unset findcurline
-	notbusy finding
-	set fprogcoord 0
-	adjustprogress
+        unset find_dirn
+        unset findcurline
+        notbusy finding
+        set fprogcoord 0
+        adjustprogress
     }
     stopblaming
 }
@@ -6807,41 +6825,41 @@
     global curview varcorder vrownum varccommits vrowmod
 
     if {![info exists find_dirn]} {
-	return 0
+        return 0
     }
     set fldtypes [list [mc "Headline"] [mc "Author"] "" [mc "Committer"] "" [mc "Comments"]]
     set l $findcurline
     set moretodo 0
     if {$find_dirn > 0} {
-	incr l
-	if {$l >= $numcommits} {
-	    set l 0
-	}
-	if {$l <= $findstartline} {
-	    set lim [expr {$findstartline + 1}]
-	} else {
-	    set lim $numcommits
-	    set moretodo $findallowwrap
-	}
+        incr l
+        if {$l >= $numcommits} {
+            set l 0
+        }
+        if {$l <= $findstartline} {
+            set lim [expr {$findstartline + 1}]
+        } else {
+            set lim $numcommits
+            set moretodo $findallowwrap
+        }
     } else {
-	if {$l == 0} {
-	    set l $numcommits
-	}
-	incr l -1
-	if {$l >= $findstartline} {
-	    set lim [expr {$findstartline - 1}]
-	} else {
-	    set lim -1
-	    set moretodo $findallowwrap
-	}
+        if {$l == 0} {
+            set l $numcommits
+        }
+        incr l -1
+        if {$l >= $findstartline} {
+            set lim [expr {$findstartline - 1}]
+        } else {
+            set lim -1
+            set moretodo $findallowwrap
+        }
     }
     set n [expr {($lim - $l) * $find_dirn}]
     if {$n > 500} {
-	set n 500
-	set moretodo 1
+        set n 500
+        set moretodo 1
     }
     if {$l + ($find_dirn > 0? $n: 1) > $vrowmod($curview)} {
-	update_arcrows $curview
+        update_arcrows $curview
     }
     set found 0
     set domore 1
@@ -6851,81 +6869,81 @@
     set ids [lindex $varccommits($curview,$a)]
     set arowend [expr {$arow + [llength $ids]}]
     if {$gdttype eq [mc "containing:"]} {
-	for {} {$n > 0} {incr n -1; incr l $find_dirn} {
-	    if {$l < $arow || $l >= $arowend} {
-		incr ai $find_dirn
-		set a [lindex $varcorder($curview) $ai]
-		set arow [lindex $vrownum($curview) $ai]
-		set ids [lindex $varccommits($curview,$a)]
-		set arowend [expr {$arow + [llength $ids]}]
-	    }
-	    set id [lindex $ids [expr {$l - $arow}]]
-	    # shouldn't happen unless git log doesn't give all the commits...
-	    if {![info exists commitdata($id)] ||
-		![doesmatch $commitdata($id)]} {
-		continue
-	    }
-	    if {![info exists commitinfo($id)]} {
-		getcommit $id
-	    }
-	    set info $commitinfo($id)
-	    foreach f $info ty $fldtypes {
-		if {$ty eq ""} continue
-		if {($findloc eq [mc "All fields"] || $findloc eq $ty) &&
-		    [doesmatch $f]} {
-		    set found 1
-		    break
-		}
-	    }
-	    if {$found} break
-	}
+        for {} {$n > 0} {incr n -1; incr l $find_dirn} {
+            if {$l < $arow || $l >= $arowend} {
+                incr ai $find_dirn
+                set a [lindex $varcorder($curview) $ai]
+                set arow [lindex $vrownum($curview) $ai]
+                set ids [lindex $varccommits($curview,$a)]
+                set arowend [expr {$arow + [llength $ids]}]
+            }
+            set id [lindex $ids [expr {$l - $arow}]]
+            # shouldn't happen unless git log doesn't give all the commits...
+            if {![info exists commitdata($id)] ||
+                ![doesmatch $commitdata($id)]} {
+                continue
+            }
+            if {![info exists commitinfo($id)]} {
+                getcommit $id
+            }
+            set info $commitinfo($id)
+            foreach f $info ty $fldtypes {
+                if {$ty eq ""} continue
+                if {($findloc eq [mc "All fields"] || $findloc eq $ty) &&
+                    [doesmatch $f]} {
+                    set found 1
+                    break
+                }
+            }
+            if {$found} break
+        }
     } else {
-	for {} {$n > 0} {incr n -1; incr l $find_dirn} {
-	    if {$l < $arow || $l >= $arowend} {
-		incr ai $find_dirn
-		set a [lindex $varcorder($curview) $ai]
-		set arow [lindex $vrownum($curview) $ai]
-		set ids [lindex $varccommits($curview,$a)]
-		set arowend [expr {$arow + [llength $ids]}]
-	    }
-	    set id [lindex $ids [expr {$l - $arow}]]
-	    if {![info exists fhighlights($id)]} {
-		# this sets fhighlights($id) to -1
-		askfilehighlight $l $id
-	    }
-	    if {$fhighlights($id) > 0} {
-		set found $domore
-		break
-	    }
-	    if {$fhighlights($id) < 0} {
-		if {$domore} {
-		    set domore 0
-		    set findcurline [expr {$l - $find_dirn}]
-		}
-	    }
-	}
+        for {} {$n > 0} {incr n -1; incr l $find_dirn} {
+            if {$l < $arow || $l >= $arowend} {
+                incr ai $find_dirn
+                set a [lindex $varcorder($curview) $ai]
+                set arow [lindex $vrownum($curview) $ai]
+                set ids [lindex $varccommits($curview,$a)]
+                set arowend [expr {$arow + [llength $ids]}]
+            }
+            set id [lindex $ids [expr {$l - $arow}]]
+            if {![info exists fhighlights($id)]} {
+                # this sets fhighlights($id) to -1
+                askfilehighlight $l $id
+            }
+            if {$fhighlights($id) > 0} {
+                set found $domore
+                break
+            }
+            if {$fhighlights($id) < 0} {
+                if {$domore} {
+                    set domore 0
+                    set findcurline [expr {$l - $find_dirn}]
+                }
+            }
+        }
     }
     if {$found || ($domore && !$moretodo)} {
-	unset findcurline
-	unset find_dirn
-	notbusy finding
-	set fprogcoord 0
-	adjustprogress
-	if {$found} {
-	    findselectline $l
-	} else {
-	    bell
-	}
-	return 0
+        unset findcurline
+        unset find_dirn
+        notbusy finding
+        set fprogcoord 0
+        adjustprogress
+        if {$found} {
+            findselectline $l
+        } else {
+            bell
+        }
+        return 0
     }
     if {!$domore} {
-	flushhighlights
+        flushhighlights
     } else {
-	set findcurline [expr {$l - $find_dirn}]
+        set findcurline [expr {$l - $find_dirn}]
     }
     set n [expr {($findcurline - $findstartline) * $find_dirn - 1}]
     if {$n < 0} {
-	incr n $numcommits
+        incr n $numcommits
     }
     set fprogcoord [expr {$n * 1.0 / $numcommits}]
     adjustprogress
@@ -6939,15 +6957,15 @@
     set findcurline $l
     selectline $l 1
     if {$markingmatches &&
-	($findloc eq [mc "All fields"] || $findloc eq [mc "Comments"])} {
-	# highlight the matches in the comments
-	set f [$ctext get 1.0 $commentend]
-	set matches [findmatches $f]
-	foreach match $matches {
-	    set start [lindex $match 0]
-	    set end [expr {[lindex $match 1] + 1}]
-	    $ctext tag add found "1.0 + $start c" "1.0 + $end c"
-	}
+        ($findloc eq [mc "All fields"] || $findloc eq [mc "Comments"])} {
+        # highlight the matches in the comments
+        set f [$ctext get 1.0 $commentend]
+        set matches [findmatches $f]
+        foreach match $matches {
+            set start [lindex $match 0]
+            set end [expr {[lindex $match 1] + 1}]
+            $ctext tag add found "1.0 + $start c" "1.0 + $end c"
+        }
     }
     drawvisible
 }
@@ -6961,18 +6979,18 @@
     set y0 [lindex $bbox 1]
     set y1 [lindex $bbox 3]
     foreach match $matches {
-	set start [lindex $match 0]
-	set end [lindex $match 1]
-	if {$start > $end} continue
-	set xoff [font measure $font [string range $str 0 [expr {$start-1}]]]
-	set xlen [font measure $font [string range $str 0 [expr {$end}]]]
-	set t [$canv create rect [expr {$x0+$xoff}] $y0 \
-		   [expr {$x0+$xlen+2}] $y1 \
-		   -outline {} -tags [list match$l matches] -fill yellow]
-	$canv lower $t
-	if {$row == $selectedline} {
-	    $canv raise $t secsel
-	}
+        set start [lindex $match 0]
+        set end [lindex $match 1]
+        if {$start > $end} continue
+        set xoff [font measure $font [string range $str 0 [expr {$start-1}]]]
+        set xlen [font measure $font [string range $str 0 [expr {$end}]]]
+        set t [$canv create rect [expr {$x0+$xoff}] $y0 \
+                   [expr {$x0+$xlen+2}] $y1 \
+                   -outline {} -tags [list match$l matches] -fill yellow]
+        $canv lower $t
+        if {$row == $selectedline} {
+            $canv raise $t secsel
+        }
     }
 }
 
@@ -6993,12 +7011,12 @@
     set y [expr {$y + $yfrac * $ymax}]
     set l [expr {int(($y - $canvy0) / $linespc + 0.5)}]
     if {$l < 0} {
-	set l 0
+        set l 0
     }
     if {$w eq $canv} {
-	set xmax [lindex [$canv cget -scrollregion] 2]
-	set xleft [expr {[lindex [$canv xview] 0] * $xmax}]
-	if {![info exists rowtextx($l)] || $xleft + $x < $rowtextx($l)} return
+        set xmax [lindex [$canv cget -scrollregion] 2]
+        set xleft [expr {[lindex [$canv xview] 0] * $xmax}]
+        if {![info exists rowtextx($l)] || $xleft + $x < $rowtextx($l)} return
     }
     unmarkmatches
     selectline $l 1
@@ -7007,11 +7025,11 @@
 proc commit_descriptor {p} {
     global commitinfo
     if {![info exists commitinfo($p)]} {
-	getcommit $p
+        getcommit $p
     }
     set l "..."
     if {[llength $commitinfo($p)] > 1} {
-	set l [lindex $commitinfo($p) 0]
+        set l [lindex $commitinfo($p) 0]
     }
     return "$p ($l)\n"
 }
@@ -7026,26 +7044,26 @@
     $ctext insert end $text $tags
     set links [regexp -indices -all -inline {(?:\m|-g)[0-9a-f]{6,40}\M} $text]
     foreach l $links {
-	set s [lindex $l 0]
-	set e [lindex $l 1]
-	set linkid [string range $text $s $e]
-	incr e
-	$ctext tag delete link$linknum
-	$ctext tag add link$linknum "$start + $s c" "$start + $e c"
-	setlink $linkid link$linknum
-	incr linknum
+        set s [lindex $l 0]
+        set e [lindex $l 1]
+        set linkid [string range $text $s $e]
+        incr e
+        $ctext tag delete link$linknum
+        $ctext tag add link$linknum "$start + $s c" "$start + $e c"
+        setlink $linkid link$linknum
+        incr linknum
     }
     set wlinks [regexp -indices -all -inline -line \
-		    {https?://[^[:space:]]+} $text]
+                    {https?://[^[:space:]]+} $text]
     foreach l $wlinks {
-	set s2 [lindex $l 0]
-	set e2 [lindex $l 1]
-	set url [string range $text $s2 $e2]
-	incr e2
-	$ctext tag delete link$linknum
-	$ctext tag add link$linknum "$start + $s2 c" "$start + $e2 c"
-	setwlink $url link$linknum
-	incr linknum
+        set s2 [lindex $l 0]
+        set e2 [lindex $l 1]
+        set url [string range $text $s2 $e2]
+        incr e2
+        $ctext tag delete link$linknum
+        $ctext tag add link$linknum "$start + $s2 c" "$start + $e2 c"
+        setwlink $url link$linknum
+        incr linknum
     }
 }
 
@@ -7059,23 +7077,23 @@
 
     set known 0
     if {[string length $id] < 40} {
-	set matches [longid $id]
-	if {[llength $matches] > 0} {
-	    if {[llength $matches] > 1} return
-	    set known 1
-	    set id [lindex $matches 0]
-	}
+        set matches [longid $id]
+        if {[llength $matches] > 0} {
+            if {[llength $matches] > 1} return
+            set known 1
+            set id [lindex $matches 0]
+        }
     } else {
-	set known [commitinview $id $curview]
+        set known [commitinview $id $curview]
     }
     if {$known} {
-	$ctext tag conf $lk -foreground $linkfgcolor -underline 1
-	$ctext tag bind $lk <1> [list selbyid $id]
-	$ctext tag bind $lk <Enter> {linkcursor %W 1}
-	$ctext tag bind $lk <Leave> {linkcursor %W -1}
+        $ctext tag conf $lk -foreground $linkfgcolor -underline 1
+        $ctext tag bind $lk <1> [list selbyid $id]
+        $ctext tag bind $lk <Enter> {linkcursor %W 1}
+        $ctext tag bind $lk <Leave> {linkcursor %W -1}
     } else {
-	lappend pendinglinks($id) $lk
-	interestedin $id {makelink %P}
+        lappend pendinglinks($id) $lk
+        interestedin $id {makelink %P}
     }
 }
 
@@ -7107,7 +7125,7 @@
 
     if {![info exists pendinglinks($id)]} return
     foreach lk $pendinglinks($id) {
-	setlink $id $lk
+        setlink $id $lk
     }
     unset pendinglinks($id)
 }
@@ -7116,12 +7134,12 @@
     global linkentercount curtextcursor
 
     if {[incr linkentercount $inc] > 0} {
-	$w configure -cursor hand2
+        $w configure -cursor hand2
     } else {
-	$w configure -cursor $curtextcursor
-	if {$linkentercount < 0} {
-	    set linkentercount 0
-	}
+        $w configure -cursor $curtextcursor
+        if {$linkentercount < 0} {
+            set linkentercount 0
+        }
     }
 }
 
@@ -7131,7 +7149,7 @@
     if {$web_browser eq {}} return
     # Use eval here in case $web_browser is a command plus some arguments
     if {[catch {eval exec $web_browser [list $url] &} err]} {
-	error_popup "[mc "Error starting web browser:"] $err"
+        error_popup "[mc "Error starting web browser:"] $err"
     }
 }
 
@@ -7144,9 +7162,9 @@
     set wtop [expr {[lindex $wnow 0] * $ymax}]
     set newtop [expr {$wtop + $dir * $linespc}]
     if {$newtop < 0} {
-	set newtop 0
+        set newtop 0
     } elseif {$newtop > $ymax} {
-	set newtop $ymax
+        set newtop $ymax
     }
     allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
 }
@@ -7157,15 +7175,15 @@
     global ctext linknum curview $var maxrefs visiblerefs mainheadid
 
     if {[catch {$ctext index $pos}]} {
-	return 0
+        return 0
     }
     $ctext conf -state normal
     $ctext delete $pos "$pos lineend"
     set tags {}
     foreach id $ids {
-	foreach tag [set $var\($id\)] {
-	    lappend tags [list $tag $id]
-	}
+        foreach tag [set $var\($id\)] {
+            lappend tags [list $tag $id]
+        }
     }
 
     set sep {}
@@ -7173,44 +7191,44 @@
     set nutags 0
 
     if {[llength $tags] > $maxrefs} {
-	# If we are displaying heads, and there are too many,
-	# see if there are some important heads to display.
-	# Currently that are the current head and heads listed in $visiblerefs option
-	set itags {}
-	if {$var eq "idheads"} {
-	    set utags {}
-	    foreach ti $tags {
-		set hname [lindex $ti 0]
-		set id [lindex $ti 1]
-		if {([lsearch -exact $visiblerefs $hname] != -1 || $id eq $mainheadid) &&
-		    [llength $itags] < $maxrefs} {
-		    lappend itags $ti
-		} else {
-		    lappend utags $ti
-		}
-	    }
-	    set tags $utags
-	}
-	if {$itags ne {}} {
-	    set str [mc "and many more"]
-	    set sep " "
-	} else {
-	    set str [mc "many"]
-	}
-	$ctext insert $pos "$str ([llength $tags])"
-	set nutags [llength $tags]
-	set tags $itags
+        # If we are displaying heads, and there are too many,
+        # see if there are some important heads to display.
+        # Currently that are the current head and heads listed in $visiblerefs option
+        set itags {}
+        if {$var eq "idheads"} {
+            set utags {}
+            foreach ti $tags {
+                set hname [lindex $ti 0]
+                set id [lindex $ti 1]
+                if {([lsearch -exact $visiblerefs $hname] != -1 || $id eq $mainheadid) &&
+                    [llength $itags] < $maxrefs} {
+                    lappend itags $ti
+                } else {
+                    lappend utags $ti
+                }
+            }
+            set tags $utags
+        }
+        if {$itags ne {}} {
+            set str [mc "and many more"]
+            set sep " "
+        } else {
+            set str [mc "many"]
+        }
+        $ctext insert $pos "$str ([llength $tags])"
+        set nutags [llength $tags]
+        set tags $itags
     }
 
     foreach ti $tags {
-	set id [lindex $ti 1]
-	set lk link$linknum
-	incr linknum
-	$ctext tag delete $lk
-	$ctext insert $pos $sep
-	$ctext insert $pos [lindex $ti 0] $lk
-	setlink $id $lk
-	set sep ", "
+        set id [lindex $ti 1]
+        set lk link$linknum
+        incr linknum
+        $ctext tag delete $lk
+        $ctext insert $pos $sep
+        $ctext insert $pos [lindex $ti 0] $lk
+        setlink $id $lk
+        set sep ", "
     }
     $ctext tag add wwrap "$pos linestart" "$pos lineend"
     $ctext conf -state disabled
@@ -7224,11 +7242,11 @@
     if {$selectedline eq {} || !$showneartags} return
     after cancel dispnexttag
     if {$delay} {
-	after 200 dispnexttag
-	set tagphase -1
+        after 200 dispnexttag
+        set tagphase -1
     } else {
-	after idle dispnexttag
-	set tagphase 0
+        after idle dispnexttag
+        set tagphase 0
     }
 }
 
@@ -7237,33 +7255,33 @@
 
     if {$selectedline eq {} || !$showneartags} return
     switch -- $tagphase {
-	0 {
-	    set dtags [desctags $currentid]
-	    if {$dtags ne {}} {
-		appendrefs precedes $dtags idtags
-	    }
-	}
-	1 {
-	    set atags [anctags $currentid]
-	    if {$atags ne {}} {
-		appendrefs follows $atags idtags
-	    }
-	}
-	2 {
-	    set dheads [descheads $currentid]
-	    if {$dheads ne {}} {
-		if {[appendrefs branch $dheads idheads] > 1
-		    && [$ctext get "branch -3c"] eq "h"} {
-		    # turn "Branch" into "Branches"
-		    $ctext conf -state normal
-		    $ctext insert "branch -2c" "es"
-		    $ctext conf -state disabled
-		}
-	    }
-	}
+        0 {
+            set dtags [desctags $currentid]
+            if {$dtags ne {}} {
+                appendrefs precedes $dtags idtags
+            }
+        }
+        1 {
+            set atags [anctags $currentid]
+            if {$atags ne {}} {
+                appendrefs follows $atags idtags
+            }
+        }
+        2 {
+            set dheads [descheads $currentid]
+            if {$dheads ne {}} {
+                if {[appendrefs branch $dheads idheads] > 1
+                    && [$ctext get "branch -3c"] eq "h"} {
+                    # turn "Branch" into "Branches"
+                    $ctext conf -state normal
+                    $ctext insert "branch -2c" "es"
+                    $ctext conf -state disabled
+                }
+            }
+        }
     }
     if {[incr tagphase] <= 2} {
-	after idle dispnexttag
+        after idle dispnexttag
     }
 }
 
@@ -7273,15 +7291,15 @@
     if {![info exists linehtag($id)]} return
     $canv delete secsel
     set t [eval $canv create rect [$canv bbox $linehtag($id)] -outline {{}} \
-	       -tags secsel -fill [$canv cget -selectbackground]]
+               -tags secsel -fill [$canv cget -selectbackground]]
     $canv lower $t
     $canv2 delete secsel
     set t [eval $canv2 create rect [$canv2 bbox $linentag($id)] -outline {{}} \
-	       -tags secsel -fill [$canv2 cget -selectbackground]]
+               -tags secsel -fill [$canv2 cget -selectbackground]]
     $canv2 lower $t
     $canv3 delete secsel
     set t [eval $canv3 create rect [$canv3 bbox $linedtag($id)] -outline {{}} \
-	       -tags secsel -fill [$canv3 cget -selectbackground]]
+               -tags secsel -fill [$canv3 cget -selectbackground]]
     $canv3 lower $t
 }
 
@@ -7291,7 +7309,7 @@
     if {![info exists linehtag($id)]} return
     $canv delete markid
     set t [eval $canv create rect [$canv bbox $linehtag($id)] \
-	       -tags markid -outline $fgcolor]
+               -tags markid -outline $fgcolor]
     $canv raise $t
 }
 
@@ -7318,7 +7336,7 @@
     set selectedline $l
     set currentid $id
     if {$lastscrollrows < $numcommits} {
-	setcanvscroll
+        setcanvscroll
     }
 
     if {$cmitmode ne "patch" && $switch_to_patch} {
@@ -7335,42 +7353,42 @@
     set wh [expr {$wbot - $wtop}]
     set newtop $wtop
     if {$ytop < $wtop} {
-	if {$ybot < $wtop} {
-	    set newtop [expr {$y - $wh / 2.0}]
-	} else {
-	    set newtop $ytop
-	    if {$newtop > $wtop - $linespc} {
-		set newtop [expr {$wtop - $linespc}]
-	    }
-	}
+        if {$ybot < $wtop} {
+            set newtop [expr {$y - $wh / 2.0}]
+        } else {
+            set newtop $ytop
+            if {$newtop > $wtop - $linespc} {
+                set newtop [expr {$wtop - $linespc}]
+            }
+        }
     } elseif {$ybot > $wbot} {
-	if {$ytop > $wbot} {
-	    set newtop [expr {$y - $wh / 2.0}]
-	} else {
-	    set newtop [expr {$ybot - $wh}]
-	    if {$newtop < $wtop + $linespc} {
-		set newtop [expr {$wtop + $linespc}]
-	    }
-	}
+        if {$ytop > $wbot} {
+            set newtop [expr {$y - $wh / 2.0}]
+        } else {
+            set newtop [expr {$ybot - $wh}]
+            if {$newtop < $wtop + $linespc} {
+                set newtop [expr {$wtop + $linespc}]
+            }
+        }
     }
     if {$newtop != $wtop} {
-	if {$newtop < 0} {
-	    set newtop 0
-	}
-	allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
-	drawvisible
+        if {$newtop < 0} {
+            set newtop 0
+        }
+        allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
+        drawvisible
     }
 
     make_secsel $id
 
     if {$isnew} {
-	addtohistory [list selbyid $id 0] savecmitpos
+        addtohistory [list selbyid $id 0] savecmitpos
     }
 
     $sha1entry delete 0 end
     $sha1entry insert 0 $id
     if {$autoselect} {
-	$sha1entry selection range 0 $autosellen
+        $sha1entry selection range 0 $autosellen
     }
     rhighlight_sel $id
 
@@ -7378,7 +7396,7 @@
     clear_ctext
     set linknum 0
     if {![info exists commitinfo($id)]} {
-	getcommit $id
+        getcommit $id
     }
     set info $commitinfo($id)
     set date [formatdate [lindex $info 2]]
@@ -7386,59 +7404,59 @@
     set date [formatdate [lindex $info 4]]
     $ctext insert end "[mc "Committer"]: [lindex $info 3]  $date\n"
     if {[info exists idtags($id)]} {
-	$ctext insert end [mc "Tags:"]
-	foreach tag $idtags($id) {
-	    $ctext insert end " $tag"
-	}
-	$ctext insert end "\n"
+        $ctext insert end [mc "Tags:"]
+        foreach tag $idtags($id) {
+            $ctext insert end " $tag"
+        }
+        $ctext insert end "\n"
     }
 
     set headers {}
     set olds $parents($curview,$id)
     if {[llength $olds] > 1} {
-	set np 0
-	foreach p $olds {
-	    if {$np >= $mergemax} {
-		set tag mmax
-	    } else {
-		set tag m$np
-	    }
-	    $ctext insert end "[mc "Parent"]: " $tag
-	    appendwithlinks [commit_descriptor $p] {}
-	    incr np
-	}
+        set np 0
+        foreach p $olds {
+            if {$np >= $mergemax} {
+                set tag mmax
+            } else {
+                set tag m$np
+            }
+            $ctext insert end "[mc "Parent"]: " $tag
+            appendwithlinks [commit_descriptor $p] {}
+            incr np
+        }
     } else {
-	foreach p $olds {
-	    append headers "[mc "Parent"]: [commit_descriptor $p]"
-	}
+        foreach p $olds {
+            append headers "[mc "Parent"]: [commit_descriptor $p]"
+        }
     }
 
     foreach c $children($curview,$id) {
-	append headers "[mc "Child"]:  [commit_descriptor $c]"
+        append headers "[mc "Child"]:  [commit_descriptor $c]"
     }
 
     # make anything that looks like a SHA1 ID be a clickable link
     appendwithlinks $headers {}
     if {$showneartags} {
-	if {![info exists allcommits]} {
-	    getallcommits
-	}
-	$ctext insert end "[mc "Branch"]: "
-	$ctext mark set branch "end -1c"
-	$ctext mark gravity branch left
-	$ctext insert end "\n[mc "Follows"]: "
-	$ctext mark set follows "end -1c"
-	$ctext mark gravity follows left
-	$ctext insert end "\n[mc "Precedes"]: "
-	$ctext mark set precedes "end -1c"
-	$ctext mark gravity precedes left
-	$ctext insert end "\n"
-	dispneartags 1
+        if {![info exists allcommits]} {
+            getallcommits
+        }
+        $ctext insert end "[mc "Branch"]: "
+        $ctext mark set branch "end -1c"
+        $ctext mark gravity branch left
+        $ctext insert end "\n[mc "Follows"]: "
+        $ctext mark set follows "end -1c"
+        $ctext mark gravity follows left
+        $ctext insert end "\n[mc "Precedes"]: "
+        $ctext mark set precedes "end -1c"
+        $ctext mark gravity precedes left
+        $ctext insert end "\n"
+        dispneartags 1
     }
     $ctext insert end "\n"
     set comment [lindex $info 5]
     if {[string first "\r" $comment] >= 0} {
-	set comment [string map {"\r" "\n    "} $comment]
+        set comment [string map {"\r" "\n    "} $comment]
     }
     appendwithlinks $comment {comment}
 
@@ -7449,13 +7467,13 @@
     set jump_to_here $desired_loc
     init_flist [mc "Comments"]
     if {$cmitmode eq "tree"} {
-	gettree $id
+        gettree $id
     } elseif {$vinlinediff($curview) == 1} {
-	showinlinediff $id
+        showinlinediff $id
     } elseif {[llength $olds] <= 1} {
-	startdiff $id
+        startdiff $id
     } else {
-	mergediff $id
+        mergediff $id
     }
 }
 
@@ -7485,14 +7503,14 @@
 
     set lpp [expr {([winfo height $canv] - 2) / $linespc}]
     if {$lpp < 1} {
-	set lpp 1
+        set lpp 1
     }
     allcanvs yview scroll [expr {$dir * $lpp}] units
     drawvisible
     if {$selectedline eq {}} return
     set l [expr {$selectedline + $dir * $lpp}]
     if {$l < 0} {
-	set l 0
+        set l 0
     } elseif {$l >= $numcommits} {
         set l [expr $numcommits - 1]
     }
@@ -7513,7 +7531,7 @@
     global selectedline
 
     if {$selectedline ne {}} {
-	selectline $selectedline 0
+        selectline $selectedline 0
     }
 }
 
@@ -7524,20 +7542,20 @@
     save_position
     set elt [list $curview $cmd $saveproc {}]
     if {$historyindex > 0
-	&& [lindex $history [expr {$historyindex - 1}]] == $elt} {
-	return
+        && [lindex $history [expr {$historyindex - 1}]] == $elt} {
+        return
     }
 
     if {$historyindex < [llength $history]} {
-	set history [lreplace $history $historyindex end $elt]
+        set history [lreplace $history $historyindex end $elt]
     } else {
-	lappend history $elt
+        lappend history $elt
     }
     incr historyindex
     if {$historyindex > 1} {
-	.tf.bar.leftbut conf -state normal
+        .tf.bar.leftbut conf -state normal
     } else {
-	.tf.bar.leftbut conf -state disabled
+        .tf.bar.leftbut conf -state disabled
     }
     .tf.bar.rightbut conf -state disabled
 }
@@ -7550,7 +7568,7 @@
     set hi [expr {$historyindex - 1}]
     set fn [lindex $history $hi 2]
     if {$fn ne {}} {
-	lset history $hi 3 [eval $fn]
+        lset history $hi 3 [eval $fn]
     }
 }
 
@@ -7558,11 +7576,11 @@
     global last_posvars
 
     if {[info exists last_posvars]} {
-	foreach {var val} $last_posvars {
-	    global $var
-	    unset -nocomplain $var
-	}
-	unset last_posvars
+        foreach {var val} $last_posvars {
+            global $var
+            unset -nocomplain $var
+        }
+        unset last_posvars
     }
 }
 
@@ -7573,12 +7591,12 @@
     set cmd [lindex $elt 1]
     set pv [lindex $elt 3]
     if {$curview != $view} {
-	showview $view
+        showview $view
     }
     unset_posvars
     foreach {var val} $pv {
-	global $var
-	set $var $val
+        global $var
+        set $var $val
     }
     set last_posvars $pv
     eval $cmd
@@ -7589,13 +7607,13 @@
     focus .
 
     if {$historyindex > 1} {
-	save_position
-	incr historyindex -1
-	godo [lindex $history [expr {$historyindex - 1}]]
-	.tf.bar.rightbut conf -state normal
+        save_position
+        incr historyindex -1
+        godo [lindex $history [expr {$historyindex - 1}]]
+        .tf.bar.rightbut conf -state normal
     }
     if {$historyindex <= 1} {
-	.tf.bar.leftbut conf -state disabled
+        .tf.bar.leftbut conf -state disabled
     }
 }
 
@@ -7604,14 +7622,14 @@
     focus .
 
     if {$historyindex < [llength $history]} {
-	save_position
-	set cmd [lindex $history $historyindex]
-	incr historyindex
-	godo $cmd
-	.tf.bar.leftbut conf -state normal
+        save_position
+        set cmd [lindex $history $historyindex]
+        incr historyindex
+        godo $cmd
+        .tf.bar.leftbut conf -state normal
     }
     if {$historyindex >= [llength $history]} {
-	.tf.bar.rightbut conf -state disabled
+        .tf.bar.rightbut conf -state disabled
     }
 }
 
@@ -7619,7 +7637,7 @@
     global parents curview targetid
     set ps $parents($curview,$targetid)
     if {[llength $ps] >= $i} {
-	selbyid [lindex $ps [expr $i - 1]]
+        selbyid [lindex $ps [expr $i - 1]]
     }
 }
 
@@ -7630,25 +7648,25 @@
     set diffids $id
     unset -nocomplain diffmergeid
     if {![info exists treefilelist($id)]} {
-	if {![info exists treepending]} {
-	    if {$id eq $nullid} {
-		set cmd [list | git ls-files]
-	    } elseif {$id eq $nullid2} {
-		set cmd [list | git ls-files --stage -t]
-	    } else {
-		set cmd [list | git ls-tree -r $id]
-	    }
-	    if {[catch {set gtf [open $cmd r]}]} {
-		return
-	    }
-	    set treepending $id
-	    set treefilelist($id) {}
-	    set treeidlist($id) {}
-	    fconfigure $gtf -blocking 0 -encoding binary
-	    filerun $gtf [list gettreeline $gtf $id]
-	}
+        if {![info exists treepending]} {
+            if {$id eq $nullid} {
+                set cmd [list | git ls-files]
+            } elseif {$id eq $nullid2} {
+                set cmd [list | git ls-files --stage -t]
+            } else {
+                set cmd [list | git ls-tree -r $id]
+            }
+            if {[catch {set gtf [open $cmd r]}]} {
+                return
+            }
+            set treepending $id
+            set treefilelist($id) {}
+            set treeidlist($id) {}
+            fconfigure $gtf -blocking 0 -encoding binary
+            filerun $gtf [list gettreeline $gtf $id]
+        }
     } else {
-	setfilelist $id
+        setfilelist $id
     }
 }
 
@@ -7657,36 +7675,36 @@
 
     set nl 0
     while {[incr nl] <= 1000 && [gets $gtf line] >= 0} {
-	if {$diffids eq $nullid} {
-	    set fname $line
-	} else {
-	    set i [string first "\t" $line]
-	    if {$i < 0} continue
-	    set fname [string range $line [expr {$i+1}] end]
-	    set line [string range $line 0 [expr {$i-1}]]
-	    if {$diffids ne $nullid2 && [lindex $line 1] ne "blob"} continue
-	    set sha1 [lindex $line 2]
-	    lappend treeidlist($id) $sha1
-	}
-	if {[string index $fname 0] eq "\""} {
-	    set fname [lindex $fname 0]
-	}
-	set fname [encoding convertfrom $fname]
-	lappend treefilelist($id) $fname
+        if {$diffids eq $nullid} {
+            set fname $line
+        } else {
+            set i [string first "\t" $line]
+            if {$i < 0} continue
+            set fname [string range $line [expr {$i+1}] end]
+            set line [string range $line 0 [expr {$i-1}]]
+            if {$diffids ne $nullid2 && [lindex $line 1] ne "blob"} continue
+            set sha1 [lindex $line 2]
+            lappend treeidlist($id) $sha1
+        }
+        if {[string index $fname 0] eq "\""} {
+            set fname [lindex $fname 0]
+        }
+        set fname [encoding convertfrom $fname]
+        lappend treefilelist($id) $fname
     }
     if {![eof $gtf]} {
-	return [expr {$nl >= 1000? 2: 1}]
+        return [expr {$nl >= 1000? 2: 1}]
     }
     close $gtf
     unset treepending
     if {$cmitmode ne "tree"} {
-	if {![info exists diffmergeid]} {
-	    gettreediffs $diffids
-	}
+        if {![info exists diffmergeid]} {
+            gettreediffs $diffids
+        }
     } elseif {$id ne $diffids} {
-	gettree $diffids
+        gettree $diffids
     } else {
-	setfilelist $id
+        setfilelist $id
     }
     return 0
 }
@@ -7698,20 +7716,20 @@
 
     set i [lsearch -exact $treefilelist($diffids) $f]
     if {$i < 0} {
-	puts "oops, $f not in list for id $diffids"
-	return
+        puts "oops, $f not in list for id $diffids"
+        return
     }
     if {$diffids eq $nullid} {
-	if {[catch {set bf [open $f r]} err]} {
-	    puts "oops, can't read $f: $err"
-	    return
-	}
+        if {[catch {set bf [open $f r]} err]} {
+            puts "oops, can't read $f: $err"
+            return
+        }
     } else {
-	set blob [lindex $treeidlist($diffids) $i]
-	if {[catch {set bf [open [concat | git cat-file blob $blob] r]} err]} {
-	    puts "oops, error reading blob $blob: $err"
-	    return
-	}
+        set blob [lindex $treeidlist($diffids) $i]
+        if {[catch {set bf [open [concat | git cat-file blob $blob] r]} err]} {
+            puts "oops, error reading blob $blob: $err"
+            return
+        }
     }
     fconfigure $bf -blocking 0 -encoding [get_path_encoding $f]
     filerun $bf [list getblobline $bf $diffids]
@@ -7730,28 +7748,28 @@
     global diffids cmitmode ctext
 
     if {$id ne $diffids || $cmitmode ne "tree"} {
-	catch {close $bf}
-	return 0
+        catch {close $bf}
+        return 0
     }
     $ctext config -state normal
     set nl 0
     while {[incr nl] <= 1000 && [gets $bf line] >= 0} {
-	$ctext insert end "$line\n"
+        $ctext insert end "$line\n"
     }
     if {[eof $bf]} {
-	global jump_to_here ctext_file_names commentend
+        global jump_to_here ctext_file_names commentend
 
-	# delete last newline
-	$ctext delete "end - 2c" "end - 1c"
-	close $bf
-	if {$jump_to_here ne {} &&
-	    [lindex $jump_to_here 0] eq [lindex $ctext_file_names 0]} {
-	    set lnum [expr {[lindex $jump_to_here 1] +
-			    [lindex [split $commentend .] 0]}]
-	    mark_ctext_line $lnum
-	}
-	$ctext config -state disabled
-	return 0
+        # delete last newline
+        $ctext delete "end - 2c" "end - 1c"
+        close $bf
+        if {$jump_to_here ne {} &&
+            [lindex $jump_to_here 0] eq [lindex $ctext_file_names 0]} {
+            set lnum [expr {[lindex $jump_to_here 1] +
+                            [lindex [split $commentend .] 0]}]
+            mark_ctext_line $lnum
+        }
+        $ctext config -state disabled
+        return 0
     }
     $ctext config -state disabled
     return [expr {$nl >= 1000? 2: 1}]
@@ -7786,13 +7804,13 @@
     set diffids $ids
     unset -nocomplain diffmergeid
     if {![info exists treediffs($ids)] ||
-	[lsearch -exact $ids $nullid] >= 0 ||
-	[lsearch -exact $ids $nullid2] >= 0} {
-	if {![info exists treepending]} {
-	    gettreediffs $ids
-	}
+        [lsearch -exact $ids $nullid] >= 0 ||
+        [lsearch -exact $ids $nullid2] >= 0} {
+        if {![info exists treepending]} {
+            gettreediffs $ids
+        }
     } else {
-	addtocflist $ids
+        addtocflist $ids
     }
 }
 
@@ -7809,13 +7827,13 @@
 
     set inhdr 0
     foreach line $difflines {
-	if {![string compare -length 5 "diff " $line]} {
-	    set inhdr 1
-	} elseif {$inhdr && ![string compare -length 4 "+++ " $line]} {
-	    # offset also accounts for the b/ prefix
-	    lappend treediff [string range $line 6 end]
-	    set inhdr 0
-	}
+        if {![string compare -length 5 "diff " $line]} {
+            set inhdr 1
+        } elseif {$inhdr && ![string compare -length 4 "+++ " $line]} {
+            # offset also accounts for the b/ prefix
+            lappend treediff [string range $line 6 end]
+            set inhdr 0
+        }
     }
 
     set treediffs($ids) $treediff
@@ -7823,7 +7841,7 @@
 
     $ctext conf -state normal
     foreach line $difflines {
-	parseblobdiffline $ids $line
+        parseblobdiffline $ids $line
     }
     maybe_scroll_ctext 1
     $ctext conf -state disabled
@@ -7834,11 +7852,11 @@
 proc path_filter {filter name} {
     set worktree [gitworktree]
     foreach p $filter {
-	set fq_p [file normalize $p]
-	set fq_n [file normalize [file join $worktree $name]]
-	if {[string match [file normalize $fq_p]* $fq_n]} {
-	    return 1
-	}
+        set fq_p [file normalize $p]
+        set fq_n [file normalize [file join $worktree $name]]
+        if {[string match [file normalize $fq_p]* $fq_n]} {
+            return 1
+        }
     }
     return 0
 }
@@ -7856,42 +7874,42 @@
     set i [lsearch -exact $ids $nullid]
     set j [lsearch -exact $ids $nullid2]
     if {$i >= 0} {
-	if {[llength $ids] > 1 && $j < 0} {
-	    # comparing working directory with some specific revision
-	    set cmd [concat | git diff-index $flags]
-	    if {$i == 0} {
-		lappend cmd -R [lindex $ids 1]
-	    } else {
-		lappend cmd [lindex $ids 0]
-	    }
-	} else {
-	    # comparing working directory with index
-	    set cmd [concat | git diff-files $flags]
-	    if {$j == 1} {
-		lappend cmd -R
-	    }
-	}
+        if {[llength $ids] > 1 && $j < 0} {
+            # comparing working directory with some specific revision
+            set cmd [concat | git diff-index $flags]
+            if {$i == 0} {
+                lappend cmd -R [lindex $ids 1]
+            } else {
+                lappend cmd [lindex $ids 0]
+            }
+        } else {
+            # comparing working directory with index
+            set cmd [concat | git diff-files $flags]
+            if {$j == 1} {
+                lappend cmd -R
+            }
+        }
     } elseif {$j >= 0} {
-	if {[package vcompare $git_version "1.7.2"] >= 0} {
-	    set flags "$flags --ignore-submodules=dirty"
-	}
-	set cmd [concat | git diff-index --cached $flags]
-	if {[llength $ids] > 1} {
-	    # comparing index with specific revision
-	    if {$j == 0} {
-		lappend cmd -R [lindex $ids 1]
-	    } else {
-		lappend cmd [lindex $ids 0]
-	    }
-	} else {
-	    # comparing index with HEAD
-	    lappend cmd HEAD
-	}
+        if {[package vcompare $git_version "1.7.2"] >= 0} {
+            set flags "$flags --ignore-submodules=dirty"
+        }
+        set cmd [concat | git diff-index --cached $flags]
+        if {[llength $ids] > 1} {
+            # comparing index with specific revision
+            if {$j == 0} {
+                lappend cmd -R [lindex $ids 1]
+            } else {
+                lappend cmd [lindex $ids 0]
+            }
+        } else {
+            # comparing index with HEAD
+            lappend cmd HEAD
+        }
     } else {
-	if {$log_showroot} {
-	    lappend flags --root
-	}
-	set cmd [concat | git diff-tree -r $flags $ids]
+        if {$log_showroot} {
+            lappend flags --root
+        }
+        set cmd [concat | git diff-tree -r $flags $ids]
     }
     return $cmd
 }
@@ -7901,7 +7919,7 @@
 
     set cmd [diffcmd $ids {--no-commit-id}]
     if {$limitdiffs && $vfilelimit($curview) ne {}} {
-	    set cmd [concat $cmd -- $vfilelimit($curview)]
+            set cmd [concat $cmd -- $vfilelimit($curview)]
     }
     if {[catch {set gdtf [open $cmd r]}]} return
 
@@ -7919,44 +7937,44 @@
     set sublist {}
     set max 1000
     if {$perfile_attrs} {
-	# cache_gitattr is slow, and even slower on win32 where we
-	# have to invoke it for only about 30 paths at a time
-	set max 500
-	if {[tk windowingsystem] == "win32"} {
-	    set max 120
-	}
+        # cache_gitattr is slow, and even slower on win32 where we
+        # have to invoke it for only about 30 paths at a time
+        set max 500
+        if {[tk windowingsystem] == "win32"} {
+            set max 120
+        }
     }
     while {[incr nr] <= $max && [gets $gdtf line] >= 0} {
-	set i [string first "\t" $line]
-	if {$i >= 0} {
-	    set file [string range $line [expr {$i+1}] end]
-	    if {[string index $file 0] eq "\""} {
-		set file [lindex $file 0]
-	    }
-	    set file [encoding convertfrom $file]
-	    if {$file ne [lindex $treediff end]} {
-		lappend treediff $file
-		lappend sublist $file
-	    }
-	}
+        set i [string first "\t" $line]
+        if {$i >= 0} {
+            set file [string range $line [expr {$i+1}] end]
+            if {[string index $file 0] eq "\""} {
+                set file [lindex $file 0]
+            }
+            set file [encoding convertfrom $file]
+            if {$file ne [lindex $treediff end]} {
+                lappend treediff $file
+                lappend sublist $file
+            }
+        }
     }
     if {$perfile_attrs} {
-	cache_gitattr encoding $sublist
+        cache_gitattr encoding $sublist
     }
     if {![eof $gdtf]} {
-	return [expr {$nr >= $max? 2: 1}]
+        return [expr {$nr >= $max? 2: 1}]
     }
     close $gdtf
     set treediffs($ids) $treediff
     unset treepending
     if {$cmitmode eq "tree" && [llength $diffids] == 1} {
-	gettree $diffids
+        gettree $diffids
     } elseif {$ids != $diffids} {
-	if {![info exists diffmergeid]} {
-	    gettreediffs $diffids
-	}
+        if {![info exists diffmergeid]} {
+            gettreediffs $diffids
+        }
     } else {
-	addtocflist $ids
+        addtocflist $ids
     }
     return 0
 }
@@ -7970,10 +7988,10 @@
     global diffcontextstring diffcontext
 
     if {[string is integer -strict $diffcontextstring]} {
-	if {$diffcontextstring >= 0} {
-	    set diffcontext $diffcontextstring
-	    reselectline
-	}
+        if {$diffcontextstring >= 0} {
+            set diffcontext $diffcontextstring
+            reselectline
+        }
     }
 }
 
@@ -8007,25 +8025,25 @@
 
     set textconv {}
     if {[package vcompare $git_version "1.6.1"] >= 0} {
-	set textconv "--textconv"
+        set textconv "--textconv"
     }
     set submodule {}
     if {[package vcompare $git_version "1.6.6"] >= 0} {
-	set submodule "--submodule"
+        set submodule "--submodule"
     }
     set cmd [diffcmd $ids "-p $textconv $submodule  -C --cc --no-commit-id -U$diffcontext"]
     if {$ignorespace} {
-	append cmd " -w"
+        append cmd " -w"
     }
     if {$worddiff ne [mc "Line diff"]} {
-	append cmd " --word-diff=porcelain"
+        append cmd " --word-diff=porcelain"
     }
     if {$limitdiffs && $vfilelimit($curview) ne {}} {
-	set cmd [concat $cmd -- $vfilelimit($curview)]
+        set cmd [concat $cmd -- $vfilelimit($curview)]
     }
     if {[catch {set bdf [open $cmd r]} err]} {
-	error_popup [mc "Error getting diffs: %s" $err]
-	return
+        error_popup [mc "Error getting diffs: %s" $err]
+        return
     }
     fconfigure $bdf -blocking 0 -encoding binary -eofchar {}
     set blobdifffd($ids) $bdf
@@ -8037,7 +8055,7 @@
     global ctext cmitmode
 
     if {$cmitmode eq "tree"} {
-	return {}
+        return {}
     }
     return [list target_scrollpos [$ctext index @0,0]]
 }
@@ -8053,9 +8071,9 @@
 
     if {![info exists target_scrollpos]} return
     if {!$ateof} {
-	set nlines [expr {[winfo height $ctext]
-			  / [font metrics textfont -linespace]}]
-	if {[$ctext compare "$target_scrollpos + $nlines lines" <= end]} return
+        set nlines [expr {[winfo height $ctext]
+                          / [font metrics textfont -linespace]}]
+        if {[$ctext compare "$target_scrollpos + $nlines lines" <= end]} return
     }
     $ctext yview $target_scrollpos
     unset target_scrollpos
@@ -8065,12 +8083,12 @@
     global $var
 
     while {[llength [set $var]] < $i} {
-	lappend $var {}
+        lappend $var {}
     }
     if {[llength [set $var]] == $i} {
-	lappend $var $val
+        lappend $var $val
     } else {
-	lset $var $i $val
+        lset $var $i $val
     }
 }
 
@@ -8082,7 +8100,7 @@
     set diffencoding [get_path_encoding $fname]
     set i [lsearch -exact $treediffs($ids) $fname]
     if {$i >= 0} {
-	setinlist difffilestart $i $curdiffstart
+        setinlist difffilestart $i $curdiffstart
     }
     lset ctext_file_names end $fname
     set l [expr {(78 - [string length $fname]) / 2}]
@@ -8090,7 +8108,7 @@
     $ctext insert $curdiffstart "$pad $fname $pad" filesep
     set targetline {}
     if {$jump_to_here ne {} && [lindex $jump_to_here 0] eq $fname} {
-	set targetline [lindex $jump_to_here 1]
+        set targetline [lindex $jump_to_here 1]
     }
     set diffline 0
 }
@@ -8098,7 +8116,7 @@
 proc blobdiffmaybeseehere {ateof} {
     global diffseehere
     if {$diffseehere >= 0} {
-	mark_ctext_line [lindex [split $diffseehere .] 0]
+        mark_ctext_line [lindex [split $diffseehere .] 0]
     }
     maybe_scroll_ctext $ateof
 }
@@ -8110,22 +8128,22 @@
     set nr 0
     $ctext conf -state normal
     while {[incr nr] <= 1000 && [gets $bdf line] >= 0} {
-	if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
-	    # Older diff read. Abort it.
-	    catch {close $bdf}
-	    if {$ids != $diffids} {
-		array unset blobdifffd $ids
-	    }
-	    return 0
-	}
-	parseblobdiffline $ids $line
+        if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
+            # Older diff read. Abort it.
+            catch {close $bdf}
+            if {$ids != $diffids} {
+                array unset blobdifffd $ids
+            }
+            return 0
+        }
+        parseblobdiffline $ids $line
     }
     $ctext conf -state disabled
     blobdiffmaybeseehere [eof $bdf]
     if {[eof $bdf]} {
-	catch {close $bdf}
-	array unset blobdifffd $ids
-	return 0
+        catch {close $bdf}
+        array unset blobdifffd $ids
+        return 0
     }
     return [expr {$nr >= 1000? 2: 1}]
 }
@@ -8139,199 +8157,199 @@
     global worddiff diffseehere
 
     if {![string compare -length 5 "diff " $line]} {
-	if {![regexp {^diff (--cc|--git) } $line m type]} {
-	    set line [encoding convertfrom $line]
-	    $ctext insert end "$line\n" hunksep
-	    continue
-	}
-	# start of a new file
-	set diffinhdr 1
-	$ctext insert end "\n"
-	set curdiffstart [$ctext index "end - 1c"]
-	lappend ctext_file_names ""
-	lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
-	$ctext insert end "\n" filesep
+        if {![regexp {^diff (--cc|--git) } $line m type]} {
+            set line [encoding convertfrom $line]
+            $ctext insert end "$line\n" hunksep
+            continue
+        }
+        # start of a new file
+        set diffinhdr 1
+        set currdiffsubmod ""
 
-	if {$type eq "--cc"} {
-	    # start of a new file in a merge diff
-	    set fname [string range $line 10 end]
-	    if {[lsearch -exact $treediffs($ids) $fname] < 0} {
-		lappend treediffs($ids) $fname
-		add_flist [list $fname]
-	    }
+        $ctext insert end "\n"
+        set curdiffstart [$ctext index "end - 1c"]
+        lappend ctext_file_names ""
+        lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
+        $ctext insert end "\n" filesep
 
-	} else {
-	    set line [string range $line 11 end]
-	    # If the name hasn't changed the length will be odd,
-	    # the middle char will be a space, and the two bits either
-	    # side will be a/name and b/name, or "a/name" and "b/name".
-	    # If the name has changed we'll get "rename from" and
-	    # "rename to" or "copy from" and "copy to" lines following
-	    # this, and we'll use them to get the filenames.
-	    # This complexity is necessary because spaces in the
-	    # filename(s) don't get escaped.
-	    set l [string length $line]
-	    set i [expr {$l / 2}]
-	    if {!(($l & 1) && [string index $line $i] eq " " &&
-		  [string range $line 2 [expr {$i - 1}]] eq \
-		      [string range $line [expr {$i + 3}] end])} {
-		return
-	    }
-	    # unescape if quoted and chop off the a/ from the front
-	    if {[string index $line 0] eq "\""} {
-		set fname [string range [lindex $line 0] 2 end]
-	    } else {
-		set fname [string range $line 2 [expr {$i - 1}]]
-	    }
-	}
-	makediffhdr $fname $ids
+        if {$type eq "--cc"} {
+            # start of a new file in a merge diff
+            set fname [string range $line 10 end]
+            if {[lsearch -exact $treediffs($ids) $fname] < 0} {
+                lappend treediffs($ids) $fname
+                add_flist [list $fname]
+            }
+
+        } else {
+            set line [string range $line 11 end]
+            # If the name hasn't changed the length will be odd,
+            # the middle char will be a space, and the two bits either
+            # side will be a/name and b/name, or "a/name" and "b/name".
+            # If the name has changed we'll get "rename from" and
+            # "rename to" or "copy from" and "copy to" lines following
+            # this, and we'll use them to get the filenames.
+            # This complexity is necessary because spaces in the
+            # filename(s) don't get escaped.
+            set l [string length $line]
+            set i [expr {$l / 2}]
+            if {!(($l & 1) && [string index $line $i] eq " " &&
+                  [string range $line 2 [expr {$i - 1}]] eq \
+                      [string range $line [expr {$i + 3}] end])} {
+                return
+            }
+            # unescape if quoted and chop off the a/ from the front
+            if {[string index $line 0] eq "\""} {
+                set fname [string range [lindex $line 0] 2 end]
+            } else {
+                set fname [string range $line 2 [expr {$i - 1}]]
+            }
+        }
+        makediffhdr $fname $ids
 
     } elseif {![string compare -length 16 "* Unmerged path " $line]} {
-	set fname [encoding convertfrom [string range $line 16 end]]
-	$ctext insert end "\n"
-	set curdiffstart [$ctext index "end - 1c"]
-	lappend ctext_file_names $fname
-	lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
-	$ctext insert end "$line\n" filesep
-	set i [lsearch -exact $treediffs($ids) $fname]
-	if {$i >= 0} {
-	    setinlist difffilestart $i $curdiffstart
-	}
+        set fname [encoding convertfrom [string range $line 16 end]]
+        $ctext insert end "\n"
+        set curdiffstart [$ctext index "end - 1c"]
+        lappend ctext_file_names $fname
+        lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
+        $ctext insert end "$line\n" filesep
+        set i [lsearch -exact $treediffs($ids) $fname]
+        if {$i >= 0} {
+            setinlist difffilestart $i $curdiffstart
+        }
 
     } elseif {![string compare -length 2 "@@" $line]} {
-	regexp {^@@+} $line ats
-	set line [encoding convertfrom $diffencoding $line]
-	$ctext insert end "$line\n" hunksep
-	if {[regexp { \+(\d+),\d+ @@} $line m nl]} {
-	    set diffline $nl
-	}
-	set diffnparents [expr {[string length $ats] - 1}]
-	set diffinhdr 0
+        regexp {^@@+} $line ats
+        set line [encoding convertfrom $diffencoding $line]
+        $ctext insert end "$line\n" hunksep
+        if {[regexp { \+(\d+),\d+ @@} $line m nl]} {
+            set diffline $nl
+        }
+        set diffnparents [expr {[string length $ats] - 1}]
+        set diffinhdr 0
 
     } elseif {![string compare -length 10 "Submodule " $line]} {
-	# start of a new submodule
-	if {[regexp -indices "\[0-9a-f\]+\\.\\." $line nameend]} {
-	    set fname [string range $line 10 [expr [lindex $nameend 0] - 2]]
-	} else {
-	    set fname [string range $line 10 [expr [string first "contains " $line] - 2]]
-	}
-	if {$currdiffsubmod != $fname} {
-	    $ctext insert end "\n";     # Add newline after commit message
-	}
-	set curdiffstart [$ctext index "end - 1c"]
-	lappend ctext_file_names ""
-	if {$currdiffsubmod != $fname} {
-	    lappend ctext_file_lines $fname
-	    makediffhdr $fname $ids
-	    set currdiffsubmod $fname
-	    $ctext insert end "\n$line\n" filesep
-	} else {
-	    $ctext insert end "$line\n" filesep
-	}
+        # start of a new submodule
+        if {[regexp -indices "\[0-9a-f\]+\\.\\." $line nameend]} {
+            set fname [string range $line 10 [expr [lindex $nameend 0] - 2]]
+        } else {
+            set fname [string range $line 10 [expr [string first "contains " $line] - 2]]
+        }
+        if {$currdiffsubmod != $fname} {
+            $ctext insert end "\n";     # Add newline after commit message
+        }
+        if {$currdiffsubmod != $fname} {
+            set curdiffstart [$ctext index "end - 1c"]
+            lappend ctext_file_names ""
+            lappend ctext_file_lines [lindex [split $curdiffstart "."] 0]
+            makediffhdr $fname $ids
+            set currdiffsubmod $fname
+            $ctext insert end "\n$line\n" filesep
+        } else {
+            $ctext insert end "$line\n" filesep
+        }
     } elseif {$currdiffsubmod != "" && ![string compare -length 3 "  >" $line]} {
-	set $currdiffsubmod ""
-	set line [encoding convertfrom $diffencoding $line]
-	$ctext insert end "$line\n" dresult
+        set line [encoding convertfrom $diffencoding $line]
+        $ctext insert end "$line\n" dresult
     } elseif {$currdiffsubmod != "" && ![string compare -length 3 "  <" $line]} {
-	set $currdiffsubmod ""
-	set line [encoding convertfrom $diffencoding $line]
-	$ctext insert end "$line\n" d0
+        set line [encoding convertfrom $diffencoding $line]
+        $ctext insert end "$line\n" d0
     } elseif {$diffinhdr} {
-	if {![string compare -length 12 "rename from " $line]} {
-	    set fname [string range $line [expr 6 + [string first " from " $line] ] end]
-	    if {[string index $fname 0] eq "\""} {
-		set fname [lindex $fname 0]
-	    }
-	    set fname [encoding convertfrom $fname]
-	    set i [lsearch -exact $treediffs($ids) $fname]
-	    if {$i >= 0} {
-		setinlist difffilestart $i $curdiffstart
-	    }
-	} elseif {![string compare -length 10 $line "rename to "] ||
-		  ![string compare -length 8 $line "copy to "]} {
-	    set fname [string range $line [expr 4 + [string first " to " $line] ] end]
-	    if {[string index $fname 0] eq "\""} {
-		set fname [lindex $fname 0]
-	    }
-	    makediffhdr $fname $ids
-	} elseif {[string compare -length 3 $line "---"] == 0} {
-	    # do nothing
-	    return
-	} elseif {[string compare -length 3 $line "+++"] == 0} {
-	    set diffinhdr 0
-	    return
-	}
-	$ctext insert end "$line\n" filesep
+        if {![string compare -length 12 "rename from " $line]} {
+            set fname [string range $line [expr 6 + [string first " from " $line] ] end]
+            if {[string index $fname 0] eq "\""} {
+                set fname [lindex $fname 0]
+            }
+            set fname [encoding convertfrom $fname]
+            set i [lsearch -exact $treediffs($ids) $fname]
+            if {$i >= 0} {
+                setinlist difffilestart $i $curdiffstart
+            }
+        } elseif {![string compare -length 10 $line "rename to "] ||
+                  ![string compare -length 8 $line "copy to "]} {
+            set fname [string range $line [expr 4 + [string first " to " $line] ] end]
+            if {[string index $fname 0] eq "\""} {
+                set fname [lindex $fname 0]
+            }
+            makediffhdr $fname $ids
+        } elseif {[string compare -length 3 $line "---"] == 0} {
+            # do nothing
+            return
+        } elseif {[string compare -length 3 $line "+++"] == 0} {
+            set diffinhdr 0
+            return
+        }
+        $ctext insert end "$line\n" filesep
 
     } else {
-	set line [string map {\x1A ^Z} \
-		      [encoding convertfrom $diffencoding $line]]
-	# parse the prefix - one ' ', '-' or '+' for each parent
-	set prefix [string range $line 0 [expr {$diffnparents - 1}]]
-	set tag [expr {$diffnparents > 1? "m": "d"}]
-	set dowords [expr {$worddiff ne [mc "Line diff"] && $diffnparents == 1}]
-	set words_pre_markup ""
-	set words_post_markup ""
-	if {[string trim $prefix " -+"] eq {}} {
-	    # prefix only has " ", "-" and "+" in it: normal diff line
-	    set num [string first "-" $prefix]
-	    if {$dowords} {
-		set line [string range $line 1 end]
-	    }
-	    if {$num >= 0} {
-		# removed line, first parent with line is $num
-		if {$num >= $mergemax} {
-		    set num "max"
-		}
-		if {$dowords && $worddiff eq [mc "Markup words"]} {
-		    $ctext insert end "\[-$line-\]" $tag$num
-		} else {
-		    $ctext insert end "$line" $tag$num
-		}
-		if {!$dowords} {
-		    $ctext insert end "\n" $tag$num
-		}
-	    } else {
-		set tags {}
-		if {[string first "+" $prefix] >= 0} {
-		    # added line
-		    lappend tags ${tag}result
-		    if {$diffnparents > 1} {
-			set num [string first " " $prefix]
-			if {$num >= 0} {
-			    if {$num >= $mergemax} {
-				set num "max"
-			    }
-			    lappend tags m$num
-			}
-		    }
-		    set words_pre_markup "{+"
-		    set words_post_markup "+}"
-		}
-		if {$targetline ne {}} {
-		    if {$diffline == $targetline} {
-			set diffseehere [$ctext index "end - 1 chars"]
-			set targetline {}
-		    } else {
-			incr diffline
-		    }
-		}
-		if {$dowords && $worddiff eq [mc "Markup words"]} {
-		    $ctext insert end "$words_pre_markup$line$words_post_markup" $tags
-		} else {
-		    $ctext insert end "$line" $tags
-		}
-		if {!$dowords} {
-		    $ctext insert end "\n" $tags
-		}
-	    }
-	} elseif {$dowords && $prefix eq "~"} {
-	    $ctext insert end "\n" {}
-	} else {
-	    # "\ No newline at end of file",
-	    # or something else we don't recognize
-	    $ctext insert end "$line\n" hunksep
-	}
+        set line [string map {\x1A ^Z} \
+                      [encoding convertfrom $diffencoding $line]]
+        # parse the prefix - one ' ', '-' or '+' for each parent
+        set prefix [string range $line 0 [expr {$diffnparents - 1}]]
+        set tag [expr {$diffnparents > 1? "m": "d"}]
+        set dowords [expr {$worddiff ne [mc "Line diff"] && $diffnparents == 1}]
+        set words_pre_markup ""
+        set words_post_markup ""
+        if {[string trim $prefix " -+"] eq {}} {
+            # prefix only has " ", "-" and "+" in it: normal diff line
+            set num [string first "-" $prefix]
+            if {$dowords} {
+                set line [string range $line 1 end]
+            }
+            if {$num >= 0} {
+                # removed line, first parent with line is $num
+                if {$num >= $mergemax} {
+                    set num "max"
+                }
+                if {$dowords && $worddiff eq [mc "Markup words"]} {
+                    $ctext insert end "\[-$line-\]" $tag$num
+                } else {
+                    $ctext insert end "$line" $tag$num
+                }
+                if {!$dowords} {
+                    $ctext insert end "\n" $tag$num
+                }
+            } else {
+                set tags {}
+                if {[string first "+" $prefix] >= 0} {
+                    # added line
+                    lappend tags ${tag}result
+                    if {$diffnparents > 1} {
+                        set num [string first " " $prefix]
+                        if {$num >= 0} {
+                            if {$num >= $mergemax} {
+                                set num "max"
+                            }
+                            lappend tags m$num
+                        }
+                    }
+                    set words_pre_markup "{+"
+                    set words_post_markup "+}"
+                }
+                if {$targetline ne {}} {
+                    if {$diffline == $targetline} {
+                        set diffseehere [$ctext index "end - 1 chars"]
+                        set targetline {}
+                    } else {
+                        incr diffline
+                    }
+                }
+                if {$dowords && $worddiff eq [mc "Markup words"]} {
+                    $ctext insert end "$words_pre_markup$line$words_post_markup" $tags
+                } else {
+                    $ctext insert end "$line" $tags
+                }
+                if {!$dowords} {
+                    $ctext insert end "\n" $tags
+                }
+            }
+        } elseif {$dowords && $prefix eq "~"} {
+            $ctext insert end "\n" {}
+        } else {
+            # "\ No newline at end of file",
+            # or something else we don't recognize
+            $ctext insert end "$line\n" hunksep
+        }
     }
 }
 
@@ -8361,9 +8379,9 @@
 
     set top [lindex [split $topidx .] 0]
     if {$difffilestart eq {} || $top < [lindex $difffilestart 0]} {
-	highlightfile 0
+        highlightfile 0
     } else {
-	highlightfile [expr {[bsearch $difffilestart $top] + 2}]
+        highlightfile [expr {[bsearch $difffilestart $top] + 2}]
     }
 }
 
@@ -8374,11 +8392,11 @@
     set prev 0.0
     set here [$ctext index @0,0]
     foreach loc $difffilestart {
-	if {[$ctext compare $loc >= $here]} {
-	    $ctext yview $prev
-	    return
-	}
-	set prev $loc
+        if {[$ctext compare $loc >= $here]} {
+            $ctext yview $prev
+            return
+        }
+        set prev $loc
     }
     $ctext yview $prev
 }
@@ -8389,10 +8407,10 @@
     if {$cmitmode eq "tree"} return
     set here [$ctext index @0,0]
     foreach loc $difffilestart {
-	if {[$ctext compare $loc > $here]} {
-	    $ctext yview $loc
-	    return
-	}
+        if {[$ctext compare $loc > $here]} {
+            $ctext yview $loc
+            return
+        }
     }
 }
 
@@ -8403,14 +8421,14 @@
 
     set l [lindex [split $first .] 0]
     if {![info exists smarktop] || [$ctext compare $first < $smarktop.0]} {
-	set smarktop $l
+        set smarktop $l
     }
     if {![info exists smarkbot] || [$ctext compare $first < $smarkbot.0]} {
-	set smarkbot $l
+        set smarkbot $l
     }
     $ctext delete $first end
     if {$first eq "1.0"} {
-	unset -nocomplain pendinglinks
+        unset -nocomplain pendinglinks
     }
     set ctext_file_names {}
     set ctext_file_lines {}
@@ -8420,16 +8438,16 @@
     global firsttabstop tabstop ctext have_tk85
 
     if {$firstab ne {} && $have_tk85} {
-	set firsttabstop $firstab
+        set firsttabstop $firstab
     }
     set w [font measure textfont "0"]
     if {$firsttabstop != 0} {
-	$ctext conf -tabs [list [expr {($firsttabstop + $tabstop) * $w}] \
-			       [expr {($firsttabstop + 2 * $tabstop) * $w}]]
+        $ctext conf -tabs [list [expr {($firsttabstop + $tabstop) * $w}] \
+                               [expr {($firsttabstop + 2 * $tabstop) * $w}]]
     } elseif {$have_tk85 || $tabstop != 8} {
-	$ctext conf -tabs [expr {$tabstop * $w}]
+        $ctext conf -tabs [expr {$tabstop * $w}]
     } else {
-	$ctext conf -tabs {}
+        $ctext conf -tabs {}
     }
 }
 
@@ -8437,26 +8455,26 @@
     global ctext searchstring searchdirn
 
     if {[catch {$ctext index anchor}]} {
-	# no anchor set, use start of selection, or of visible area
-	set sel [$ctext tag ranges sel]
-	if {$sel ne {}} {
-	    $ctext mark set anchor [lindex $sel 0]
-	} elseif {$searchdirn eq "-forwards"} {
-	    $ctext mark set anchor @0,0
-	} else {
-	    $ctext mark set anchor @0,[winfo height $ctext]
-	}
+        # no anchor set, use start of selection, or of visible area
+        set sel [$ctext tag ranges sel]
+        if {$sel ne {}} {
+            $ctext mark set anchor [lindex $sel 0]
+        } elseif {$searchdirn eq "-forwards"} {
+            $ctext mark set anchor @0,0
+        } else {
+            $ctext mark set anchor @0,[winfo height $ctext]
+        }
     }
     if {$searchstring ne {}} {
-	set here [$ctext search -count mlen $searchdirn -- $searchstring anchor]
-	if {$here ne {}} {
-	    $ctext see $here
-	    set mend "$here + $mlen c"
-	    $ctext tag remove sel 1.0 end
-	    $ctext tag add sel $here $mend
-	    suppress_highlighting_file_for_current_scrollpos
-	    highlightfile_for_scrollpos $here
-	}
+        set here [$ctext search -count mlen $searchdirn -- $searchstring anchor]
+        if {$here ne {}} {
+            $ctext see $here
+            set mend "$here + $mlen c"
+            $ctext tag remove sel 1.0 end
+            $ctext tag add sel $here $mend
+            suppress_highlighting_file_for_current_scrollpos
+            highlightfile_for_scrollpos $here
+        }
     }
     rehighlight_search_results
 }
@@ -8468,25 +8486,25 @@
     $sstring icursor end
     set searchdirn -forwards
     if {$searchstring ne {}} {
-	set sel [$ctext tag ranges sel]
-	if {$sel ne {}} {
-	    set start "[lindex $sel 0] + 1c"
-	} elseif {[catch {set start [$ctext index anchor]}]} {
-	    set start "@0,0"
-	}
-	set match [$ctext search -count mlen -- $searchstring $start]
-	$ctext tag remove sel 1.0 end
-	if {$match eq {}} {
-	    bell
-	    return
-	}
-	$ctext see $match
-	suppress_highlighting_file_for_current_scrollpos
-	highlightfile_for_scrollpos $match
-	set mend "$match + $mlen c"
-	$ctext tag add sel $match $mend
-	$ctext mark unset anchor
-	rehighlight_search_results
+        set sel [$ctext tag ranges sel]
+        if {$sel ne {}} {
+            set start "[lindex $sel 0] + 1c"
+        } elseif {[catch {set start [$ctext index anchor]}]} {
+            set start "@0,0"
+        }
+        set match [$ctext search -count mlen -- $searchstring $start]
+        $ctext tag remove sel 1.0 end
+        if {$match eq {}} {
+            bell
+            return
+        }
+        $ctext see $match
+        suppress_highlighting_file_for_current_scrollpos
+        highlightfile_for_scrollpos $match
+        set mend "$match + $mlen c"
+        $ctext tag add sel $match $mend
+        $ctext mark unset anchor
+        rehighlight_search_results
     }
 }
 
@@ -8497,25 +8515,25 @@
     $sstring icursor end
     set searchdirn -backwards
     if {$searchstring ne {}} {
-	set sel [$ctext tag ranges sel]
-	if {$sel ne {}} {
-	    set start [lindex $sel 0]
-	} elseif {[catch {set start [$ctext index anchor]}]} {
-	    set start @0,[winfo height $ctext]
-	}
-	set match [$ctext search -backwards -count ml -- $searchstring $start]
-	$ctext tag remove sel 1.0 end
-	if {$match eq {}} {
-	    bell
-	    return
-	}
-	$ctext see $match
-	suppress_highlighting_file_for_current_scrollpos
-	highlightfile_for_scrollpos $match
-	set mend "$match + $ml c"
-	$ctext tag add sel $match $mend
-	$ctext mark unset anchor
-	rehighlight_search_results
+        set sel [$ctext tag ranges sel]
+        if {$sel ne {}} {
+            set start [lindex $sel 0]
+        } elseif {[catch {set start [$ctext index anchor]}]} {
+            set start @0,[winfo height $ctext]
+        }
+        set match [$ctext search -backwards -count ml -- $searchstring $start]
+        $ctext tag remove sel 1.0 end
+        if {$match eq {}} {
+            bell
+            return
+        }
+        $ctext see $match
+        suppress_highlighting_file_for_current_scrollpos
+        highlightfile_for_scrollpos $match
+        set mend "$match + $ml c"
+        $ctext tag add sel $match $mend
+        $ctext mark unset anchor
+        rehighlight_search_results
     }
 }
 
@@ -8526,7 +8544,7 @@
     $ctext tag remove currentsearchhit 1.0 end
 
     if {$searchstring ne {}} {
-	searchmarkvisible 1
+        searchmarkvisible 1
     }
 }
 
@@ -8537,14 +8555,14 @@
 
     set mend $first.0
     while {1} {
-	set match [$ctext search -count mlen -- $searchstring $mend $last.end]
-	if {$match eq {}} break
-	set mend "$match + $mlen c"
-	if {$sel ne {} && [$ctext compare $match == [lindex $sel 0]]} {
-	    $ctext tag add currentsearchhit $match $mend
-	} else {
-	    $ctext tag add found $match $mend
-	}
+        set match [$ctext search -count mlen -- $searchstring $mend $last.end]
+        if {$match eq {}} break
+        set mend "$match + $mlen c"
+        if {$sel ne {} && [$ctext compare $match == [lindex $sel 0]]} {
+            $ctext tag add currentsearchhit $match $mend
+        } else {
+            $ctext tag add found $match $mend
+        }
     }
 }
 
@@ -8554,19 +8572,19 @@
     set topline [lindex [split [$ctext index @0,0] .] 0]
     set botline [lindex [split [$ctext index @0,[winfo height $ctext]] .] 0]
     if {$doall || $botline < $smarktop || $topline > $smarkbot} {
-	# no overlap with previous
-	searchmark $topline $botline
-	set smarktop $topline
-	set smarkbot $botline
+        # no overlap with previous
+        searchmark $topline $botline
+        set smarktop $topline
+        set smarkbot $botline
     } else {
-	if {$topline < $smarktop} {
-	    searchmark $topline [expr {$smarktop-1}]
-	    set smarktop $topline
-	}
-	if {$botline > $smarkbot} {
-	    searchmark [expr {$smarkbot+1}] $botline
-	    set smarkbot $botline
-	}
+        if {$topline < $smarktop} {
+            searchmark $topline [expr {$smarktop-1}]
+            set smarktop $topline
+        }
+        if {$botline > $smarkbot} {
+            searchmark [expr {$smarkbot+1}] $botline
+            set smarkbot $botline
+        }
     }
 }
 
@@ -8582,15 +8600,15 @@
 
     set topidx [$ctext index @0,0]
     if {![info exists suppress_highlighting_file_for_this_scrollpos]
-	|| $topidx ne $suppress_highlighting_file_for_this_scrollpos} {
-	highlightfile_for_scrollpos $topidx
+        || $topidx ne $suppress_highlighting_file_for_this_scrollpos} {
+        highlightfile_for_scrollpos $topidx
     }
 
     unset -nocomplain suppress_highlighting_file_for_this_scrollpos
 
     .bleft.bottom.sb set $f0 $f1
     if {$searchstring ne {}} {
-	searchmarkvisible 0
+        searchmarkvisible 0
     }
 }
 
@@ -8619,8 +8637,8 @@
     allcanvs yview moveto [lindex $span 0]
     drawvisible
     if {$selectedline ne {}} {
-	selectline $selectedline 0
-	allcanvs yview moveto [lindex $span 0]
+        selectline $selectedline 0
+        allcanvs yview moveto [lindex $span 0]
     }
 }
 
@@ -8630,20 +8648,20 @@
     set fontattr($f,family) [lindex $n 0]
     set s [lindex $n 1]
     if {$s eq {} || $s == 0} {
-	set s 10
+        set s 10
     } elseif {$s < 0} {
-	set s [expr {int(-$s / [winfo fpixels . 1p] + 0.5)}]
+        set s [expr {int(-$s / [winfo fpixels . 1p] + 0.5)}]
     }
     set fontattr($f,size) $s
     set fontattr($f,weight) normal
     set fontattr($f,slant) roman
     foreach style [lrange $n 2 end] {
-	switch -- $style {
-	    "normal" -
-	    "bold"   {set fontattr($f,weight) $style}
-	    "roman" -
-	    "italic" {set fontattr($f,slant) $style}
-	}
+        switch -- $style {
+            "normal" -
+            "bold"   {set fontattr($f,weight) $style}
+            "roman" -
+            "italic" {set fontattr($f,slant) $style}
+        }
     }
 }
 
@@ -8651,8 +8669,8 @@
     global fontattr
 
     return [list -family $fontattr($f,family) -size $fontattr($f,size) \
-		-weight [expr {$isbold? "bold": $fontattr($f,weight)}] \
-		-slant $fontattr($f,slant)]
+                -weight [expr {$isbold? "bold": $fontattr($f,weight)}] \
+                -slant $fontattr($f,slant)]
 }
 
 proc fontname {f} {
@@ -8660,10 +8678,10 @@
 
     set n [list $fontattr($f,family) $fontattr($f,size)]
     if {$fontattr($f,weight) eq "bold"} {
-	lappend n "bold"
+        lappend n "bold"
     }
     if {$fontattr($f,slant) eq "italic"} {
-	lappend n "italic"
+        lappend n "italic"
     }
     return $n
 }
@@ -8676,7 +8694,7 @@
     set s $fontattr(mainfont,size)
     incr s $inc
     if {$s < 1} {
-	set s 1
+        set s 1
     }
     set fontattr(mainfont,size) $s
     font config mainfont -size $s
@@ -8685,7 +8703,7 @@
     set s $fontattr(textfont,size)
     incr s $inc
     if {$s < 1} {
-	set s 1
+        set s 1
     }
     set fontattr(textfont,size) $s
     font config textfont -size $s
@@ -8699,23 +8717,23 @@
 proc clearsha1 {} {
     global sha1entry sha1string
     if {[string length $sha1string] == 40} {
-	$sha1entry delete 0 end
+        $sha1entry delete 0 end
     }
 }
 
 proc sha1change {n1 n2 op} {
     global sha1string currentid sha1but
     if {$sha1string == {}
-	|| ([info exists currentid] && $sha1string == $currentid)} {
-	set state disabled
+        || ([info exists currentid] && $sha1string == $currentid)} {
+        set state disabled
     } else {
-	set state normal
+        set state normal
     }
     if {[$sha1but cget -state] == $state} return
     if {$state == "normal"} {
-	$sha1but conf -state normal -relief raised -text "[mc "Goto:"] "
+        $sha1but conf -state normal -relief raised -text "[mc "Goto:"] "
     } else {
-	$sha1but conf -state disabled -relief flat -text "[mc "SHA1 ID:"] "
+        $sha1but conf -state disabled -relief flat -text "[mc "SHA1 ID:"] "
     }
 }
 
@@ -8723,37 +8741,37 @@
     global sha1string tagids headids curview varcid
 
     if {$sha1string == {}
-	|| ([info exists currentid] && $sha1string == $currentid)} return
+        || ([info exists currentid] && $sha1string == $currentid)} return
     if {[info exists tagids($sha1string)]} {
-	set id $tagids($sha1string)
+        set id $tagids($sha1string)
     } elseif {[info exists headids($sha1string)]} {
-	set id $headids($sha1string)
+        set id $headids($sha1string)
     } else {
-	set id [string tolower $sha1string]
-	if {[regexp {^[0-9a-f]{4,39}$} $id]} {
-	    set matches [longid $id]
-	    if {$matches ne {}} {
-		if {[llength $matches] > 1} {
-		    error_popup [mc "Short SHA1 id %s is ambiguous" $id]
-		    return
-		}
-		set id [lindex $matches 0]
-	    }
-	} else {
-	    if {[catch {set id [exec git rev-parse --verify $sha1string]}]} {
-		error_popup [mc "Revision %s is not known" $sha1string]
-		return
-	    }
-	}
+        set id [string tolower $sha1string]
+        if {[regexp {^[0-9a-f]{4,39}$} $id]} {
+            set matches [longid $id]
+            if {$matches ne {}} {
+                if {[llength $matches] > 1} {
+                    error_popup [mc "Short SHA1 id %s is ambiguous" $id]
+                    return
+                }
+                set id [lindex $matches 0]
+            }
+        } else {
+            if {[catch {set id [exec git rev-parse --verify $sha1string]}]} {
+                error_popup [mc "Revision %s is not known" $sha1string]
+                return
+            }
+        }
     }
     if {[commitinview $id $curview]} {
-	selectline [rowofcommit $id] 1
-	return
+        selectline [rowofcommit $id] 1
+        return
     }
     if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} {
-	set msg [mc "SHA1 id %s is not known" $sha1string]
+        set msg [mc "SHA1 id %s is not known" $sha1string]
     } else {
-	set msg [mc "Revision %s is not in the current view" $sha1string]
+        set msg [mc "Revision %s is not in the current view" $sha1string]
     }
     error_popup $msg
 }
@@ -8767,7 +8785,7 @@
     set hovery $y
     set hoverid $id
     if {[info exists hovertimer]} {
-	after cancel $hovertimer
+        after cancel $hovertimer
     }
     set hovertimer [after 500 linehover]
     $canv delete hover
@@ -8777,12 +8795,12 @@
     global hoverx hovery hoverid hovertimer
 
     if {[info exists hoverid] && $id == $hoverid} {
-	set hoverx $x
-	set hovery $y
-	if {[info exists hovertimer]} {
-	    after cancel $hovertimer
-	}
-	set hovertimer [after 500 linehover]
+        set hoverx $x
+        set hovery $y
+        if {[info exists hovertimer]} {
+            after cancel $hovertimer
+        }
+        set hovertimer [after 500 linehover]
     }
 }
 
@@ -8790,12 +8808,12 @@
     global hoverid hovertimer canv
 
     if {[info exists hoverid] && $id == $hoverid} {
-	$canv delete hover
-	if {[info exists hovertimer]} {
-	    after cancel $hovertimer
-	    unset hovertimer
-	}
-	unset hoverid
+        $canv delete hover
+        if {[info exists hovertimer]} {
+            after cancel $hovertimer
+            unset hovertimer
+        }
+        unset hoverid
     }
 }
 
@@ -8817,11 +8835,11 @@
     set x1 [expr {$x + [font measure mainfont $text] + 2 * $lthickness}]
     set y1 [expr {$y + $linespc + 2 * $lthickness}]
     set t [$canv create rectangle $x0 $y0 $x1 $y1 \
-	       -fill $linehoverbgcolor -outline $linehoveroutlinecolor \
-	       -width 1 -tags hover]
+               -fill $linehoverbgcolor -outline $linehoveroutlinecolor \
+               -width 1 -tags hover]
     $canv raise $t
     set t [$canv create text $x $y -anchor nw -text $text -tags hover \
-	       -font mainfont -fill $linehoverfgcolor]
+               -font mainfont -fill $linehoverfgcolor]
     $canv raise $t
 }
 
@@ -8832,10 +8850,10 @@
     set thresh [expr {2 * $lthickness + 6}]
     set n [expr {[llength $ranges] - 1}]
     for {set i 1} {$i < $n} {incr i} {
-	set row [lindex $ranges $i]
-	if {abs([yc $row] - $y) < $thresh} {
-	    return $i
-	}
+        set row [lindex $ranges $i]
+        if {abs([yc $row] - $y) < $thresh} {
+            return $i
+        }
     }
     return {}
 }
@@ -8853,7 +8871,7 @@
     set yspan [expr {[lindex $view 1] - [lindex $view 0]}]
     set yfrac [expr {$yt / $ymax - $yspan / 2}]
     if {$yfrac < 0} {
-	set yfrac 0
+        set yfrac 0
     }
     allcanvs yview moveto $yfrac
 }
@@ -8870,19 +8888,19 @@
     set thickerline $id
     drawlines $id
     if {$isnew} {
-	set ymax [lindex [$canv cget -scrollregion] 3]
-	if {$ymax eq {}} return
-	set yfrac [lindex [$canv yview] 0]
-	set y [expr {$y + $yfrac * $ymax}]
+        set ymax [lindex [$canv cget -scrollregion] 3]
+        if {$ymax eq {}} return
+        set yfrac [lindex [$canv yview] 0]
+        set y [expr {$y + $yfrac * $ymax}]
     }
     set dirn [clickisonarrow $id $y]
     if {$dirn ne {}} {
-	arrowjump $id $dirn $y
-	return
+        arrowjump $id $dirn $y
+        return
     }
 
     if {$isnew} {
-	addtohistory [list lineclick $x $y $id 0] savectextpos
+        addtohistory [list lineclick $x $y $id 0] savectextpos
     }
     # fill the details pane with info about this line
     $ctext conf -state normal
@@ -8898,20 +8916,20 @@
     $ctext insert end "\t[mc "Date"]:\t$date\n"
     set kids $children($curview,$id)
     if {$kids ne {}} {
-	$ctext insert end "\n[mc "Children"]:"
-	set i 0
-	foreach child $kids {
-	    incr i
-	    if {![info exists commitinfo($child)] && ![getcommit $child]} continue
-	    set info $commitinfo($child)
-	    $ctext insert end "\n\t"
-	    $ctext insert end $child link$i
-	    setlink $child link$i
-	    $ctext insert end "\n\t[lindex $info 0]"
-	    $ctext insert end "\n\t[mc "Author"]:\t[lindex $info 1]"
-	    set date [formatdate [lindex $info 2]]
-	    $ctext insert end "\n\t[mc "Date"]:\t$date\n"
-	}
+        $ctext insert end "\n[mc "Children"]:"
+        set i 0
+        foreach child $kids {
+            incr i
+            if {![info exists commitinfo($child)] && ![getcommit $child]} continue
+            set info $commitinfo($child)
+            $ctext insert end "\n\t"
+            $ctext insert end $child link$i
+            setlink $child link$i
+            $ctext insert end "\n\t[lindex $info 0]"
+            $ctext insert end "\n\t[mc "Author"]:\t[lindex $info 1]"
+            set date [formatdate [lindex $info 2]]
+            $ctext insert end "\n\t[mc "Date"]:\t$date\n"
+        }
     }
     maybe_scroll_ctext 1
     $ctext conf -state disabled
@@ -8921,23 +8939,23 @@
 proc normalline {} {
     global thickerline
     if {[info exists thickerline]} {
-	set id $thickerline
-	unset thickerline
-	drawlines $id
+        set id $thickerline
+        unset thickerline
+        drawlines $id
     }
 }
 
 proc selbyid {id {isnew 1}} {
     global curview
     if {[commitinview $id $curview]} {
-	selectline [rowofcommit $id] $isnew
+        selectline [rowofcommit $id] $isnew
     }
 }
 
 proc mstime {} {
     global startmstime
     if {![info exists startmstime]} {
-	set startmstime [clock clicks -milliseconds]
+        set startmstime [clock clicks -milliseconds]
     }
     return [format "%.3f" [expr {([clock click -milliseconds] - $startmstime) / 1000.0}]]
 }
@@ -8949,27 +8967,27 @@
     stopfinding
     set rowmenuid $id
     if {$selectedline eq {} || [rowofcommit $id] eq $selectedline} {
-	set state disabled
+        set state disabled
     } else {
-	set state normal
+        set state normal
     }
     if {[info exists markedid] && $markedid ne $id} {
-	set mstate normal
+        set mstate normal
     } else {
-	set mstate disabled
+        set mstate disabled
     }
     if {$id ne $nullid && $id ne $nullid2} {
-	set menu $rowctxmenu
-	if {$mainhead ne {}} {
-	    $menu entryconfigure 8 -label [mc "Reset %s branch to here" $mainhead] -state normal
-	} else {
-	    $menu entryconfigure 8 -label [mc "Detached head: can't reset" $mainhead] -state disabled
-	}
-	$menu entryconfigure 10 -state $mstate
-	$menu entryconfigure 11 -state $mstate
-	$menu entryconfigure 12 -state $mstate
+        set menu $rowctxmenu
+        if {$mainhead ne {}} {
+            $menu entryconfigure 8 -label [mc "Reset %s branch to here" $mainhead] -state normal
+        } else {
+            $menu entryconfigure 8 -label [mc "Detached head: can't reset" $mainhead] -state disabled
+        }
+        $menu entryconfigure 10 -state $mstate
+        $menu entryconfigure 11 -state $mstate
+        $menu entryconfigure 12 -state $mstate
     } else {
-	set menu $fakerowmenu
+        set menu $fakerowmenu
     }
     $menu entryconfigure [mca "Diff this -> selected"] -state $state
     $menu entryconfigure [mca "Diff selected -> this"] -state $state
@@ -8990,7 +9008,7 @@
     global markedid
 
     if {[info exists markedid]} {
-	selbyid $markedid
+        selbyid $markedid
     }
 }
 
@@ -9000,7 +9018,7 @@
     set id [commitonrow $r]
     set l [lreplace $l 0 0]
     foreach kid $children($curview,$id) {
-	lappend l [rowofcommit $kid]
+        lappend l [rowofcommit $kid]
     }
     return [lsort -integer -decreasing -unique $l]
 }
@@ -9010,23 +9028,23 @@
 
     if {![info exists markedid]} return
     if {![commitinview $markedid $curview] ||
-	![commitinview $rowmenuid $curview]} return
+        ![commitinview $rowmenuid $curview]} return
     #set t1 [clock clicks -milliseconds]
     set l1 [list [rowofcommit $markedid]]
     set l2 [list [rowofcommit $rowmenuid]]
     while 1 {
-	set r1 [lindex $l1 0]
-	set r2 [lindex $l2 0]
-	if {$r1 eq {} || $r2 eq {}} break
-	if {$r1 == $r2} {
-	    selectline $r1 1
-	    break
-	}
-	if {$r1 > $r2} {
-	    set l1 [replace_by_kids $l1 $r1]
-	} else {
-	    set l2 [replace_by_kids $l2 $r2]
-	}
+        set r1 [lindex $l1 0]
+        set r2 [lindex $l2 0]
+        if {$r1 eq {} || $r2 eq {}} break
+        if {$r1 == $r2} {
+            selectline $r1 1
+            break
+        }
+        if {$r1 > $r2} {
+            set l1 [replace_by_kids $l1 $r1]
+        } else {
+            set l2 [replace_by_kids $l2 $r2]
+        }
     }
     #set t2 [clock clicks -milliseconds]
     #puts "took [expr {$t2-$t1}]ms"
@@ -9045,15 +9063,15 @@
     global patchids
 
     if {![info exists patchids($id)]} {
-	set cmd [diffcmd [list $id] {-p --root}]
-	# trim off the initial "|"
-	set cmd [lrange $cmd 1 end]
-	if {[catch {
-	    set x [eval exec $cmd | git patch-id]
-	    set patchids($id) [lindex $x 0]
-	}]} {
-	    set patchids($id) "error"
-	}
+        set cmd [diffcmd [list $id] {-p --root}]
+        # trim off the initial "|"
+        set cmd [lrange $cmd 1 end]
+        if {[catch {
+            set x [eval exec $cmd | git patch-id]
+            set patchids($id) [lindex $x 0]
+        }]} {
+            set patchids($id) "error"
+        }
     }
     return $patchids($id)
 }
@@ -9065,75 +9083,75 @@
     clear_ctext
     init_flist {}
     for {set i 0} {$i < 100} {incr i} {
-	set skipa 0
-	set skipb 0
-	if {[llength $parents($curview,$a)] > 1} {
-	    appendshortlink $a [mc "Skipping merge commit "] "\n"
-	    set skipa 1
-	} else {
-	    set patcha [getpatchid $a]
-	}
-	if {[llength $parents($curview,$b)] > 1} {
-	    appendshortlink $b [mc "Skipping merge commit "] "\n"
-	    set skipb 1
-	} else {
-	    set patchb [getpatchid $b]
-	}
-	if {!$skipa && !$skipb} {
-	    set heada [lindex $commitinfo($a) 0]
-	    set headb [lindex $commitinfo($b) 0]
-	    if {$patcha eq "error"} {
-		appendshortlink $a [mc "Error getting patch ID for "] \
-		    [mc " - stopping\n"]
-		break
-	    }
-	    if {$patchb eq "error"} {
-		appendshortlink $b [mc "Error getting patch ID for "] \
-		    [mc " - stopping\n"]
-		break
-	    }
-	    if {$patcha eq $patchb} {
-		if {$heada eq $headb} {
-		    appendshortlink $a [mc "Commit "]
-		    appendshortlink $b " == " "  $heada\n"
-		} else {
-		    appendshortlink $a [mc "Commit "] "  $heada\n"
-		    appendshortlink $b [mc " is the same patch as\n       "] \
-			"  $headb\n"
-		}
-		set skipa 1
-		set skipb 1
-	    } else {
-		$ctext insert end "\n"
-		appendshortlink $a [mc "Commit "] "  $heada\n"
-		appendshortlink $b [mc " differs from\n       "] \
-		    "  $headb\n"
-		$ctext insert end [mc "Diff of commits:\n\n"]
-		$ctext conf -state disabled
-		update
-		diffcommits $a $b
-		return
-	    }
-	}
-	if {$skipa} {
-	    set kids [real_children $curview,$a]
-	    if {[llength $kids] != 1} {
-		$ctext insert end "\n"
-		appendshortlink $a [mc "Commit "] \
-		    [mc " has %s children - stopping\n" [llength $kids]]
-		break
-	    }
-	    set a [lindex $kids 0]
-	}
-	if {$skipb} {
-	    set kids [real_children $curview,$b]
-	    if {[llength $kids] != 1} {
-		appendshortlink $b [mc "Commit "] \
-		    [mc " has %s children - stopping\n" [llength $kids]]
-		break
-	    }
-	    set b [lindex $kids 0]
-	}
+        set skipa 0
+        set skipb 0
+        if {[llength $parents($curview,$a)] > 1} {
+            appendshortlink $a [mc "Skipping merge commit "] "\n"
+            set skipa 1
+        } else {
+            set patcha [getpatchid $a]
+        }
+        if {[llength $parents($curview,$b)] > 1} {
+            appendshortlink $b [mc "Skipping merge commit "] "\n"
+            set skipb 1
+        } else {
+            set patchb [getpatchid $b]
+        }
+        if {!$skipa && !$skipb} {
+            set heada [lindex $commitinfo($a) 0]
+            set headb [lindex $commitinfo($b) 0]
+            if {$patcha eq "error"} {
+                appendshortlink $a [mc "Error getting patch ID for "] \
+                    [mc " - stopping\n"]
+                break
+            }
+            if {$patchb eq "error"} {
+                appendshortlink $b [mc "Error getting patch ID for "] \
+                    [mc " - stopping\n"]
+                break
+            }
+            if {$patcha eq $patchb} {
+                if {$heada eq $headb} {
+                    appendshortlink $a [mc "Commit "]
+                    appendshortlink $b " == " "  $heada\n"
+                } else {
+                    appendshortlink $a [mc "Commit "] "  $heada\n"
+                    appendshortlink $b [mc " is the same patch as\n       "] \
+                        "  $headb\n"
+                }
+                set skipa 1
+                set skipb 1
+            } else {
+                $ctext insert end "\n"
+                appendshortlink $a [mc "Commit "] "  $heada\n"
+                appendshortlink $b [mc " differs from\n       "] \
+                    "  $headb\n"
+                $ctext insert end [mc "Diff of commits:\n\n"]
+                $ctext conf -state disabled
+                update
+                diffcommits $a $b
+                return
+            }
+        }
+        if {$skipa} {
+            set kids [real_children $curview,$a]
+            if {[llength $kids] != 1} {
+                $ctext insert end "\n"
+                appendshortlink $a [mc "Commit "] \
+                    [mc " has %s children - stopping\n" [llength $kids]]
+                break
+            }
+            set a [lindex $kids 0]
+        }
+        if {$skipb} {
+            set kids [real_children $curview,$b]
+            if {[llength $kids] != 1} {
+                appendshortlink $b [mc "Commit "] \
+                    [mc " has %s children - stopping\n" [llength $kids]]
+                break
+            }
+            set b [lindex $kids 0]
+        }
     }
     $ctext conf -state disabled
 }
@@ -9145,17 +9163,17 @@
     set fna [file join $tmpdir "commit-[string range $a 0 7]"]
     set fnb [file join $tmpdir "commit-[string range $b 0 7]"]
     if {[catch {
-	exec git diff-tree -p --pretty $a >$fna
-	exec git diff-tree -p --pretty $b >$fnb
+        exec git diff-tree -p --pretty $a >$fna
+        exec git diff-tree -p --pretty $b >$fnb
     } err]} {
-	error_popup [mc "Error writing commit to file: %s" $err]
-	return
+        error_popup [mc "Error writing commit to file: %s" $err]
+        return
     }
     if {[catch {
-	set fd [open "| diff -U$diffcontext $fna $fnb" r]
+        set fd [open "| diff -U$diffcontext $fna $fnb" r]
     } err]} {
-	error_popup [mc "Error diffing commits: %s" $err]
-	return
+        error_popup [mc "Error diffing commits: %s" $err]
+        return
     }
     set diffids [list commits $a $b]
     set blobdifffd($diffids) $fd
@@ -9169,11 +9187,11 @@
 
     if {$selectedline eq {}} return
     if {$dirn} {
-	set oldid [commitonrow $selectedline]
-	set newid $rowmenuid
+        set oldid [commitonrow $selectedline]
+        set newid $rowmenuid
     } else {
-	set oldid $rowmenuid
-	set newid [commitonrow $selectedline]
+        set oldid $rowmenuid
+        set newid [commitonrow $selectedline]
     }
     addtohistory [list doseldiff $oldid $newid] savectextpos
     doseldiff $oldid $newid
@@ -9184,11 +9202,11 @@
 
     if {![info exists markedid]} return
     if {$dirn} {
-	set oldid $markedid
-	set newid $rowmenuid
+        set oldid $markedid
+        set newid $rowmenuid
     } else {
-	set oldid $rowmenuid
-	set newid $markedid
+        set oldid $rowmenuid
+        set newid $markedid
     }
     addtohistory [list doseldiff $oldid $newid] savectextpos
     doseldiff $oldid $newid
@@ -9277,11 +9295,11 @@
     set newid [$patchtop.tosha1 get]
     set newhead [$patchtop.tohead get]
     foreach e [list fromsha1 fromhead tosha1 tohead] \
-	    v [list $newid $newhead $oldid $oldhead] {
-	$patchtop.$e conf -state normal
-	$patchtop.$e delete 0 end
-	$patchtop.$e insert 0 $v
-	$patchtop.$e conf -state readonly
+            v [list $newid $newhead $oldid $oldhead] {
+        $patchtop.$e conf -state normal
+        $patchtop.$e delete 0 end
+        $patchtop.$e insert 0 $v
+        $patchtop.$e conf -state readonly
     }
 }
 
@@ -9296,7 +9314,7 @@
     set cmd [lrange $cmd 1 end]
     lappend cmd >$fname &
     if {[catch {eval exec $cmd} err]} {
-	error_popup "[mc "Error creating patch:"] $err" $patchtop
+        error_popup "[mc "Error creating patch:"] $err" $patchtop
     }
     catch {destroy $patchtop}
     unset patchtop
@@ -9355,22 +9373,22 @@
     set tag [$mktagtop.tag get]
     set msg [$mktagtop.msg get]
     if {$tag == {}} {
-	error_popup [mc "No tag name specified"] $mktagtop
-	return 0
+        error_popup [mc "No tag name specified"] $mktagtop
+        return 0
     }
     if {[info exists tagids($tag)]} {
-	error_popup [mc "Tag \"%s\" already exists" $tag] $mktagtop
-	return 0
+        error_popup [mc "Tag \"%s\" already exists" $tag] $mktagtop
+        return 0
     }
     if {[catch {
-	if {$msg != {}} {
-	    exec git tag -a -m $msg $tag $id
-	} else {
-	    exec git tag $tag $id
-	}
+        if {$msg != {}} {
+            exec git tag -a -m $msg $tag $id
+        } else {
+            exec git tag $tag $id
+        }
     } err]} {
-	error_popup "[mc "Error creating tag:"] $err" $mktagtop
-	return 0
+        error_popup "[mc "Error creating tag:"] $err" $mktagtop
+        return 0
     }
 
     set tagids($tag) $id
@@ -9391,9 +9409,9 @@
     if {![info exists iddrawn($id)]} return
     set row [rowofcommit $id]
     if {$id eq $mainheadid} {
-	set ofill $mainheadcirclecolor
+        set ofill $mainheadcirclecolor
     } else {
-	set ofill [lindex $circlecolors $cmitlisted($curview,$id)]
+        set ofill [lindex $circlecolors $cmitlisted($curview,$id)]
     }
     $canv itemconf $circleitem($row) -fill $ofill
     $canv delete tag.$id
@@ -9403,14 +9421,14 @@
     set font [$canv itemcget $linehtag($id) -font]
     set xr [expr {$xt + [font measure $font $text]}]
     if {$xr > $canvxmax} {
-	set canvxmax $xr
-	setcanvscroll
+        set canvxmax $xr
+        setcanvscroll
     }
     if {[info exists currentid] && $currentid == $id} {
-	make_secsel $id
+        make_secsel $id
     }
     if {[info exists markedid] && $markedid eq $id} {
-	make_idmark $id
+        make_idmark $id
     }
 }
 
@@ -9426,7 +9444,7 @@
     mktagcan
 }
 
-proc copysummary {} {
+proc copyreference {} {
     global rowmenuid autosellen
 
     set format "%h (\"%s\", %ad)"
@@ -9434,10 +9452,10 @@
     if {$autosellen < 40} {
         lappend cmd --abbrev=$autosellen
     }
-    set summary [eval exec $cmd $rowmenuid]
+    set reference [eval exec $cmd $rowmenuid]
 
     clipboard clear
-    clipboard append $summary
+    clipboard append $reference
 }
 
 proc writecommit {} {
@@ -9485,7 +9503,7 @@
     set cmd "echo $id | [$wrcomtop.cmd get]"
     set fname [$wrcomtop.fname get]
     if {[catch {exec sh -c $cmd >$fname &} err]} {
-	error_popup "[mc "Error writing commit:"] $err" $wrcomtop
+        error_popup "[mc "Error writing commit:"] $err" $wrcomtop
     }
     catch {destroy $wrcomtop}
     unset wrcomtop
@@ -9572,41 +9590,41 @@
     set cmdargs {}
     set old_id {}
     if {$name eq {}} {
-	error_popup [mc "Please specify a name for the new branch"] $top
-	return
+        error_popup [mc "Please specify a name for the new branch"] $top
+        return
     }
     if {[info exists headids($name)]} {
-	if {![confirm_popup [mc \
-		"Branch '%s' already exists. Overwrite?" $name] $top]} {
-	    return
-	}
-	set old_id $headids($name)
-	lappend cmdargs -f
+        if {![confirm_popup [mc \
+                "Branch '%s' already exists. Overwrite?" $name] $top]} {
+            return
+        }
+        set old_id $headids($name)
+        lappend cmdargs -f
     }
     catch {destroy $top}
     lappend cmdargs $name $id
     nowbusy newbranch
     update
     if {[catch {
-	eval exec git branch $cmdargs
+        eval exec git branch $cmdargs
     } err]} {
-	notbusy newbranch
-	error_popup $err
+        notbusy newbranch
+        error_popup $err
     } else {
-	notbusy newbranch
-	if {$old_id ne {}} {
-	    movehead $id $name
-	    movedhead $id $name
-	    redrawtags $old_id
-	    redrawtags $id
-	} else {
-	    set headids($name) $id
-	    lappend idheads($id) $name
-	    addedhead $id $name
-	    redrawtags $id
-	}
-	dispneartags 0
-	run refill_reflist
+        notbusy newbranch
+        if {$old_id ne {}} {
+            movehead $id $name
+            movedhead $id $name
+            redrawtags $old_id
+            redrawtags $id
+        } else {
+            set headids($name) $id
+            lappend idheads($id) $name
+            addedhead $id $name
+            redrawtags $id
+        }
+        dispneartags 0
+        run refill_reflist
     }
 }
 
@@ -9617,36 +9635,36 @@
     set id [$top.sha1 get]
     set cmdargs {}
     if {$name eq $prevname} {
-	catch {destroy $top}
-	return
+        catch {destroy $top}
+        return
     }
     if {$name eq {}} {
-	error_popup [mc "Please specify a new name for the branch"] $top
-	return
+        error_popup [mc "Please specify a new name for the branch"] $top
+        return
     }
     catch {destroy $top}
     lappend cmdargs -m $prevname $name
     nowbusy renamebranch
     update
     if {[catch {
-	eval exec git branch $cmdargs
+        eval exec git branch $cmdargs
     } err]} {
-	notbusy renamebranch
-	error_popup $err
+        notbusy renamebranch
+        error_popup $err
     } else {
-	notbusy renamebranch
-	removehead $id $prevname
-	removedhead $id $prevname
-	set headids($name) $id
-	lappend idheads($id) $name
-	addedhead $id $name
-	if {$prevname eq $mainhead} {
-	    set mainhead $name
-	    set mainheadid $id
-	}
-	redrawtags $id
-	dispneartags 0
-	run refill_reflist
+        notbusy renamebranch
+        removehead $id $prevname
+        removedhead $id $prevname
+        set headids($name) $id
+        lappend idheads($id) $name
+        addedhead $id $name
+        if {$prevname eq $mainhead} {
+            set mainhead $name
+            set mainheadid $id
+        }
+        redrawtags $id
+        dispneartags 0
+        run refill_reflist
     }
 }
 
@@ -9656,18 +9674,18 @@
     set save_env [array get env GIT_AUTHOR_*]
 
     if {$baseid ne {}} {
-	if {![info exists commitinfo($baseid)]} {
-	    getcommit $baseid
-	}
-	set author [lindex $commitinfo($baseid) 1]
-	set date [lindex $commitinfo($baseid) 2]
-	if {[regexp {^\s*(\S.*\S|\S)\s*<(.*)>\s*$} \
-	            $author author name email]
-	    && $date ne {}} {
-	    set env(GIT_AUTHOR_NAME) $name
-	    set env(GIT_AUTHOR_EMAIL) $email
-	    set env(GIT_AUTHOR_DATE) $date
-	}
+        if {![info exists commitinfo($baseid)]} {
+            getcommit $baseid
+        }
+        set author [lindex $commitinfo($baseid) 1]
+        set date [lindex $commitinfo($baseid) 2]
+        if {[regexp {^\s*(\S.*\S|\S)\s*<(.*)>\s*$} \
+                    $author author name email]
+            && $date ne {}} {
+            set env(GIT_AUTHOR_NAME) $name
+            set env(GIT_AUTHOR_EMAIL) $email
+            set env(GIT_AUTHOR_DATE) $date
+        }
     }
 
     eval exec git citool $tool_args &
@@ -9684,57 +9702,57 @@
     set oldhead [exec git rev-parse HEAD]
     set dheads [descheads $rowmenuid]
     if {$dheads ne {} && [lsearch -exact $dheads $oldhead] >= 0} {
-	set ok [confirm_popup [mc "Commit %s is already\
-		included in branch %s -- really re-apply it?" \
-				   [string range $rowmenuid 0 7] $mainhead]]
-	if {!$ok} return
+        set ok [confirm_popup [mc "Commit %s is already\
+                included in branch %s -- really re-apply it?" \
+                                   [string range $rowmenuid 0 7] $mainhead]]
+        if {!$ok} return
     }
     nowbusy cherrypick [mc "Cherry-picking"]
     update
     # Unfortunately git-cherry-pick writes stuff to stderr even when
     # no error occurs, and exec takes that as an indication of error...
     if {[catch {exec sh -c "git cherry-pick -r $rowmenuid 2>&1"} err]} {
-	notbusy cherrypick
-	if {[regexp -line \
-		 {Entry '(.*)' (would be overwritten by merge|not uptodate)} \
-		 $err msg fname]} {
-	    error_popup [mc "Cherry-pick failed because of local changes\
-			to file '%s'.\nPlease commit, reset or stash\
-			your changes and try again." $fname]
-	} elseif {[regexp -line \
-		       {^(CONFLICT \(.*\):|Automatic cherry-pick failed|error: could not apply)} \
-		       $err]} {
-	    if {[confirm_popup [mc "Cherry-pick failed because of merge\
-			conflict.\nDo you wish to run git citool to\
-			resolve it?"]]} {
-		# Force citool to read MERGE_MSG
-		file delete [file join $gitdir "GITGUI_MSG"]
-		exec_citool {} $rowmenuid
-	    }
-	} else {
-	    error_popup $err
-	}
-	run updatecommits
-	return
+        notbusy cherrypick
+        if {[regexp -line \
+                 {Entry '(.*)' (would be overwritten by merge|not uptodate)} \
+                 $err msg fname]} {
+            error_popup [mc "Cherry-pick failed because of local changes\
+                        to file '%s'.\nPlease commit, reset or stash\
+                        your changes and try again." $fname]
+        } elseif {[regexp -line \
+                       {^(CONFLICT \(.*\):|Automatic cherry-pick failed|error: could not apply)} \
+                       $err]} {
+            if {[confirm_popup [mc "Cherry-pick failed because of merge\
+                        conflict.\nDo you wish to run git citool to\
+                        resolve it?"]]} {
+                # Force citool to read MERGE_MSG
+                file delete [file join $gitdir "GITGUI_MSG"]
+                exec_citool {} $rowmenuid
+            }
+        } else {
+            error_popup $err
+        }
+        run updatecommits
+        return
     }
     set newhead [exec git rev-parse HEAD]
     if {$newhead eq $oldhead} {
-	notbusy cherrypick
-	error_popup [mc "No changes committed"]
-	return
+        notbusy cherrypick
+        error_popup [mc "No changes committed"]
+        return
     }
     addnewchild $newhead $oldhead
     if {[commitinview $oldhead $curview]} {
-	# XXX this isn't right if we have a path limit...
-	insertrow $newhead $oldhead $curview
-	if {$mainhead ne {}} {
-	    movehead $newhead $mainhead
-	    movedhead $newhead $mainhead
-	}
-	set mainheadid $newhead
-	redrawtags $oldhead
-	redrawtags $newhead
-	selbyid $newhead
+        # XXX this isn't right if we have a path limit...
+        insertrow $newhead $oldhead $curview
+        if {$mainhead ne {}} {
+            movehead $newhead $mainhead
+            movedhead $newhead $mainhead
+        }
+        set mainheadid $newhead
+        redrawtags $oldhead
+        redrawtags $newhead
+        selbyid $newhead
     }
     notbusy cherrypick
 }
@@ -9809,18 +9827,18 @@
     make_transient $w .
     wm title $w [mc "Confirm reset"]
     ${NS}::label $w.m -text \
-	[mc "Reset branch %s to %s?" $mainhead [string range $rowmenuid 0 7]]
+        [mc "Reset branch %s to %s?" $mainhead [string range $rowmenuid 0 7]]
     pack $w.m -side top -fill x -padx 20 -pady 20
     ${NS}::labelframe $w.f -text [mc "Reset type:"]
     set resettype mixed
     ${NS}::radiobutton $w.f.soft -value soft -variable resettype \
-	-text [mc "Soft: Leave working tree and index untouched"]
+        -text [mc "Soft: Leave working tree and index untouched"]
     grid $w.f.soft -sticky w
     ${NS}::radiobutton $w.f.mixed -value mixed -variable resettype \
-	-text [mc "Mixed: Leave working tree untouched, reset index"]
+        -text [mc "Mixed: Leave working tree untouched, reset index"]
     grid $w.f.mixed -sticky w
     ${NS}::radiobutton $w.f.hard -value hard -variable resettype \
-	-text [mc "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 -padx 4
     ${NS}::button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w"
@@ -9832,13 +9850,13 @@
     tkwait window $w
     if {!$confirm_ok} return
     if {[catch {set fd [open \
-	    [list | git reset --$resettype $rowmenuid 2>@1] r]} err]} {
-	error_popup $err
+            [list | git reset --$resettype $rowmenuid 2>@1] r]} err]} {
+        error_popup $err
     } else {
-	dohidelocalchanges
-	filerun $fd [list readresetstat $fd]
-	nowbusy reset [mc "Resetting"]
-	selbyid $rowmenuid
+        dohidelocalchanges
+        filerun $fd [list readresetstat $fd]
+        nowbusy reset [mc "Resetting"]
+        selbyid $rowmenuid
     }
 }
 
@@ -9846,29 +9864,29 @@
     global mainhead mainheadid showlocalchanges rprogcoord
 
     if {[gets $fd line] >= 0} {
-	if {[regexp {([0-9]+)% \(([0-9]+)/([0-9]+)\)} $line match p m n]} {
-	    set rprogcoord [expr {1.0 * $m / $n}]
-	    adjustprogress
-	}
-	return 1
+        if {[regexp {([0-9]+)% \(([0-9]+)/([0-9]+)\)} $line match p m n]} {
+            set rprogcoord [expr {1.0 * $m / $n}]
+            adjustprogress
+        }
+        return 1
     }
     set rprogcoord 0
     adjustprogress
     notbusy reset
     if {[catch {close $fd} err]} {
-	error_popup $err
+        error_popup $err
     }
     set oldhead $mainheadid
     set newhead [exec git rev-parse HEAD]
     if {$newhead ne $oldhead} {
-	movehead $newhead $mainhead
-	movedhead $newhead $mainhead
-	set mainheadid $newhead
-	redrawtags $oldhead
-	redrawtags $newhead
+        movehead $newhead $mainhead
+        movedhead $newhead $mainhead
+        set mainheadid $newhead
+        redrawtags $oldhead
+        redrawtags $newhead
     }
     if {$showlocalchanges} {
-	doshowlocalchanges
+        doshowlocalchanges
     }
     return 0
 }
@@ -9882,17 +9900,17 @@
     set headmenuhead $head
     array set state {0 normal 1 normal 2 normal}
     if {[string match "remotes/*" $head]} {
-	set localhead [string range $head [expr [string last / $head] + 1] end]
-	if {[info exists headids($localhead)]} {
-	    set state(0) disabled
-	}
-	array set state {1 disabled 2 disabled}
+        set localhead [string range $head [expr [string last / $head] + 1] end]
+        if {[info exists headids($localhead)]} {
+            set state(0) disabled
+        }
+        array set state {1 disabled 2 disabled}
     }
     if {$head eq $mainhead} {
-	array set state {0 disabled 2 disabled}
+        array set state {0 disabled 2 disabled}
     }
     foreach i {0 1 2} {
-	$headctxmenu entryconfigure $i -state $state($i)
+        $headctxmenu entryconfigure $i -state $state($i)
     }
     tk_popup $headctxmenu $x $y
 }
@@ -9905,32 +9923,32 @@
     set newhead $headmenuhead
     set command [list | git checkout]
     if {[string match "remotes/*" $newhead]} {
-	set remote $newhead
-	set newhead [string range $newhead [expr [string last / $newhead] + 1] end]
-	# The following check is redundant - the menu option should
-	# be disabled to begin with...
-	if {[info exists headids($newhead)]} {
-	    error_popup [mc "A local branch named %s exists already" $newhead]
-	    return
-	}
-	lappend command -b $newhead --track $remote
+        set remote $newhead
+        set newhead [string range $newhead [expr [string last / $newhead] + 1] end]
+        # The following check is redundant - the menu option should
+        # be disabled to begin with...
+        if {[info exists headids($newhead)]} {
+            error_popup [mc "A local branch named %s exists already" $newhead]
+            return
+        }
+        lappend command -b $newhead --track $remote
     } else {
-	lappend command $newhead
+        lappend command $newhead
     }
     lappend command 2>@1
     nowbusy checkout [mc "Checking out"]
     update
     dohidelocalchanges
     if {[catch {
-	set fd [open $command r]
+        set fd [open $command r]
     } err]} {
-	notbusy checkout
-	error_popup $err
-	if {$showlocalchanges} {
-	    dodiffindex
-	}
+        notbusy checkout
+        error_popup $err
+        if {$showlocalchanges} {
+            dodiffindex
+        }
     } else {
-	filerun $fd [list readcheckoutstat $fd $newhead $headmenuid]
+        filerun $fd [list readcheckoutstat $fd $newhead $headmenuid]
     }
 }
 
@@ -9939,24 +9957,24 @@
     global viewmainheadid curview
 
     if {[gets $fd line] >= 0} {
-	if {[regexp {([0-9]+)% \(([0-9]+)/([0-9]+)\)} $line match p m n]} {
-	    set progresscoords [list 0 [expr {1.0 * $m / $n}]]
-	    adjustprogress
-	}
-	return 1
+        if {[regexp {([0-9]+)% \(([0-9]+)/([0-9]+)\)} $line match p m n]} {
+            set progresscoords [list 0 [expr {1.0 * $m / $n}]]
+            adjustprogress
+        }
+        return 1
     }
     set progresscoords {0 0}
     adjustprogress
     notbusy checkout
     if {[catch {close $fd} err]} {
-	error_popup $err
-	return
+        error_popup $err
+        return
     }
     set oldmainid $mainheadid
     if {! [info exists headids($newhead)]} {
-	set headids($newhead) $newheadid
-	lappend idheads($newheadid) $newhead
-	addedhead $newheadid $newhead
+        set headids($newhead) $newheadid
+        lappend idheads($newheadid) $newhead
+        addedhead $newheadid $newhead
     }
     set mainhead $newhead
     set mainheadid $newheadid
@@ -9965,7 +9983,7 @@
     redrawtags $newheadid
     selbyid $newheadid
     if {$showlocalchanges} {
-	dodiffindex
+        dodiffindex
     }
 }
 
@@ -9977,21 +9995,21 @@
     set id $headmenuid
     # this check shouldn't be needed any more...
     if {$head eq $mainhead} {
-	error_popup [mc "Cannot delete the currently checked-out branch"]
-	return
+        error_popup [mc "Cannot delete the currently checked-out branch"]
+        return
     }
     set dheads [descheads $id]
     if {[llength $dheads] == 1 && $idheads($dheads) eq $head} {
-	# the stuff on this branch isn't on any other branch
-	if {![confirm_popup [mc "The commits on branch %s aren't on any other\
-			branch.\nReally delete branch %s?" $head $head]]} return
+        # the stuff on this branch isn't on any other branch
+        if {![confirm_popup [mc "The commits on branch %s aren't on any other\
+                        branch.\nReally delete branch %s?" $head $head]]} return
     }
     nowbusy rmbranch
     update
     if {[catch {exec git branch -D $head} err]} {
-	notbusy rmbranch
-	error_popup $err
-	return
+        notbusy rmbranch
+        error_popup $err
+        return
     }
     removehead $id $head
     removedhead $id $head
@@ -10009,22 +10027,22 @@
     set top .showrefs
     set showrefstop $top
     if {[winfo exists $top]} {
-	raise $top
-	refill_reflist
-	return
+        raise $top
+        refill_reflist
+        return
     }
     ttk_toplevel $top
     wm title $top [mc "Tags and heads: %s" [file tail [pwd]]]
     make_transient $top .
     text $top.list -background $bgcolor -foreground $fgcolor \
-	-selectbackground $selectbgcolor -font mainfont \
-	-xscrollcommand "$top.xsb set" -yscrollcommand "$top.ysb set" \
-	-width 30 -height 20 -cursor $maincursor \
-	-spacing1 1 -spacing3 1 -state disabled
+        -selectbackground $selectbgcolor -font mainfont \
+        -xscrollcommand "$top.xsb set" -yscrollcommand "$top.ysb set" \
+        -width 30 -height 20 -cursor $maincursor \
+        -spacing1 1 -spacing3 1 -state disabled
     $top.list tag configure highlight -background $selectbgcolor
     if {![lsearch -exact $bglist $top.list]} {
-	lappend bglist $top.list
-	lappend fglist $top.list
+        lappend bglist $top.list
+        lappend fglist $top.list
     }
     ${NS}::scrollbar $top.ysb -command "$top.list yview" -orient vertical
     ${NS}::scrollbar $top.xsb -command "$top.list xview" -orient horizontal
@@ -10058,10 +10076,10 @@
     set ref [lindex $reflist [expr {$l-1}]]
     set n [lindex $ref 0]
     switch -- [lindex $ref 1] {
-	"H" {selbyid $headids($n)}
-	"R" {selbyid $headids($n)}
-	"T" {selbyid $tagids($n)}
-	"o" {selbyid $otherrefids($n)}
+        "H" {selbyid $headids($n)}
+        "R" {selbyid $headids($n)}
+        "T" {selbyid $tagids($n)}
+        "o" {selbyid $otherrefids($n)}
     }
     $showrefstop.list tag add highlight $l.0 "$l.0 lineend"
 }
@@ -10087,35 +10105,35 @@
     if {![info exists showrefstop] || ![winfo exists $showrefstop]} return
     set refs {}
     foreach n [array names headids] {
-	if {[string match $reflistfilter $n]} {
-	    if {[commitinview $headids($n) $curview]} {
-		if {[string match "remotes/*" $n]} {
-		    lappend refs [list $n R]
-		} else {
-		    lappend refs [list $n H]
-		}
-	    } else {
-		interestedin $headids($n) {run refill_reflist}
-	    }
-	}
+        if {[string match $reflistfilter $n]} {
+            if {[commitinview $headids($n) $curview]} {
+                if {[string match "remotes/*" $n]} {
+                    lappend refs [list $n R]
+                } else {
+                    lappend refs [list $n H]
+                }
+            } else {
+                interestedin $headids($n) {run refill_reflist}
+            }
+        }
     }
     foreach n [array names tagids] {
-	if {[string match $reflistfilter $n]} {
-	    if {[commitinview $tagids($n) $curview]} {
-		lappend refs [list $n T]
-	    } else {
-		interestedin $tagids($n) {run refill_reflist}
-	    }
-	}
+        if {[string match $reflistfilter $n]} {
+            if {[commitinview $tagids($n) $curview]} {
+                lappend refs [list $n T]
+            } else {
+                interestedin $tagids($n) {run refill_reflist}
+            }
+        }
     }
     foreach n [array names otherrefids] {
-	if {[string match $reflistfilter $n]} {
-	    if {[commitinview $otherrefids($n) $curview]} {
-		lappend refs [list $n o]
-	    } else {
-		interestedin $otherrefids($n) {run refill_reflist}
-	    }
-	}
+        if {[string match $reflistfilter $n]} {
+            if {[commitinview $otherrefids($n) $curview]} {
+                lappend refs [list $n o]
+            } else {
+                interestedin $otherrefids($n) {run refill_reflist}
+            }
+        }
     }
     set refs [lsort -index 0 $refs]
     if {$refs eq $reflist} return
@@ -10127,37 +10145,37 @@
     set i 0
     set j 0
     while {$i < [llength $reflist] || $j < [llength $refs]} {
-	if {$i < [llength $reflist]} {
-	    if {$j < [llength $refs]} {
-		set cmp [string compare [lindex $reflist $i 0] \
-			     [lindex $refs $j 0]]
-		if {$cmp == 0} {
-		    set cmp [string compare [lindex $reflist $i 1] \
-				 [lindex $refs $j 1]]
-		}
-	    } else {
-		set cmp -1
-	    }
-	} else {
-	    set cmp 1
-	}
-	switch -- $cmp {
-	    -1 {
-		$showrefstop.list delete "[expr {$j+1}].0" "[expr {$j+2}].0"
-		incr i
-	    }
-	    0 {
-		incr i
-		incr j
-	    }
-	    1 {
-		set l [expr {$j + 1}]
-		$showrefstop.list image create $l.0 -align baseline \
-		    -image reficon-[lindex $refs $j 1] -padx 2
-		$showrefstop.list insert $l.1 "[lindex $refs $j 0]\n"
-		incr j
-	    }
-	}
+        if {$i < [llength $reflist]} {
+            if {$j < [llength $refs]} {
+                set cmp [string compare [lindex $reflist $i 0] \
+                             [lindex $refs $j 0]]
+                if {$cmp == 0} {
+                    set cmp [string compare [lindex $reflist $i 1] \
+                                 [lindex $refs $j 1]]
+                }
+            } else {
+                set cmp -1
+            }
+        } else {
+            set cmp 1
+        }
+        switch -- $cmp {
+            -1 {
+                $showrefstop.list delete "[expr {$j+1}].0" "[expr {$j+2}].0"
+                incr i
+            }
+            0 {
+                incr i
+                incr j
+            }
+            1 {
+                set l [expr {$j + 1}]
+                $showrefstop.list image create $l.0 -align baseline \
+                    -image reficon-[lindex $refs $j 1] -padx 2
+                $showrefstop.list insert $l.1 "[lindex $refs $j 0]\n"
+                incr j
+            }
+        }
     }
     set reflist $refs
     # delete last newline
@@ -10172,54 +10190,54 @@
     global gitdir
 
     if {![info exists allcommits]} {
-	set nextarc 0
-	set allcommits 0
-	set seeds {}
-	set allcwait 0
-	set cachedarcs 0
-	set allccache [file join $gitdir "gitk.cache"]
-	if {![catch {
-	    set f [open $allccache r]
-	    set allcwait 1
-	    getcache $f
-	}]} return
+        set nextarc 0
+        set allcommits 0
+        set seeds {}
+        set allcwait 0
+        set cachedarcs 0
+        set allccache [file join $gitdir "gitk.cache"]
+        if {![catch {
+            set f [open $allccache r]
+            set allcwait 1
+            getcache $f
+        }]} return
     }
 
     if {$allcwait} {
-	return
+        return
     }
     set cmd [list | git rev-list --parents]
     set allcupdate [expr {$seeds ne {}}]
     if {!$allcupdate} {
-	set ids "--all"
+        set ids "--all"
     } else {
-	set refs [concat [array names idheads] [array names idtags] \
-		      [array names idotherrefs]]
-	set ids {}
-	set tagobjs {}
-	foreach name [array names tagobjid] {
-	    lappend tagobjs $tagobjid($name)
-	}
-	foreach id [lsort -unique $refs] {
-	    if {![info exists allparents($id)] &&
-		[lsearch -exact $tagobjs $id] < 0} {
-		lappend ids $id
-	    }
-	}
-	if {$ids ne {}} {
-	    foreach id $seeds {
-		lappend ids "^$id"
-	    }
-	}
+        set refs [concat [array names idheads] [array names idtags] \
+                      [array names idotherrefs]]
+        set ids {}
+        set tagobjs {}
+        foreach name [array names tagobjid] {
+            lappend tagobjs $tagobjid($name)
+        }
+        foreach id [lsort -unique $refs] {
+            if {![info exists allparents($id)] &&
+                [lsearch -exact $tagobjs $id] < 0} {
+                lappend ids $id
+            }
+        }
+        if {$ids ne {}} {
+            foreach id $seeds {
+                lappend ids "^$id"
+            }
+        }
     }
     if {$ids ne {}} {
-	set fd [open [concat $cmd $ids] r]
-	fconfigure $fd -blocking 0
-	incr allcommits
-	nowbusy allcommits
-	filerun $fd [list getallclines $fd]
+        set fd [open [concat $cmd $ids] r]
+        fconfigure $fd -blocking 0
+        incr allcommits
+        nowbusy allcommits
+        filerun $fd [list getallclines $fd]
     } else {
-	dispneartags 0
+        dispneartags 0
     }
 }
 
@@ -10245,103 +10263,103 @@
 
     set nid 0
     while {[incr nid] <= 1000 && [gets $fd line] >= 0} {
-	set id [lindex $line 0]
-	if {[info exists allparents($id)]} {
-	    # seen it already
-	    continue
-	}
-	set cachedarcs 0
-	set olds [lrange $line 1 end]
-	set allparents($id) $olds
-	if {![info exists allchildren($id)]} {
-	    set allchildren($id) {}
-	    set arcnos($id) {}
-	    lappend seeds $id
-	} else {
-	    set a $arcnos($id)
-	    if {[llength $olds] == 1 && [llength $a] == 1} {
-		lappend arcids($a) $id
-		if {[info exists idtags($id)]} {
-		    lappend arctags($a) $id
-		}
-		if {[info exists idheads($id)]} {
-		    lappend archeads($a) $id
-		}
-		if {[info exists allparents($olds)]} {
-		    # seen parent already
-		    if {![info exists arcout($olds)]} {
-			splitarc $olds
-		    }
-		    lappend arcids($a) $olds
-		    set arcend($a) $olds
-		    unset growing($a)
-		}
-		lappend allchildren($olds) $id
-		lappend arcnos($olds) $a
-		continue
-	    }
-	}
-	foreach a $arcnos($id) {
-	    lappend arcids($a) $id
-	    set arcend($a) $id
-	    unset growing($a)
-	}
+        set id [lindex $line 0]
+        if {[info exists allparents($id)]} {
+            # seen it already
+            continue
+        }
+        set cachedarcs 0
+        set olds [lrange $line 1 end]
+        set allparents($id) $olds
+        if {![info exists allchildren($id)]} {
+            set allchildren($id) {}
+            set arcnos($id) {}
+            lappend seeds $id
+        } else {
+            set a $arcnos($id)
+            if {[llength $olds] == 1 && [llength $a] == 1} {
+                lappend arcids($a) $id
+                if {[info exists idtags($id)]} {
+                    lappend arctags($a) $id
+                }
+                if {[info exists idheads($id)]} {
+                    lappend archeads($a) $id
+                }
+                if {[info exists allparents($olds)]} {
+                    # seen parent already
+                    if {![info exists arcout($olds)]} {
+                        splitarc $olds
+                    }
+                    lappend arcids($a) $olds
+                    set arcend($a) $olds
+                    unset growing($a)
+                }
+                lappend allchildren($olds) $id
+                lappend arcnos($olds) $a
+                continue
+            }
+        }
+        foreach a $arcnos($id) {
+            lappend arcids($a) $id
+            set arcend($a) $id
+            unset growing($a)
+        }
 
-	set ao {}
-	foreach p $olds {
-	    lappend allchildren($p) $id
-	    set a [incr nextarc]
-	    set arcstart($a) $id
-	    set archeads($a) {}
-	    set arctags($a) {}
-	    set archeads($a) {}
-	    set arcids($a) {}
-	    lappend ao $a
-	    set growing($a) 1
-	    if {[info exists allparents($p)]} {
-		# seen it already, may need to make a new branch
-		if {![info exists arcout($p)]} {
-		    splitarc $p
-		}
-		lappend arcids($a) $p
-		set arcend($a) $p
-		unset growing($a)
-	    }
-	    lappend arcnos($p) $a
-	}
-	set arcout($id) $ao
+        set ao {}
+        foreach p $olds {
+            lappend allchildren($p) $id
+            set a [incr nextarc]
+            set arcstart($a) $id
+            set archeads($a) {}
+            set arctags($a) {}
+            set archeads($a) {}
+            set arcids($a) {}
+            lappend ao $a
+            set growing($a) 1
+            if {[info exists allparents($p)]} {
+                # seen it already, may need to make a new branch
+                if {![info exists arcout($p)]} {
+                    splitarc $p
+                }
+                lappend arcids($a) $p
+                set arcend($a) $p
+                unset growing($a)
+            }
+            lappend arcnos($p) $a
+        }
+        set arcout($id) $ao
     }
     if {$nid > 0} {
-	global cached_dheads cached_dtags cached_atags
-	unset -nocomplain cached_dheads
-	unset -nocomplain cached_dtags
-	unset -nocomplain cached_atags
+        global cached_dheads cached_dtags cached_atags
+        unset -nocomplain cached_dheads
+        unset -nocomplain cached_dtags
+        unset -nocomplain cached_atags
     }
     if {![eof $fd]} {
-	return [expr {$nid >= 1000? 2: 1}]
+        return [expr {$nid >= 1000? 2: 1}]
     }
     set cacheok 1
     if {[catch {
-	fconfigure $fd -blocking 1
-	close $fd
+        fconfigure $fd -blocking 1
+        close $fd
     } err]} {
-	# got an error reading the list of commits
-	# if we were updating, try rereading the whole thing again
-	if {$allcupdate} {
-	    incr allcommits -1
-	    dropcache $err
-	    return
-	}
-	error_popup "[mc "Error reading commit topology information;\
-		branch and preceding/following tag information\
-	        will be incomplete."]\n($err)"
-	set cacheok 0
+        # got an error reading the list of commits
+        # if we were updating, try rereading the whole thing again
+        if {$allcupdate} {
+            incr allcommits -1
+            dropcache $err
+            return
+        }
+        error_popup "[mc "Error reading commit topology information;\
+                branch and preceding/following tag information\
+                will be incomplete."]\n($err)"
+        set cacheok 0
     }
     if {[incr allcommits -1] == 0} {
-	notbusy allcommits
-	if {$cacheok} {
-	    run savecache
-	}
+        notbusy allcommits
+        if {$cacheok} {
+            run savecache
+        }
     }
     dispneartags 0
     return 0
@@ -10353,12 +10371,12 @@
     set at {}
     set ah {}
     foreach id [lrange $arcids($a) 0 end-1] {
-	if {[info exists idtags($id)]} {
-	    lappend at $id
-	}
-	if {[info exists idheads($id)]} {
-	    lappend ah $id
-	}
+        if {[info exists idtags($id)]} {
+            lappend at $id
+        }
+        if {[info exists idheads($id)]} {
+            lappend ah $id
+        }
     }
     set arctags($a) $at
     set archeads($a) $ah
@@ -10370,22 +10388,22 @@
 
     set a $arcnos($p)
     if {[llength $a] != 1} {
-	puts "oops splitarc called but [llength $a] arcs already"
-	return
+        puts "oops splitarc called but [llength $a] arcs already"
+        return
     }
     set a [lindex $a 0]
     set i [lsearch -exact $arcids($a) $p]
     if {$i < 0} {
-	puts "oops splitarc $p not in arc $a"
-	return
+        puts "oops splitarc $p not in arc $a"
+        return
     }
     set na [incr nextarc]
     if {[info exists arcend($a)]} {
-	set arcend($na) $arcend($a)
+        set arcend($na) $arcend($a)
     } else {
-	set l [lindex $allparents([lindex $arcids($a) end]) 0]
-	set j [lsearch -exact $arcnos($l) $a]
-	set arcnos($l) [lreplace $arcnos($l) $j $j $na]
+        set l [lindex $allparents([lindex $arcids($a) end]) 0]
+        set j [lsearch -exact $arcnos($l) $a]
+        set arcnos($l) [lreplace $arcnos($l) $j $j $na]
     }
     set tail [lrange $arcids($a) [expr {$i+1}] end]
     set arcids($a) [lrange $arcids($a) 0 $i]
@@ -10394,26 +10412,26 @@
     set arcout($p) $na
     set arcids($na) $tail
     if {[info exists growing($a)]} {
-	set growing($na) 1
-	unset growing($a)
+        set growing($na) 1
+        unset growing($a)
     }
 
     foreach id $tail {
-	if {[llength $arcnos($id)] == 1} {
-	    set arcnos($id) $na
-	} else {
-	    set j [lsearch -exact $arcnos($id) $a]
-	    set arcnos($id) [lreplace $arcnos($id) $j $j $na]
-	}
+        if {[llength $arcnos($id)] == 1} {
+            set arcnos($id) $na
+        } else {
+            set j [lsearch -exact $arcnos($id) $a]
+            set arcnos($id) [lreplace $arcnos($id) $j $j $na]
+        }
     }
 
     # reconstruct tags and heads lists
     if {$arctags($a) ne {} || $archeads($a) ne {}} {
-	recalcarc $a
-	recalcarc $na
+        recalcarc $a
+        recalcarc $na
     } else {
-	set arctags($na) {}
-	set archeads($na) {}
+        set arctags($na) {}
+        set archeads($na) {}
     }
 }
 
@@ -10437,7 +10455,7 @@
     set arcids($a) [list $p]
     set arcend($a) $p
     if {![info exists arcout($p)]} {
-	splitarc $p
+        splitarc $p
     }
     lappend arcnos($p) $a
     set arcout($id) [list $a]
@@ -10454,78 +10472,78 @@
     set a $nextarc
     set lim $cachedarcs
     if {$lim - $a > 500} {
-	set lim [expr {$a + 500}]
+        set lim [expr {$a + 500}]
     }
     if {[catch {
-	if {$a == $lim} {
-	    # finish reading the cache and setting up arctags, etc.
-	    set line [gets $f]
-	    if {$line ne "1"} {error "bad final version"}
-	    close $f
-	    foreach id [array names idtags] {
-		if {[info exists arcnos($id)] && [llength $arcnos($id)] == 1 &&
-		    [llength $allparents($id)] == 1} {
-		    set a [lindex $arcnos($id) 0]
-		    if {$arctags($a) eq {}} {
-			recalcarc $a
-		    }
-		}
-	    }
-	    foreach id [array names idheads] {
-		if {[info exists arcnos($id)] && [llength $arcnos($id)] == 1 &&
-		    [llength $allparents($id)] == 1} {
-		    set a [lindex $arcnos($id) 0]
-		    if {$archeads($a) eq {}} {
-			recalcarc $a
-		    }
-		}
-	    }
-	    foreach id [lsort -unique $possible_seeds] {
-		if {$arcnos($id) eq {}} {
-		    lappend seeds $id
-		}
-	    }
-	    set allcwait 0
-	} else {
-	    while {[incr a] <= $lim} {
-		set line [gets $f]
-		if {[llength $line] != 3} {error "bad line"}
-		set s [lindex $line 0]
-		set arcstart($a) $s
-		lappend arcout($s) $a
-		if {![info exists arcnos($s)]} {
-		    lappend possible_seeds $s
-		    set arcnos($s) {}
-		}
-		set e [lindex $line 1]
-		if {$e eq {}} {
-		    set growing($a) 1
-		} else {
-		    set arcend($a) $e
-		    if {![info exists arcout($e)]} {
-			set arcout($e) {}
-		    }
-		}
-		set arcids($a) [lindex $line 2]
-		foreach id $arcids($a) {
-		    lappend allparents($s) $id
-		    set s $id
-		    lappend arcnos($id) $a
-		}
-		if {![info exists allparents($s)]} {
-		    set allparents($s) {}
-		}
-		set arctags($a) {}
-		set archeads($a) {}
-	    }
-	    set nextarc [expr {$a - 1}]
-	}
+        if {$a == $lim} {
+            # finish reading the cache and setting up arctags, etc.
+            set line [gets $f]
+            if {$line ne "1"} {error "bad final version"}
+            close $f
+            foreach id [array names idtags] {
+                if {[info exists arcnos($id)] && [llength $arcnos($id)] == 1 &&
+                    [llength $allparents($id)] == 1} {
+                    set a [lindex $arcnos($id) 0]
+                    if {$arctags($a) eq {}} {
+                        recalcarc $a
+                    }
+                }
+            }
+            foreach id [array names idheads] {
+                if {[info exists arcnos($id)] && [llength $arcnos($id)] == 1 &&
+                    [llength $allparents($id)] == 1} {
+                    set a [lindex $arcnos($id) 0]
+                    if {$archeads($a) eq {}} {
+                        recalcarc $a
+                    }
+                }
+            }
+            foreach id [lsort -unique $possible_seeds] {
+                if {$arcnos($id) eq {}} {
+                    lappend seeds $id
+                }
+            }
+            set allcwait 0
+        } else {
+            while {[incr a] <= $lim} {
+                set line [gets $f]
+                if {[llength $line] != 3} {error "bad line"}
+                set s [lindex $line 0]
+                set arcstart($a) $s
+                lappend arcout($s) $a
+                if {![info exists arcnos($s)]} {
+                    lappend possible_seeds $s
+                    set arcnos($s) {}
+                }
+                set e [lindex $line 1]
+                if {$e eq {}} {
+                    set growing($a) 1
+                } else {
+                    set arcend($a) $e
+                    if {![info exists arcout($e)]} {
+                        set arcout($e) {}
+                    }
+                }
+                set arcids($a) [lindex $line 2]
+                foreach id $arcids($a) {
+                    lappend allparents($s) $id
+                    set s $id
+                    lappend arcnos($id) $a
+                }
+                if {![info exists allparents($s)]} {
+                    set allparents($s) {}
+                }
+                set arctags($a) {}
+                set archeads($a) {}
+            }
+            set nextarc [expr {$a - 1}]
+        }
     } err]} {
-	dropcache $err
-	return 0
+        dropcache $err
+        return 0
     }
     if {!$allcwait} {
-	getallcommits
+        getallcommits
     }
     return $allcwait
 }
@@ -10534,16 +10552,16 @@
     global nextarc cachedarcs possible_seeds
 
     if {[catch {
-	set line [gets $f]
-	if {[llength $line] != 2 || [lindex $line 0] ne "1"} {error "bad version"}
-	# make sure it's an integer
-	set cachedarcs [expr {int([lindex $line 1])}]
-	if {$cachedarcs < 0} {error "bad number of arcs"}
-	set nextarc 0
-	set possible_seeds {}
-	run readcache $f
+        set line [gets $f]
+        if {[llength $line] != 2 || [lindex $line 0] ne "1"} {error "bad version"}
+        # make sure it's an integer
+        set cachedarcs [expr {int([lindex $line 1])}]
+        if {$cachedarcs < 0} {error "bad number of arcs"}
+        set nextarc 0
+        set possible_seeds {}
+        run readcache $f
     } err]} {
-	dropcache $err
+        dropcache $err
     }
     return 0
 }
@@ -10553,9 +10571,9 @@
 
     #puts "dropping cache ($err)"
     foreach v {arcnos arcout arcids arcstart arcend growing \
-		   arctags archeads allparents allchildren} {
-	global $v
-	unset -nocomplain $v
+                   arctags archeads allparents allchildren} {
+        global $v
+        unset -nocomplain $v
     }
     set allcwait 0
     set nextarc 0
@@ -10571,27 +10589,27 @@
     set a $cachearc
     set lim $cachedarcs
     if {$lim - $a > 1000} {
-	set lim [expr {$a + 1000}]
+        set lim [expr {$a + 1000}]
     }
     if {[catch {
-	while {[incr a] <= $lim} {
-	    if {[info exists arcend($a)]} {
-		puts $f [list $arcstart($a) $arcend($a) $arcids($a)]
-	    } else {
-		puts $f [list $arcstart($a) {} $arcids($a)]
-	    }
-	}
+        while {[incr a] <= $lim} {
+            if {[info exists arcend($a)]} {
+                puts $f [list $arcstart($a) $arcend($a) $arcids($a)]
+            } else {
+                puts $f [list $arcstart($a) {} $arcids($a)]
+            }
+        }
     } err]} {
-	catch {close $f}
-	catch {file delete $allccache}
-	#puts "writing cache failed ($err)"
-	return 0
+        catch {close $f}
+        catch {file delete $allccache}
+        #puts "writing cache failed ($err)"
+        return 0
     }
     set cachearc [expr {$a - 1}]
     if {$a > $cachedarcs} {
-	puts $f "1"
-	close $f
-	return 0
+        puts $f "1"
+        close $f
+        return 0
     }
     return 1
 }
@@ -10603,9 +10621,9 @@
     set cachearc 0
     set cachedarcs $nextarc
     catch {
-	set f [open $allccache w]
-	puts $f [list 1 $cachedarcs]
-	run writecache $f
+        set f [open $allccache w]
+        puts $f [list 1 $cachedarcs]
+        run writecache $f
     }
 }
 
@@ -10615,92 +10633,92 @@
     global arcout arcstart arcend arcnos cached_isanc
 
     if {$arcnos($a) eq $arcnos($b)} {
-	# Both are on the same arc(s); either both are the same BMP,
-	# or if one is not a BMP, the other is also not a BMP or is
-	# the BMP at end of the arc (and it only has 1 incoming arc).
-	# Or both can be BMPs with no incoming arcs.
-	if {$a eq $b || $arcnos($a) eq {}} {
-	    return 0
-	}
-	# assert {[llength $arcnos($a)] == 1}
-	set arc [lindex $arcnos($a) 0]
-	set i [lsearch -exact $arcids($arc) $a]
-	set j [lsearch -exact $arcids($arc) $b]
-	if {$i < 0 || $i > $j} {
-	    return 1
-	} else {
-	    return -1
-	}
+        # Both are on the same arc(s); either both are the same BMP,
+        # or if one is not a BMP, the other is also not a BMP or is
+        # the BMP at end of the arc (and it only has 1 incoming arc).
+        # Or both can be BMPs with no incoming arcs.
+        if {$a eq $b || $arcnos($a) eq {}} {
+            return 0
+        }
+        # assert {[llength $arcnos($a)] == 1}
+        set arc [lindex $arcnos($a) 0]
+        set i [lsearch -exact $arcids($arc) $a]
+        set j [lsearch -exact $arcids($arc) $b]
+        if {$i < 0 || $i > $j} {
+            return 1
+        } else {
+            return -1
+        }
     }
 
     if {![info exists arcout($a)]} {
-	set arc [lindex $arcnos($a) 0]
-	if {[info exists arcend($arc)]} {
-	    set aend $arcend($arc)
-	} else {
-	    set aend {}
-	}
-	set a $arcstart($arc)
+        set arc [lindex $arcnos($a) 0]
+        if {[info exists arcend($arc)]} {
+            set aend $arcend($arc)
+        } else {
+            set aend {}
+        }
+        set a $arcstart($arc)
     } else {
-	set aend $a
+        set aend $a
     }
     if {![info exists arcout($b)]} {
-	set arc [lindex $arcnos($b) 0]
-	if {[info exists arcend($arc)]} {
-	    set bend $arcend($arc)
-	} else {
-	    set bend {}
-	}
-	set b $arcstart($arc)
+        set arc [lindex $arcnos($b) 0]
+        if {[info exists arcend($arc)]} {
+            set bend $arcend($arc)
+        } else {
+            set bend {}
+        }
+        set b $arcstart($arc)
     } else {
-	set bend $b
+        set bend $b
     }
     if {$a eq $bend} {
-	return 1
+        return 1
     }
     if {$b eq $aend} {
-	return -1
+        return -1
     }
     if {[info exists cached_isanc($a,$bend)]} {
-	if {$cached_isanc($a,$bend)} {
-	    return 1
-	}
+        if {$cached_isanc($a,$bend)} {
+            return 1
+        }
     }
     if {[info exists cached_isanc($b,$aend)]} {
-	if {$cached_isanc($b,$aend)} {
-	    return -1
-	}
-	if {[info exists cached_isanc($a,$bend)]} {
-	    return 0
-	}
+        if {$cached_isanc($b,$aend)} {
+            return -1
+        }
+        if {[info exists cached_isanc($a,$bend)]} {
+            return 0
+        }
     }
 
     set todo [list $a $b]
     set anc($a) a
     set anc($b) b
     for {set i 0} {$i < [llength $todo]} {incr i} {
-	set x [lindex $todo $i]
-	if {$anc($x) eq {}} {
-	    continue
-	}
-	foreach arc $arcnos($x) {
-	    set xd $arcstart($arc)
-	    if {$xd eq $bend} {
-		set cached_isanc($a,$bend) 1
-		set cached_isanc($b,$aend) 0
-		return 1
-	    } elseif {$xd eq $aend} {
-		set cached_isanc($b,$aend) 1
-		set cached_isanc($a,$bend) 0
-		return -1
-	    }
-	    if {![info exists anc($xd)]} {
-		set anc($xd) $anc($x)
-		lappend todo $xd
-	    } elseif {$anc($xd) ne $anc($x)} {
-		set anc($xd) {}
-	    }
-	}
+        set x [lindex $todo $i]
+        if {$anc($x) eq {}} {
+            continue
+        }
+        foreach arc $arcnos($x) {
+            set xd $arcstart($arc)
+            if {$xd eq $bend} {
+                set cached_isanc($a,$bend) 1
+                set cached_isanc($b,$aend) 0
+                return 1
+            } elseif {$xd eq $aend} {
+                set cached_isanc($b,$aend) 1
+                set cached_isanc($a,$bend) 0
+                return -1
+            }
+            if {![info exists anc($xd)]} {
+                set anc($xd) $anc($x)
+                lappend todo $xd
+            } elseif {$anc($xd) ne $anc($x)} {
+                set anc($xd) {}
+            }
+        }
     }
     set cached_isanc($a,$bend) 0
     set cached_isanc($b,$aend) 0
@@ -10723,90 +10741,90 @@
 
     set certain {}
     if {[llength $arcnos($anc)] == 1} {
-	# tags on the same arc are certain
-	if {$arcnos($desc) eq $arcnos($anc)} {
-	    return 1
-	}
-	if {![info exists arcout($anc)]} {
-	    # if $anc is partway along an arc, use the start of the arc instead
-	    set a [lindex $arcnos($anc) 0]
-	    set anc $arcstart($a)
-	}
+        # tags on the same arc are certain
+        if {$arcnos($desc) eq $arcnos($anc)} {
+            return 1
+        }
+        if {![info exists arcout($anc)]} {
+            # if $anc is partway along an arc, use the start of the arc instead
+            set a [lindex $arcnos($anc) 0]
+            set anc $arcstart($a)
+        }
     }
     if {[llength $arcnos($desc)] > 1 || [info exists arcout($desc)]} {
-	set x $desc
+        set x $desc
     } else {
-	set a [lindex $arcnos($desc) 0]
-	set x $arcend($a)
+        set a [lindex $arcnos($desc) 0]
+        set x $arcend($a)
     }
     if {$x == $anc} {
-	return 1
+        return 1
     }
     set anclist [list $x]
     set dl($x) 1
     set nnh 1
     set ngrowanc 0
     for {set i 0} {$i < [llength $anclist] && ($nnh > 0 || $ngrowanc > 0)} {incr i} {
-	set x [lindex $anclist $i]
-	if {$dl($x)} {
-	    incr nnh -1
-	}
-	set done($x) 1
-	foreach a $arcout($x) {
-	    if {[info exists growing($a)]} {
-		if {![info exists growanc($x)] && $dl($x)} {
-		    set growanc($x) 1
-		    incr ngrowanc
-		}
-	    } else {
-		set y $arcend($a)
-		if {[info exists dl($y)]} {
-		    if {$dl($y)} {
-			if {!$dl($x)} {
-			    set dl($y) 0
-			    if {![info exists done($y)]} {
-				incr nnh -1
-			    }
-			    if {[info exists growanc($x)]} {
-				incr ngrowanc -1
-			    }
-			    set xl [list $y]
-			    for {set k 0} {$k < [llength $xl]} {incr k} {
-				set z [lindex $xl $k]
-				foreach c $arcout($z) {
-				    if {[info exists arcend($c)]} {
-					set v $arcend($c)
-					if {[info exists dl($v)] && $dl($v)} {
-					    set dl($v) 0
-					    if {![info exists done($v)]} {
-						incr nnh -1
-					    }
-					    if {[info exists growanc($v)]} {
-						incr ngrowanc -1
-					    }
-					    lappend xl $v
-					}
-				    }
-				}
-			    }
-			}
-		    }
-		} elseif {$y eq $anc || !$dl($x)} {
-		    set dl($y) 0
-		    lappend anclist $y
-		} else {
-		    set dl($y) 1
-		    lappend anclist $y
-		    incr nnh
-		}
-	    }
-	}
+        set x [lindex $anclist $i]
+        if {$dl($x)} {
+            incr nnh -1
+        }
+        set done($x) 1
+        foreach a $arcout($x) {
+            if {[info exists growing($a)]} {
+                if {![info exists growanc($x)] && $dl($x)} {
+                    set growanc($x) 1
+                    incr ngrowanc
+                }
+            } else {
+                set y $arcend($a)
+                if {[info exists dl($y)]} {
+                    if {$dl($y)} {
+                        if {!$dl($x)} {
+                            set dl($y) 0
+                            if {![info exists done($y)]} {
+                                incr nnh -1
+                            }
+                            if {[info exists growanc($x)]} {
+                                incr ngrowanc -1
+                            }
+                            set xl [list $y]
+                            for {set k 0} {$k < [llength $xl]} {incr k} {
+                                set z [lindex $xl $k]
+                                foreach c $arcout($z) {
+                                    if {[info exists arcend($c)]} {
+                                        set v $arcend($c)
+                                        if {[info exists dl($v)] && $dl($v)} {
+                                            set dl($v) 0
+                                            if {![info exists done($v)]} {
+                                                incr nnh -1
+                                            }
+                                            if {[info exists growanc($v)]} {
+                                                incr ngrowanc -1
+                                            }
+                                            lappend xl $v
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } elseif {$y eq $anc || !$dl($x)} {
+                    set dl($y) 0
+                    lappend anclist $y
+                } else {
+                    set dl($y) 1
+                    lappend anclist $y
+                    incr nnh
+                }
+            }
+        }
     }
     foreach x [array names growanc] {
-	if {$dl($x)} {
-	    return 0
-	}
-	return 0
+        if {$dl($x)} {
+            return 0
+        }
+        return 0
     }
     return 1
 }
@@ -10817,11 +10835,11 @@
     set i -1
     set na $arctags($a)
     foreach id $arctags($a) {
-	incr i
-	if {![info exists idtags($id)]} {
-	    set na [lreplace $na $i $i]
-	    incr i -1
-	}
+        incr i
+        if {![info exists idtags($id)]} {
+            set na [lreplace $na $i $i]
+            incr i -1
+        }
     }
     set arctags($a) $na
 }
@@ -10832,11 +10850,11 @@
     set i -1
     set na $archeads($a)
     foreach id $archeads($a) {
-	incr i
-	if {![info exists idheads($id)]} {
-	    set na [lreplace $na $i $i]
-	    incr i -1
-	}
+        incr i
+        if {![info exists idheads($id)]} {
+            set na [lreplace $na $i $i]
+            incr i -1
+        }
     }
     set archeads($a) $na
 }
@@ -10848,33 +10866,33 @@
     global growing cached_dtags
 
     if {![info exists allparents($id)]} {
-	return {}
+        return {}
     }
     set t1 [clock clicks -milliseconds]
     set argid $id
     if {[llength $arcnos($id)] == 1 && [llength $allparents($id)] == 1} {
-	# part-way along an arc; check that arc first
-	set a [lindex $arcnos($id) 0]
-	if {$arctags($a) ne {}} {
-	    validate_arctags $a
-	    set i [lsearch -exact $arcids($a) $id]
-	    set tid {}
-	    foreach t $arctags($a) {
-		set j [lsearch -exact $arcids($a) $t]
-		if {$j >= $i} break
-		set tid $t
-	    }
-	    if {$tid ne {}} {
-		return $tid
-	    }
-	}
-	set id $arcstart($a)
-	if {[info exists idtags($id)]} {
-	    return $id
-	}
+        # part-way along an arc; check that arc first
+        set a [lindex $arcnos($id) 0]
+        if {$arctags($a) ne {}} {
+            validate_arctags $a
+            set i [lsearch -exact $arcids($a) $id]
+            set tid {}
+            foreach t $arctags($a) {
+                set j [lsearch -exact $arcids($a) $t]
+                if {$j >= $i} break
+                set tid $t
+            }
+            if {$tid ne {}} {
+                return $tid
+            }
+        }
+        set id $arcstart($a)
+        if {[info exists idtags($id)]} {
+            return $id
+        }
     }
     if {[info exists cached_dtags($id)]} {
-	return $cached_dtags($id)
+        return $cached_dtags($id)
     }
 
     set origid $id
@@ -10882,111 +10900,111 @@
     set queued($id) 1
     set nc 1
     for {set i 0} {$i < [llength $todo] && $nc > 0} {incr i} {
-	set id [lindex $todo $i]
-	set done($id) 1
-	set ta [info exists hastaggedancestor($id)]
-	if {!$ta} {
-	    incr nc -1
-	}
-	# ignore tags on starting node
-	if {!$ta && $i > 0} {
-	    if {[info exists idtags($id)]} {
-		set tagloc($id) $id
-		set ta 1
-	    } elseif {[info exists cached_dtags($id)]} {
-		set tagloc($id) $cached_dtags($id)
-		set ta 1
-	    }
-	}
-	foreach a $arcnos($id) {
-	    set d $arcstart($a)
-	    if {!$ta && $arctags($a) ne {}} {
-		validate_arctags $a
-		if {$arctags($a) ne {}} {
-		    lappend tagloc($id) [lindex $arctags($a) end]
-		}
-	    }
-	    if {$ta || $arctags($a) ne {}} {
-		set tomark [list $d]
-		for {set j 0} {$j < [llength $tomark]} {incr j} {
-		    set dd [lindex $tomark $j]
-		    if {![info exists hastaggedancestor($dd)]} {
-			if {[info exists done($dd)]} {
-			    foreach b $arcnos($dd) {
-				lappend tomark $arcstart($b)
-			    }
-			    if {[info exists tagloc($dd)]} {
-				unset tagloc($dd)
-			    }
-			} elseif {[info exists queued($dd)]} {
-			    incr nc -1
-			}
-			set hastaggedancestor($dd) 1
-		    }
-		}
-	    }
-	    if {![info exists queued($d)]} {
-		lappend todo $d
-		set queued($d) 1
-		if {![info exists hastaggedancestor($d)]} {
-		    incr nc
-		}
-	    }
-	}
+        set id [lindex $todo $i]
+        set done($id) 1
+        set ta [info exists hastaggedancestor($id)]
+        if {!$ta} {
+            incr nc -1
+        }
+        # ignore tags on starting node
+        if {!$ta && $i > 0} {
+            if {[info exists idtags($id)]} {
+                set tagloc($id) $id
+                set ta 1
+            } elseif {[info exists cached_dtags($id)]} {
+                set tagloc($id) $cached_dtags($id)
+                set ta 1
+            }
+        }
+        foreach a $arcnos($id) {
+            set d $arcstart($a)
+            if {!$ta && $arctags($a) ne {}} {
+                validate_arctags $a
+                if {$arctags($a) ne {}} {
+                    lappend tagloc($id) [lindex $arctags($a) end]
+                }
+            }
+            if {$ta || $arctags($a) ne {}} {
+                set tomark [list $d]
+                for {set j 0} {$j < [llength $tomark]} {incr j} {
+                    set dd [lindex $tomark $j]
+                    if {![info exists hastaggedancestor($dd)]} {
+                        if {[info exists done($dd)]} {
+                            foreach b $arcnos($dd) {
+                                lappend tomark $arcstart($b)
+                            }
+                            if {[info exists tagloc($dd)]} {
+                                unset tagloc($dd)
+                            }
+                        } elseif {[info exists queued($dd)]} {
+                            incr nc -1
+                        }
+                        set hastaggedancestor($dd) 1
+                    }
+                }
+            }
+            if {![info exists queued($d)]} {
+                lappend todo $d
+                set queued($d) 1
+                if {![info exists hastaggedancestor($d)]} {
+                    incr nc
+                }
+            }
+        }
     }
     set tags {}
     foreach id [array names tagloc] {
-	if {![info exists hastaggedancestor($id)]} {
-	    foreach t $tagloc($id) {
-		if {[lsearch -exact $tags $t] < 0} {
-		    lappend tags $t
-		}
-	    }
-	}
+        if {![info exists hastaggedancestor($id)]} {
+            foreach t $tagloc($id) {
+                if {[lsearch -exact $tags $t] < 0} {
+                    lappend tags $t
+                }
+            }
+        }
     }
     set t2 [clock clicks -milliseconds]
     set loopix $i
 
     # remove tags that are descendents of other tags
     for {set i 0} {$i < [llength $tags]} {incr i} {
-	set a [lindex $tags $i]
-	for {set j 0} {$j < $i} {incr j} {
-	    set b [lindex $tags $j]
-	    set r [anc_or_desc $a $b]
-	    if {$r == 1} {
-		set tags [lreplace $tags $j $j]
-		incr j -1
-		incr i -1
-	    } elseif {$r == -1} {
-		set tags [lreplace $tags $i $i]
-		incr i -1
-		break
-	    }
-	}
+        set a [lindex $tags $i]
+        for {set j 0} {$j < $i} {incr j} {
+            set b [lindex $tags $j]
+            set r [anc_or_desc $a $b]
+            if {$r == 1} {
+                set tags [lreplace $tags $j $j]
+                incr j -1
+                incr i -1
+            } elseif {$r == -1} {
+                set tags [lreplace $tags $i $i]
+                incr i -1
+                break
+            }
+        }
     }
 
     if {[array names growing] ne {}} {
-	# graph isn't finished, need to check if any tag could get
-	# eclipsed by another tag coming later.  Simply ignore any
-	# tags that could later get eclipsed.
-	set ctags {}
-	foreach t $tags {
-	    if {[is_certain $t $origid]} {
-		lappend ctags $t
-	    }
-	}
-	if {$tags eq $ctags} {
-	    set cached_dtags($origid) $tags
-	} else {
-	    set tags $ctags
-	}
+        # graph isn't finished, need to check if any tag could get
+        # eclipsed by another tag coming later.  Simply ignore any
+        # tags that could later get eclipsed.
+        set ctags {}
+        foreach t $tags {
+            if {[is_certain $t $origid]} {
+                lappend ctags $t
+            }
+        }
+        if {$tags eq $ctags} {
+            set cached_dtags($origid) $tags
+        } else {
+            set tags $ctags
+        }
     } else {
-	set cached_dtags($origid) $tags
+        set cached_dtags($origid) $tags
     }
     set t3 [clock clicks -milliseconds]
     if {0 && $t3 - $t1 >= 100} {
-	puts "iterating descendents ($loopix/[llength $todo] nodes) took\
-    	    [expr {$t2-$t1}]+[expr {$t3-$t2}]ms, $nc candidates left"
+        puts "iterating descendents ($loopix/[llength $todo] nodes) took\
+            [expr {$t2-$t1}]+[expr {$t3-$t2}]ms, $nc candidates left"
     }
     return $tags
 }
@@ -10996,33 +11014,33 @@
     global growing cached_atags
 
     if {![info exists allparents($id)]} {
-	return {}
+        return {}
     }
     set t1 [clock clicks -milliseconds]
     set argid $id
     if {[llength $arcnos($id)] == 1 && [llength $allparents($id)] == 1} {
-	# part-way along an arc; check that arc first
-	set a [lindex $arcnos($id) 0]
-	if {$arctags($a) ne {}} {
-	    validate_arctags $a
-	    set i [lsearch -exact $arcids($a) $id]
-	    foreach t $arctags($a) {
-		set j [lsearch -exact $arcids($a) $t]
-		if {$j > $i} {
-		    return $t
-		}
-	    }
-	}
-	if {![info exists arcend($a)]} {
-	    return {}
-	}
-	set id $arcend($a)
-	if {[info exists idtags($id)]} {
-	    return $id
-	}
+        # part-way along an arc; check that arc first
+        set a [lindex $arcnos($id) 0]
+        if {$arctags($a) ne {}} {
+            validate_arctags $a
+            set i [lsearch -exact $arcids($a) $id]
+            foreach t $arctags($a) {
+                set j [lsearch -exact $arcids($a) $t]
+                if {$j > $i} {
+                    return $t
+                }
+            }
+        }
+        if {![info exists arcend($a)]} {
+            return {}
+        }
+        set id $arcend($a)
+        if {[info exists idtags($id)]} {
+            return $id
+        }
     }
     if {[info exists cached_atags($id)]} {
-	return $cached_atags($id)
+        return $cached_atags($id)
     }
 
     set origid $id
@@ -11031,114 +11049,114 @@
     set taglist {}
     set nc 1
     for {set i 0} {$i < [llength $todo] && $nc > 0} {incr i} {
-	set id [lindex $todo $i]
-	set done($id) 1
-	set td [info exists hastaggeddescendent($id)]
-	if {!$td} {
-	    incr nc -1
-	}
-	# ignore tags on starting node
-	if {!$td && $i > 0} {
-	    if {[info exists idtags($id)]} {
-		set tagloc($id) $id
-		set td 1
-	    } elseif {[info exists cached_atags($id)]} {
-		set tagloc($id) $cached_atags($id)
-		set td 1
-	    }
-	}
-	foreach a $arcout($id) {
-	    if {!$td && $arctags($a) ne {}} {
-		validate_arctags $a
-		if {$arctags($a) ne {}} {
-		    lappend tagloc($id) [lindex $arctags($a) 0]
-		}
-	    }
-	    if {![info exists arcend($a)]} continue
-	    set d $arcend($a)
-	    if {$td || $arctags($a) ne {}} {
-		set tomark [list $d]
-		for {set j 0} {$j < [llength $tomark]} {incr j} {
-		    set dd [lindex $tomark $j]
-		    if {![info exists hastaggeddescendent($dd)]} {
-			if {[info exists done($dd)]} {
-			    foreach b $arcout($dd) {
-				if {[info exists arcend($b)]} {
-				    lappend tomark $arcend($b)
-				}
-			    }
-			    if {[info exists tagloc($dd)]} {
-				unset tagloc($dd)
-			    }
-			} elseif {[info exists queued($dd)]} {
-			    incr nc -1
-			}
-			set hastaggeddescendent($dd) 1
-		    }
-		}
-	    }
-	    if {![info exists queued($d)]} {
-		lappend todo $d
-		set queued($d) 1
-		if {![info exists hastaggeddescendent($d)]} {
-		    incr nc
-		}
-	    }
-	}
+        set id [lindex $todo $i]
+        set done($id) 1
+        set td [info exists hastaggeddescendent($id)]
+        if {!$td} {
+            incr nc -1
+        }
+        # ignore tags on starting node
+        if {!$td && $i > 0} {
+            if {[info exists idtags($id)]} {
+                set tagloc($id) $id
+                set td 1
+            } elseif {[info exists cached_atags($id)]} {
+                set tagloc($id) $cached_atags($id)
+                set td 1
+            }
+        }
+        foreach a $arcout($id) {
+            if {!$td && $arctags($a) ne {}} {
+                validate_arctags $a
+                if {$arctags($a) ne {}} {
+                    lappend tagloc($id) [lindex $arctags($a) 0]
+                }
+            }
+            if {![info exists arcend($a)]} continue
+            set d $arcend($a)
+            if {$td || $arctags($a) ne {}} {
+                set tomark [list $d]
+                for {set j 0} {$j < [llength $tomark]} {incr j} {
+                    set dd [lindex $tomark $j]
+                    if {![info exists hastaggeddescendent($dd)]} {
+                        if {[info exists done($dd)]} {
+                            foreach b $arcout($dd) {
+                                if {[info exists arcend($b)]} {
+                                    lappend tomark $arcend($b)
+                                }
+                            }
+                            if {[info exists tagloc($dd)]} {
+                                unset tagloc($dd)
+                            }
+                        } elseif {[info exists queued($dd)]} {
+                            incr nc -1
+                        }
+                        set hastaggeddescendent($dd) 1
+                    }
+                }
+            }
+            if {![info exists queued($d)]} {
+                lappend todo $d
+                set queued($d) 1
+                if {![info exists hastaggeddescendent($d)]} {
+                    incr nc
+                }
+            }
+        }
     }
     set t2 [clock clicks -milliseconds]
     set loopix $i
     set tags {}
     foreach id [array names tagloc] {
-	if {![info exists hastaggeddescendent($id)]} {
-	    foreach t $tagloc($id) {
-		if {[lsearch -exact $tags $t] < 0} {
-		    lappend tags $t
-		}
-	    }
-	}
+        if {![info exists hastaggeddescendent($id)]} {
+            foreach t $tagloc($id) {
+                if {[lsearch -exact $tags $t] < 0} {
+                    lappend tags $t
+                }
+            }
+        }
     }
 
     # remove tags that are ancestors of other tags
     for {set i 0} {$i < [llength $tags]} {incr i} {
-	set a [lindex $tags $i]
-	for {set j 0} {$j < $i} {incr j} {
-	    set b [lindex $tags $j]
-	    set r [anc_or_desc $a $b]
-	    if {$r == -1} {
-		set tags [lreplace $tags $j $j]
-		incr j -1
-		incr i -1
-	    } elseif {$r == 1} {
-		set tags [lreplace $tags $i $i]
-		incr i -1
-		break
-	    }
-	}
+        set a [lindex $tags $i]
+        for {set j 0} {$j < $i} {incr j} {
+            set b [lindex $tags $j]
+            set r [anc_or_desc $a $b]
+            if {$r == -1} {
+                set tags [lreplace $tags $j $j]
+                incr j -1
+                incr i -1
+            } elseif {$r == 1} {
+                set tags [lreplace $tags $i $i]
+                incr i -1
+                break
+            }
+        }
     }
 
     if {[array names growing] ne {}} {
-	# graph isn't finished, need to check if any tag could get
-	# eclipsed by another tag coming later.  Simply ignore any
-	# tags that could later get eclipsed.
-	set ctags {}
-	foreach t $tags {
-	    if {[is_certain $origid $t]} {
-		lappend ctags $t
-	    }
-	}
-	if {$tags eq $ctags} {
-	    set cached_atags($origid) $tags
-	} else {
-	    set tags $ctags
-	}
+        # graph isn't finished, need to check if any tag could get
+        # eclipsed by another tag coming later.  Simply ignore any
+        # tags that could later get eclipsed.
+        set ctags {}
+        foreach t $tags {
+            if {[is_certain $origid $t]} {
+                lappend ctags $t
+            }
+        }
+        if {$tags eq $ctags} {
+            set cached_atags($origid) $tags
+        } else {
+            set tags $ctags
+        }
     } else {
-	set cached_atags($origid) $tags
+        set cached_atags($origid) $tags
     }
     set t3 [clock clicks -milliseconds]
     if {0 && $t3 - $t1 >= 100} {
-	puts "iterating ancestors ($loopix/[llength $todo] nodes) took\
-    	    [expr {$t2-$t1}]+[expr {$t3-$t2}]ms, $nc candidates left"
+        puts "iterating ancestors ($loopix/[llength $todo] nodes) took\
+            [expr {$t2-$t1}]+[expr {$t3-$t2}]ms, $nc candidates left"
     }
     return $tags
 }
@@ -11150,49 +11168,49 @@
     global allparents arcout
 
     if {![info exists allparents($id)]} {
-	return {}
+        return {}
     }
     set aret {}
     if {![info exists arcout($id)]} {
-	# part-way along an arc; check it first
-	set a [lindex $arcnos($id) 0]
-	if {$archeads($a) ne {}} {
-	    validate_archeads $a
-	    set i [lsearch -exact $arcids($a) $id]
-	    foreach t $archeads($a) {
-		set j [lsearch -exact $arcids($a) $t]
-		if {$j > $i} break
-		lappend aret $t
-	    }
-	}
-	set id $arcstart($a)
+        # part-way along an arc; check it first
+        set a [lindex $arcnos($id) 0]
+        if {$archeads($a) ne {}} {
+            validate_archeads $a
+            set i [lsearch -exact $arcids($a) $id]
+            foreach t $archeads($a) {
+                set j [lsearch -exact $arcids($a) $t]
+                if {$j > $i} break
+                lappend aret $t
+            }
+        }
+        set id $arcstart($a)
     }
     set origid $id
     set todo [list $id]
     set seen($id) 1
     set ret {}
     for {set i 0} {$i < [llength $todo]} {incr i} {
-	set id [lindex $todo $i]
-	if {[info exists cached_dheads($id)]} {
-	    set ret [concat $ret $cached_dheads($id)]
-	} else {
-	    if {[info exists idheads($id)]} {
-		lappend ret $id
-	    }
-	    foreach a $arcnos($id) {
-		if {$archeads($a) ne {}} {
-		    validate_archeads $a
-		    if {$archeads($a) ne {}} {
-			set ret [concat $ret $archeads($a)]
-		    }
-		}
-		set d $arcstart($a)
-		if {![info exists seen($d)]} {
-		    lappend todo $d
-		    set seen($d) 1
-		}
-	    }
-	}
+        set id [lindex $todo $i]
+        if {[info exists cached_dheads($id)]} {
+            set ret [concat $ret $cached_dheads($id)]
+        } else {
+            if {[info exists idheads($id)]} {
+                lappend ret $id
+            }
+            foreach a $arcnos($id) {
+                if {$archeads($a) ne {}} {
+                    validate_archeads $a
+                    if {$archeads($a) ne {}} {
+                        set ret [concat $ret $archeads($a)]
+                    }
+                }
+                set d $arcstart($a)
+                if {![info exists seen($d)]} {
+                    lappend todo $d
+                    set seen($d) 1
+                }
+            }
+        }
     }
     set ret [lsort -unique $ret]
     set cached_dheads($origid) $ret
@@ -11204,7 +11222,7 @@
 
     if {![info exists arcnos($id)]} return
     if {![info exists arcout($id)]} {
-	recalcarc [lindex $arcnos($id) 0]
+        recalcarc [lindex $arcnos($id) 0]
     }
     unset -nocomplain cached_dtags
     unset -nocomplain cached_atags
@@ -11215,7 +11233,7 @@
 
     if {![info exists arcnos($hid)]} return
     if {![info exists arcout($hid)]} {
-	recalcarc [lindex $arcnos($hid) 0]
+        recalcarc [lindex $arcnos($hid) 0]
     }
     unset -nocomplain cached_dheads
 }
@@ -11231,7 +11249,7 @@
 
     if {![info exists arcnos($hid)]} return
     if {![info exists arcout($hid)]} {
-	recalcarc [lindex $arcnos($hid) 0]
+        recalcarc [lindex $arcnos($hid) 0]
     }
     unset -nocomplain cached_dheads
 }
@@ -11241,13 +11259,13 @@
     global arctags archeads arcnos arcout idheads idtags
 
     foreach id [concat [array names idheads] [array names idtags]] {
-	if {[info exists arcnos($id)] && ![info exists arcout($id)]} {
-	    set a [lindex $arcnos($id) 0]
-	    if {![info exists donearc($a)]} {
-		recalcarc $a
-		set donearc($a) 1
-	    }
-	}
+        if {[info exists arcnos($id)] && ![info exists arcout($id)]} {
+            set a [lindex $arcnos($id) 0]
+            if {![info exists donearc($a)]} {
+                recalcarc $a
+                set donearc($a) 1
+            }
+        }
     }
     unset -nocomplain cached_tagcontent
     unset -nocomplain cached_dtags
@@ -11259,26 +11277,26 @@
     global idtags idheads idotherrefs mainheadid
 
     set refids [concat [array names idtags] \
-		    [array names idheads] [array names idotherrefs]]
+                    [array names idheads] [array names idotherrefs]]
     foreach id $refids {
-	if {![info exists ref($id)]} {
-	    set ref($id) [listrefs $id]
-	}
+        if {![info exists ref($id)]} {
+            set ref($id) [listrefs $id]
+        }
     }
     set oldmainhead $mainheadid
     readrefs
     changedrefs
     set refids [lsort -unique [concat $refids [array names idtags] \
-			[array names idheads] [array names idotherrefs]]]
+                        [array names idheads] [array names idotherrefs]]]
     foreach id $refids {
-	set v [listrefs $id]
-	if {![info exists ref($id)] || $ref($id) != $v} {
-	    redrawtags $id
-	}
+        set v [listrefs $id]
+        if {![info exists ref($id)] || $ref($id) != $v} {
+            redrawtags $id
+        }
     }
     if {$oldmainhead ne $mainheadid} {
-	redrawtags $oldmainhead
-	redrawtags $mainheadid
+        redrawtags $oldmainhead
+        redrawtags $mainheadid
     }
     run refill_reflist
 }
@@ -11288,15 +11306,15 @@
 
     set x {}
     if {[info exists idtags($id)]} {
-	set x $idtags($id)
+        set x $idtags($id)
     }
     set y {}
     if {[info exists idheads($id)]} {
-	set y $idheads($id)
+        set y $idheads($id)
     }
     set z {}
     if {[info exists idotherrefs($id)]} {
-	set z $idotherrefs($id)
+        set z $idotherrefs($id)
     }
     return [list $x $y $z]
 }
@@ -11305,15 +11323,15 @@
     global ctext cached_tagcontent tagids
 
     if {![info exists cached_tagcontent($tag)]} {
-	catch {
-	    set cached_tagcontent($tag) [exec git cat-file -p $tag]
-	}
+        catch {
+            set cached_tagcontent($tag) [exec git cat-file -p $tag]
+        }
     }
     $ctext insert end "[mc "Tag"]: $tag\n" bold
     if {[info exists cached_tagcontent($tag)]} {
-	set text $cached_tagcontent($tag)
+        set text $cached_tagcontent($tag)
     } else {
-	set text "[mc "Id"]:  $tagids($tag)"
+        set text "[mc "Id"]:  $tagids($tag)"
     }
     appendwithlinks $text {}
 }
@@ -11322,7 +11340,7 @@
     global ctext cached_tagcontent tagids linknum tagobjid
 
     if {$isnew} {
-	addtohistory [list showtag $tag 0] savectextpos
+        addtohistory [list showtag $tag 0] savectextpos
     }
     $ctext conf -state normal
     clear_ctext
@@ -11338,7 +11356,7 @@
     global idtags ctext linknum
 
     if {$isnew} {
-	addtohistory [list showtags $id 0] savectextpos
+        addtohistory [list showtags $id 0] savectextpos
     }
     $ctext conf -state normal
     clear_ctext
@@ -11346,9 +11364,9 @@
     set linknum 0
     set sep {}
     foreach tag $idtags($id) {
-	$ctext insert end $sep
-	add_tag_ctext $tag
-	set sep "\n\n"
+        $ctext insert end $sep
+        add_tag_ctext $tag
+        set sep "\n\n"
     }
     maybe_scroll_ctext 1
     $ctext conf -state disabled
@@ -11364,7 +11382,7 @@
     destroy .
 
     if {[info exists gitktmpdir]} {
-	catch {file delete -force $gitktmpdir}
+        catch {file delete -force $gitktmpdir}
     }
 }
 
@@ -11373,9 +11391,9 @@
 
     set fontpref($font) [set $font]
     ${NS}::button $top.${font}but -text $which \
-	-command [list choosefont $font $which]
+        -command [list choosefont $font $which]
     ${NS}::label $top.$font -relief flat -font $font \
-	-text $fontattr($font,family) -justify left
+        -text $fontattr($font,family) -justify left
     grid x $top.${font}but $top.$font -sticky w
 }
 
@@ -11392,58 +11410,58 @@
     set top .gitkfont
     set fonttop $top
     if {![winfo exists $top]} {
-	font create sample
-	eval font config sample [font actual $font]
-	ttk_toplevel $top
-	make_transient $top $prefstop
-	wm title $top [mc "Gitk font chooser"]
-	${NS}::label $top.l -textvariable fontparam(which)
-	pack $top.l -side top
-	set fontlist [lsort [font families]]
-	${NS}::frame $top.f
-	listbox $top.f.fam -listvariable fontlist \
-	    -yscrollcommand [list $top.f.sb set]
-	bind $top.f.fam <<ListboxSelect>> selfontfam
-	${NS}::scrollbar $top.f.sb -command [list $top.f.fam yview]
-	pack $top.f.sb -side right -fill y
-	pack $top.f.fam -side left -fill both -expand 1
-	pack $top.f -side top -fill both -expand 1
-	${NS}::frame $top.g
-	spinbox $top.g.size -from 4 -to 40 -width 4 \
-	    -textvariable fontparam(size) \
-	    -validatecommand {string is integer -strict %s}
-	checkbutton $top.g.bold -padx 5 \
-	    -font {{Times New Roman} 12 bold} -text [mc "B"] -indicatoron 0 \
-	    -variable fontparam(weight) -onvalue bold -offvalue normal
-	checkbutton $top.g.ital -padx 5 \
-	    -font {{Times New Roman} 12 italic} -text [mc "I"] -indicatoron 0  \
-	    -variable fontparam(slant) -onvalue italic -offvalue roman
-	pack $top.g.size $top.g.bold $top.g.ital -side left
-	pack $top.g -side top
-	canvas $top.c -width 150 -height 50 -border 2 -relief sunk \
-	    -background white
-	$top.c create text 100 25 -anchor center -text $which -font sample \
-	    -fill black -tags text
-	bind $top.c <Configure> [list centertext $top.c]
-	pack $top.c -side top -fill x
-	${NS}::frame $top.buts
-	${NS}::button $top.buts.ok -text [mc "OK"] -command fontok -default active
-	${NS}::button $top.buts.can -text [mc "Cancel"] -command fontcan -default normal
-	bind $top <Key-Return> fontok
-	bind $top <Key-Escape> fontcan
-	grid $top.buts.ok $top.buts.can
-	grid columnconfigure $top.buts 0 -weight 1 -uniform a
-	grid columnconfigure $top.buts 1 -weight 1 -uniform a
-	pack $top.buts -side bottom -fill x
-	trace add variable fontparam write chg_fontparam
+        font create sample
+        eval font config sample [font actual $font]
+        ttk_toplevel $top
+        make_transient $top $prefstop
+        wm title $top [mc "Gitk font chooser"]
+        ${NS}::label $top.l -textvariable fontparam(which)
+        pack $top.l -side top
+        set fontlist [lsort [font families]]
+        ${NS}::frame $top.f
+        listbox $top.f.fam -listvariable fontlist \
+            -yscrollcommand [list $top.f.sb set]
+        bind $top.f.fam <<ListboxSelect>> selfontfam
+        ${NS}::scrollbar $top.f.sb -command [list $top.f.fam yview]
+        pack $top.f.sb -side right -fill y
+        pack $top.f.fam -side left -fill both -expand 1
+        pack $top.f -side top -fill both -expand 1
+        ${NS}::frame $top.g
+        spinbox $top.g.size -from 4 -to 40 -width 4 \
+            -textvariable fontparam(size) \
+            -validatecommand {string is integer -strict %s}
+        checkbutton $top.g.bold -padx 5 \
+            -font {{Times New Roman} 12 bold} -text [mc "B"] -indicatoron 0 \
+            -variable fontparam(weight) -onvalue bold -offvalue normal
+        checkbutton $top.g.ital -padx 5 \
+            -font {{Times New Roman} 12 italic} -text [mc "I"] -indicatoron 0  \
+            -variable fontparam(slant) -onvalue italic -offvalue roman
+        pack $top.g.size $top.g.bold $top.g.ital -side left
+        pack $top.g -side top
+        canvas $top.c -width 150 -height 50 -border 2 -relief sunk \
+            -background white
+        $top.c create text 100 25 -anchor center -text $which -font sample \
+            -fill black -tags text
+        bind $top.c <Configure> [list centertext $top.c]
+        pack $top.c -side top -fill x
+        ${NS}::frame $top.buts
+        ${NS}::button $top.buts.ok -text [mc "OK"] -command fontok -default active
+        ${NS}::button $top.buts.can -text [mc "Cancel"] -command fontcan -default normal
+        bind $top <Key-Return> fontok
+        bind $top <Key-Escape> fontcan
+        grid $top.buts.ok $top.buts.can
+        grid columnconfigure $top.buts 0 -weight 1 -uniform a
+        grid columnconfigure $top.buts 1 -weight 1 -uniform a
+        pack $top.buts -side bottom -fill x
+        trace add variable fontparam write chg_fontparam
     } else {
-	raise $top
-	$top.c itemconf text -text $which
+        raise $top
+        $top.c itemconf text -text $which
     }
     set i [lsearch -exact $fontlist $fontparam(family)]
     if {$i >= 0} {
-	$top.f.fam selection set $i
-	$top.f.fam see $i
+        $top.f.fam selection set $i
+        $top.f.fam see $i
     }
 }
 
@@ -11457,10 +11475,10 @@
     set f $fontparam(font)
     set fontpref($f) [list $fontparam(family) $fontparam(size)]
     if {$fontparam(weight) eq "bold"} {
-	lappend fontpref($f) "bold"
+        lappend fontpref($f) "bold"
     }
     if {$fontparam(slant) eq "italic"} {
-	lappend fontpref($f) "italic"
+        lappend fontpref($f) "italic"
     }
     set w $prefstop.notebook.fonts.$f
     $w conf -text $fontparam(family) -font $fontpref($f)
@@ -11472,10 +11490,10 @@
     global fonttop fontparam
 
     if {[info exists fonttop]} {
-	catch {destroy $fonttop}
-	catch {font delete sample}
-	unset fonttop
-	unset fontparam
+        catch {destroy $fonttop}
+        catch {font delete sample}
+        unset fonttop
+        unset fontparam
     }
 }
 
@@ -11483,21 +11501,21 @@
     # In Tk 8.6 we have a native font chooser dialog. Overwrite the above
     # function to make use of it.
     proc choosefont {font which} {
-	tk fontchooser configure -title $which -font $font \
-	    -command [list on_choosefont $font $which]
-	tk fontchooser show
+        tk fontchooser configure -title $which -font $font \
+            -command [list on_choosefont $font $which]
+        tk fontchooser show
     }
     proc on_choosefont {font which newfont} {
-	global fontparam
-	puts stderr "$font $newfont"
-	array set f [font actual $newfont]
-	set fontparam(which) $which
-	set fontparam(font) $font
-	set fontparam(family) $f(-family)
-	set fontparam(size) $f(-size)
-	set fontparam(weight) $f(-weight)
-	set fontparam(slant) $f(-slant)
-	fontok
+        global fontparam
+        puts stderr "$font $newfont"
+        array set f [font actual $newfont]
+        set fontparam(which) $which
+        set fontparam(font) $font
+        set fontparam(family) $f(-family)
+        set fontparam(size) $f(-size)
+        set fontparam(weight) $f(-weight)
+        set fontparam(slant) $f(-slant)
+        fontok
     }
 }
 
@@ -11506,7 +11524,7 @@
 
     set i [$fonttop.f.fam curselection]
     if {$i ne {}} {
-	set fontparam(family) [$fonttop.f.fam get $i]
+        set fontparam(family) [$fonttop.f.fam get $i]
     }
 }
 
@@ -11521,9 +11539,9 @@
     global NS
     set parent [join [lrange [split $w .] 0 end-1] .]
     if {[winfo class $parent] eq "TNotebook"} {
-	${NS}::frame $w
+        ${NS}::frame $w
     } else {
-	${NS}::labelframe $w
+        ${NS}::labelframe $w
     }
 }
 
@@ -11545,14 +11563,14 @@
     spinbox $page.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
     grid x $page.maxpctl $page.maxpct -sticky w
     ${NS}::checkbutton $page.showlocal -text [mc "Show local changes"] \
-	-variable showlocalchanges
+        -variable showlocalchanges
     grid x $page.showlocal -sticky w
     ${NS}::checkbutton $page.autoselect -text [mc "Auto-select SHA1 (length)"] \
-	-variable autoselect
+        -variable autoselect
     spinbox $page.autosellen -from 1 -to 40 -width 4 -textvariable autosellen
     grid x $page.autoselect $page.autosellen -sticky w
     ${NS}::checkbutton $page.hideremotes -text [mc "Hide remote refs"] \
-	-variable hideremotes
+        -variable hideremotes
     grid x $page.hideremotes -sticky w
 
     ${NS}::label $page.ddisp -text [mc "Diff display options"]
@@ -11561,16 +11579,16 @@
     spinbox $page.tabstop -from 1 -to 20 -width 4 -textvariable tabstop
     grid x $page.tabstopl $page.tabstop -sticky w
     ${NS}::checkbutton $page.ntag -text [mc "Display nearby tags/heads"] \
-	-variable showneartags
+        -variable showneartags
     grid x $page.ntag -sticky w
     ${NS}::label $page.maxrefsl -text [mc "Maximum # tags/heads to show"]
     spinbox $page.maxrefs -from 1 -to 1000 -width 4 -textvariable maxrefs
     grid x $page.maxrefsl $page.maxrefs -sticky w
     ${NS}::checkbutton $page.ldiff -text [mc "Limit diffs to listed paths"] \
-	-variable limitdiffs
+        -variable limitdiffs
     grid x $page.ldiff -sticky w
     ${NS}::checkbutton $page.lattr -text [mc "Support per-file encodings"] \
-	-variable perfile_attrs
+        -variable perfile_attrs
     grid x $page.lattr -sticky w
 
     ${NS}::entry $page.extdifft -textvariable extdifftool
@@ -11591,11 +11609,11 @@
     ${NS}::label $page.lgen -text [mc "General options"]
     grid $page.lgen - -sticky w -pady 10
     ${NS}::checkbutton $page.want_ttk -variable want_ttk \
-	-text [mc "Use themed widgets"]
+        -text [mc "Use themed widgets"]
     if {$have_ttk} {
-	${NS}::label $page.ttk_note -text [mc "(change requires restart)"]
+        ${NS}::label $page.ttk_note -text [mc "(change requires restart)"]
     } else {
-	${NS}::label $page.ttk_note -text [mc "(currently unavailable)"]
+        ${NS}::label $page.ttk_note -text [mc "(currently unavailable)"]
     }
     grid x $page.want_ttk $page.ttk_note -sticky w
     return $page
@@ -11603,6 +11621,7 @@
 
 proc prefspage_colors {notebook} {
     global NS uicolor bgcolor fgcolor ctext diffcolors selectbgcolor markbgcolor
+    global diffbgcolors
 
     set page [create_prefs_page $notebook.colors]
 
@@ -11614,37 +11633,49 @@
     grid x $page.uibut $page.ui -sticky w
     label $page.bg -padx 40 -relief sunk -background $bgcolor
     ${NS}::button $page.bgbut -text [mc "Background"] \
-	-command [list choosecolor bgcolor {} $page.bg [mc "background"] setbg]
+        -command [list choosecolor bgcolor {} $page.bg [mc "background"] setbg]
     grid x $page.bgbut $page.bg -sticky w
     label $page.fg -padx 40 -relief sunk -background $fgcolor
     ${NS}::button $page.fgbut -text [mc "Foreground"] \
-	-command [list choosecolor fgcolor {} $page.fg [mc "foreground"] setfg]
+        -command [list choosecolor fgcolor {} $page.fg [mc "foreground"] setfg]
     grid x $page.fgbut $page.fg -sticky w
     label $page.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0]
     ${NS}::button $page.diffoldbut -text [mc "Diff: old lines"] \
-	-command [list choosecolor diffcolors 0 $page.diffold [mc "diff old lines"] \
-		      [list $ctext tag conf d0 -foreground]]
+        -command [list choosecolor diffcolors 0 $page.diffold [mc "diff old lines"] \
+                      [list $ctext tag conf d0 -foreground]]
     grid x $page.diffoldbut $page.diffold -sticky w
+    label $page.diffoldbg -padx 40 -relief sunk -background [lindex $diffbgcolors 0]
+    ${NS}::button $page.diffoldbgbut -text [mc "Diff: old lines bg"] \
+        -command [list choosecolor diffbgcolors 0 $page.diffoldbg \
+                      [mc "diff old lines bg"] \
+                      [list $ctext tag conf d0 -background]]
+    grid x $page.diffoldbgbut $page.diffoldbg -sticky w
     label $page.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1]
     ${NS}::button $page.diffnewbut -text [mc "Diff: new lines"] \
-	-command [list choosecolor diffcolors 1 $page.diffnew [mc "diff new lines"] \
-		      [list $ctext tag conf dresult -foreground]]
+        -command [list choosecolor diffcolors 1 $page.diffnew [mc "diff new lines"] \
+                      [list $ctext tag conf dresult -foreground]]
     grid x $page.diffnewbut $page.diffnew -sticky w
+    label $page.diffnewbg -padx 40 -relief sunk -background [lindex $diffbgcolors 1]
+    ${NS}::button $page.diffnewbgbut -text [mc "Diff: new lines bg"] \
+        -command [list choosecolor diffbgcolors 1 $page.diffnewbg \
+                      [mc "diff new lines bg"] \
+                      [list $ctext tag conf dresult -background]]
+    grid x $page.diffnewbgbut $page.diffnewbg -sticky w
     label $page.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2]
     ${NS}::button $page.hunksepbut -text [mc "Diff: hunk header"] \
-	-command [list choosecolor diffcolors 2 $page.hunksep \
-		      [mc "diff hunk header"] \
-		      [list $ctext tag conf hunksep -foreground]]
+        -command [list choosecolor diffcolors 2 $page.hunksep \
+                      [mc "diff hunk header"] \
+                      [list $ctext tag conf hunksep -foreground]]
     grid x $page.hunksepbut $page.hunksep -sticky w
     label $page.markbgsep -padx 40 -relief sunk -background $markbgcolor
     ${NS}::button $page.markbgbut -text [mc "Marked line bg"] \
-	-command [list choosecolor markbgcolor {} $page.markbgsep \
-		      [mc "marked line background"] \
-		      [list $ctext tag conf omark -background]]
+        -command [list choosecolor markbgcolor {} $page.markbgsep \
+                      [mc "marked line background"] \
+                      [list $ctext tag conf omark -background]]
     grid x $page.markbgbut $page.markbgsep -sticky w
     label $page.selbgsep -padx 40 -relief sunk -background $selectbgcolor
     ${NS}::button $page.selbgbut -text [mc "Select bg"] \
-	-command [list choosecolor selectbgcolor {} $page.selbgsep [mc "background"] setselbg]
+        -command [list choosecolor selectbgcolor {} $page.selbgsep [mc "background"] setselbg]
     grid x $page.selbgbut $page.selbgsep -sticky w
     return $page
 }
@@ -11670,21 +11701,21 @@
     set top .gitkprefs
     set prefstop $top
     if {[winfo exists $top]} {
-	raise $top
-	return
+        raise $top
+        return
     }
     foreach v {maxwidth maxgraphpct showneartags showlocalchanges \
-		   limitdiffs tabstop perfile_attrs hideremotes want_ttk} {
-	set oldprefs($v) [set $v]
+                   limitdiffs tabstop perfile_attrs hideremotes want_ttk} {
+        set oldprefs($v) [set $v]
     }
     ttk_toplevel $top
     wm title $top [mc "Gitk preferences"]
     make_transient $top .
 
     if {[set use_notebook [expr {$use_ttk && [info command ::ttk::notebook] ne ""}]]} {
-	set notebook [ttk::notebook $top.notebook]
+        set notebook [ttk::notebook $top.notebook]
     } else {
-	set notebook [${NS}::frame $top.notebook -borderwidth 0 -relief flat]
+        set notebook [${NS}::frame $top.notebook -borderwidth 0 -relief flat]
     }
 
     lappend pages [prefspage_general $notebook] [mc "General"]
@@ -11692,21 +11723,21 @@
     lappend pages [prefspage_fonts $notebook] [mc "Fonts"]
     set col 0
     foreach {page title} $pages {
-	if {$use_notebook} {
-	    $notebook add $page -text $title
-	} else {
-	    set btn [${NS}::button $notebook.b_[string map {. X} $page] \
-			 -text $title -command [list raise $page]]
-	    $page configure -text $title
-	    grid $btn -row 0 -column [incr col] -sticky w
-	    grid $page -row 1 -column 0 -sticky news -columnspan 100
-	}
+        if {$use_notebook} {
+            $notebook add $page -text $title
+        } else {
+            set btn [${NS}::button $notebook.b_[string map {. X} $page] \
+                         -text $title -command [list raise $page]]
+            $page configure -text $title
+            grid $btn -row 0 -column [incr col] -sticky w
+            grid $page -row 1 -column 0 -sticky news -columnspan 100
+        }
     }
 
     if {!$use_notebook} {
-	grid columnconfigure $notebook 0 -weight 1
-	grid rowconfigure $notebook 1 -weight 1
-	raise [lindex $pages 0]
+        grid columnconfigure $notebook 0 -weight 1
+        grid rowconfigure $notebook 1 -weight 1
+        raise [lindex $pages 0]
     }
 
     grid $notebook -sticky news -padx 2 -pady 2
@@ -11731,7 +11762,7 @@
 
     set prog [tk_getOpenFile -title [mc "External diff tool"] -multiple false]
     if {$prog ne {}} {
-	set extdifftool $prog
+        set extdifftool $prog
     }
 }
 
@@ -11739,7 +11770,7 @@
     global $v
 
     set c [tk_chooseColor -initialcolor [lindex [set $v] $vi] \
-	       -title [mc "Gitk: choose color for %s" $x]]
+               -title [mc "Gitk: choose color for %s" $x]]
     if {$c eq {}} return
     $w conf -background $c
     lset $v $vi $c
@@ -11749,12 +11780,12 @@
 proc setselbg {c} {
     global bglist cflist
     foreach w $bglist {
-	if {[winfo exists $w]} {
-	    $w configure -selectbackground $c
-	}
+        if {[winfo exists $w]} {
+            $w configure -selectbackground $c
+        }
     }
     $cflist tag configure highlight \
-	-background [$cflist cget -selectbackground]
+        -background [$cflist cget -selectbackground]
     allcanvs itemconf secsel -fill $c
 }
 
@@ -11768,7 +11799,7 @@
     set bg [winfo rgb . $c]
     set selc black
     if {[lindex $bg 0] + 1.5 * [lindex $bg 1] + 0.5 * [lindex $bg 2] > 100000} {
-	set selc white
+        set selc white
     }
     tk_setPalette background $c selectColor $selc
 }
@@ -11777,9 +11808,9 @@
     global bglist
 
     foreach w $bglist {
-	if {[winfo exists $w]} {
-	    $w conf -background $c
-	}
+        if {[winfo exists $w]} {
+            $w conf -background $c
+        }
     }
 }
 
@@ -11787,9 +11818,9 @@
     global fglist canv
 
     foreach w $fglist {
-	if {[winfo exists $w]} {
-	    $w conf -foreground $c
-	}
+        if {[winfo exists $w]} {
+            $w conf -foreground $c
+        }
     }
     allcanvs itemconf text -fill $c
     $canv itemconf circle -outline $c
@@ -11800,9 +11831,9 @@
     global oldprefs prefstop
 
     foreach v {maxwidth maxgraphpct showneartags showlocalchanges \
-		   limitdiffs tabstop perfile_attrs hideremotes want_ttk} {
-	global $v
-	set $v $oldprefs($v)
+                   limitdiffs tabstop perfile_attrs hideremotes want_ttk} {
+        global $v
+        set $v $oldprefs($v)
     }
     catch {destroy $prefstop}
     unset prefstop
@@ -11821,76 +11852,76 @@
     fontcan
     set fontchanged 0
     if {$mainfont ne $fontpref(mainfont)} {
-	set mainfont $fontpref(mainfont)
-	parsefont mainfont $mainfont
-	eval font configure mainfont [fontflags mainfont]
-	eval font configure mainfontbold [fontflags mainfont 1]
-	setcoords
-	set fontchanged 1
+        set mainfont $fontpref(mainfont)
+        parsefont mainfont $mainfont
+        eval font configure mainfont [fontflags mainfont]
+        eval font configure mainfontbold [fontflags mainfont 1]
+        setcoords
+        set fontchanged 1
     }
     if {$textfont ne $fontpref(textfont)} {
-	set textfont $fontpref(textfont)
-	parsefont textfont $textfont
-	eval font configure textfont [fontflags textfont]
-	eval font configure textfontbold [fontflags textfont 1]
+        set textfont $fontpref(textfont)
+        parsefont textfont $textfont
+        eval font configure textfont [fontflags textfont]
+        eval font configure textfontbold [fontflags textfont 1]
     }
     if {$uifont ne $fontpref(uifont)} {
-	set uifont $fontpref(uifont)
-	parsefont uifont $uifont
-	eval font configure uifont [fontflags uifont]
+        set uifont $fontpref(uifont)
+        parsefont uifont $uifont
+        eval font configure uifont [fontflags uifont]
     }
     settabs
     if {$showlocalchanges != $oldprefs(showlocalchanges)} {
-	if {$showlocalchanges} {
-	    doshowlocalchanges
-	} else {
-	    dohidelocalchanges
-	}
+        if {$showlocalchanges} {
+            doshowlocalchanges
+        } else {
+            dohidelocalchanges
+        }
     }
     if {$limitdiffs != $oldprefs(limitdiffs) ||
-	($perfile_attrs && !$oldprefs(perfile_attrs))} {
-	# treediffs elements are limited by path;
-	# won't have encodings cached if perfile_attrs was just turned on
-	unset -nocomplain treediffs
+        ($perfile_attrs && !$oldprefs(perfile_attrs))} {
+        # treediffs elements are limited by path;
+        # won't have encodings cached if perfile_attrs was just turned on
+        unset -nocomplain treediffs
     }
     if {$fontchanged || $maxwidth != $oldprefs(maxwidth)
-	|| $maxgraphpct != $oldprefs(maxgraphpct)} {
-	redisplay
+        || $maxgraphpct != $oldprefs(maxgraphpct)} {
+        redisplay
     } elseif {$showneartags != $oldprefs(showneartags) ||
-	  $limitdiffs != $oldprefs(limitdiffs)} {
-	reselectline
+          $limitdiffs != $oldprefs(limitdiffs)} {
+        reselectline
     }
     if {$hideremotes != $oldprefs(hideremotes)} {
-	rereadrefs
+        rereadrefs
     }
 }
 
 proc formatdate {d} {
     global datetimeformat
     if {$d ne {}} {
-	# If $datetimeformat includes a timezone, display in the
-	# timezone of the argument.  Otherwise, display in local time.
-	if {[string match {*%[zZ]*} $datetimeformat]} {
-	    if {[catch {set d [clock format [lindex $d 0] -timezone [lindex $d 1] -format $datetimeformat]}]} {
-		# Tcl < 8.5 does not support -timezone.  Emulate it by
-		# setting TZ (e.g. TZ=<-0430>+04:30).
-		global env
-		if {[info exists env(TZ)]} {
-		    set savedTZ $env(TZ)
-		}
-		set zone [lindex $d 1]
-		set sign [string map {+ - - +} [string index $zone 0]]
-		set env(TZ) <$zone>$sign[string range $zone 1 2]:[string range $zone 3 4]
-		set d [clock format [lindex $d 0] -format $datetimeformat]
-		if {[info exists savedTZ]} {
-		    set env(TZ) $savedTZ
-		} else {
-		    unset env(TZ)
-		}
-	    }
-	} else {
-	    set d [clock format [lindex $d 0] -format $datetimeformat]
-	}
+        # If $datetimeformat includes a timezone, display in the
+        # timezone of the argument.  Otherwise, display in local time.
+        if {[string match {*%[zZ]*} $datetimeformat]} {
+            if {[catch {set d [clock format [lindex $d 0] -timezone [lindex $d 1] -format $datetimeformat]}]} {
+                # Tcl < 8.5 does not support -timezone.  Emulate it by
+                # setting TZ (e.g. TZ=<-0430>+04:30).
+                global env
+                if {[info exists env(TZ)]} {
+                    set savedTZ $env(TZ)
+                }
+                set zone [lindex $d 1]
+                set sign [string map {+ - - +} [string index $zone 0]]
+                set env(TZ) <$zone>$sign[string range $zone 1 2]:[string range $zone 3 4]
+                set d [clock format [lindex $d 0] -format $datetimeformat]
+                if {[info exists savedTZ]} {
+                    set env(TZ) $savedTZ
+                } else {
+                    unset env(TZ)
+                }
+            }
+        } else {
+            set d [clock format [lindex $d 0] -format $datetimeformat]
+        }
     }
     return $d
 }
@@ -12136,38 +12167,38 @@
 proc tcl_encoding {enc} {
     global encoding_aliases tcl_encoding_cache
     if {[info exists tcl_encoding_cache($enc)]} {
-	return $tcl_encoding_cache($enc)
+        return $tcl_encoding_cache($enc)
     }
     set names [encoding names]
     set lcnames [string tolower $names]
     set enc [string tolower $enc]
     set i [lsearch -exact $lcnames $enc]
     if {$i < 0} {
-	# look for "isonnn" instead of "iso-nnn" or "iso_nnn"
-	if {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\1} encx]} {
-	    set i [lsearch -exact $lcnames $encx]
-	}
+        # look for "isonnn" instead of "iso-nnn" or "iso_nnn"
+        if {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\1} encx]} {
+            set i [lsearch -exact $lcnames $encx]
+        }
     }
     if {$i < 0} {
-	foreach l $encoding_aliases {
-	    set ll [string tolower $l]
-	    if {[lsearch -exact $ll $enc] < 0} continue
-	    # look through the aliases for one that tcl knows about
-	    foreach e $ll {
-		set i [lsearch -exact $lcnames $e]
-		if {$i < 0} {
-		    if {[regsub {^(iso|cp|ibm|jis)[-_]} $e {\1} ex]} {
-			set i [lsearch -exact $lcnames $ex]
-		    }
-		}
-		if {$i >= 0} break
-	    }
-	    break
-	}
+        foreach l $encoding_aliases {
+            set ll [string tolower $l]
+            if {[lsearch -exact $ll $enc] < 0} continue
+            # look through the aliases for one that tcl knows about
+            foreach e $ll {
+                set i [lsearch -exact $lcnames $e]
+                if {$i < 0} {
+                    if {[regsub {^(iso|cp|ibm|jis)[-_]} $e {\1} ex]} {
+                        set i [lsearch -exact $lcnames $ex]
+                    }
+                }
+                if {$i >= 0} break
+            }
+            break
+        }
     }
     set tclenc {}
     if {$i >= 0} {
-	set tclenc [lindex $names $i]
+        set tclenc [lindex $names $i]
     }
     set tcl_encoding_cache($enc) $tclenc
     return $tclenc
@@ -12176,16 +12207,16 @@
 proc gitattr {path attr default} {
     global path_attr_cache
     if {[info exists path_attr_cache($attr,$path)]} {
-	set r $path_attr_cache($attr,$path)
+        set r $path_attr_cache($attr,$path)
     } else {
-	set r "unspecified"
-	if {![catch {set line [exec git check-attr $attr -- $path]}]} {
-	    regexp "(.*): $attr: (.*)" $line m f r
-	}
-	set path_attr_cache($attr,$path) $r
+        set r "unspecified"
+        if {![catch {set line [exec git check-attr $attr -- $path]}]} {
+            regexp "(.*): $attr: (.*)" $line m f r
+        }
+        set path_attr_cache($attr,$path) $r
     }
     if {$r eq "unspecified"} {
-	return $default
+        return $default
     }
     return $r
 }
@@ -12194,28 +12225,28 @@
     global path_attr_cache
     set newlist {}
     foreach path $pathlist {
-	if {![info exists path_attr_cache($attr,$path)]} {
-	    lappend newlist $path
-	}
+        if {![info exists path_attr_cache($attr,$path)]} {
+            lappend newlist $path
+        }
     }
     set lim 1000
     if {[tk windowingsystem] == "win32"} {
-	# windows has a 32k limit on the arguments to a command...
-	set lim 30
+        # windows has a 32k limit on the arguments to a command...
+        set lim 30
     }
     while {$newlist ne {}} {
-	set head [lrange $newlist 0 [expr {$lim - 1}]]
-	set newlist [lrange $newlist $lim end]
-	if {![catch {set rlist [eval exec git check-attr $attr -- $head]}]} {
-	    foreach row [split $rlist "\n"] {
-		if {[regexp "(.*): $attr: (.*)" $row m path value]} {
-		    if {[string index $path 0] eq "\""} {
-			set path [encoding convertfrom [lindex $path 0]]
-		    }
-		    set path_attr_cache($attr,$path) $value
-		}
-	    }
-	}
+        set head [lrange $newlist 0 [expr {$lim - 1}]]
+        set newlist [lrange $newlist $lim end]
+        if {![catch {set rlist [eval exec git check-attr $attr -- $head]}]} {
+            foreach row [split $rlist "\n"] {
+                if {[regexp "(.*): $attr: (.*)" $row m path value]} {
+                    if {[string index $path 0] eq "\""} {
+                        set path [encoding convertfrom [lindex $path 0]]
+                    }
+                    set path_attr_cache($attr,$path) $value
+                }
+            }
+        }
     }
 }
 
@@ -12223,10 +12254,10 @@
     global gui_encoding perfile_attrs
     set tcl_enc $gui_encoding
     if {$path ne {} && $perfile_attrs} {
-	set enc2 [tcl_encoding [gitattr $path encoding $tcl_enc]]
-	if {$enc2 ne {}} {
-	    set tcl_enc $enc2
-	}
+        set enc2 [tcl_encoding [gitattr $path encoding $tcl_enc]]
+        if {$enc2 ne {}} {
+            set tcl_enc $enc2
+        }
     }
     return $tcl_enc
 }
@@ -12253,7 +12284,7 @@
 # First check that Tcl/Tk is recent enough
 if {[catch {package require Tk 8.4} err]} {
     show_error {} . [mc "Sorry, gitk cannot run with this version of Tcl/Tk.\n\
-			 Gitk requires at least Tcl/Tk 8.4."]
+                         Gitk requires at least Tcl/Tk 8.4."]
     exit 1
 }
 
@@ -12293,12 +12324,12 @@
 catch {
     set enc [exec git config --get gui.encoding]
     if {$enc ne {}} {
-	set tclenc [tcl_encoding $enc]
-	if {$tclenc ne {}} {
-	    set gui_encoding $tclenc
-	} else {
-	    puts stderr "Warning: encoding $enc is not supported by Tcl/Tk"
-	}
+        set tclenc [tcl_encoding $enc]
+        if {$tclenc ne {}} {
+            set gui_encoding $tclenc
+        } else {
+            puts stderr "Warning: encoding $enc is not supported by Tcl/Tk"
+        }
     }
 }
 
@@ -12368,12 +12399,13 @@
     set fgcolor black
     set selectbgcolor gray85
     if {[tk windowingsystem] eq "aqua"} {
-	set web_browser "open"
+        set web_browser "open"
     } else {
-	set web_browser "xdg-open"
+        set web_browser "xdg-open"
     }
 }
-set diffcolors {red "#00a000" blue}
+set diffcolors {"#c30000" "#009800" blue}
+set diffbgcolors {"#fff3f3" "#f0fff0"}
 set diffcontext 3
 set mergecolors {red blue "#00ff00" purple brown "#009090" magenta "#808000" "#009000" "#ff0080" cyan "#b07070" "#70b0f0" "#70f0b0" "#f0b070" "#ff70b0"}
 set ignorespace 0
@@ -12413,22 +12445,22 @@
     # follow the XDG base directory specification by default. See
     # http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
     if {[info exists env(XDG_CONFIG_HOME)] && $env(XDG_CONFIG_HOME) ne ""} {
-	# XDG_CONFIG_HOME environment variable is set
-	set config_file [file join $env(XDG_CONFIG_HOME) git gitk]
-	set config_file_tmp [file join $env(XDG_CONFIG_HOME) git gitk-tmp]
+        # XDG_CONFIG_HOME environment variable is set
+        set config_file [file join $env(XDG_CONFIG_HOME) git gitk]
+        set config_file_tmp [file join $env(XDG_CONFIG_HOME) git gitk-tmp]
     } else {
-	# default XDG_CONFIG_HOME
-	set config_file "~/.config/git/gitk"
-	set config_file_tmp "~/.config/git/gitk-tmp"
+        # default XDG_CONFIG_HOME
+        set config_file "~/.config/git/gitk"
+        set config_file_tmp "~/.config/git/gitk-tmp"
     }
     if {![file exists $config_file]} {
-	# for backward compatibility use the old config file if it exists
-	if {[file exists "~/.gitk"]} {
-	    set config_file "~/.gitk"
-	    set config_file_tmp "~/.gitk-tmp"
-	} elseif {![file exists [file dirname $config_file]]} {
-	    file mkdir [file dirname $config_file]
-	}
+        # for backward compatibility use the old config file if it exists
+        if {[file exists "~/.gitk"]} {
+            set config_file "~/.gitk"
+            set config_file_tmp "~/.gitk-tmp"
+        } elseif {![file exists [file dirname $config_file]]} {
+            file mkdir [file dirname $config_file]
+        }
     }
     source $config_file
 }
@@ -12444,7 +12476,7 @@
     remotebgcolor tagbgcolor tagfgcolor tagoutlinecolor reflinecolor
     filesepbgcolor filesepfgcolor linehoverbgcolor linehoverfgcolor
     linehoveroutlinecolor mainheadcirclecolor workingfilescirclecolor
-    indexcirclecolor circlecolors linkfgcolor circleoutlinecolor
+    indexcirclecolor circlecolors linkfgcolor circleoutlinecolor diffbgcolors
     web_browser
 }
 foreach var $config_variables {
@@ -12482,20 +12514,20 @@
 set revtreeargscmd {}
 foreach arg $argv {
     switch -glob -- $arg {
-	"" { }
-	"--" {
-	    set cmdline_files [lrange $argv [expr {$i + 1}] end]
-	    break
-	}
-	"--select-commit=*" {
-	    set selecthead [string range $arg 16 end]
-	}
-	"--argscmd=*" {
-	    set revtreeargscmd [string range $arg 10 end]
-	}
-	default {
-	    lappend revtreeargs $arg
-	}
+        "" { }
+        "--" {
+            set cmdline_files [lrange $argv [expr {$i + 1}] end]
+            break
+        }
+        "--select-commit=*" {
+            set selecthead [string range $arg 16 end]
+        }
+        "--argscmd=*" {
+            set revtreeargscmd [string range $arg 10 end]
+        }
+        default {
+            lappend revtreeargs $arg
+        }
     }
     incr i
 }
@@ -12507,29 +12539,29 @@
 if {$i >= [llength $argv] && $revtreeargs ne {}} {
     # no -- on command line, but some arguments (other than --argscmd)
     if {[catch {
-	set f [eval exec git rev-parse --no-revs --no-flags $revtreeargs]
-	set cmdline_files [split $f "\n"]
-	set n [llength $cmdline_files]
-	set revtreeargs [lrange $revtreeargs 0 end-$n]
-	# Unfortunately git rev-parse doesn't produce an error when
-	# something is both a revision and a filename.  To be consistent
-	# with git log and git rev-list, check revtreeargs for filenames.
-	foreach arg $revtreeargs {
-	    if {[file exists $arg]} {
-		show_error {} . [mc "Ambiguous argument '%s': both revision\
-				 and filename" $arg]
-		exit 1
-	    }
-	}
+        set f [eval exec git rev-parse --no-revs --no-flags $revtreeargs]
+        set cmdline_files [split $f "\n"]
+        set n [llength $cmdline_files]
+        set revtreeargs [lrange $revtreeargs 0 end-$n]
+        # Unfortunately git rev-parse doesn't produce an error when
+        # something is both a revision and a filename.  To be consistent
+        # with git log and git rev-list, check revtreeargs for filenames.
+        foreach arg $revtreeargs {
+            if {[file exists $arg]} {
+                show_error {} . [mc "Ambiguous argument '%s': both revision\
+                                 and filename" $arg]
+                exit 1
+            }
+        }
     } err]} {
-	# unfortunately we get both stdout and stderr in $err,
-	# so look for "fatal:".
-	set i [string first "fatal:" $err]
-	if {$i > 0} {
-	    set err [string range $err [expr {$i + 6}] end]
-	}
-	show_error {} . "[mc "Bad arguments to gitk:"]\n$err"
-	exit 1
+        # unfortunately we get both stdout and stderr in $err,
+        # so look for "fatal:".
+        set i [string first "fatal:" $err]
+        if {$i > 0} {
+            set err [string range $err [expr {$i + 6}] end]
+        }
+        show_error {} . "[mc "Bad arguments to gitk:"]\n$err"
+        exit 1
     }
 }
 
@@ -12599,7 +12631,7 @@
 if {[expr {[exec git rev-parse --is-inside-work-tree] == "true"}]} {
     set cdup [exec git rev-parse --show-cdup]
 }
-set worktree [exec git rev-parse --show-toplevel]
+set worktree [gitworktree]
 setcoords
 makewindow
 catch {
@@ -12650,15 +12682,15 @@
 
 if {[info exists permviews]} {
     foreach v $permviews {
-	set n $nextviewnum
-	incr nextviewnum
-	set viewname($n) [lindex $v 0]
-	set viewfiles($n) [lindex $v 1]
-	set viewargs($n) [lindex $v 2]
-	set viewargscmd($n) [lindex $v 3]
-	set viewperm($n) 1
-	set viewchanged($n) 0
-	addviewmenu $n
+        set n $nextviewnum
+        incr nextviewnum
+        set viewname($n) [lindex $v 0]
+        set viewfiles($n) [lindex $v 1]
+        set viewargs($n) [lindex $v 2]
+        set viewargscmd($n) [lindex $v 3]
+        set viewperm($n) 1
+        set viewchanged($n) 0
+        addviewmenu $n
     }
 }
 
diff --git a/hashmap.h b/hashmap.h
index ef220de..b011b39 100644
--- a/hashmap.h
+++ b/hashmap.h
@@ -449,7 +449,8 @@
  * containing a @member which is a "struct hashmap_entry"
  */
 #define hashmap_for_each_entry(map, iter, var, member) \
-	for (var = hashmap_iter_first_entry_offset(map, iter, \
+	for (var = NULL, /* for systems without typeof */ \
+	     var = hashmap_iter_first_entry_offset(map, iter, \
 						OFFSETOF_VAR(var, member)); \
 		var; \
 		var = hashmap_iter_next_entry_offset(iter, \
diff --git a/log-tree.c b/log-tree.c
index cb8942f..1927f91 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -885,7 +885,7 @@
 
 static int do_diff_combined(struct rev_info *opt, struct commit *commit)
 {
-	diff_tree_combined_merge(commit, opt->dense_combined_merges, opt);
+	diff_tree_combined_merge(commit, opt);
 	return !opt->loginfo;
 }
 
diff --git a/oidset.c b/oidset.c
index 15d4e18..2d0ab76 100644
--- a/oidset.c
+++ b/oidset.c
@@ -43,6 +43,12 @@
 
 void oidset_parse_file(struct oidset *set, const char *path)
 {
+	oidset_parse_file_carefully(set, path, NULL, NULL);
+}
+
+void oidset_parse_file_carefully(struct oidset *set, const char *path,
+				 oidset_parse_tweak_fn fn, void *cbdata)
+{
 	FILE *fp;
 	struct strbuf sb = STRBUF_INIT;
 	struct object_id oid;
@@ -66,7 +72,8 @@
 		if (!sb.len)
 			continue;
 
-		if (parse_oid_hex(sb.buf, &oid, &p) || *p != '\0')
+		if (parse_oid_hex(sb.buf, &oid, &p) || *p != '\0' ||
+		    (fn && fn(&oid, cbdata)))
 			die("invalid object name: %s", sb.buf);
 		oidset_insert(set, &oid);
 	}
diff --git a/oidset.h b/oidset.h
index 209ae7a..01f6560 100644
--- a/oidset.h
+++ b/oidset.h
@@ -73,6 +73,15 @@
  */
 void oidset_parse_file(struct oidset *set, const char *path);
 
+/*
+ * Similar to the above, but with a callback which can (1) return non-zero to
+ * signal displeasure with the object and (2) replace object ID with something
+ * else (meant to be used to "peel").
+ */
+typedef int (*oidset_parse_tweak_fn)(struct object_id *, void *);
+void oidset_parse_file_carefully(struct oidset *set, const char *path,
+				 oidset_parse_tweak_fn fn, void *cbdata);
+
 struct oidset_iter {
 	kh_oid_set_t *set;
 	khiter_t iter;
diff --git a/packfile.c b/packfile.c
index e69012e..0929ebe 100644
--- a/packfile.c
+++ b/packfile.c
@@ -1475,7 +1475,7 @@
 static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
 	void *base, unsigned long base_size, enum object_type type)
 {
-	struct delta_base_cache_entry *ent = xmalloc(sizeof(*ent));
+	struct delta_base_cache_entry *ent;
 	struct list_head *lru, *tmp;
 
 	/*
@@ -1483,8 +1483,10 @@
 	 * is unpacking the same object, in unpack_entry() (since its phases I
 	 * and III might run concurrently across multiple threads).
 	 */
-	if (in_delta_base_cache(p, base_offset))
+	if (in_delta_base_cache(p, base_offset)) {
+		free(base);
 		return;
+	}
 
 	delta_base_cached += base_size;
 
@@ -1496,6 +1498,7 @@
 		release_delta_base_cache(f);
 	}
 
+	ent = xmalloc(sizeof(*ent));
 	ent->key.p = p;
 	ent->key.base_offset = base_offset;
 	ent->type = type;
@@ -1776,12 +1779,10 @@
 		void *external_base = NULL;
 		unsigned long delta_size, base_size = size;
 		int i;
+		off_t base_obj_offset = obj_offset;
 
 		data = NULL;
 
-		if (base)
-			add_delta_base_cache(p, obj_offset, base, base_size, type);
-
 		if (!base) {
 			/*
 			 * We're probably in deep shit, but let's try to fetch
@@ -1819,24 +1820,33 @@
 			      "at offset %"PRIuMAX" from %s",
 			      (uintmax_t)curpos, p->pack_name);
 			data = NULL;
-			free(external_base);
-			continue;
+		} else {
+			data = patch_delta(base, base_size, delta_data,
+					   delta_size, &size);
+
+			/*
+			 * We could not apply the delta; warn the user, but
+			 * keep going. Our failure will be noticed either in
+			 * the next iteration of the loop, or if this is the
+			 * final delta, in the caller when we return NULL.
+			 * Those code paths will take care of making a more
+			 * explicit warning and retrying with another copy of
+			 * the object.
+			 */
+			if (!data)
+				error("failed to apply delta");
 		}
 
-		data = patch_delta(base, base_size,
-				   delta_data, delta_size,
-				   &size);
-
 		/*
-		 * We could not apply the delta; warn the user, but keep going.
-		 * Our failure will be noticed either in the next iteration of
-		 * the loop, or if this is the final delta, in the caller when
-		 * we return NULL. Those code paths will take care of making
-		 * a more explicit warning and retrying with another copy of
-		 * the object.
+		 * We delay adding `base` to the cache until the end of the loop
+		 * because unpack_compressed_entry() momentarily releases the
+		 * obj_read_mutex, giving another thread the chance to access
+		 * the cache. Therefore, if `base` was already there, this other
+		 * thread could free() it (e.g. to make space for another entry)
+		 * before we are done using it.
 		 */
-		if (!data)
-			error("failed to apply delta");
+		if (!external_base)
+			add_delta_base_cache(p, base_obj_offset, base, base_size, type);
 
 		free(delta_data);
 		free(external_base);
diff --git a/ref-filter.c b/ref-filter.c
index 5550a0d..c62f6b4 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -1557,9 +1557,7 @@
 		strbuf_addstr(&desc, _("no branch"));
 	strbuf_addch(&desc, ')');
 
-	free(state.branch);
-	free(state.onto);
-	free(state.detached_from);
+	wt_status_state_free_buffers(&state);
 	return strbuf_detach(&desc, NULL);
 }
 
@@ -2239,12 +2237,14 @@
 {
 	struct rev_info revs;
 	int i, old_nr;
-	struct commit **to_clear = xcalloc(sizeof(struct commit *), array->nr);
+	struct commit **to_clear;
 	struct commit_list *cr;
 
 	if (!check_reachable)
 		return;
 
+	to_clear = xcalloc(sizeof(struct commit *), array->nr);
+
 	repo_init_revisions(the_repository, &revs, NULL);
 
 	for (i = 0; i < array->nr; i++) {
diff --git a/sequencer.c b/sequencer.c
index e454264..00acb12 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -120,7 +120,7 @@
 static GIT_PATH_FUNC(rebase_path_amend, "rebase-merge/amend")
 /*
  * When we stop at a given patch via the "edit" command, this file contains
- * the abbreviated commit name of the corresponding patch.
+ * the commit object name of the corresponding patch.
  */
 static GIT_PATH_FUNC(rebase_path_stopped_sha, "rebase-merge/stopped-sha")
 /*
@@ -3119,11 +3119,12 @@
 {
 	struct strbuf buf = STRBUF_INIT;
 	struct rev_info log_tree_opt;
-	const char *subject, *p;
+	const char *subject;
+	char hex[GIT_MAX_HEXSZ + 1];
 	int res = 0;
 
-	p = short_commit_name(commit);
-	if (write_message(p, strlen(p), rebase_path_stopped_sha(), 1) < 0)
+	oid_to_hex_r(hex, &commit->object.oid);
+	if (write_message(hex, strlen(hex), rebase_path_stopped_sha(), 1) < 0)
 		return -1;
 	res |= write_rebase_head(&commit->object.oid);
 
@@ -4535,7 +4536,7 @@
 
 		if (read_oneliner(&buf, rebase_path_stopped_sha(),
 				  READ_ONELINER_SKIP_IF_EMPTY) &&
-		    !get_oid_committish(buf.buf, &oid))
+		    !get_oid_hex(buf.buf, &oid))
 			record_in_rewritten(&oid, peek_command(&todo_list, 0));
 		strbuf_release(&buf);
 	}
diff --git a/shortlog.h b/shortlog.h
index 2fa61c4..64be879 100644
--- a/shortlog.h
+++ b/shortlog.h
@@ -15,7 +15,13 @@
 	int in2;
 	int user_format;
 	int abbrev;
-	int committer;
+
+	enum {
+		SHORTLOG_GROUP_AUTHOR = (1 << 0),
+		SHORTLOG_GROUP_COMMITTER = (1 << 1),
+		SHORTLOG_GROUP_TRAILER = (1 << 2),
+	} groups;
+	struct string_list trailers;
 
 	char *common_repo_prefix;
 	int email;
diff --git a/submodule.c b/submodule.c
index 543b112..b3bb59f 100644
--- a/submodule.c
+++ b/submodule.c
@@ -865,7 +865,8 @@
 		diff_rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
 		diff_rev.diffopt.format_callback = collect_changed_submodules_cb;
 		diff_rev.diffopt.format_callback_data = &data;
-		diff_tree_combined_merge(commit, 1, &diff_rev);
+		diff_rev.dense_combined_merges = 1;
+		diff_tree_combined_merge(commit, &diff_rev);
 	}
 
 	reset_revision_walk();
diff --git a/t/helper/test-reach.c b/t/helper/test-reach.c
index 14a3655..cda804e 100644
--- a/t/helper/test-reach.c
+++ b/t/helper/test-reach.c
@@ -107,6 +107,8 @@
 		printf("%s(A,B):%d\n", av[1], ref_newer(&oid_A, &oid_B));
 	else if (!strcmp(av[1], "in_merge_bases"))
 		printf("%s(A,B):%d\n", av[1], in_merge_bases(A, B));
+	else if (!strcmp(av[1], "in_merge_bases_many"))
+		printf("%s(A,X):%d\n", av[1], in_merge_bases_many(A, X_nr, X_array));
 	else if (!strcmp(av[1], "is_descendant_of"))
 		printf("%s(A,X):%d\n", av[1], repo_is_descendant_of(r, A, X));
 	else if (!strcmp(av[1], "get_merge_bases_many")) {
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index c24c663..6efe7a4 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -234,10 +234,10 @@
 	git branch -M master master
 '
 
-test_expect_success 'git branch -M master2 master2 should work when master is checked out' '
+test_expect_success 'git branch -M topic topic should work when master is checked out' '
 	git checkout master &&
-	git branch master2 &&
-	git branch -M master2 master2
+	git branch topic &&
+	git branch -M topic topic
 '
 
 test_expect_success 'git branch -v -d t should work' '
@@ -324,8 +324,8 @@
 test_expect_success 'git branch --column' '
 	COLUMNS=81 git branch --column=column >actual &&
 	cat >expect <<\EOF &&
-  a/b/c     bam       foo       l       * master    mb        o/o       q
-  abc       bar       j/k       m/m       master2   n         o/p       r
+  a/b/c    bam      foo      l      * master   n        o/p      r
+  abc      bar      j/k      m/m      mb       o/o      q        topic
 EOF
 	test_cmp expect actual
 '
@@ -346,13 +346,13 @@
   l
   m/m
 * master
-  master2
   mb
   n
   o/o
   o/p
   q
   r
+  topic
   $long
 EOF
 	test_cmp expect actual
@@ -365,8 +365,8 @@
 	git config --unset column.branch &&
 	git config --unset column.ui &&
 	cat >expect <<\EOF &&
-  a/b/c   bam   foo   l   * master    mb   o/o   q
-  abc     bar   j/k   m/m   master2   n    o/p   r
+  a/b/c   bam   foo   l   * master   n     o/p   r
+  abc     bar   j/k   m/m   mb       o/o   q     topic
 EOF
 	test_cmp expect actual
 '
@@ -377,7 +377,7 @@
 
 test_expect_success 'git branch -v with column.ui ignored' '
 	git config column.ui column &&
-	COLUMNS=80 git branch -v | cut -c -10 | sed "s/ *$//" >actual &&
+	COLUMNS=80 git branch -v | cut -c -9 | sed "s/ *$//" >actual &&
 	git config --unset column.ui &&
 	cat >expect <<\EOF &&
   a/b/c
@@ -389,13 +389,13 @@
   l
   m/m
 * master
-  master2
   mb
   n
   o/o
   o/p
   q
   r
+  topic
 EOF
 	test_cmp expect actual
 '
@@ -597,10 +597,10 @@
 	git branch -C master master
 '
 
-test_expect_success 'git branch -C master5 master5 should work when master is checked out' '
+test_expect_success 'git branch -C main5 main5 should work when master is checked out' '
 	git checkout master &&
-	git branch master5 &&
-	git branch -C master5 master5
+	git branch main5 &&
+	git branch -C main5 main5
 '
 
 test_expect_success 'git branch -C ab cd should overwrite existing config for cd' '
@@ -711,11 +711,11 @@
 '
 
 test_expect_success 'renaming a symref is not allowed' '
-	git symbolic-ref refs/heads/master2 refs/heads/master &&
-	test_must_fail git branch -m master2 master3 &&
-	git symbolic-ref refs/heads/master2 &&
+	git symbolic-ref refs/heads/topic refs/heads/master &&
+	test_must_fail git branch -m topic new-topic &&
+	git symbolic-ref refs/heads/topic &&
 	test_path_is_file .git/refs/heads/master &&
-	test_path_is_missing .git/refs/heads/master3
+	test_path_is_missing .git/refs/heads/new-topic
 '
 
 test_expect_success SYMLINKS 'git branch -m u v should fail when the reflog for u is a symlink' '
diff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh
index 79e43a3..2a7d958 100755
--- a/t/t3427-rebase-subtree.sh
+++ b/t/t3427-rebase-subtree.sh
@@ -15,12 +15,12 @@
 # this test script tries to document them.  First, the following commit history
 # is generated (the onelines are shown, time flows from left to right):
 #
-# master1 - master2 - master3
+# topic_1 - topic_2 - topic_3
 #                             \
-# README ---------------------- Add subproject master - master4 - files_subtree/master5
+# README ---------------------- Add subproject master - topic_4 - files_subtree/topic_5
 #
 # Where the merge moves the files master[123].t into the subdirectory
-# files_subtree/ and master4 as well as files_subtree/master5 add files to that
+# files_subtree/ and topic_4 as well as files_subtree/topic_5 add files to that
 # directory directly.
 #
 # Then, in subsequent test cases, `git filter-branch` is used to distill just
@@ -28,11 +28,11 @@
 # an empty commit is added on top. The pre-rebase commit history looks like
 # this:
 #
-# Add subproject master - master4 - files_subtree/master5 - Empty commit
+# Add subproject master - topic_4 - files_subtree/topic_5 - Empty commit
 #
-# where the root commit adds three files: master1.t, master2.t and master3.t.
+# where the root commit adds three files: topic_1.t, topic_2.t and topic_3.t.
 #
-# This commit history is then rebased onto `master3` with the
+# This commit history is then rebased onto `topic_3` with the
 # `-Xsubtree=files_subtree` option in three different ways:
 #
 # 1. using `--preserve-merges`
@@ -43,9 +43,9 @@
 	test_commit README &&
 
 	git init files &&
-	test_commit -C files master1 &&
-	test_commit -C files master2 &&
-	test_commit -C files master3 &&
+	test_commit -C files topic_1 &&
+	test_commit -C files topic_2 &&
+	test_commit -C files topic_3 &&
 
 	: perform subtree merge into files_subtree/ &&
 	git fetch files refs/heads/master:refs/heads/files-master &&
@@ -55,8 +55,8 @@
 	git commit -m "Add subproject master" &&
 
 	: add two extra commits to rebase &&
-	test_commit -C files_subtree master4 &&
-	test_commit files_subtree/master5 &&
+	test_commit -C files_subtree topic_4 &&
+	test_commit files_subtree/topic_5 &&
 
 	git checkout -b to-rebase &&
 	git fast-export --no-data HEAD -- files_subtree/ |
@@ -66,22 +66,22 @@
 	git commit -m "Empty commit" --allow-empty
 '
 
-# FAILURE: Does not preserve master4.
+# FAILURE: Does not preserve topic_4.
 test_expect_failure REBASE_P 'Rebase -Xsubtree --preserve-merges --onto commit' '
 	reset_rebase &&
 	git checkout -b rebase-preserve-merges to-rebase &&
 	git rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master &&
-	verbose test "$(commit_message HEAD~)" = "master4" &&
-	verbose test "$(commit_message HEAD)" = "files_subtree/master5"
+	verbose test "$(commit_message HEAD~)" = "topic_4" &&
+	verbose test "$(commit_message HEAD)" = "files_subtree/topic_5"
 '
 
-# FAILURE: Does not preserve master4.
+# FAILURE: Does not preserve topic_4.
 test_expect_failure REBASE_P 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit' '
 	reset_rebase &&
 	git checkout -b rebase-keep-empty to-rebase &&
 	git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&
-	verbose test "$(commit_message HEAD~2)" = "master4" &&
-	verbose test "$(commit_message HEAD~)" = "files_subtree/master5" &&
+	verbose test "$(commit_message HEAD~2)" = "topic_4" &&
+	verbose test "$(commit_message HEAD~)" = "files_subtree/topic_5" &&
 	verbose test "$(commit_message HEAD)" = "Empty commit"
 '
 
@@ -91,8 +91,8 @@
 	test_must_fail git rebase -Xsubtree=files_subtree --empty=ask --onto files-master master &&
 	: first pick results in no changes &&
 	git rebase --skip &&
-	verbose test "$(commit_message HEAD~2)" = "master4" &&
-	verbose test "$(commit_message HEAD~)" = "files_subtree/master5" &&
+	verbose test "$(commit_message HEAD~2)" = "topic_4" &&
+	verbose test "$(commit_message HEAD~)" = "files_subtree/topic_5" &&
 	verbose test "$(commit_message HEAD)" = "Empty commit"
 '
 
@@ -102,8 +102,8 @@
 	test_must_fail git rebase -Xsubtree=files_subtree --empty=ask --rebase-merges --onto files-master --root &&
 	: first pick results in no changes &&
 	git rebase --skip &&
-	verbose test "$(commit_message HEAD~2)" = "master4" &&
-	verbose test "$(commit_message HEAD~)" = "files_subtree/master5" &&
+	verbose test "$(commit_message HEAD~2)" = "topic_4" &&
+	verbose test "$(commit_message HEAD~)" = "files_subtree/topic_5" &&
 	verbose test "$(commit_message HEAD)" = "Empty commit"
 '
 
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index 1da8ab1..3ecbef6 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -465,7 +465,7 @@
 test_expect_success 'am --signoff adds Signed-off-by: line' '
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
-	git checkout -b master2 first &&
+	git checkout -b topic_2 first &&
 	git am --signoff <patch2 &&
 	{
 		printf "third\n\nSigned-off-by: %s <%s>\n\n" \
@@ -479,7 +479,7 @@
 '
 
 test_expect_success 'am stays in branch' '
-	echo refs/heads/master2 >expected &&
+	echo refs/heads/topic_2 >expected &&
 	git symbolic-ref HEAD >actual &&
 	test_cmp expected actual
 '
@@ -540,7 +540,7 @@
 	git reset --hard HEAD^ &&
 	git am <patch4 &&
 	git rev-parse HEAD >expected &&
-	git rev-parse master2 >actual &&
+	git rev-parse topic_2 >actual &&
 	test_cmp expected actual
 '
 
@@ -567,7 +567,7 @@
 test_expect_success 'setup am -3' '
 	rm -fr .git/rebase-apply &&
 	git reset --hard &&
-	git checkout -b base3way master2 &&
+	git checkout -b base3way topic_2 &&
 	sed -n -e "3,\$p" msg >file &&
 	head -n 9 msg >>file &&
 	git add file &&
diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh
index d3a7ce6..3d5c4a2 100755
--- a/t/t4201-shortlog.sh
+++ b/t/t4201-shortlog.sh
@@ -215,4 +215,145 @@
 	test_cmp expect actual
 '
 
+test_expect_success '--group=committer is the same as --committer' '
+	git shortlog -ns --group=committer HEAD >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'shortlog --group=trailer:signed-off-by' '
+	git commit --allow-empty -m foo -s &&
+	GIT_COMMITTER_NAME="SOB One" \
+	GIT_COMMITTER_EMAIL=sob@example.com \
+		git commit --allow-empty -m foo -s &&
+	git commit --allow-empty --amend --no-edit -s &&
+	cat >expect <<-\EOF &&
+	     2	C O Mitter <committer@example.com>
+	     1	SOB One <sob@example.com>
+	EOF
+	git shortlog -nse --group=trailer:signed-off-by HEAD >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'trailer idents are split' '
+	cat >expect <<-\EOF &&
+	     2	C O Mitter
+	     1	SOB One
+	EOF
+	git shortlog -ns --group=trailer:signed-off-by HEAD >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'trailer idents are mailmapped' '
+	cat >expect <<-\EOF &&
+	     2	C O Mitter
+	     1	Another Name
+	EOF
+	echo "Another Name <sob@example.com>" >mail.map &&
+	git -c mailmap.file=mail.map shortlog -ns \
+		--group=trailer:signed-off-by HEAD >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'shortlog de-duplicates trailers in a single commit' '
+	git commit --allow-empty -F - <<-\EOF &&
+	subject one
+
+	this message has two distinct values, plus a repeat
+
+	Repeated-trailer: Foo
+	Repeated-trailer: Bar
+	Repeated-trailer: Foo
+	EOF
+
+	git commit --allow-empty -F - <<-\EOF &&
+	subject two
+
+	similar to the previous, but without the second distinct value
+
+	Repeated-trailer: Foo
+	Repeated-trailer: Foo
+	EOF
+
+	cat >expect <<-\EOF &&
+	     2	Foo
+	     1	Bar
+	EOF
+	git shortlog -ns --group=trailer:repeated-trailer -2 HEAD >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'shortlog can match multiple groups' '
+	git commit --allow-empty -F - <<-\EOF &&
+	subject one
+
+	this has two trailers that are distinct from the author; it will count
+	3 times in the output
+
+	Some-trailer: User A <a@example.com>
+	Another-trailer: User B <b@example.com>
+	EOF
+
+	git commit --allow-empty -F - <<-\EOF &&
+	subject two
+
+	this one has two trailers, one of which is a duplicate with the author;
+	it will only be counted once for them
+
+	Another-trailer: A U Thor <author@example.com>
+	Some-trailer: User B <b@example.com>
+	EOF
+
+	cat >expect <<-\EOF &&
+	     2	A U Thor
+	     2	User B
+	     1	User A
+	EOF
+	git shortlog -ns \
+		--group=author \
+		--group=trailer:some-trailer \
+		--group=trailer:another-trailer \
+		-2 HEAD >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'set up option selection tests' '
+	git commit --allow-empty -F - <<-\EOF
+	subject
+
+	body
+
+	Trailer-one: value-one
+	Trailer-two: value-two
+	EOF
+'
+
+test_expect_success '--no-group resets group list to author' '
+	cat >expect <<-\EOF &&
+	     1	A U Thor
+	EOF
+	git shortlog -ns \
+		--group=committer \
+		--group=trailer:trailer-one \
+		--no-group \
+		-1 HEAD >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '--no-group resets trailer list' '
+	cat >expect <<-\EOF &&
+	     1	value-two
+	EOF
+	git shortlog -ns \
+		--group=trailer:trailer-one \
+		--no-group \
+		--group=trailer:trailer-two \
+		-1 HEAD >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'stdin with multiple groups reports error' '
+	git log >log &&
+	test_must_fail git shortlog --group=author --group=committer <log
+'
+
 test_done
diff --git a/t/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh
index 9d6a46f..70a9d2d 100755
--- a/t/t5515-fetch-merge-logic.sh
+++ b/t/t5515-fetch-merge-logic.sh
@@ -15,7 +15,7 @@
 
 build_script () {
 	script="$1" &&
-	for i in one three_file master master2 one_tree three two two2 three2
+	for i in one three_file master topic_2 one_tree three two two2 three2
 	do
 		echo "s/$(test_oid --hash=sha1 "$i")/$(test_oid "$i")/g" >>"$script"
 	done
@@ -52,8 +52,8 @@
 	two sha1:525b7fb068d59950d185a8779dc957c77eed73ba
 	two sha256:3b21de3440cd38c2a9e9b464adb923f7054949ed4c918e1a0ac4c95cd52774db
 
-	master2 sha1:754b754407bf032e9a2f9d5a9ad05ca79a6b228f
-	master2 sha256:6c7abaea8a6d8ef4d89877e68462758dc6774690fbbbb0e6d7dd57415c9abde0
+	topic_2 sha1:754b754407bf032e9a2f9d5a9ad05ca79a6b228f
+	topic_2 sha256:6c7abaea8a6d8ef4d89877e68462758dc6774690fbbbb0e6d7dd57415c9abde0
 
 	two2 sha1:6134ee8f857693b96ff1cc98d3e2fd62b199e5a8
 	two2 sha256:87a2d3ee29c83a3dc7afd41c0606b11f67603120b910a7be7840accdc18344d4
diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh
index c0df81a..e47b5db 100755
--- a/t/t5523-push-upstream.sh
+++ b/t/t5523-push-upstream.sh
@@ -41,20 +41,20 @@
 	check_config master upstream refs/heads/other
 '
 
-test_expect_success 'push -u master2:master2' '
-	git branch master2 &&
-	git push -u upstream master2:master2 &&
-	check_config master2 upstream refs/heads/master2
+test_expect_success 'push -u topic_2:topic_2' '
+	git branch topic_2 &&
+	git push -u upstream topic_2:topic_2 &&
+	check_config topic_2 upstream refs/heads/topic_2
 '
 
-test_expect_success 'push -u master2:other2' '
-	git push -u upstream master2:other2 &&
-	check_config master2 upstream refs/heads/other2
+test_expect_success 'push -u topic_2:other2' '
+	git push -u upstream topic_2:other2 &&
+	check_config topic_2 upstream refs/heads/other2
 '
 
-test_expect_success 'push -u :master2' '
-	git push -u upstream :master2 &&
-	check_config master2 upstream refs/heads/other2
+test_expect_success 'push -u :topic_2' '
+	git push -u upstream :topic_2 &&
+	check_config topic_2 upstream refs/heads/other2
 '
 
 test_expect_success 'push -u --all' '
diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh
index b31ff7e..fe2f3ce 100755
--- a/t/t6018-rev-list-glob.sh
+++ b/t/t6018-rev-list-glob.sh
@@ -32,11 +32,11 @@
 	git checkout -b someref master &&
 	commit some &&
 	git checkout master &&
-	commit master2 &&
+	commit topic_2 &&
 	git tag foo/bar master &&
-	commit master3 &&
+	commit topic_3 &&
 	git update-ref refs/remotes/foo/baz master &&
-	commit master4 &&
+	commit topic_4 &&
 	git update-ref refs/remotes/upstream/one subspace/one &&
 	git update-ref refs/remotes/upstream/two subspace/two &&
 	git update-ref refs/remotes/upstream/x subspace-x &&
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index b886529..aa22638 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -82,6 +82,13 @@
 	git bisect bad $HASH4
 '
 
+test_expect_success 'bisect start without -- takes unknown arg as pathspec' '
+	git bisect reset &&
+	git bisect start foo bar &&
+	grep foo ".git/BISECT_NAMES" &&
+	grep bar ".git/BISECT_NAMES"
+'
+
 test_expect_success 'bisect reset: back in the master branch' '
 	git bisect reset &&
 	echo "* master" > branch.expect &&
diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh
index ad1922b..50a934e 100755
--- a/t/t6040-tracking-info.sh
+++ b/t/t6040-tracking-info.sh
@@ -264,25 +264,25 @@
 test_expect_success '--set-upstream-to does not change branch' '
 	git branch from-master master &&
 	git branch --set-upstream-to master from-master &&
-	git branch from-master2 master &&
-	test_must_fail git config branch.from-master2.merge > actual &&
-	git rev-list from-master2 &&
-	git update-ref refs/heads/from-master2 from-master2^ &&
-	git rev-parse from-master2 >expect2 &&
-	git branch --set-upstream-to master from-master2 &&
+	git branch from-topic_2 master &&
+	test_must_fail git config branch.from-topic_2.merge > actual &&
+	git rev-list from-topic_2 &&
+	git update-ref refs/heads/from-topic_2 from-topic_2^ &&
+	git rev-parse from-topic_2 >expect2 &&
+	git branch --set-upstream-to master from-topic_2 &&
 	git config branch.from-master.merge > actual &&
-	git rev-parse from-master2 >actual2 &&
+	git rev-parse from-topic_2 >actual2 &&
 	grep -q "^refs/heads/master$" actual &&
 	cmp expect2 actual2
 '
 
 test_expect_success '--set-upstream-to @{-1}' '
 	git checkout follower &&
-	git checkout from-master2 &&
-	git config branch.from-master2.merge > expect2 &&
+	git checkout from-topic_2 &&
+	git config branch.from-topic_2.merge > expect2 &&
 	git branch --set-upstream-to @{-1} from-master &&
 	git config branch.from-master.merge > actual &&
-	git config branch.from-master2.merge > actual2 &&
+	git config branch.from-topic_2.merge > actual2 &&
 	git branch --set-upstream-to follower from-master &&
 	git config branch.from-master.merge > expect &&
 	test_cmp expect2 actual2 &&
diff --git a/t/t6409-merge-subtree.sh b/t/t6409-merge-subtree.sh
index 793f0c8..1a0d0e2 100755
--- a/t/t6409-merge-subtree.sh
+++ b/t/t6409-merge-subtree.sh
@@ -94,10 +94,10 @@
 	echo git-gui2 > git-gui.sh &&
 	o3=$(git hash-object git-gui.sh) &&
 	git add git-gui.sh &&
-	git checkout -b master2 &&
+	git checkout -b topic_2 &&
 	git commit -m "update git-gui" &&
 	cd ../git &&
-	git pull -s subtree gui master2 &&
+	git pull -s subtree gui topic_2 &&
 	git ls-files -s >actual &&
 	(
 		echo "100644 $o3 0	git-gui/git-gui.sh" &&
@@ -109,7 +109,7 @@
 test_expect_success 'initial ambiguous subtree' '
 	cd ../git &&
 	git reset --hard master &&
-	git checkout -b master2 &&
+	git checkout -b topic_2 &&
 	git merge -s ours --no-commit gui/master &&
 	git read-tree --prefix=git-gui2/ -u gui/master &&
 	git commit -m "Merge git-gui2 as our subdirectory" &&
@@ -125,8 +125,8 @@
 
 test_expect_success 'merge using explicit' '
 	cd ../git &&
-	git reset --hard master2 &&
-	git pull -Xsubtree=git-gui gui master2 &&
+	git reset --hard topic_2 &&
+	git pull -Xsubtree=git-gui gui topic_2 &&
 	git ls-files -s >actual &&
 	(
 		echo "100644 $o3 0	git-gui/git-gui.sh" &&
@@ -138,8 +138,8 @@
 
 test_expect_success 'merge2 using explicit' '
 	cd ../git &&
-	git reset --hard master2 &&
-	git pull -Xsubtree=git-gui2 gui master2 &&
+	git reset --hard topic_2 &&
+	git pull -Xsubtree=git-gui2 gui topic_2 &&
 	git ls-files -s >actual &&
 	(
 		echo "100644 $o1 0	git-gui/git-gui.sh" &&
diff --git a/t/t6600-test-reach.sh b/t/t6600-test-reach.sh
index 475564b..f807276 100755
--- a/t/t6600-test-reach.sh
+++ b/t/t6600-test-reach.sh
@@ -110,6 +110,36 @@
 	test_three_modes in_merge_bases
 '
 
+test_expect_success 'in_merge_bases_many:hit' '
+	cat >input <<-\EOF &&
+	A:commit-6-8
+	X:commit-6-9
+	X:commit-5-7
+	EOF
+	echo "in_merge_bases_many(A,X):1" >expect &&
+	test_three_modes in_merge_bases_many
+'
+
+test_expect_success 'in_merge_bases_many:miss' '
+	cat >input <<-\EOF &&
+	A:commit-6-8
+	X:commit-7-7
+	X:commit-8-6
+	EOF
+	echo "in_merge_bases_many(A,X):0" >expect &&
+	test_three_modes in_merge_bases_many
+'
+
+test_expect_success 'in_merge_bases_many:miss-heuristic' '
+	cat >input <<-\EOF &&
+	A:commit-6-8
+	X:commit-7-5
+	X:commit-6-6
+	EOF
+	echo "in_merge_bases_many(A,X):0" >expect &&
+	test_three_modes in_merge_bases_many
+'
+
 test_expect_success 'is_descendant_of:hit' '
 	cat >input <<-\EOF &&
 	A:commit-5-7
diff --git a/t/t8013-blame-ignore-revs.sh b/t/t8013-blame-ignore-revs.sh
index 36dc31e..24ae501 100755
--- a/t/t8013-blame-ignore-revs.sh
+++ b/t/t8013-blame-ignore-revs.sh
@@ -21,6 +21,7 @@
 	test_tick &&
 	git commit -m X &&
 	git tag X &&
+	git tag -a -m "X (annotated)" XT &&
 
 	git blame --line-porcelain file >blame_raw &&
 
@@ -31,20 +32,36 @@
 	grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual &&
 	git rev-parse X >expect &&
 	test_cmp expect actual
+'
+
+# Ensure bogus --ignore-rev requests are caught
+test_expect_success 'validate --ignore-rev' '
+	test_must_fail git blame --ignore-rev X^{tree} file
+'
+
+# Ensure bogus --ignore-revs-file requests are caught
+test_expect_success 'validate --ignore-revs-file' '
+	git rev-parse X^{tree} >ignore_x &&
+	test_must_fail git blame --ignore-revs-file ignore_x file
+'
+
+for I in X XT
+do
+	# Ignore X (or XT), make sure A is blamed for line 1 and B for line 2.
+	# Giving X (i.e. commit) and XT (i.e. annotated tag to commit) should
+	# produce the same result.
+	test_expect_success "ignore_rev_changing_lines ($I)" '
+		git blame --line-porcelain --ignore-rev $I file >blame_raw &&
+
+		grep -E "^[0-9a-f]+ [0-9]+ 1" blame_raw | sed -e "s/ .*//" >actual &&
+		git rev-parse A >expect &&
+		test_cmp expect actual &&
+
+		grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual &&
+		git rev-parse B >expect &&
+		test_cmp expect actual
 	'
-
-# Ignore X, make sure A is blamed for line 1 and B for line 2.
-test_expect_success ignore_rev_changing_lines '
-	git blame --line-porcelain --ignore-rev X file >blame_raw &&
-
-	grep -E "^[0-9a-f]+ [0-9]+ 1" blame_raw | sed -e "s/ .*//" >actual &&
-	git rev-parse A >expect &&
-	test_cmp expect actual &&
-
-	grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual &&
-	git rev-parse B >expect &&
-	test_cmp expect actual
-	'
+done
 
 # For ignored revs that have added 'unblamable' lines, attribute those to the
 # ignored commit.
@@ -67,7 +84,7 @@
 
 	grep -E "^[0-9a-f]+ [0-9]+ 4" blame_raw | sed -e "s/ .*//" >actual &&
 	test_cmp expect actual
-	'
+'
 
 # Ignore X and Y, both in separate files.  Lines 1 == A, 2 == B.
 test_expect_success ignore_revs_from_files '
@@ -82,7 +99,7 @@
 	grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual &&
 	git rev-parse B >expect &&
 	test_cmp expect actual
-	'
+'
 
 # Ignore X from the config option, Y from a file.
 test_expect_success ignore_revs_from_configs_and_files '
@@ -96,7 +113,7 @@
 	grep -E "^[0-9a-f]+ [0-9]+ 2" blame_raw | sed -e "s/ .*//" >actual &&
 	git rev-parse B >expect &&
 	test_cmp expect actual
-	'
+'
 
 # Override blame.ignoreRevsFile (ignore_x) with an empty string.  X should be
 # blamed now for lines 1 and 2, since we are no longer ignoring X.
@@ -120,7 +137,7 @@
 	echo NOREV >ignore_norev &&
 	test_must_fail git blame file --ignore-revs-file ignore_norev 2>err &&
 	test_i18ngrep "invalid object name: NOREV" err
-	'
+'
 
 # For ignored revs that have added 'unblamable' lines, mark those lines with a
 # '*'
@@ -138,7 +155,7 @@
 
 	sed -n "4p" blame_raw | cut -c1 >actual &&
 	test_cmp expect actual
-	'
+'
 
 # Commit Z will touch the first two lines.  Y touched all four.
 # 	A--B--X--Y--Z
@@ -171,7 +188,7 @@
 
 	sed -n "4p" blame_raw | cut -c1 >actual &&
 	! test_cmp expect actual
-	'
+'
 
 # For ignored revs that added 'unblamable' lines and more recent commits changed
 # the blamable lines, mark the unblamable lines with a
@@ -190,7 +207,7 @@
 
 	sed -n "4p" blame_raw | cut -c1 >actual &&
 	test_cmp expect actual
-	'
+'
 
 # The heuristic called by guess_line_blames() tries to find the size of a
 # blame_entry 'e' in the parent's address space.  Those calculations need to
@@ -227,7 +244,7 @@
 	git tag C &&
 
 	git blame file --ignore-rev B >blame_raw
-	'
+'
 
 # Resetting the repo and creating:
 #
@@ -269,6 +286,6 @@
 	grep -E "^[0-9a-f]+ [0-9]+ 9" blame_raw | sed -e "s/ .*//" >actual &&
 	git rev-parse C >expect &&
 	test_cmp expect actual
-	'
+'
 
 test_done
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 8425b9a..7b7bc6e 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -542,37 +542,37 @@
 '
 
 read -r -d "" refs <<-\EOF
+main
 maint
-master
 next
 seen
 EOF
 
 test_expect_success '__gitcomp_nl - trailing space' '
 	test_gitcomp_nl "m" "$refs" <<-EOF
+	main Z
 	maint Z
-	master Z
 	EOF
 '
 
 test_expect_success '__gitcomp_nl - prefix' '
 	test_gitcomp_nl "--fixup=m" "$refs" "--fixup=" "m" <<-EOF
+	--fixup=main Z
 	--fixup=maint Z
-	--fixup=master Z
 	EOF
 '
 
 test_expect_success '__gitcomp_nl - suffix' '
 	test_gitcomp_nl "branch.ma" "$refs" "branch." "ma" "." <<-\EOF
+	branch.main.Z
 	branch.maint.Z
-	branch.master.Z
 	EOF
 '
 
 test_expect_success '__gitcomp_nl - no suffix' '
 	test_gitcomp_nl "ma" "$refs" "" "ma" "" <<-\EOF
+	mainZ
 	maintZ
-	masterZ
 	EOF
 '
 
diff --git a/t/test-terminal.perl b/t/test-terminal.perl
index 46bf618..1bcf01a 100755
--- a/t/test-terminal.perl
+++ b/t/test-terminal.perl
@@ -81,24 +81,24 @@
 	die "usage: test-terminal program args";
 }
 $ENV{TERM} = 'vt100';
-my $master_in = new IO::Pty;
-my $master_out = new IO::Pty;
-my $master_err = new IO::Pty;
-$master_in->set_raw();
-$master_out->set_raw();
-$master_err->set_raw();
-$master_in->slave->set_raw();
-$master_out->slave->set_raw();
-$master_err->slave->set_raw();
-my $pid = start_child(\@ARGV, $master_in->slave, $master_out->slave, $master_err->slave);
-close $master_in->slave;
-close $master_out->slave;
-close $master_err->slave;
-my $in_pid = copy_stdin($master_in);
-copy_stdio($master_out, $master_err);
+my $parent_in = new IO::Pty;
+my $parent_out = new IO::Pty;
+my $parent_err = new IO::Pty;
+$parent_in->set_raw();
+$parent_out->set_raw();
+$parent_err->set_raw();
+$parent_in->slave->set_raw();
+$parent_out->slave->set_raw();
+$parent_err->slave->set_raw();
+my $pid = start_child(\@ARGV, $parent_in->slave, $parent_out->slave, $parent_err->slave);
+close $parent_in->slave;
+close $parent_out->slave;
+close $parent_err->slave;
+my $in_pid = copy_stdin($parent_in);
+copy_stdio($parent_out, $parent_err);
 my $ret = finish_child($pid);
 # If the child process terminates before our copy_stdin() process is able to
-# write all of its data to $master_in, the copy_stdin() process could stall.
+# write all of its data to $parent_in, the copy_stdin() process could stall.
 # Send SIGTERM to it to ensure it terminates.
 kill 'TERM', $in_pid;
 finish_child($in_pid);
diff --git a/trailer.c b/trailer.c
index 68dabc2..3f7391d 100644
--- a/trailer.c
+++ b/trailer.c
@@ -1183,3 +1183,39 @@
 	format_trailer_info(out, &info, opts);
 	trailer_info_release(&info);
 }
+
+void trailer_iterator_init(struct trailer_iterator *iter, const char *msg)
+{
+	struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
+	strbuf_init(&iter->key, 0);
+	strbuf_init(&iter->val, 0);
+	opts.no_divider = 1;
+	trailer_info_get(&iter->info, msg, &opts);
+	iter->cur = 0;
+}
+
+int trailer_iterator_advance(struct trailer_iterator *iter)
+{
+	while (iter->cur < iter->info.trailer_nr) {
+		char *trailer = iter->info.trailers[iter->cur++];
+		int separator_pos = find_separator(trailer, separators);
+
+		if (separator_pos < 1)
+			continue; /* not a real trailer */
+
+		strbuf_reset(&iter->key);
+		strbuf_reset(&iter->val);
+		parse_trailer(&iter->key, &iter->val, NULL,
+			      trailer, separator_pos);
+		unfold_value(&iter->val);
+		return 1;
+	}
+	return 0;
+}
+
+void trailer_iterator_release(struct trailer_iterator *iter)
+{
+	trailer_info_release(&iter->info);
+	strbuf_release(&iter->val);
+	strbuf_release(&iter->key);
+}
diff --git a/trailer.h b/trailer.h
index 203acf4..cd93e7d 100644
--- a/trailer.h
+++ b/trailer.h
@@ -2,8 +2,7 @@
 #define TRAILER_H
 
 #include "list.h"
-
-struct strbuf;
+#include "strbuf.h"
 
 enum trailer_where {
 	WHERE_DEFAULT,
@@ -103,4 +102,46 @@
 void format_trailers_from_commit(struct strbuf *out, const char *msg,
 				 const struct process_trailer_options *opts);
 
+/*
+ * An interface for iterating over the trailers found in a particular commit
+ * message. Use like:
+ *
+ *   struct trailer_iterator iter;
+ *   trailer_iterator_init(&iter, msg);
+ *   while (trailer_iterator_advance(&iter))
+ *      ... do something with iter.key and iter.val ...
+ *   trailer_iterator_release(&iter);
+ */
+struct trailer_iterator {
+	struct strbuf key;
+	struct strbuf val;
+
+	/* private */
+	struct trailer_info info;
+	size_t cur;
+};
+
+/*
+ * Initialize "iter" in preparation for walking over the trailers in the commit
+ * message "msg". The "msg" pointer must remain valid until the iterator is
+ * released.
+ *
+ * After initializing, note that key/val will not yet point to any trailer.
+ * Call advance() to parse the first one (if any).
+ */
+void trailer_iterator_init(struct trailer_iterator *iter, const char *msg);
+
+/*
+ * Advance to the next trailer of the iterator. Returns 0 if there is no such
+ * trailer, and 1 otherwise. The key and value of the trailer can be
+ * fetched from the iter->key and iter->value fields (which are valid
+ * only until the next advance).
+ */
+int trailer_iterator_advance(struct trailer_iterator *iter);
+
+/*
+ * Release all resources associated with the trailer iteration.
+ */
+void trailer_iterator_release(struct trailer_iterator *iter);
+
 #endif /* TRAILER_H */
diff --git a/worktree.c b/worktree.c
index 46a5fb8..f84ceae 100644
--- a/worktree.c
+++ b/worktree.c
@@ -21,7 +21,7 @@
 }
 
 /**
- * Update head_sha1, head_ref and is_detached of the given worktree
+ * Update head_oid, head_ref and is_detached of the given worktree
  */
 static void add_head_info(struct worktree *wt)
 {
@@ -352,13 +352,12 @@
 
 	memset(&state, 0, sizeof(state));
 	found_rebase = wt_status_check_rebase(wt, &state) &&
-		((state.rebase_in_progress ||
-		  state.rebase_interactive_in_progress) &&
-		 state.branch &&
-		 starts_with(target, "refs/heads/") &&
-		 !strcmp(state.branch, target + strlen("refs/heads/")));
-	free(state.branch);
-	free(state.onto);
+		       (state.rebase_in_progress ||
+			state.rebase_interactive_in_progress) &&
+		       state.branch &&
+		       skip_prefix(target, "refs/heads/", &target) &&
+		       !strcmp(state.branch, target);
+	wt_status_state_free_buffers(&state);
 	return found_rebase;
 }
 
@@ -366,15 +365,15 @@
 			       const char *target)
 {
 	struct wt_status_state state;
-	int found_rebase;
+	int found_bisect;
 
 	memset(&state, 0, sizeof(state));
-	found_rebase = wt_status_check_bisect(wt, &state) &&
-		state.branch &&
-		starts_with(target, "refs/heads/") &&
-		!strcmp(state.branch, target + strlen("refs/heads/"));
-	free(state.branch);
-	return found_rebase;
+	found_bisect = wt_status_check_bisect(wt, &state) &&
+		       state.branch &&
+		       skip_prefix(target, "refs/heads/", &target) &&
+		       !strcmp(state.branch, target);
+	wt_status_state_free_buffers(&state);
+	return found_bisect;
 }
 
 /*
@@ -537,18 +536,10 @@
 	strbuf_addstr(sb, refname);
 }
 
-const char *worktree_ref(const struct worktree *wt, const char *refname)
-{
-	static struct strbuf sb = STRBUF_INIT;
-
-	strbuf_reset(&sb);
-	strbuf_worktree_ref(wt, &sb, refname);
-	return sb.buf;
-}
-
 int other_head_refs(each_ref_fn fn, void *cb_data)
 {
 	struct worktree **worktrees, **p;
+	struct strbuf refname = STRBUF_INIT;
 	int ret = 0;
 
 	worktrees = get_worktrees();
@@ -560,15 +551,18 @@
 		if (wt->is_current)
 			continue;
 
+		strbuf_reset(&refname);
+		strbuf_worktree_ref(wt, &refname, "HEAD");
 		if (!refs_read_ref_full(get_main_ref_store(the_repository),
-					worktree_ref(wt, "HEAD"),
+					refname.buf,
 					RESOLVE_REF_READING,
 					&oid, &flag))
-			ret = fn(worktree_ref(wt, "HEAD"), &oid, flag, cb_data);
+			ret = fn(refname.buf, &oid, flag, cb_data);
 		if (ret)
 			break;
 	}
 	free_worktrees(worktrees);
+	strbuf_release(&refname);
 	return ret;
 }
 
diff --git a/worktree.h b/worktree.h
index ff7b62e..f38e6fd 100644
--- a/worktree.h
+++ b/worktree.h
@@ -159,11 +159,4 @@
 			 struct strbuf *sb,
 			 const char *refname);
 
-/*
- * Return a refname suitable for access from the current ref
- * store. The result will be destroyed at the next call.
- */
-const char *worktree_ref(const struct worktree *wt,
-			 const char *refname);
-
 #endif
diff --git a/wt-status.c b/wt-status.c
index 160d149..7074bbd 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -776,9 +776,14 @@
 
 void wt_status_collect_free_buffers(struct wt_status *s)
 {
-	free(s->state.branch);
-	free(s->state.onto);
-	free(s->state.detached_from);
+	wt_status_state_free_buffers(&s->state);
+}
+
+void wt_status_state_free_buffers(struct wt_status_state *state)
+{
+	FREE_AND_NULL(state->branch);
+	FREE_AND_NULL(state->onto);
+	FREE_AND_NULL(state->detached_from);
 }
 
 static void wt_longstatus_print_unmerged(struct wt_status *s)
@@ -1225,7 +1230,7 @@
  * The function assumes that the line does not contain useless spaces
  * before or after the command.
  */
-static void abbrev_sha1_in_line(struct strbuf *line)
+static void abbrev_oid_in_line(struct strbuf *line)
 {
 	struct strbuf **split;
 	int i;
@@ -1275,7 +1280,7 @@
 		strbuf_trim(&line);
 		if (!line.len)
 			continue;
-		abbrev_sha1_in_line(&line);
+		abbrev_oid_in_line(&line);
 		string_list_append(lines, line.buf);
 	}
 	fclose(f);
@@ -1568,9 +1573,9 @@
 	}
 
 	if (dwim_ref(cb.buf.buf, cb.buf.len, &oid, &ref, 1) == 1 &&
-	    /* sha1 is a commit? match without further lookup */
+	    /* oid is a commit? match without further lookup */
 	    (oideq(&cb.noid, &oid) ||
-	     /* perhaps sha1 is a tag, try to dereference to a commit */
+	     /* perhaps oid is a tag, try to dereference to a commit */
 	     ((commit = lookup_commit_reference_gently(r, &oid, 1)) != NULL &&
 	      oideq(&cb.noid, &commit->object.oid)))) {
 		const char *from = ref;
@@ -1799,29 +1804,36 @@
 			; /* nothing */
 		else if (s->workdir_dirty) {
 			if (s->hints)
-				printf(_("no changes added to commit "
-					 "(use \"git add\" and/or \"git commit -a\")\n"));
+				fprintf(s->fp, _("no changes added to commit "
+						 "(use \"git add\" and/or "
+						 "\"git commit -a\")\n"));
 			else
-				printf(_("no changes added to commit\n"));
+				fprintf(s->fp, _("no changes added to "
+						 "commit\n"));
 		} else if (s->untracked.nr) {
 			if (s->hints)
-				printf(_("nothing added to commit but untracked files "
-					 "present (use \"git add\" to track)\n"));
+				fprintf(s->fp, _("nothing added to commit but "
+						 "untracked files present (use "
+						 "\"git add\" to track)\n"));
 			else
-				printf(_("nothing added to commit but untracked files present\n"));
+				fprintf(s->fp, _("nothing added to commit but "
+						 "untracked files present\n"));
 		} else if (s->is_initial) {
 			if (s->hints)
-				printf(_("nothing to commit (create/copy files "
-					 "and use \"git add\" to track)\n"));
+				fprintf(s->fp, _("nothing to commit (create/"
+						 "copy files and use \"git "
+						 "add\" to track)\n"));
 			else
-				printf(_("nothing to commit\n"));
+				fprintf(s->fp, _("nothing to commit\n"));
 		} else if (!s->show_untracked_files) {
 			if (s->hints)
-				printf(_("nothing to commit (use -u to show untracked files)\n"));
+				fprintf(s->fp, _("nothing to commit (use -u to "
+						 "show untracked files)\n"));
 			else
-				printf(_("nothing to commit\n"));
+				fprintf(s->fp, _("nothing to commit\n"));
 		} else
-			printf(_("nothing to commit, working tree clean\n"));
+			fprintf(s->fp, _("nothing to commit, working tree "
+					 "clean\n"));
 	}
 	if(s->show_stash)
 		wt_longstatus_print_stash_summary(s);
@@ -1844,12 +1856,12 @@
 	}
 	color_fprintf(s->fp, color(WT_STATUS_UNMERGED, s), "%s", how);
 	if (s->null_termination) {
-		fprintf(stdout, " %s%c", it->string, 0);
+		fprintf(s->fp, " %s%c", it->string, 0);
 	} else {
 		struct strbuf onebuf = STRBUF_INIT;
 		const char *one;
 		one = quote_path(it->string, s->prefix, &onebuf, QUOTE_PATH_QUOTE_SP);
-		printf(" %s\n", one);
+		fprintf(s->fp, " %s\n", one);
 		strbuf_release(&onebuf);
 	}
 }
@@ -1862,16 +1874,16 @@
 	if (d->index_status)
 		color_fprintf(s->fp, color(WT_STATUS_UPDATED, s), "%c", d->index_status);
 	else
-		putchar(' ');
+		fputc(' ', s->fp);
 	if (d->worktree_status)
 		color_fprintf(s->fp, color(WT_STATUS_CHANGED, s), "%c", d->worktree_status);
 	else
-		putchar(' ');
-	putchar(' ');
+		fputc(' ', s->fp);
+	fputc(' ', s->fp);
 	if (s->null_termination) {
-		fprintf(stdout, "%s%c", it->string, 0);
+		fprintf(s->fp, "%s%c", it->string, 0);
 		if (d->rename_source)
-			fprintf(stdout, "%s%c", d->rename_source, 0);
+			fprintf(s->fp, "%s%c", d->rename_source, 0);
 	} else {
 		struct strbuf onebuf = STRBUF_INIT;
 		const char *one;
@@ -1879,11 +1891,11 @@
 		if (d->rename_source) {
 			one = quote_path(d->rename_source, s->prefix, &onebuf,
 					 QUOTE_PATH_QUOTE_SP);
-			printf("%s -> ", one);
+			fprintf(s->fp, "%s -> ", one);
 			strbuf_release(&onebuf);
 		}
 		one = quote_path(it->string, s->prefix, &onebuf, QUOTE_PATH_QUOTE_SP);
-		printf("%s\n", one);
+		fprintf(s->fp, "%s\n", one);
 		strbuf_release(&onebuf);
 	}
 }
@@ -1892,13 +1904,13 @@
 				 struct wt_status *s, const char *sign)
 {
 	if (s->null_termination) {
-		fprintf(stdout, "%s %s%c", sign, it->string, 0);
+		fprintf(s->fp, "%s %s%c", sign, it->string, 0);
 	} else {
 		struct strbuf onebuf = STRBUF_INIT;
 		const char *one;
 		one = quote_path(it->string, s->prefix, &onebuf, QUOTE_PATH_QUOTE_SP);
 		color_fprintf(s->fp, color(WT_STATUS_UNTRACKED, s), "%s", sign);
-		printf(" %s\n", one);
+		fprintf(s->fp, " %s\n", one);
 		strbuf_release(&onebuf);
 	}
 }
diff --git a/wt-status.h b/wt-status.h
index f1fa0ec..35b44c3 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -151,7 +151,14 @@
 void wt_status_prepare(struct repository *r, struct wt_status *s);
 void wt_status_print(struct wt_status *s);
 void wt_status_collect(struct wt_status *s);
+/*
+ * Frees the buffers allocated by wt_status_collect.
+ */
 void wt_status_collect_free_buffers(struct wt_status *s);
+/*
+ * Frees the buffers of the wt_status_state.
+ */
+void wt_status_state_free_buffers(struct wt_status_state *s);
 void wt_status_get_state(struct repository *repo,
 			 struct wt_status_state *state,
 			 int get_detached_from);