Git development
 help / color / mirror / Atom feed
* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Jakub Narebski @ 2006-04-25 10:08 UTC (permalink / raw)
  To: git
In-Reply-To: <7vmzeax9gj.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano wrote:

> Jakub Narebski <jnareb@gmail.com> writes:
> 
>> Actually, this can be resolved using automatic history grafts to the
>> remote repository we pulled from, if the commit is not present on local
>> side (and removing graft when commit appears on local side).
> 
> You do not even need history grafts.  The "cherry-pick source"
> was a bad example.  Maybe using "related" as a way to implement
> "bind" would have been a better example -- we want inter-commit
> relationship that requires connectivity but without ancestry for
> them.
> 
> You can just have two kinds of 'related'.  One that means
> connectivity, the other that does not.

Good idea.

Another problem for core git, but I think orthogonal to the "related"/"note"
distinction is if the relation (or note) should be used as helper in
merges, perhaps by some agreed upon convention on the
comment/description/value part (e.g. "mergehelper" or "mergeinfo").

BTW. in your first example, what "key" relation should mean?
"cherrypick" (which should be "note" as we don't need connectivity) is
quite obvious (or equivalent "origin" if rebase wouldn't destroy the branch
picked from).

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* [PATCH] Make die() and error() prefix line with binary name if set
From: Rocco Rutte @ 2006-04-25 10:12 UTC (permalink / raw)
  To: git

Since lots of logic is implemented via shell scripts, it's in
general useful to print out where an error occured. Previously
only some commands manually added the binary name to die() and
error() calls.

Now, git_set_appname() can be used to set the name of the binary
as first call in a binary's main() routine which will be used
as prefix in die() and error(). If it was not called, no prefix
will be printed.

Signed-off-by: Rocco Rutte <pdmef@gmx.net>

---

  apply.c              |   10 ++++++----
  blame.c              |    2 ++
  cat-file.c           |   10 ++++++----
  check-ref-format.c   |    2 ++
  checkout-index.c     |    8 +++++---
  clone-pack.c         |    2 ++
  commit-tree.c        |    2 ++
  connect.c            |    4 ++--
  convert-objects.c    |    2 ++
  daemon.c             |    4 +++-
  describe.c           |    2 ++
  diff-files.c         |    5 ++++-
  diff-index.c         |    5 ++++-
  diff-stages.c        |    5 ++++-
  diff-tree.c          |    2 ++
  entry.c              |   14 +++++++-------
  fetch-clone.c        |    2 +-
  fetch-pack.c         |    4 +++-
  fsck-objects.c       |    2 ++
  get-tar-commit-id.c  |    2 ++
  git-compat-util.h    |    1 +
  git.c                |    2 ++
  hash-object.c        |    2 ++
  http-fetch.c         |    2 ++
  http-push.c          |    2 ++
  index-pack.c         |    2 ++
  init-db.c            |    2 ++
  local-fetch.c        |    2 ++
  ls-files.c           |    8 +++++---
  ls-tree.c            |    2 ++
  mailinfo.c           |    2 ++
  mailsplit.c          |    2 ++
  merge-base.c         |    2 ++
  merge-index.c        |    8 +++++---
  merge-tree.c         |    2 ++
  mktag.c              |    2 ++
  mktree.c             |    2 ++
  name-rev.c           |    2 ++
  pack-objects.c       |    2 ++
  pack-redundant.c     |    2 ++
  patch-id.c           |    2 ++
  peek-remote.c        |    2 ++
  prune-packed.c       |    2 ++
  read-tree.c          |    2 ++
  receive-pack.c       |    2 ++
  repo-config.c        |    2 ++
  rev-list.c           |    2 ++
  rev-parse.c          |    5 ++++-
  send-pack.c          |    2 ++
  shell.c              |    2 ++
  show-branch.c        |    2 ++
  show-index.c         |    2 ++
  ssh-fetch.c          |    2 ++
  ssh-upload.c         |    2 ++
  stripspace.c         |    2 ++
  symbolic-ref.c       |    2 ++
  tar-tree.c           |    6 ++++--
  test-date.c          |    2 ++
  test-delta.c         |    2 ++
  tree-diff.c          |    2 +-
  unpack-file.c        |    2 ++
  unpack-objects.c     |    2 ++
  update-index.c       |   23 ++++++++++++++---------
  update-ref.c         |    2 ++
  update-server-info.c |    3 +++
  upload-pack.c        |   20 +++++++++++---------
  usage.c              |   14 ++++++++++++++
  var.c                |    3 +++
  verify-pack.c        |    2 ++
  write-tree.c         |   10 ++++++----
  70 files changed, 210 insertions(+), 58 deletions(-)

92e903a0273996028d069b28fde6c5a990e1157b
diff --git a/apply.c b/apply.c
index 269210a..84879d2 100644
--- a/apply.c
+++ b/apply.c
@@ -142,7 +142,7 @@ static void *read_patch_file(int fd, uns
  		if (!nr)
  			break;
  		if (nr < 0)
-			die("git-apply: read returned %s", strerror(errno));
+			die("read returned %s", strerror(errno));
  		size += nr;
  	}
  	*sizep = size;
@@ -320,17 +320,17 @@ static char *gitdiff_verify_name(const c
  		name = orig_name;
  		len = strlen(name);
  		if (isnull)
-			die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
+			die("bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
  		another = find_name(line, NULL, 1, 0);
  		if (!another || memcmp(another, name, len))
-			die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
+			die("bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
  		free(another);
  		return orig_name;
  	}
  	else {
  		/* expect "/dev/null" */
  		if (memcmp("/dev/null", line, 9) || line[9] != '\n')
-			die("git-apply: bad git-diff - expected /dev/null on line %d", linenr);
+			die("bad git-diff - expected /dev/null on line %d", linenr);
  		return NULL;
  	}
  }
@@ -1960,6 +1960,8 @@ int main(int argc, char **argv)
  	int read_stdin = 1;
  	const char *whitespace_option = NULL;
  
+	git_set_appname("git-apply");
+
  	for (i = 1; i < argc; i++) {
  		const char *arg = argv[i];
  		char *end;
diff --git a/blame.c b/blame.c
index 07d2d27..804f108 100644
--- a/blame.c
+++ b/blame.c
@@ -752,6 +752,8 @@ int main(int argc, const char **argv)
  	int longest_file, longest_author;
  	int found_rename;
  
+	git_set_appname("git-blame");
+
  	const char* prefix = setup_git_directory();
  	git_config(git_default_config);
  
diff --git a/cat-file.c b/cat-file.c
index 628f6ca..75c400a 100644
--- a/cat-file.c
+++ b/cat-file.c
@@ -16,9 +16,9 @@ static void flush_buffer(const char *buf
  			/* Ignore epipe */
  			if (errno == EPIPE)
  				break;
-			die("git-cat-file: %s", strerror(errno));
+			die("%s", strerror(errno));
  		} else if (!ret) {
-			die("git-cat-file: disk full?");
+			die("disk full?");
  		}
  		size -= ret;
  		buf += ret;
@@ -101,6 +101,8 @@ int main(int argc, char **argv)
  	unsigned long size;
  	int opt;
  
+	git_set_appname("git-cat-file");
+
  	setup_git_directory();
  	git_config(git_default_config);
  	if (argc != 3 || get_sha1(argv[2], sha1))
@@ -154,11 +156,11 @@ int main(int argc, char **argv)
  		break;
  
  	default:
-		die("git-cat-file: unknown option: %s\n", argv[1]);
+		die("unknown option: %s\n", argv[1]);
  	}
  
  	if (!buf)
-		die("git-cat-file %s: bad file", argv[2]);
+		die("bad file", argv[2]);
  
  	flush_buffer(buf, size);
  	return 0;
diff --git a/check-ref-format.c b/check-ref-format.c
index a0adb3d..ce08eda 100644
--- a/check-ref-format.c
+++ b/check-ref-format.c
@@ -9,6 +9,8 @@ #include <stdio.h>
  
  int main(int ac, char **av)
  {
+	git_set_appname("git-check-ref-format");
+
  	if (ac != 2)
  		usage("git-check-ref-format refname");
  	if (check_ref_format(av[1]))
diff --git a/checkout-index.c b/checkout-index.c
index dd6a2d8..b515651 100644
--- a/checkout-index.c
+++ b/checkout-index.c
@@ -176,6 +176,8 @@ int main(int argc, char **argv)
  	int all = 0;
  	int read_from_stdin = 0;
  
+	git_set_appname("git-checkout-index");
+
  	prefix = setup_git_directory();
  	git_config(git_default_config);
  	prefix_length = prefix ? strlen(prefix) : 0;
@@ -271,16 +273,16 @@ int main(int argc, char **argv)
  		const char *arg = argv[i];
  
  		if (all)
-			die("git-checkout-index: don't mix '--all' and explicit filenames");
+			die("don't mix '--all' and explicit filenames");
  		if (read_from_stdin)
-			die("git-checkout-index: don't mix '--stdin' and explicit filenames");
+			die("don't mix '--stdin' and explicit filenames");
  		checkout_file(prefix_path(prefix, prefix_length, arg));
  	}
  
  	if (read_from_stdin) {
  		struct strbuf buf;
  		if (all)
-			die("git-checkout-index: don't mix '--all' and '--stdin'");
+			die("don't mix '--all' and '--stdin'");
  		strbuf_init(&buf);
  		while (1) {
  			char *path_name;
diff --git a/clone-pack.c b/clone-pack.c
index a4370f5..0139745 100644
--- a/clone-pack.c
+++ b/clone-pack.c
@@ -150,6 +150,8 @@ int main(int argc, char **argv)
  	int fd[2];
  	pid_t pid;
  
+	git_set_appname("git-clone-pack");
+
  	setup_git_directory();
  
  	nr_heads = 0;
diff --git a/commit-tree.c b/commit-tree.c
index 2d86518..e07b0eb 100644
--- a/commit-tree.c
+++ b/commit-tree.c
@@ -87,6 +87,8 @@ int main(int argc, char **argv)
  	char *buffer;
  	unsigned int size;
  
+	git_set_appname("git-commit-tree");
+
  	setup_ident();
  	setup_git_directory();
  
diff --git a/connect.c b/connect.c
index 6a8f8a6..70ab5ad 100644
--- a/connect.c
+++ b/connect.c
@@ -69,7 +69,7 @@ int get_ack(int fd, unsigned char *resul
  	int len = packet_read_line(fd, line, sizeof(line));
  
  	if (!len)
-		die("git-fetch-pack: expected ACK/NAK, got EOF");
+		die("expected ACK/NAK, got EOF");
  	if (line[len-1] == '\n')
  		line[--len] = 0;
  	if (!strcmp(line, "NAK"))
@@ -81,7 +81,7 @@ int get_ack(int fd, unsigned char *resul
  			return 1;
  		}
  	}
-	die("git-fetch_pack: expected ACK/NAK, got '%s'", line);
+	die("expected ACK/NAK, got '%s'", line);
  }
  
  int path_match(const char *path, int nr, char **match)
diff --git a/convert-objects.c b/convert-objects.c
index 12aacef..6b5d955 100644
--- a/convert-objects.c
+++ b/convert-objects.c
@@ -319,6 +319,8 @@ int main(int argc, char **argv)
  	unsigned char sha1[20];
  	struct entry *entry;
  
+	git_set_appname("git-convert-object");
+
  	setup_git_directory();
  
  	if (argc != 2 || get_sha1(argv[1], sha1))
diff --git a/daemon.c b/daemon.c
index a1ccda3..ddf59d0 100644
--- a/daemon.c
+++ b/daemon.c
@@ -666,6 +666,8 @@ int main(int argc, char **argv)
  	int inetd_mode = 0;
  	int i;
  
+	git_set_appname("git-daemon");
+
  	for (i = 1; i < argc; i++) {
  		char *arg = argv[i];
  
@@ -739,7 +741,7 @@ int main(int argc, char **argv)
  
  	if (strict_paths && (!ok_paths || !*ok_paths)) {
  		if (!inetd_mode)
-			die("git-daemon: option --strict-paths requires a whitelist");
+			die("option --strict-paths requires a whitelist");
  
  		logerror("option --strict-paths requires a whitelist");
  		exit (1);
diff --git a/describe.c b/describe.c
index ff65742..a882d00 100644
--- a/describe.c
+++ b/describe.c
@@ -143,6 +143,8 @@ int main(int argc, char **argv)
  {
  	int i;
  
+	git_set_appname("git-describe");
+
  	for (i = 1; i < argc; i++) {
  		const char *arg = argv[i];
  
diff --git a/diff-files.c b/diff-files.c
index ffbef48..0c99c00 100644
--- a/diff-files.c
+++ b/diff-files.c
@@ -39,9 +39,12 @@ static void show_modified(int oldmode, i
  int main(int argc, const char **argv)
  {
  	const char **pathspec;
-	const char *prefix = setup_git_directory();
+	const char *prefix;
  	int entries, i;
  
+	git_set_appname("git-diff-files");
+
+	prefix = setup_git_directory();
  	git_config(git_diff_config);
  	diff_setup(&rev.diffopt);
  	while (1 < argc && argv[1][0] == '-') {
diff --git a/diff-index.c b/diff-index.c
index e376d65..b066d48 100644
--- a/diff-index.c
+++ b/diff-index.c
@@ -171,13 +171,16 @@ int main(int argc, const char **argv)
  {
  	const char *tree_name = NULL;
  	unsigned char sha1[20];
-	const char *prefix = setup_git_directory();
+	const char *prefix;
  	const char **pathspec = NULL;
  	struct tree *tree;
  	int ret;
  	int allow_options = 1;
  	int i;
  
+	git_set_appname("git-diff-index");
+
+	prefix = setup_git_directory();
  	git_config(git_diff_config);
  	diff_setup(&diff_options);
  	for (i = 1; i < argc; i++) {
diff --git a/diff-stages.c b/diff-stages.c
index dcd20e7..bd40b8e 100644
--- a/diff-stages.c
+++ b/diff-stages.c
@@ -57,9 +57,12 @@ static void diff_stages(int stage1, int 
  int main(int ac, const char **av)
  {
  	int stage1, stage2;
-	const char *prefix = setup_git_directory();
+	const char *prefix;
  	const char **pathspec = NULL;
  
+	git_set_appname("git-diff-stages");
+
+	prefix = setup_git_directory();
  	git_config(git_diff_config);
  	read_cache();
  	diff_setup(&diff_options);
diff --git a/diff-tree.c b/diff-tree.c
index 7207867..76222d5 100644
--- a/diff-tree.c
+++ b/diff-tree.c
@@ -67,6 +67,8 @@ int main(int argc, const char **argv)
  	struct object_list *list;
  	int read_stdin = 0;
  
+	git_set_appname("git-diff-tree");
+
  	git_config(git_diff_config);
  	nr_sha1 = 0;
  	init_revisions(opt);
diff --git a/entry.c b/entry.c
index 793724f..5cf36f9 100644
--- a/entry.c
+++ b/entry.c
@@ -76,7 +76,7 @@ static int write_entry(struct cache_entr
  	if (!new || strcmp(type, blob_type)) {
  		if (new)
  			free(new);
-		return error("git-checkout-index: unable to read sha1 file of %s (%s)",
+		return error("unable to read sha1 file of %s (%s)",
  			path, sha1_to_hex(ce->sha1));
  	}
  	switch (ntohl(ce->ce_mode) & S_IFMT) {
@@ -88,14 +88,14 @@ static int write_entry(struct cache_entr
  			fd = create_file(path, ntohl(ce->ce_mode));
  		if (fd < 0) {
  			free(new);
-			return error("git-checkout-index: unable to create file %s (%s)",
+			return error("unable to create file %s (%s)",
  				path, strerror(errno));
  		}
  		wrote = write(fd, new, size);
  		close(fd);
  		free(new);
  		if (wrote != size)
-			return error("git-checkout-index: unable to write file %s", path);
+			return error("unable to write file %s", path);
  		break;
  	case S_IFLNK:
  		if (to_tempfile) {
@@ -103,26 +103,26 @@ static int write_entry(struct cache_entr
  			fd = mkstemp(path);
  			if (fd < 0) {
  				free(new);
-				return error("git-checkout-index: unable to create "
+				return error("unable to create "
  						 "file %s (%s)", path, strerror(errno));
  			}
  			wrote = write(fd, new, size);
  			close(fd);
  			free(new);
  			if (wrote != size)
-				return error("git-checkout-index: unable to write file %s",
+				return error("unable to write file %s",
  					path);
  		} else {
  			wrote = symlink(new, path);
  			free(new);
  			if (wrote)
-				return error("git-checkout-index: unable to create "
+				return error("unable to create "
  						 "symlink %s (%s)", path, strerror(errno));
  		}
  		break;
  	default:
  		free(new);
-		return error("git-checkout-index: unknown file mode for %s", path);
+		return error("unknown file mode for %s", path);
  	}
  
  	if (state->refresh_cache) {
diff --git a/fetch-clone.c b/fetch-clone.c
index da1b3ff..b44ab8f 100644
--- a/fetch-clone.c
+++ b/fetch-clone.c
@@ -23,7 +23,7 @@ static int finish_pack(const char *pack_
  
  	pid = fork();
  	if (pid < 0)
-		die("git-clone-pack: unable to fork off git-index-pack");
+		die("unable to fork off git-index-pack");
  	if (!pid) {
  		close(0);
  		dup2(pipe_fd[1], 1);
diff --git a/fetch-pack.c b/fetch-pack.c
index a3bcad0..f7053e7 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -390,7 +390,7 @@ static int fetch_pack(int fd[2], int nr_
  		status = receive_unpack_pack(fd, "git-fetch-pack", quiet);
  
  	if (status)
-		die("git-fetch-pack: fetch failed.");
+		die("fetch failed.");
  
   all_done:
  	while (ref) {
@@ -408,6 +408,8 @@ int main(int argc, char **argv)
  	int fd[2];
  	pid_t pid;
  
+	git_set_appname("git-fetch-pack");
+
  	setup_git_directory();
  
  	nr_heads = 0;
diff --git a/fsck-objects.c b/fsck-objects.c
index 59b2590..5e004b6 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -442,6 +442,8 @@ int main(int argc, char **argv)
  {
  	int i, heads;
  
+	git_set_appname("git-fsck-objects");
+
  	setup_git_directory();
  
  	for (i = 1; i < argc; i++) {
diff --git a/get-tar-commit-id.c b/get-tar-commit-id.c
index 4166290..036094d 100644
--- a/get-tar-commit-id.c
+++ b/get-tar-commit-id.c
@@ -12,6 +12,8 @@ int main(int argc, char **argv)
  	char buffer[HEADERSIZE];
  	ssize_t n;
  
+	git_set_appname("git-get-tar-commit-id");
+
  	n = read(0, buffer, HEADERSIZE);
  	if (n < HEADERSIZE) {
  		fprintf(stderr, "read error\n");
diff --git a/git-compat-util.h b/git-compat-util.h
index 5d543d2..cc5370c 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -39,6 +39,7 @@ #endif
  extern void usage(const char *err) NORETURN;
  extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
  extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
+extern void git_set_appname(const char *name);
  
  #ifdef NO_MMAP
  
diff --git a/git.c b/git.c
index aa2b814..ad49bb7 100644
--- a/git.c
+++ b/git.c
@@ -71,6 +71,8 @@ int main(int argc, const char **argv, ch
  	char git_command[PATH_MAX + 1];
  	const char *exec_path = NULL;
  
+	git_set_appname("git");
+
  	/*
  	 * Take the basename of argv[0] as the command
  	 * name, and the dirname as the default exec_path
diff --git a/hash-object.c b/hash-object.c
index 43bd93b..0c95d05 100644
--- a/hash-object.c
+++ b/hash-object.c
@@ -42,6 +42,8 @@ int main(int argc, char **argv)
  	int prefix_length = -1;
  	int no_more_flags = 0;
  
+	git_set_appname("git-hash-object");
+
  	for (i = 1 ; i < argc; i++) {
  		if (!no_more_flags && argv[i][0] == '-') {
  			if (!strcmp(argv[i], "-t")) {
diff --git a/http-fetch.c b/http-fetch.c
index 861644b..69c7cdb 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -1222,6 +1222,8 @@ int main(int argc, char **argv)
  	int arg = 1;
  	int rc = 0;
  
+	git_set_appname("git-http-fetch");
+
  	setup_git_directory();
  
  	while (arg < argc && argv[arg][0] == '-') {
diff --git a/http-push.c b/http-push.c
index b4327d9..75a544b 100644
--- a/http-push.c
+++ b/http-push.c
@@ -2315,6 +2315,8 @@ int main(int argc, char **argv)
  	int new_refs;
  	struct ref *ref;
  
+	git_set_appname("git-http-push");
+
  	setup_git_directory();
  	setup_ident();
  
diff --git a/index-pack.c b/index-pack.c
index b39953d..a69e51a 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -425,6 +425,8 @@ int main(int argc, char **argv)
  	char *index_name_buf = NULL;
  	unsigned char sha1[20];
  
+	git_set_appname("git-index-pack");
+
  	for (i = 1; i < argc; i++) {
  		const char *arg = argv[i];
  
diff --git a/init-db.c b/init-db.c
index ff29496..29c93e3 100644
--- a/init-db.c
+++ b/init-db.c
@@ -241,6 +241,8 @@ int main(int argc, char **argv)
  	char *path, *template_dir = NULL;
  	int len, i;
  
+	git_set_appname("git-init-db");
+
  	for (i = 1; i < argc; i++, argv++) {
  		char *arg = argv[1];
  		if (!strncmp(arg, "--template=", 11))
diff --git a/local-fetch.c b/local-fetch.c
index fa9e697..11bf6f8 100644
--- a/local-fetch.c
+++ b/local-fetch.c
@@ -207,6 +207,8 @@ int main(int argc, char **argv)
  	char *commit_id;
  	int arg = 1;
  
+	git_set_appname("git-local-fetch");
+
  	setup_git_directory();
  
  	while (arg < argc && argv[arg][0] == '-') {
diff --git a/ls-files.c b/ls-files.c
index 4a4af1c..15a9bb2 100644
--- a/ls-files.c
+++ b/ls-files.c
@@ -383,7 +383,7 @@ static void show_dir_entry(const char *t
  	int offset = prefix_offset;
  
  	if (len >= ent->len)
-		die("git-ls-files: internal error - directory entry not superset of prefix");
+		die("internal error - directory entry not superset of prefix");
  
  	if (pathspec && !match(pathspec, ps_matched, ent->name, len))
  		return;
@@ -471,7 +471,7 @@ static void show_ce_entry(const char *ta
  	int offset = prefix_offset;
  
  	if (len >= ce_namelen(ce))
-		die("git-ls-files: internal error - cache entry not superset of prefix");
+		die("internal error - cache entry not superset of prefix");
  
  	if (pathspec && !match(pathspec, ps_matched, ce->name, len))
  		return;
@@ -630,7 +630,7 @@ static void verify_pathspec(void)
  	}
  
  	if (prefix_offset > max || memcmp(prev, prefix, prefix_offset))
-		die("git-ls-files: cannot generate relative filenames containing '..'");
+		die("cannot generate relative filenames containing '..'");
  
  	real_prefix = NULL;
  	prefix_len = max;
@@ -653,6 +653,8 @@ int main(int argc, const char **argv)
  	int i;
  	int exc_given = 0;
  
+	git_set_appname("git-ls-files");
+
  	prefix = setup_git_directory();
  	if (prefix)
  		prefix_offset = strlen(prefix);
diff --git a/ls-tree.c b/ls-tree.c
index e4ef200..e037bf0 100644
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -89,6 +89,8 @@ int main(int argc, const char **argv)
  	unsigned char sha1[20];
  	struct tree *tree;
  
+	git_set_appname("git-ls-tree");
+
  	prefix = setup_git_directory();
  	git_config(git_default_config);
  	if (prefix && *prefix)
diff --git a/mailinfo.c b/mailinfo.c
index b276519..7baa3ff 100644
--- a/mailinfo.c
+++ b/mailinfo.c
@@ -757,6 +757,8 @@ static const char mailinfo_usage[] =
  
  int main(int argc, char **argv)
  {
+	git_set_appname("git-mailinfo");
+
  	/* NEEDSWORK: might want to do the optional .git/ directory
  	 * discovery
  	 */
diff --git a/mailsplit.c b/mailsplit.c
index c529e2d..686920e 100644
--- a/mailsplit.c
+++ b/mailsplit.c
@@ -111,6 +111,8 @@ int main(int argc, const char **argv)
  	static const char *stdin_only[] = { "-", NULL };
  	char *name;
  
+	git_set_appname("git-mailsplit");
+
  	for (argp = argv+1; *argp; argp++) {
  		const char *arg = *argp;
  
diff --git a/merge-base.c b/merge-base.c
index 07f5ab4..29cdbd7 100644
--- a/merge-base.c
+++ b/merge-base.c
@@ -236,6 +236,8 @@ int main(int argc, char **argv)
  	struct commit *rev1, *rev2;
  	unsigned char rev1key[20], rev2key[20];
  
+	git_set_appname("git-merge-base");
+
  	setup_git_directory();
  	git_config(git_default_config);
  
diff --git a/merge-index.c b/merge-index.c
index 024196e..3430da5 100644
--- a/merge-index.c
+++ b/merge-index.c
@@ -42,7 +42,7 @@ static int merge_entry(int pos, const ch
  	int found;
  	
  	if (pos >= active_nr)
-		die("git-merge-index: %s not in the cache", path);
+		die("%s not in the cache", path);
  	arguments[0] = pgm;
  	arguments[1] = "";
  	arguments[2] = "";
@@ -67,7 +67,7 @@ static int merge_entry(int pos, const ch
  		arguments[stage + 4] = ownbuf[stage];
  	} while (++pos < active_nr);
  	if (!found)
-		die("git-merge-index: %s not in the cache", path);
+		die("%s not in the cache", path);
  	run_program();
  	return found;
  }
@@ -99,6 +99,8 @@ int main(int argc, char **argv)
  {
  	int i, force_file = 0;
  
+	git_set_appname("git-merge-index");
+
  	if (argc < 3)
  		usage("git-merge-index [-o] [-q] <merge-program> (-a | <filename>*)");
  
@@ -126,7 +128,7 @@ int main(int argc, char **argv)
  				merge_all();
  				continue;
  			}
-			die("git-merge-index: unknown option %s", arg);
+			die("unknown option %s", arg);
  		}
  		merge_file(arg);
  	}
diff --git a/merge-tree.c b/merge-tree.c
index 50528d5..1eca1d7 100644
--- a/merge-tree.c
+++ b/merge-tree.c
@@ -164,6 +164,8 @@ int main(int argc, char **argv)
  	struct tree_desc t[3];
  	void *buf1, *buf2, *buf3;
  
+	git_set_appname("git-merge-tree");
+
  	if (argc < 4)
  		usage(merge_tree_usage);
  
diff --git a/mktag.c b/mktag.c
index 2328878..dcc917e 100644
--- a/mktag.c
+++ b/mktag.c
@@ -109,6 +109,8 @@ int main(int argc, char **argv)
  	char buffer[MAXSIZE];
  	unsigned char result_sha1[20];
  
+	git_set_appname("git-mktag");
+
  	if (argc != 1)
  		usage("cat <signaturefile> | git-mktag");
  
diff --git a/mktree.c b/mktree.c
index ab63cd9..a1ac929 100644
--- a/mktree.c
+++ b/mktree.c
@@ -79,6 +79,8 @@ int main(int ac, char **av)
  	unsigned char sha1[20];
  	int line_termination = '\n';
  
+	git_set_appname("git-mktree");
+
  	setup_git_directory();
  
  	while ((1 < ac) && av[1][0] == '-') {
diff --git a/name-rev.c b/name-rev.c
index bad8a53..c426059 100644
--- a/name-rev.c
+++ b/name-rev.c
@@ -126,6 +126,8 @@ int main(int argc, char **argv)
  	struct object_list **walker = &revs;
  	int as_is = 0, all = 0, transform_stdin = 0;
  
+	git_set_appname("git-name-rev");
+
  	setup_git_directory();
  	git_config(git_default_config);
  
diff --git a/pack-objects.c b/pack-objects.c
index c0acc46..de733b6 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -1237,6 +1237,8 @@ int main(int argc, char **argv)
  	int num_preferred_base = 0;
  	int i;
  
+	git_set_appname("git-pack-objects");
+
  	setup_git_directory();
  
  	for (i = 1; i < argc; i++) {
diff --git a/pack-redundant.c b/pack-redundant.c
index cd81f5a..e2eff1b 100644
--- a/pack-redundant.c
+++ b/pack-redundant.c
@@ -589,6 +589,8 @@ int main(int argc, char **argv)
  	unsigned char *sha1;
  	char buf[42]; /* 40 byte sha1 + \n + \0 */
  
+	git_set_appname("git-pack-redundant");
+
  	setup_git_directory();
  
  	for (i = 1; i < argc; i++) {
diff --git a/patch-id.c b/patch-id.c
index edbc4aa..0e2bd85 100644
--- a/patch-id.c
+++ b/patch-id.c
@@ -74,6 +74,8 @@ static const char patch_id_usage[] = "gi
  
  int main(int argc, char **argv)
  {
+	git_set_appname("git-patch-id");
+
  	if (argc != 1)
  		usage(patch_id_usage);
  
diff --git a/peek-remote.c b/peek-remote.c
index a90cf22..99dac1b 100644
--- a/peek-remote.c
+++ b/peek-remote.c
@@ -29,6 +29,8 @@ int main(int argc, char **argv)
  	pid_t pid;
  	int nongit = 0;
  
+	git_set_appname("git-pack-remote");
+
  	setup_git_directory_gently(&nongit);
  
  	for (i = 1; i < argc; i++) {
diff --git a/prune-packed.c b/prune-packed.c
index d24b097..106cc39 100644
--- a/prune-packed.c
+++ b/prune-packed.c
@@ -58,6 +58,8 @@ int main(int argc, char **argv)
  {
  	int i;
  
+	git_set_appname("git-prune-packed");
+
  	setup_git_directory();
  
  	for (i = 1; i < argc; i++) {
diff --git a/read-tree.c b/read-tree.c
index 26f4f7e..23c2014 100644
--- a/read-tree.c
+++ b/read-tree.c
@@ -723,6 +723,8 @@ int main(int argc, char **argv)
  	unsigned char sha1[20];
  	merge_fn_t fn = NULL;
  
+	git_set_appname("git-read-tree");
+
  	setup_git_directory();
  	git_config(git_default_config);
  
diff --git a/receive-pack.c b/receive-pack.c
index 93929b5..8ad291c 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -304,6 +304,8 @@ int main(int argc, char **argv)
  	int i;
  	char *dir = NULL;
  
+	git_set_appname("git-receive-pack");
+
  	argv++;
  	for (i = 1; i < argc; i++) {
  		char *arg = *argv++;
diff --git a/repo-config.c b/repo-config.c
index c5ebb76..793af68 100644
--- a/repo-config.c
+++ b/repo-config.c
@@ -86,6 +86,8 @@ static int get_value(const char* key_, c
  
  int main(int argc, const char **argv)
  {
+	git_set_appname("git-repo-config");
+
  	setup_git_directory();
  
  	while (1 < argc) {
diff --git a/rev-list.c b/rev-list.c
index 8b0ec38..4646372 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -296,6 +296,8 @@ int main(int argc, const char **argv)
  	struct commit_list *list;
  	int i;
  
+	git_set_appname("git-rev-list");
+
  	init_revisions(&revs);
  	revs.abbrev = 0;
  	revs.commit_format = CMIT_FMT_UNSPECIFIED;
diff --git a/rev-parse.c b/rev-parse.c
index e956cd5..b0b701e 100644
--- a/rev-parse.c
+++ b/rev-parse.c
@@ -164,8 +164,11 @@ int main(int argc, char **argv)
  {
  	int i, as_is = 0, verify = 0;
  	unsigned char sha1[20];
-	const char *prefix = setup_git_directory();
+	const char *prefix;
  	
+	git_set_appname("git-rev-parse");
+
+	prefix = setup_git_directory();
  	git_config(git_default_config);
  
  	for (i = 1; i < argc; i++) {
diff --git a/send-pack.c b/send-pack.c
index 409f188..803e193 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -361,6 +361,8 @@ int main(int argc, char **argv)
  	int fd[2], ret;
  	pid_t pid;
  
+	git_set_appname("git-send-pack");
+
  	setup_git_directory();
  	git_config(git_default_config);
  
diff --git a/shell.c b/shell.c
index 8c08cf0..c22cde1 100644
--- a/shell.c
+++ b/shell.c
@@ -32,6 +32,8 @@ int main(int argc, char **argv)
  	char *prog;
  	struct commands *cmd;
  
+	git_set_appname("git-shell");
+
  	/* We want to see "-c cmd args", and nothing else */
  	if (argc != 3 || strcmp(argv[1], "-c"))
  		die("What do you think I am? A shell?");
diff --git a/show-branch.c b/show-branch.c
index 24efb65..9ec3553 100644
--- a/show-branch.c
+++ b/show-branch.c
@@ -549,6 +549,8 @@ int main(int ac, char **av)
  	int head_at = -1;
  	int topics = 0;
  
+	git_set_appname("git-show-branch");
+
  	setup_git_directory();
  	git_config(git_show_branch_config);
  
diff --git a/show-index.c b/show-index.c
index c21d660..b8a9fba 100644
--- a/show-index.c
+++ b/show-index.c
@@ -7,6 +7,8 @@ int main(int argc, char **argv)
  	unsigned int entry[6];
  	static unsigned int top_index[256];
  
+	git_set_appname("git-show-index");
+
  	if (fread(top_index, sizeof(top_index), 1, stdin) != 1)
  		die("unable to read idex");
  	nr = 0;
diff --git a/ssh-fetch.c b/ssh-fetch.c
index 4eb9e04..4bab7e7 100644
--- a/ssh-fetch.c
+++ b/ssh-fetch.c
@@ -128,6 +128,8 @@ int main(int argc, char **argv)
  	int arg = 1;
  	const char *prog;
  
+	git_set_appname("git-ssh-fetch");
+
  	prog = getenv("GIT_SSH_PUSH");
  	if (!prog) prog = "git-ssh-upload";
  
diff --git a/ssh-upload.c b/ssh-upload.c
index b675a0b..9860cf4 100644
--- a/ssh-upload.c
+++ b/ssh-upload.c
@@ -119,6 +119,8 @@ int main(int argc, char **argv)
  	unsigned char sha1[20];
  	char hex[41];
  
+	git_set_appname("git-ssh-upload");
+
  	prog = getenv(COUNTERPART_ENV_NAME);
  	if (!prog) prog = COUNTERPART_PROGRAM_NAME;
  
diff --git a/stripspace.c b/stripspace.c
index 65a6346..95c2e43 100644
--- a/stripspace.c
+++ b/stripspace.c
@@ -34,6 +34,8 @@ int main(int argc, char **argv)
  	int incomplete = 0;
  	char line[1024];
  
+	git_set_appname("git-stripspace");
+
  	while (fgets(line, sizeof(line), stdin)) {
  		incomplete = cleanup(line);
  
diff --git a/symbolic-ref.c b/symbolic-ref.c
index 193c87c..a8b3b9d 100644
--- a/symbolic-ref.c
+++ b/symbolic-ref.c
@@ -19,6 +19,8 @@ static void check_symref(const char *HEA
  
  int main(int argc, const char **argv)
  {
+	git_set_appname("git-symbolic-ref");
+
  	setup_git_directory();
  	git_config(git_default_config);
  	switch (argc) {
diff --git a/tar-tree.c b/tar-tree.c
index fc60a90..7a388f5 100644
--- a/tar-tree.c
+++ b/tar-tree.c
@@ -26,9 +26,9 @@ static void reliable_write(void *buf, un
  		if (ret < 0) {
  			if (errno == EPIPE)
  				exit(0);
-			die("git-tar-tree: %s", strerror(errno));
+			die("%s", strerror(errno));
  		} else if (!ret) {
-			die("git-tar-tree: disk full?");
+			die("disk full?");
  		}
  		size -= ret;
  		buf += ret;
@@ -308,6 +308,8 @@ int main(int argc, char **argv)
  	struct tree_desc tree;
  	struct strbuf current_path;
  
+	git_set_appname("git-tar-tree");
+
  	current_path.buf = xmalloc(PATH_MAX);
  	current_path.alloc = PATH_MAX;
  	current_path.len = current_path.eof = 0;
diff --git a/test-date.c b/test-date.c
index 93e8027..3d2cfbb 100644
--- a/test-date.c
+++ b/test-date.c
@@ -7,6 +7,8 @@ int main(int argc, char **argv)
  {
  	int i;
  
+	git_set_appname("git-test-date");
+
  	for (i = 1; i < argc; i++) {
  		char result[100];
  		time_t t;
diff --git a/test-delta.c b/test-delta.c
index 1be8ee0..bf6c6ac 100644
--- a/test-delta.c
+++ b/test-delta.c
@@ -27,6 +27,8 @@ int main(int argc, char *argv[])
  	void *from_buf, *data_buf, *out_buf;
  	unsigned long from_size, data_size, out_size;
  
+	git_set_appname("git-test-delta");
+
  	if (argc != 5 || (strcmp(argv[1], "-d") && strcmp(argv[1], "-p"))) {
  		fprintf(stderr, "Usage: %s\n", usage);
  		return 1;
diff --git a/tree-diff.c b/tree-diff.c
index 1cdf8aa..5170ddf 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -191,7 +191,7 @@ int diff_tree(struct tree_desc *t1, stru
  			update_tree_entry(t2);
  			continue;
  		}
-		die("git-diff-tree: internal error");
+		die("internal error");
  	}
  	return 0;
  }
diff --git a/unpack-file.c b/unpack-file.c
index 23a8562..a49e230 100644
--- a/unpack-file.c
+++ b/unpack-file.c
@@ -27,6 +27,8 @@ int main(int argc, char **argv)
  {
  	unsigned char sha1[20];
  
+	git_set_appname("git-unpack-file");
+
  	if (argc != 2 || get_sha1(argv[1], sha1))
  		usage("git-unpack-file <sha1>");
  
diff --git a/unpack-objects.c b/unpack-objects.c
index 3b824b0..315ea67 100644
--- a/unpack-objects.c
+++ b/unpack-objects.c
@@ -270,6 +270,8 @@ int main(int argc, char **argv)
  	int i;
  	unsigned char sha1[20];
  
+	git_set_appname("git-unpack-objects");
+
  	setup_git_directory();
  
  	quiet = !isatty(2);
diff --git a/update-index.c b/update-index.c
index 1efac27..1972328 100644
--- a/update-index.c
+++ b/update-index.c
@@ -370,7 +370,7 @@ static void update_one(const char *path,
  
  	if (force_remove) {
  		if (remove_file_from_cache(p))
-			die("git-update-index: unable to remove %s", path);
+			die("unable to remove %s", path);
  		report("remove '%s'", path);
  		return;
  	}
@@ -446,7 +446,7 @@ static void read_index_info(int line_ter
  		if (!mode) {
  			/* mode == 0 means there is no such path -- remove */
  			if (remove_file_from_cache(path_name))
-				die("git-update-index: unable to remove %s",
+				die("unable to remove %s",
  				    ptr);
  		}
  		else {
@@ -456,7 +456,7 @@ static void read_index_info(int line_ter
  			 */
  			ptr[-42] = ptr[-1] = 0;
  			if (add_cacheinfo(mode, sha1, path_name, stage))
-				die("git-update-index: unable to update %s",
+				die("unable to update %s",
  				    path_name);
  		}
  		if (path_name != ptr)
@@ -476,8 +476,13 @@ int main(int argc, const char **argv)
  	int i, newfd, entries, has_errors = 0, line_termination = '\n';
  	int allow_options = 1;
  	int read_from_stdin = 0;
-	const char *prefix = setup_git_directory();
-	int prefix_length = prefix ? strlen(prefix) : 0;
+	const char *prefix;
+	int prefix_length;
+
+	git_set_appname("git-unpack-index");
+
+	prefix = setup_git_directory();
+	prefix_length = prefix ? strlen(prefix) : 0;
  
  	git_config(git_default_config);
  
@@ -530,12 +535,12 @@ int main(int argc, const char **argv)
  				unsigned int mode;
  
  				if (i+3 >= argc)
-					die("git-update-index: --cacheinfo <mode> <sha1> <path>");
+					die("--cacheinfo <mode> <sha1> <path>");
  
  				if ((sscanf(argv[i+1], "%o", &mode) != 1) ||
  				    get_sha1_hex(argv[i+2], sha1) ||
  				    add_cacheinfo(mode, sha1, argv[i+3], 0))
-					die("git-update-index: --cacheinfo"
+					die("--cacheinfo"
  					    " cannot add %s", argv[i+3]);
  				i += 3;
  				continue;
@@ -543,9 +548,9 @@ int main(int argc, const char **argv)
  			if (!strcmp(path, "--chmod=-x") ||
  			    !strcmp(path, "--chmod=+x")) {
  				if (argc <= i+1)
-					die("git-update-index: %s <path>", path);
+					die("%s <path>", path);
  				if (chmod_path(path[8], argv[++i]))
-					die("git-update-index: %s cannot chmod %s", path, argv[i]);
+					die("%s cannot chmod %s", path, argv[i]);
  				continue;
  			}
  			if (!strcmp(path, "--assume-unchanged")) {
diff --git a/update-ref.c b/update-ref.c
index ba4bf51..1fd32d1 100644
--- a/update-ref.c
+++ b/update-ref.c
@@ -24,6 +24,8 @@ int main(int argc, char **argv)
  	unsigned char sha1[20], oldsha1[20], currsha1[20];
  	int fd, written;
  
+	git_set_appname("git-update-ref");
+
  	setup_git_directory();
  	git_config(git_default_config);
  	if (argc < 3 || argc > 4)
diff --git a/update-server-info.c b/update-server-info.c
index 0b6c383..3496d0e 100644
--- a/update-server-info.c
+++ b/update-server-info.c
@@ -7,6 +7,9 @@ int main(int ac, char **av)
  {
  	int i;
  	int force = 0;
+
+	git_set_appname("git-update-server-info");
+
  	for (i = 1; i < ac; i++) {
  		if (av[i][0] == '-') {
  			if (!strcmp("--force", av[i]) ||
diff --git a/upload-pack.c b/upload-pack.c
index 47560c9..4b8d690 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -38,10 +38,10 @@ static void create_pack_file(void)
  	int create_full_pack = (nr_our_refs == nr_needs && !nr_has);
  
  	if (pipe(fd) < 0)
-		die("git-upload-pack: unable to create pipe");
+		die("unable to create pipe");
  	pid = fork();
  	if (pid < 0)
-		die("git-upload-pack: unable to fork git-rev-list");
+		die("unable to fork git-rev-list");
  
  	if (!pid) {
  		int i;
@@ -84,19 +84,19 @@ static void create_pack_file(void)
  			}
  		*p++ = NULL;
  		execv_git_cmd(argv);
-		die("git-upload-pack: unable to exec git-rev-list");
+		die("unable to exec git-rev-list");
  	}
  	dup2(fd[0], 0);
  	close(fd[0]);
  	close(fd[1]);
  	execl_git_cmd("pack-objects", "--stdout", NULL);
-	die("git-upload-pack: unable to exec git-pack-objects");
+	die("unable to exec git-pack-objects");
  }
  
  static int got_sha1(char *hex, unsigned char *sha1)
  {
  	if (get_sha1_hex(hex, sha1))
-		die("git-upload-pack: expected SHA1 object, got '%s'", hex);
+		die("expected SHA1 object, got '%s'", hex);
  	if (!has_sha1_file(sha1))
  		return 0;
  	if (nr_has < MAX_HAS) {
@@ -162,7 +162,7 @@ static int get_common_commits(void)
  			packet_write(1, "NAK\n");
  			return -1;
  		}
-		die("git-upload-pack: expected SHA1 list, got '%s'", line);
+		die("expected SHA1 list, got '%s'", line);
  	}
  }
  
@@ -191,7 +191,7 @@ static int receive_needs(void)
  			sha1_buf = needs_sha1[needs];
  
  		if (strncmp("want ", line, 5) || get_sha1_hex(line+5, sha1_buf))
-			die("git-upload-pack: protocol error, "
+			die("protocol error, "
  			    "expected to get sha, not '%s'", line);
  		if (strstr(line+45, "multi_ack"))
  			multi_ack = 1;
@@ -208,7 +208,7 @@ static int receive_needs(void)
  		 */
  		o = lookup_object(sha1_buf);
  		if (!o || !(o->flags & OUR_REF))
-			die("git-upload-pack: not our ref %s", line+5);
+			die("not our ref %s", line+5);
  		if (!(o->flags & WANTED)) {
  			o->flags |= WANTED;
  			needs++;
@@ -222,7 +222,7 @@ static int send_ref(const char *refname,
  	struct object *o = parse_object(sha1);
  
  	if (!o)
-		die("git-upload-pack: cannot find object %s:", sha1_to_hex(sha1));
+		die("cannot find object %s:", sha1_to_hex(sha1));
  
  	if (capabilities)
  		packet_write(1, "%s %s%c%s\n", sha1_to_hex(sha1), refname,
@@ -261,6 +261,8 @@ int main(int argc, char **argv)
  	int i;
  	int strict = 0;
  
+	git_set_appname("git-upload-pack");
+
  	for (i = 1; i < argc; i++) {
  		char *arg = argv[i];
  
diff --git a/usage.c b/usage.c
index 1fa924c..27dd5f5 100644
--- a/usage.c
+++ b/usage.c
@@ -5,8 +5,11 @@
   */
  #include "git-compat-util.h"
  
+static char appname[32+3]="";      /* +3 for ': \0' */
+
  static void report(const char *prefix, const char *err, va_list params)
  {
+	fputs(appname[0]?appname:"",stderr);
  	fputs(prefix, stderr);
  	vfprintf(stderr, err, params);
  	fputs("\n", stderr);
@@ -37,3 +40,14 @@ int error(const char *err, ...)
  	va_end(params);
  	return -1;
  }
+
+void git_set_appname(const char *name)
+{
+	size_t len=strlen(name && *name ? name : "");
+	if (0==len)
+		return;
+	memcpy(appname,name,len>sizeof(appname)-3?sizeof(appname)-3:len);
+	appname[len++]=':';
+	appname[len++]=' ';
+	appname[len++]='\0';
+}
diff --git a/var.c b/var.c
index a57a33b..a816373 100644
--- a/var.c
+++ b/var.c
@@ -54,6 +54,9 @@ static int show_config(const char *var, 
  int main(int argc, char **argv)
  {
  	const char *val;
+
+	git_set_appname("git-var");
+
  	if (argc != 2) {
  		usage(var_usage);
  	}
diff --git a/verify-pack.c b/verify-pack.c
index c99db9d..e1b3b01 100644
--- a/verify-pack.c
+++ b/verify-pack.c
@@ -35,6 +35,8 @@ int main(int ac, char **av)
  	int verbose = 0;
  	int no_more_options = 0;
  
+	git_set_appname("git-verify-pack");
+
  	while (1 < ac) {
  		char path[PATH_MAX];
  
diff --git a/write-tree.c b/write-tree.c
index dcad6e6..9f68fda 100644
--- a/write-tree.c
+++ b/write-tree.c
@@ -92,6 +92,8 @@ int main(int argc, char **argv)
  	int entries;
  	unsigned char sha1[20];
  	
+	git_set_appname("git-write-tree");
+
  	setup_git_directory();
  
  	entries = read_cache();
@@ -106,7 +108,7 @@ int main(int argc, char **argv)
  		die("too many options");
  
  	if (entries < 0)
-		die("git-write-tree: error reading cache");
+		die("error reading cache");
  
  	/* Verify that the tree is merged */
  	funny = 0;
@@ -121,7 +123,7 @@ int main(int argc, char **argv)
  		}
  	}
  	if (funny)
-		die("git-write-tree: not able to write tree");
+		die("not able to write tree");
  
  	/* Also verify that the cache does not have path and path/file
  	 * at the same time.  At this point we know the cache has only
@@ -148,11 +150,11 @@ int main(int argc, char **argv)
  		}
  	}
  	if (funny)
-		die("git-write-tree: not able to write tree");
+		die("not able to write tree");
  
  	/* Ok, write it out */
  	if (write_tree(active_cache, entries, "", 0, sha1) != entries)
-		die("git-write-tree: internal error");
+		die("internal error");
  	printf("%s\n", sha1_to_hex(sha1));
  	return 0;
  }
-- 
1.3.0.ge649-dirty

^ permalink raw reply related

* Re: [PATCH] Make die() and error() prefix line with binary name if set
From: Jakub Narebski @ 2006-04-25 10:22 UTC (permalink / raw)
  To: git
In-Reply-To: <20060425101207.GC5482@bolero.cs.tu-berlin.de>

Rocco Rutte wrote:

> +        size_t len=strlen(name && *name ? name : "");
> +        if (0==len)

Wouldn't it be easier (and less idiomatic) to just do

+        size_t len= *name ? strlen(name) : 0;
+        if (0==len)

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* [PATCH] Make die() and error() prefix line with binary name if set
From: Rocco Rutte @ 2006-04-25 14:08 UTC (permalink / raw)
  To: git

Since lots of logic is implemented via shell scripts, it's in
general useful to print out where an error occured. Previously
only some commands manually added the binary name to die() and
error() calls.

Now, git_set_appname() can be used to set the name of the binary
as first call in a binary's main() routine which will be used
as prefix in die() and error(). If it was not called, no prefix
will be printed.

Also fix minor identation issues.

Signed-off-by: Rocco Rutte <pdmef@gmx.net>

---

  apply.c              |   13 +++++++------
  blame.c              |    2 ++
  cat-file.c           |   10 ++++++----
  check-ref-format.c   |    2 ++
  checkout-index.c     |    8 +++++---
  clone-pack.c         |    2 ++
  commit-tree.c        |    2 ++
  connect.c            |    4 ++--
  convert-objects.c    |    2 ++
  daemon.c             |    4 +++-
  describe.c           |    2 ++
  diff-files.c         |    5 ++++-
  diff-index.c         |    5 ++++-
  diff-stages.c        |    5 ++++-
  diff-tree.c          |    2 ++
  entry.c              |   14 +++++++-------
  fetch-clone.c        |    8 +++-----
  fetch-pack.c         |    4 +++-
  fsck-objects.c       |    2 ++
  get-tar-commit-id.c  |    2 ++
  git-compat-util.h    |    1 +
  git.c                |    2 ++
  hash-object.c        |    2 ++
  http-fetch.c         |    2 ++
  http-push.c          |    5 +++--
  index-pack.c         |   17 +++++++----------
  init-db.c            |    2 ++
  local-fetch.c        |    2 ++
  ls-files.c           |    8 +++++---
  ls-tree.c            |    2 ++
  mailinfo.c           |    2 ++
  mailsplit.c          |    2 ++
  merge-base.c         |    2 ++
  merge-index.c        |    8 +++++---
  merge-tree.c         |    2 ++
  mktag.c              |    2 ++
  mktree.c             |    2 ++
  name-rev.c           |    2 ++
  pack-objects.c       |    5 +++--
  pack-redundant.c     |    2 ++
  patch-id.c           |    2 ++
  peek-remote.c        |    2 ++
  prune-packed.c       |    2 ++
  read-tree.c          |    5 +++--
  receive-pack.c       |    5 +++--
  repo-config.c        |    2 ++
  rev-list.c           |    2 ++
  rev-parse.c          |    5 ++++-
  send-pack.c          |    2 ++
  shell.c              |    2 ++
  show-branch.c        |    2 ++
  show-index.c         |    2 ++
  ssh-fetch.c          |    2 ++
  ssh-upload.c         |    2 ++
  stripspace.c         |    2 ++
  symbolic-ref.c       |    2 ++
  tar-tree.c           |    6 ++++--
  test-date.c          |    2 ++
  test-delta.c         |    2 ++
  tree-diff.c          |    2 +-
  unpack-file.c        |    2 ++
  unpack-objects.c     |    2 ++
  update-index.c       |   26 ++++++++++++++------------
  update-ref.c         |    2 ++
  update-server-info.c |    3 +++
  upload-pack.c        |   21 +++++++++++----------
  usage.c              |   14 ++++++++++++++
  var.c                |    3 +++
  verify-pack.c        |    2 ++
  write-tree.c         |   10 ++++++----
  70 files changed, 222 insertions(+), 86 deletions(-)

cb3d0f89bcead397d38e3445c1925d1107bcf062
diff --git a/apply.c b/apply.c
index 269210a..90c4c7c 100644
--- a/apply.c
+++ b/apply.c
@@ -142,7 +142,7 @@ static void *read_patch_file(int fd, uns
  		if (!nr)
  			break;
  		if (nr < 0)
-			die("git-apply: read returned %s", strerror(errno));
+			die("read returned %s", strerror(errno));
  		size += nr;
  	}
  	*sizep = size;
@@ -320,17 +320,17 @@ static char *gitdiff_verify_name(const c
  		name = orig_name;
  		len = strlen(name);
  		if (isnull)
-			die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
+			die("bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
  		another = find_name(line, NULL, 1, 0);
  		if (!another || memcmp(another, name, len))
-			die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
+			die("bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
  		free(another);
  		return orig_name;
  	}
  	else {
  		/* expect "/dev/null" */
  		if (memcmp("/dev/null", line, 9) || line[9] != '\n')
-			die("git-apply: bad git-diff - expected /dev/null on line %d", linenr);
+			die("bad git-diff - expected /dev/null on line %d", linenr);
  		return NULL;
  	}
  }
@@ -1570,8 +1570,7 @@ static void show_index_list(struct patch
  		if (patch->is_new)
  			sha1_ptr = null_sha1;
  		else if (get_sha1(patch->old_sha1_prefix, sha1))
-			die("sha1 information is lacking or useless (%s).",
-			    name);
+			die("sha1 information is lacking or useless (%s).", name);
  		else
  			sha1_ptr = sha1;
  
@@ -1960,6 +1959,8 @@ int main(int argc, char **argv)
  	int read_stdin = 1;
  	const char *whitespace_option = NULL;
  
+	git_set_appname("git-apply");
+
  	for (i = 1; i < argc; i++) {
  		const char *arg = argv[i];
  		char *end;
diff --git a/blame.c b/blame.c
index 07d2d27..804f108 100644
--- a/blame.c
+++ b/blame.c
@@ -752,6 +752,8 @@ int main(int argc, const char **argv)
  	int longest_file, longest_author;
  	int found_rename;
  
+	git_set_appname("git-blame");
+
  	const char* prefix = setup_git_directory();
  	git_config(git_default_config);
  
diff --git a/cat-file.c b/cat-file.c
index 628f6ca..75c400a 100644
--- a/cat-file.c
+++ b/cat-file.c
@@ -16,9 +16,9 @@ static void flush_buffer(const char *buf
  			/* Ignore epipe */
  			if (errno == EPIPE)
  				break;
-			die("git-cat-file: %s", strerror(errno));
+			die("%s", strerror(errno));
  		} else if (!ret) {
-			die("git-cat-file: disk full?");
+			die("disk full?");
  		}
  		size -= ret;
  		buf += ret;
@@ -101,6 +101,8 @@ int main(int argc, char **argv)
  	unsigned long size;
  	int opt;
  
+	git_set_appname("git-cat-file");
+
  	setup_git_directory();
  	git_config(git_default_config);
  	if (argc != 3 || get_sha1(argv[2], sha1))
@@ -154,11 +156,11 @@ int main(int argc, char **argv)
  		break;
  
  	default:
-		die("git-cat-file: unknown option: %s\n", argv[1]);
+		die("unknown option: %s\n", argv[1]);
  	}
  
  	if (!buf)
-		die("git-cat-file %s: bad file", argv[2]);
+		die("bad file", argv[2]);
  
  	flush_buffer(buf, size);
  	return 0;
diff --git a/check-ref-format.c b/check-ref-format.c
index a0adb3d..ce08eda 100644
--- a/check-ref-format.c
+++ b/check-ref-format.c
@@ -9,6 +9,8 @@ #include <stdio.h>
  
  int main(int ac, char **av)
  {
+	git_set_appname("git-check-ref-format");
+
  	if (ac != 2)
  		usage("git-check-ref-format refname");
  	if (check_ref_format(av[1]))
diff --git a/checkout-index.c b/checkout-index.c
index dd6a2d8..b515651 100644
--- a/checkout-index.c
+++ b/checkout-index.c
@@ -176,6 +176,8 @@ int main(int argc, char **argv)
  	int all = 0;
  	int read_from_stdin = 0;
  
+	git_set_appname("git-checkout-index");
+
  	prefix = setup_git_directory();
  	git_config(git_default_config);
  	prefix_length = prefix ? strlen(prefix) : 0;
@@ -271,16 +273,16 @@ int main(int argc, char **argv)
  		const char *arg = argv[i];
  
  		if (all)
-			die("git-checkout-index: don't mix '--all' and explicit filenames");
+			die("don't mix '--all' and explicit filenames");
  		if (read_from_stdin)
-			die("git-checkout-index: don't mix '--stdin' and explicit filenames");
+			die("don't mix '--stdin' and explicit filenames");
  		checkout_file(prefix_path(prefix, prefix_length, arg));
  	}
  
  	if (read_from_stdin) {
  		struct strbuf buf;
  		if (all)
-			die("git-checkout-index: don't mix '--all' and '--stdin'");
+			die("don't mix '--all' and '--stdin'");
  		strbuf_init(&buf);
  		while (1) {
  			char *path_name;
diff --git a/clone-pack.c b/clone-pack.c
index a4370f5..0139745 100644
--- a/clone-pack.c
+++ b/clone-pack.c
@@ -150,6 +150,8 @@ int main(int argc, char **argv)
  	int fd[2];
  	pid_t pid;
  
+	git_set_appname("git-clone-pack");
+
  	setup_git_directory();
  
  	nr_heads = 0;
diff --git a/commit-tree.c b/commit-tree.c
index 2d86518..e07b0eb 100644
--- a/commit-tree.c
+++ b/commit-tree.c
@@ -87,6 +87,8 @@ int main(int argc, char **argv)
  	char *buffer;
  	unsigned int size;
  
+	git_set_appname("git-commit-tree");
+
  	setup_ident();
  	setup_git_directory();
  
diff --git a/connect.c b/connect.c
index 6a8f8a6..70ab5ad 100644
--- a/connect.c
+++ b/connect.c
@@ -69,7 +69,7 @@ int get_ack(int fd, unsigned char *resul
  	int len = packet_read_line(fd, line, sizeof(line));
  
  	if (!len)
-		die("git-fetch-pack: expected ACK/NAK, got EOF");
+		die("expected ACK/NAK, got EOF");
  	if (line[len-1] == '\n')
  		line[--len] = 0;
  	if (!strcmp(line, "NAK"))
@@ -81,7 +81,7 @@ int get_ack(int fd, unsigned char *resul
  			return 1;
  		}
  	}
-	die("git-fetch_pack: expected ACK/NAK, got '%s'", line);
+	die("expected ACK/NAK, got '%s'", line);
  }
  
  int path_match(const char *path, int nr, char **match)
diff --git a/convert-objects.c b/convert-objects.c
index 12aacef..6b5d955 100644
--- a/convert-objects.c
+++ b/convert-objects.c
@@ -319,6 +319,8 @@ int main(int argc, char **argv)
  	unsigned char sha1[20];
  	struct entry *entry;
  
+	git_set_appname("git-convert-object");
+
  	setup_git_directory();
  
  	if (argc != 2 || get_sha1(argv[1], sha1))
diff --git a/daemon.c b/daemon.c
index 776749e..0bb84e8 100644
--- a/daemon.c
+++ b/daemon.c
@@ -666,6 +666,8 @@ int main(int argc, char **argv)
  	int inetd_mode = 0;
  	int i;
  
+	git_set_appname("git-daemon");
+
  	for (i = 1; i < argc; i++) {
  		char *arg = argv[i];
  
@@ -739,7 +741,7 @@ int main(int argc, char **argv)
  
  	if (strict_paths && (!ok_paths || !*ok_paths)) {
  		if (!inetd_mode)
-			die("git-daemon: option --strict-paths requires a whitelist");
+			die("option --strict-paths requires a whitelist");
  
  		logerror("option --strict-paths requires a whitelist");
  		exit (1);
diff --git a/describe.c b/describe.c
index ff65742..a882d00 100644
--- a/describe.c
+++ b/describe.c
@@ -143,6 +143,8 @@ int main(int argc, char **argv)
  {
  	int i;
  
+	git_set_appname("git-describe");
+
  	for (i = 1; i < argc; i++) {
  		const char *arg = argv[i];
  
diff --git a/diff-files.c b/diff-files.c
index ffbef48..0c99c00 100644
--- a/diff-files.c
+++ b/diff-files.c
@@ -39,9 +39,12 @@ static void show_modified(int oldmode, i
  int main(int argc, const char **argv)
  {
  	const char **pathspec;
-	const char *prefix = setup_git_directory();
+	const char *prefix;
  	int entries, i;
  
+	git_set_appname("git-diff-files");
+
+	prefix = setup_git_directory();
  	git_config(git_diff_config);
  	diff_setup(&rev.diffopt);
  	while (1 < argc && argv[1][0] == '-') {
diff --git a/diff-index.c b/diff-index.c
index e376d65..b066d48 100644
--- a/diff-index.c
+++ b/diff-index.c
@@ -171,13 +171,16 @@ int main(int argc, const char **argv)
  {
  	const char *tree_name = NULL;
  	unsigned char sha1[20];
-	const char *prefix = setup_git_directory();
+	const char *prefix;
  	const char **pathspec = NULL;
  	struct tree *tree;
  	int ret;
  	int allow_options = 1;
  	int i;
  
+	git_set_appname("git-diff-index");
+
+	prefix = setup_git_directory();
  	git_config(git_diff_config);
  	diff_setup(&diff_options);
  	for (i = 1; i < argc; i++) {
diff --git a/diff-stages.c b/diff-stages.c
index dcd20e7..bd40b8e 100644
--- a/diff-stages.c
+++ b/diff-stages.c
@@ -57,9 +57,12 @@ static void diff_stages(int stage1, int 
  int main(int ac, const char **av)
  {
  	int stage1, stage2;
-	const char *prefix = setup_git_directory();
+	const char *prefix;
  	const char **pathspec = NULL;
  
+	git_set_appname("git-diff-stages");
+
+	prefix = setup_git_directory();
  	git_config(git_diff_config);
  	read_cache();
  	diff_setup(&diff_options);
diff --git a/diff-tree.c b/diff-tree.c
index 7207867..76222d5 100644
--- a/diff-tree.c
+++ b/diff-tree.c
@@ -67,6 +67,8 @@ int main(int argc, const char **argv)
  	struct object_list *list;
  	int read_stdin = 0;
  
+	git_set_appname("git-diff-tree");
+
  	git_config(git_diff_config);
  	nr_sha1 = 0;
  	init_revisions(opt);
diff --git a/entry.c b/entry.c
index 793724f..5cf36f9 100644
--- a/entry.c
+++ b/entry.c
@@ -76,7 +76,7 @@ static int write_entry(struct cache_entr
  	if (!new || strcmp(type, blob_type)) {
  		if (new)
  			free(new);
-		return error("git-checkout-index: unable to read sha1 file of %s (%s)",
+		return error("unable to read sha1 file of %s (%s)",
  			path, sha1_to_hex(ce->sha1));
  	}
  	switch (ntohl(ce->ce_mode) & S_IFMT) {
@@ -88,14 +88,14 @@ static int write_entry(struct cache_entr
  			fd = create_file(path, ntohl(ce->ce_mode));
  		if (fd < 0) {
  			free(new);
-			return error("git-checkout-index: unable to create file %s (%s)",
+			return error("unable to create file %s (%s)",
  				path, strerror(errno));
  		}
  		wrote = write(fd, new, size);
  		close(fd);
  		free(new);
  		if (wrote != size)
-			return error("git-checkout-index: unable to write file %s", path);
+			return error("unable to write file %s", path);
  		break;
  	case S_IFLNK:
  		if (to_tempfile) {
@@ -103,26 +103,26 @@ static int write_entry(struct cache_entr
  			fd = mkstemp(path);
  			if (fd < 0) {
  				free(new);
-				return error("git-checkout-index: unable to create "
+				return error("unable to create "
  						 "file %s (%s)", path, strerror(errno));
  			}
  			wrote = write(fd, new, size);
  			close(fd);
  			free(new);
  			if (wrote != size)
-				return error("git-checkout-index: unable to write file %s",
+				return error("unable to write file %s",
  					path);
  		} else {
  			wrote = symlink(new, path);
  			free(new);
  			if (wrote)
-				return error("git-checkout-index: unable to create "
+				return error("unable to create "
  						 "symlink %s (%s)", path, strerror(errno));
  		}
  		break;
  	default:
  		free(new);
-		return error("git-checkout-index: unknown file mode for %s", path);
+		return error("unknown file mode for %s", path);
  	}
  
  	if (state->refresh_cache) {
diff --git a/fetch-clone.c b/fetch-clone.c
index da1b3ff..d94c252 100644
--- a/fetch-clone.c
+++ b/fetch-clone.c
@@ -23,7 +23,7 @@ static int finish_pack(const char *pack_
  
  	pid = fork();
  	if (pid < 0)
-		die("git-clone-pack: unable to fork off git-index-pack");
+		die("unable to fork off git-index-pack");
  	if (!pid) {
  		close(0);
  		dup2(pipe_fd[1], 1);
@@ -113,14 +113,12 @@ int receive_unpack_pack(int fd[2], const
  	close(fd[1]);
  	while (waitpid(pid, &status, 0) < 0) {
  		if (errno != EINTR)
-			die("waiting for git-unpack-objects: %s",
-			    strerror(errno));
+			die("waiting for git-unpack-objects: %s", strerror(errno));
  	}
  	if (WIFEXITED(status)) {
  		int code = WEXITSTATUS(status);
  		if (code)
-			die("git-unpack-objects died with error code %d",
-			    code);
+			die("git-unpack-objects died with error code %d", code);
  		return 0;
  	}
  	if (WIFSIGNALED(status)) {
diff --git a/fetch-pack.c b/fetch-pack.c
index a3bcad0..f7053e7 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -390,7 +390,7 @@ static int fetch_pack(int fd[2], int nr_
  		status = receive_unpack_pack(fd, "git-fetch-pack", quiet);
  
  	if (status)
-		die("git-fetch-pack: fetch failed.");
+		die("fetch failed.");
  
   all_done:
  	while (ref) {
@@ -408,6 +408,8 @@ int main(int argc, char **argv)
  	int fd[2];
  	pid_t pid;
  
+	git_set_appname("git-fetch-pack");
+
  	setup_git_directory();
  
  	nr_heads = 0;
diff --git a/fsck-objects.c b/fsck-objects.c
index 59b2590..5e004b6 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -442,6 +442,8 @@ int main(int argc, char **argv)
  {
  	int i, heads;
  
+	git_set_appname("git-fsck-objects");
+
  	setup_git_directory();
  
  	for (i = 1; i < argc; i++) {
diff --git a/get-tar-commit-id.c b/get-tar-commit-id.c
index 4166290..036094d 100644
--- a/get-tar-commit-id.c
+++ b/get-tar-commit-id.c
@@ -12,6 +12,8 @@ int main(int argc, char **argv)
  	char buffer[HEADERSIZE];
  	ssize_t n;
  
+	git_set_appname("git-get-tar-commit-id");
+
  	n = read(0, buffer, HEADERSIZE);
  	if (n < HEADERSIZE) {
  		fprintf(stderr, "read error\n");
diff --git a/git-compat-util.h b/git-compat-util.h
index 5d543d2..cc5370c 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -39,6 +39,7 @@ #endif
  extern void usage(const char *err) NORETURN;
  extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
  extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
+extern void git_set_appname(const char *name);
  
  #ifdef NO_MMAP
  
diff --git a/git.c b/git.c
index aa2b814..ad49bb7 100644
--- a/git.c
+++ b/git.c
@@ -71,6 +71,8 @@ int main(int argc, const char **argv, ch
  	char git_command[PATH_MAX + 1];
  	const char *exec_path = NULL;
  
+	git_set_appname("git");
+
  	/*
  	 * Take the basename of argv[0] as the command
  	 * name, and the dirname as the default exec_path
diff --git a/hash-object.c b/hash-object.c
index 43bd93b..0c95d05 100644
--- a/hash-object.c
+++ b/hash-object.c
@@ -42,6 +42,8 @@ int main(int argc, char **argv)
  	int prefix_length = -1;
  	int no_more_flags = 0;
  
+	git_set_appname("git-hash-object");
+
  	for (i = 1 ; i < argc; i++) {
  		if (!no_more_flags && argv[i][0] == '-') {
  			if (!strcmp(argv[i], "-t")) {
diff --git a/http-fetch.c b/http-fetch.c
index 861644b..69c7cdb 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -1222,6 +1222,8 @@ int main(int argc, char **argv)
  	int arg = 1;
  	int rc = 0;
  
+	git_set_appname("git-http-fetch");
+
  	setup_git_directory();
  
  	while (arg < argc && argv[arg][0] == '-') {
diff --git a/http-push.c b/http-push.c
index b4327d9..0ff5b05 100644
--- a/http-push.c
+++ b/http-push.c
@@ -2130,8 +2130,7 @@ static void fetch_symref(char *path, cha
  	if (start_active_slot(slot)) {
  		run_active_slot(slot);
  		if (results.curl_result != CURLE_OK) {
-			die("Couldn't get %s for remote symref\n%s",
-			    url, curl_errorstr);
+			die("Couldn't get %s for remote symref\n%s", url, curl_errorstr);
  		}
  	} else {
  		die("Unable to start remote symref request");
@@ -2315,6 +2314,8 @@ int main(int argc, char **argv)
  	int new_refs;
  	struct ref *ref;
  
+	git_set_appname("git-http-push");
+
  	setup_git_directory();
  	setup_ident();
  
diff --git a/index-pack.c b/index-pack.c
index b39953d..bcfd116 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -39,21 +39,18 @@ static void open_pack_file(void)
  
  	fd = open(pack_name, O_RDONLY);
  	if (fd < 0)
-		die("cannot open packfile '%s': %s", pack_name,
-		    strerror(errno));
+		die("cannot open packfile '%s': %s", pack_name, strerror(errno));
  	if (fstat(fd, &st)) {
  		int err = errno;
  		close(fd);
-		die("cannot fstat packfile '%s': %s", pack_name,
-		    strerror(err));
+		die("cannot fstat packfile '%s': %s", pack_name, strerror(err));
  	}
  	pack_size = st.st_size;
  	pack_base = mmap(NULL, pack_size, PROT_READ, MAP_PRIVATE, fd, 0);
  	if (pack_base == MAP_FAILED) {
  		int err = errno;
  		close(fd);
-		die("cannot mmap packfile '%s': %s", pack_name,
-		    strerror(err));
+		die("cannot mmap packfile '%s': %s", pack_name, strerror(err));
  	}
  	close(fd);
  }
@@ -97,8 +94,7 @@ static void bad_object(unsigned long off
  	va_start(params, format);
  	vsnprintf(buf, sizeof(buf), format, params);
  	va_end(params);
-	die("packfile '%s': bad object at offset %lu: %s",
-	    pack_name, offset, buf);
+	die("packfile '%s': bad object at offset %lu: %s", pack_name, offset, buf);
  }
  
  static void *unpack_entry_data(unsigned long offset,
@@ -425,6 +421,8 @@ int main(int argc, char **argv)
  	char *index_name_buf = NULL;
  	unsigned char sha1[20];
  
+	git_set_appname("git-index-pack");
+
  	for (i = 1; i < argc; i++) {
  		const char *arg = argv[i];
  
@@ -448,8 +446,7 @@ int main(int argc, char **argv)
  	if (!index_name) {
  		int len = strlen(pack_name);
  		if (len < 5 || strcmp(pack_name + len - 5, ".pack"))
-			die("packfile name '%s' does not end with '.pack'",
-			    pack_name);
+			die("packfile name '%s' does not end with '.pack'", pack_name);
  		index_name_buf = xmalloc(len);
  		memcpy(index_name_buf, pack_name, len - 5);
  		strcpy(index_name_buf + len - 5, ".idx");
diff --git a/init-db.c b/init-db.c
index ff29496..29c93e3 100644
--- a/init-db.c
+++ b/init-db.c
@@ -241,6 +241,8 @@ int main(int argc, char **argv)
  	char *path, *template_dir = NULL;
  	int len, i;
  
+	git_set_appname("git-init-db");
+
  	for (i = 1; i < argc; i++, argv++) {
  		char *arg = argv[1];
  		if (!strncmp(arg, "--template=", 11))
diff --git a/local-fetch.c b/local-fetch.c
index fa9e697..11bf6f8 100644
--- a/local-fetch.c
+++ b/local-fetch.c
@@ -207,6 +207,8 @@ int main(int argc, char **argv)
  	char *commit_id;
  	int arg = 1;
  
+	git_set_appname("git-local-fetch");
+
  	setup_git_directory();
  
  	while (arg < argc && argv[arg][0] == '-') {
diff --git a/ls-files.c b/ls-files.c
index 4a4af1c..15a9bb2 100644
--- a/ls-files.c
+++ b/ls-files.c
@@ -383,7 +383,7 @@ static void show_dir_entry(const char *t
  	int offset = prefix_offset;
  
  	if (len >= ent->len)
-		die("git-ls-files: internal error - directory entry not superset of prefix");
+		die("internal error - directory entry not superset of prefix");
  
  	if (pathspec && !match(pathspec, ps_matched, ent->name, len))
  		return;
@@ -471,7 +471,7 @@ static void show_ce_entry(const char *ta
  	int offset = prefix_offset;
  
  	if (len >= ce_namelen(ce))
-		die("git-ls-files: internal error - cache entry not superset of prefix");
+		die("internal error - cache entry not superset of prefix");
  
  	if (pathspec && !match(pathspec, ps_matched, ce->name, len))
  		return;
@@ -630,7 +630,7 @@ static void verify_pathspec(void)
  	}
  
  	if (prefix_offset > max || memcmp(prev, prefix, prefix_offset))
-		die("git-ls-files: cannot generate relative filenames containing '..'");
+		die("cannot generate relative filenames containing '..'");
  
  	real_prefix = NULL;
  	prefix_len = max;
@@ -653,6 +653,8 @@ int main(int argc, const char **argv)
  	int i;
  	int exc_given = 0;
  
+	git_set_appname("git-ls-files");
+
  	prefix = setup_git_directory();
  	if (prefix)
  		prefix_offset = strlen(prefix);
diff --git a/ls-tree.c b/ls-tree.c
index e4ef200..e037bf0 100644
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -89,6 +89,8 @@ int main(int argc, const char **argv)
  	unsigned char sha1[20];
  	struct tree *tree;
  
+	git_set_appname("git-ls-tree");
+
  	prefix = setup_git_directory();
  	git_config(git_default_config);
  	if (prefix && *prefix)
diff --git a/mailinfo.c b/mailinfo.c
index b276519..7baa3ff 100644
--- a/mailinfo.c
+++ b/mailinfo.c
@@ -757,6 +757,8 @@ static const char mailinfo_usage[] =
  
  int main(int argc, char **argv)
  {
+	git_set_appname("git-mailinfo");
+
  	/* NEEDSWORK: might want to do the optional .git/ directory
  	 * discovery
  	 */
diff --git a/mailsplit.c b/mailsplit.c
index c529e2d..686920e 100644
--- a/mailsplit.c
+++ b/mailsplit.c
@@ -111,6 +111,8 @@ int main(int argc, const char **argv)
  	static const char *stdin_only[] = { "-", NULL };
  	char *name;
  
+	git_set_appname("git-mailsplit");
+
  	for (argp = argv+1; *argp; argp++) {
  		const char *arg = *argp;
  
diff --git a/merge-base.c b/merge-base.c
index 07f5ab4..29cdbd7 100644
--- a/merge-base.c
+++ b/merge-base.c
@@ -236,6 +236,8 @@ int main(int argc, char **argv)
  	struct commit *rev1, *rev2;
  	unsigned char rev1key[20], rev2key[20];
  
+	git_set_appname("git-merge-base");
+
  	setup_git_directory();
  	git_config(git_default_config);
  
diff --git a/merge-index.c b/merge-index.c
index 024196e..3430da5 100644
--- a/merge-index.c
+++ b/merge-index.c
@@ -42,7 +42,7 @@ static int merge_entry(int pos, const ch
  	int found;
  	
  	if (pos >= active_nr)
-		die("git-merge-index: %s not in the cache", path);
+		die("%s not in the cache", path);
  	arguments[0] = pgm;
  	arguments[1] = "";
  	arguments[2] = "";
@@ -67,7 +67,7 @@ static int merge_entry(int pos, const ch
  		arguments[stage + 4] = ownbuf[stage];
  	} while (++pos < active_nr);
  	if (!found)
-		die("git-merge-index: %s not in the cache", path);
+		die("%s not in the cache", path);
  	run_program();
  	return found;
  }
@@ -99,6 +99,8 @@ int main(int argc, char **argv)
  {
  	int i, force_file = 0;
  
+	git_set_appname("git-merge-index");
+
  	if (argc < 3)
  		usage("git-merge-index [-o] [-q] <merge-program> (-a | <filename>*)");
  
@@ -126,7 +128,7 @@ int main(int argc, char **argv)
  				merge_all();
  				continue;
  			}
-			die("git-merge-index: unknown option %s", arg);
+			die("unknown option %s", arg);
  		}
  		merge_file(arg);
  	}
diff --git a/merge-tree.c b/merge-tree.c
index 50528d5..1eca1d7 100644
--- a/merge-tree.c
+++ b/merge-tree.c
@@ -164,6 +164,8 @@ int main(int argc, char **argv)
  	struct tree_desc t[3];
  	void *buf1, *buf2, *buf3;
  
+	git_set_appname("git-merge-tree");
+
  	if (argc < 4)
  		usage(merge_tree_usage);
  
diff --git a/mktag.c b/mktag.c
index 2328878..dcc917e 100644
--- a/mktag.c
+++ b/mktag.c
@@ -109,6 +109,8 @@ int main(int argc, char **argv)
  	char buffer[MAXSIZE];
  	unsigned char result_sha1[20];
  
+	git_set_appname("git-mktag");
+
  	if (argc != 1)
  		usage("cat <signaturefile> | git-mktag");
  
diff --git a/mktree.c b/mktree.c
index ab63cd9..a1ac929 100644
--- a/mktree.c
+++ b/mktree.c
@@ -79,6 +79,8 @@ int main(int ac, char **av)
  	unsigned char sha1[20];
  	int line_termination = '\n';
  
+	git_set_appname("git-mktree");
+
  	setup_git_directory();
  
  	while ((1 < ac) && av[1][0] == '-') {
diff --git a/name-rev.c b/name-rev.c
index bad8a53..c426059 100644
--- a/name-rev.c
+++ b/name-rev.c
@@ -126,6 +126,8 @@ int main(int argc, char **argv)
  	struct object_list **walker = &revs;
  	int as_is = 0, all = 0, transform_stdin = 0;
  
+	git_set_appname("git-name-rev");
+
  	setup_git_directory();
  	git_config(git_default_config);
  
diff --git a/pack-objects.c b/pack-objects.c
index c0acc46..ecbe9f9 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -1237,6 +1237,8 @@ int main(int argc, char **argv)
  	int num_preferred_base = 0;
  	int i;
  
+	git_set_appname("git-pack-objects");
+
  	setup_git_directory();
  
  	for (i = 1; i < argc; i++) {
@@ -1315,8 +1317,7 @@ int main(int argc, char **argv)
  
  		if (line[0] == '-') {
  			if (get_sha1_hex(line+1, sha1))
-				die("expected edge sha1, got garbage:\n %s",
-				    line+1);
+				die("expected edge sha1, got garbage:\n %s", line+1);
  			if (num_preferred_base++ < window)
  				add_preferred_base(sha1);
  			continue;
diff --git a/pack-redundant.c b/pack-redundant.c
index cd81f5a..e2eff1b 100644
--- a/pack-redundant.c
+++ b/pack-redundant.c
@@ -589,6 +589,8 @@ int main(int argc, char **argv)
  	unsigned char *sha1;
  	char buf[42]; /* 40 byte sha1 + \n + \0 */
  
+	git_set_appname("git-pack-redundant");
+
  	setup_git_directory();
  
  	for (i = 1; i < argc; i++) {
diff --git a/patch-id.c b/patch-id.c
index edbc4aa..0e2bd85 100644
--- a/patch-id.c
+++ b/patch-id.c
@@ -74,6 +74,8 @@ static const char patch_id_usage[] = "gi
  
  int main(int argc, char **argv)
  {
+	git_set_appname("git-patch-id");
+
  	if (argc != 1)
  		usage(patch_id_usage);
  
diff --git a/peek-remote.c b/peek-remote.c
index a90cf22..99dac1b 100644
--- a/peek-remote.c
+++ b/peek-remote.c
@@ -29,6 +29,8 @@ int main(int argc, char **argv)
  	pid_t pid;
  	int nongit = 0;
  
+	git_set_appname("git-pack-remote");
+
  	setup_git_directory_gently(&nongit);
  
  	for (i = 1; i < argc; i++) {
diff --git a/prune-packed.c b/prune-packed.c
index d24b097..106cc39 100644
--- a/prune-packed.c
+++ b/prune-packed.c
@@ -58,6 +58,8 @@ int main(int argc, char **argv)
  {
  	int i;
  
+	git_set_appname("git-prune-packed");
+
  	setup_git_directory();
  
  	for (i = 1; i < argc; i++) {
diff --git a/read-tree.c b/read-tree.c
index 26f4f7e..6e1b698 100644
--- a/read-tree.c
+++ b/read-tree.c
@@ -235,8 +235,7 @@ #endif
  
  static void reject_merge(struct cache_entry *ce)
  {
-	die("Entry '%s' would be overwritten by merge. Cannot merge.", 
-	    ce->name);
+	die("Entry '%s' would be overwritten by merge. Cannot merge.", ce->name);
  }
  
  /* Unlink the last component and attempt to remove leading
@@ -723,6 +722,8 @@ int main(int argc, char **argv)
  	unsigned char sha1[20];
  	merge_fn_t fn = NULL;
  
+	git_set_appname("git-read-tree");
+
  	setup_git_directory();
  	git_config(git_default_config);
  
diff --git a/receive-pack.c b/receive-pack.c
index 93929b5..54ec6dc 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -237,8 +237,7 @@ static void read_head_info(void)
  		    line[81] != ' ' ||
  		    get_sha1_hex(line, old_sha1) ||
  		    get_sha1_hex(line + 41, new_sha1))
-			die("protocol error: expected old/new/ref, got '%s'",
-			    line);
+			die("protocol error: expected old/new/ref, got '%s'", line);
  
  		refname = line + 82;
  		reflen = strlen(refname);
@@ -304,6 +303,8 @@ int main(int argc, char **argv)
  	int i;
  	char *dir = NULL;
  
+	git_set_appname("git-receive-pack");
+
  	argv++;
  	for (i = 1; i < argc; i++) {
  		char *arg = *argv++;
diff --git a/repo-config.c b/repo-config.c
index c5ebb76..793af68 100644
--- a/repo-config.c
+++ b/repo-config.c
@@ -86,6 +86,8 @@ static int get_value(const char* key_, c
  
  int main(int argc, const char **argv)
  {
+	git_set_appname("git-repo-config");
+
  	setup_git_directory();
  
  	while (1 < argc) {
diff --git a/rev-list.c b/rev-list.c
index 8b0ec38..4646372 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -296,6 +296,8 @@ int main(int argc, const char **argv)
  	struct commit_list *list;
  	int i;
  
+	git_set_appname("git-rev-list");
+
  	init_revisions(&revs);
  	revs.abbrev = 0;
  	revs.commit_format = CMIT_FMT_UNSPECIFIED;
diff --git a/rev-parse.c b/rev-parse.c
index 7f66ae2..aaaf813 100644
--- a/rev-parse.c
+++ b/rev-parse.c
@@ -172,8 +172,11 @@ int main(int argc, char **argv)
  {
  	int i, as_is = 0, verify = 0;
  	unsigned char sha1[20];
-	const char *prefix = setup_git_directory();
+	const char *prefix;
  	
+	git_set_appname("git-rev-parse");
+
+	prefix = setup_git_directory();
  	git_config(git_default_config);
  
  	for (i = 1; i < argc; i++) {
diff --git a/send-pack.c b/send-pack.c
index 409f188..803e193 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -361,6 +361,8 @@ int main(int argc, char **argv)
  	int fd[2], ret;
  	pid_t pid;
  
+	git_set_appname("git-send-pack");
+
  	setup_git_directory();
  	git_config(git_default_config);
  
diff --git a/shell.c b/shell.c
index 8c08cf0..c22cde1 100644
--- a/shell.c
+++ b/shell.c
@@ -32,6 +32,8 @@ int main(int argc, char **argv)
  	char *prog;
  	struct commands *cmd;
  
+	git_set_appname("git-shell");
+
  	/* We want to see "-c cmd args", and nothing else */
  	if (argc != 3 || strcmp(argv[1], "-c"))
  		die("What do you think I am? A shell?");
diff --git a/show-branch.c b/show-branch.c
index 24efb65..9ec3553 100644
--- a/show-branch.c
+++ b/show-branch.c
@@ -549,6 +549,8 @@ int main(int ac, char **av)
  	int head_at = -1;
  	int topics = 0;
  
+	git_set_appname("git-show-branch");
+
  	setup_git_directory();
  	git_config(git_show_branch_config);
  
diff --git a/show-index.c b/show-index.c
index c21d660..b8a9fba 100644
--- a/show-index.c
+++ b/show-index.c
@@ -7,6 +7,8 @@ int main(int argc, char **argv)
  	unsigned int entry[6];
  	static unsigned int top_index[256];
  
+	git_set_appname("git-show-index");
+
  	if (fread(top_index, sizeof(top_index), 1, stdin) != 1)
  		die("unable to read idex");
  	nr = 0;
diff --git a/ssh-fetch.c b/ssh-fetch.c
index 4eb9e04..4bab7e7 100644
--- a/ssh-fetch.c
+++ b/ssh-fetch.c
@@ -128,6 +128,8 @@ int main(int argc, char **argv)
  	int arg = 1;
  	const char *prog;
  
+	git_set_appname("git-ssh-fetch");
+
  	prog = getenv("GIT_SSH_PUSH");
  	if (!prog) prog = "git-ssh-upload";
  
diff --git a/ssh-upload.c b/ssh-upload.c
index b675a0b..9860cf4 100644
--- a/ssh-upload.c
+++ b/ssh-upload.c
@@ -119,6 +119,8 @@ int main(int argc, char **argv)
  	unsigned char sha1[20];
  	char hex[41];
  
+	git_set_appname("git-ssh-upload");
+
  	prog = getenv(COUNTERPART_ENV_NAME);
  	if (!prog) prog = COUNTERPART_PROGRAM_NAME;
  
diff --git a/stripspace.c b/stripspace.c
index 65a6346..95c2e43 100644
--- a/stripspace.c
+++ b/stripspace.c
@@ -34,6 +34,8 @@ int main(int argc, char **argv)
  	int incomplete = 0;
  	char line[1024];
  
+	git_set_appname("git-stripspace");
+
  	while (fgets(line, sizeof(line), stdin)) {
  		incomplete = cleanup(line);
  
diff --git a/symbolic-ref.c b/symbolic-ref.c
index 193c87c..a8b3b9d 100644
--- a/symbolic-ref.c
+++ b/symbolic-ref.c
@@ -19,6 +19,8 @@ static void check_symref(const char *HEA
  
  int main(int argc, const char **argv)
  {
+	git_set_appname("git-symbolic-ref");
+
  	setup_git_directory();
  	git_config(git_default_config);
  	switch (argc) {
diff --git a/tar-tree.c b/tar-tree.c
index fc60a90..7a388f5 100644
--- a/tar-tree.c
+++ b/tar-tree.c
@@ -26,9 +26,9 @@ static void reliable_write(void *buf, un
  		if (ret < 0) {
  			if (errno == EPIPE)
  				exit(0);
-			die("git-tar-tree: %s", strerror(errno));
+			die("%s", strerror(errno));
  		} else if (!ret) {
-			die("git-tar-tree: disk full?");
+			die("disk full?");
  		}
  		size -= ret;
  		buf += ret;
@@ -308,6 +308,8 @@ int main(int argc, char **argv)
  	struct tree_desc tree;
  	struct strbuf current_path;
  
+	git_set_appname("git-tar-tree");
+
  	current_path.buf = xmalloc(PATH_MAX);
  	current_path.alloc = PATH_MAX;
  	current_path.len = current_path.eof = 0;
diff --git a/test-date.c b/test-date.c
index 93e8027..3d2cfbb 100644
--- a/test-date.c
+++ b/test-date.c
@@ -7,6 +7,8 @@ int main(int argc, char **argv)
  {
  	int i;
  
+	git_set_appname("git-test-date");
+
  	for (i = 1; i < argc; i++) {
  		char result[100];
  		time_t t;
diff --git a/test-delta.c b/test-delta.c
index 1be8ee0..bf6c6ac 100644
--- a/test-delta.c
+++ b/test-delta.c
@@ -27,6 +27,8 @@ int main(int argc, char *argv[])
  	void *from_buf, *data_buf, *out_buf;
  	unsigned long from_size, data_size, out_size;
  
+	git_set_appname("git-test-delta");
+
  	if (argc != 5 || (strcmp(argv[1], "-d") && strcmp(argv[1], "-p"))) {
  		fprintf(stderr, "Usage: %s\n", usage);
  		return 1;
diff --git a/tree-diff.c b/tree-diff.c
index 1cdf8aa..5170ddf 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -191,7 +191,7 @@ int diff_tree(struct tree_desc *t1, stru
  			update_tree_entry(t2);
  			continue;
  		}
-		die("git-diff-tree: internal error");
+		die("internal error");
  	}
  	return 0;
  }
diff --git a/unpack-file.c b/unpack-file.c
index 23a8562..a49e230 100644
--- a/unpack-file.c
+++ b/unpack-file.c
@@ -27,6 +27,8 @@ int main(int argc, char **argv)
  {
  	unsigned char sha1[20];
  
+	git_set_appname("git-unpack-file");
+
  	if (argc != 2 || get_sha1(argv[1], sha1))
  		usage("git-unpack-file <sha1>");
  
diff --git a/unpack-objects.c b/unpack-objects.c
index 3b824b0..315ea67 100644
--- a/unpack-objects.c
+++ b/unpack-objects.c
@@ -270,6 +270,8 @@ int main(int argc, char **argv)
  	int i;
  	unsigned char sha1[20];
  
+	git_set_appname("git-unpack-objects");
+
  	setup_git_directory();
  
  	quiet = !isatty(2);
diff --git a/update-index.c b/update-index.c
index facec8d..f8e24d4 100644
--- a/update-index.c
+++ b/update-index.c
@@ -354,7 +354,7 @@ static void chmod_path(int flip, const c
  	report("chmod %cx '%s'", flip, path);
  	return;
   fail:
-	die("git-update-index: cannot chmod %cx '%s'", flip, path);
+	die("cannot chmod %cx '%s'", flip, path);
  }
  
  static struct cache_file cache_file;
@@ -374,7 +374,7 @@ static void update_one(const char *path,
  
  	if (force_remove) {
  		if (remove_file_from_cache(p))
-			die("git-update-index: unable to remove %s", path);
+			die("unable to remove %s", path);
  		report("remove '%s'", path);
  		return;
  	}
@@ -450,8 +450,7 @@ static void read_index_info(int line_ter
  		if (!mode) {
  			/* mode == 0 means there is no such path -- remove */
  			if (remove_file_from_cache(path_name))
-				die("git-update-index: unable to remove %s",
-				    ptr);
+				die("unable to remove %s", ptr);
  		}
  		else {
  			/* mode ' ' sha1 '\t' name
@@ -460,8 +459,7 @@ static void read_index_info(int line_ter
  			 */
  			ptr[-42] = ptr[-1] = 0;
  			if (add_cacheinfo(mode, sha1, path_name, stage))
-				die("git-update-index: unable to update %s",
-				    path_name);
+				die("unable to update %s", path_name);
  		}
  		if (path_name != ptr)
  			free(path_name);
@@ -598,12 +596,17 @@ int main(int argc, const char **argv)
  	int i, newfd, entries, has_errors = 0, line_termination = '\n';
  	int allow_options = 1;
  	int read_from_stdin = 0;
-	const char *prefix = setup_git_directory();
-	int prefix_length = prefix ? strlen(prefix) : 0;
+	const char *prefix;
+	int prefix_length;
  	char set_executable_bit = 0;
  
+	git_set_appname("git-update-index");
+
  	git_config(git_default_config);
  
+	prefix = setup_git_directory();
+	prefix_length = prefix ? strlen(prefix) : 0;
+
  	newfd = hold_index_file_for_update(&cache_file, get_index_file());
  	if (newfd < 0)
  		die("unable to create new cachefile");
@@ -653,20 +656,19 @@ int main(int argc, const char **argv)
  				unsigned int mode;
  
  				if (i+3 >= argc)
-					die("git-update-index: --cacheinfo <mode> <sha1> <path>");
+					die("--cacheinfo <mode> <sha1> <path>");
  
  				if ((sscanf(argv[i+1], "%o", &mode) != 1) ||
  				    get_sha1_hex(argv[i+2], sha1) ||
  				    add_cacheinfo(mode, sha1, argv[i+3], 0))
-					die("git-update-index: --cacheinfo"
-					    " cannot add %s", argv[i+3]);
+					die("--cacheinfo cannot add %s", argv[i+3]);
  				i += 3;
  				continue;
  			}
  			if (!strcmp(path, "--chmod=-x") ||
  			    !strcmp(path, "--chmod=+x")) {
  				if (argc <= i+1)
-					die("git-update-index: %s <path>", path);
+					die("%s <path>", path);
  				set_executable_bit = path[8];
  				continue;
  			}
diff --git a/update-ref.c b/update-ref.c
index ba4bf51..1fd32d1 100644
--- a/update-ref.c
+++ b/update-ref.c
@@ -24,6 +24,8 @@ int main(int argc, char **argv)
  	unsigned char sha1[20], oldsha1[20], currsha1[20];
  	int fd, written;
  
+	git_set_appname("git-update-ref");
+
  	setup_git_directory();
  	git_config(git_default_config);
  	if (argc < 3 || argc > 4)
diff --git a/update-server-info.c b/update-server-info.c
index 0b6c383..3496d0e 100644
--- a/update-server-info.c
+++ b/update-server-info.c
@@ -7,6 +7,9 @@ int main(int ac, char **av)
  {
  	int i;
  	int force = 0;
+
+	git_set_appname("git-update-server-info");
+
  	for (i = 1; i < ac; i++) {
  		if (av[i][0] == '-') {
  			if (!strcmp("--force", av[i]) ||
diff --git a/upload-pack.c b/upload-pack.c
index 47560c9..ed16b53 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -38,10 +38,10 @@ static void create_pack_file(void)
  	int create_full_pack = (nr_our_refs == nr_needs && !nr_has);
  
  	if (pipe(fd) < 0)
-		die("git-upload-pack: unable to create pipe");
+		die("unable to create pipe");
  	pid = fork();
  	if (pid < 0)
-		die("git-upload-pack: unable to fork git-rev-list");
+		die("unable to fork git-rev-list");
  
  	if (!pid) {
  		int i;
@@ -84,19 +84,19 @@ static void create_pack_file(void)
  			}
  		*p++ = NULL;
  		execv_git_cmd(argv);
-		die("git-upload-pack: unable to exec git-rev-list");
+		die("unable to exec git-rev-list");
  	}
  	dup2(fd[0], 0);
  	close(fd[0]);
  	close(fd[1]);
  	execl_git_cmd("pack-objects", "--stdout", NULL);
-	die("git-upload-pack: unable to exec git-pack-objects");
+	die("unable to exec git-pack-objects");
  }
  
  static int got_sha1(char *hex, unsigned char *sha1)
  {
  	if (get_sha1_hex(hex, sha1))
-		die("git-upload-pack: expected SHA1 object, got '%s'", hex);
+		die("expected SHA1 object, got '%s'", hex);
  	if (!has_sha1_file(sha1))
  		return 0;
  	if (nr_has < MAX_HAS) {
@@ -162,7 +162,7 @@ static int get_common_commits(void)
  			packet_write(1, "NAK\n");
  			return -1;
  		}
-		die("git-upload-pack: expected SHA1 list, got '%s'", line);
+		die("expected SHA1 list, got '%s'", line);
  	}
  }
  
@@ -191,8 +191,7 @@ static int receive_needs(void)
  			sha1_buf = needs_sha1[needs];
  
  		if (strncmp("want ", line, 5) || get_sha1_hex(line+5, sha1_buf))
-			die("git-upload-pack: protocol error, "
-			    "expected to get sha, not '%s'", line);
+			die("protocol error, expected to get sha, not '%s'", line);
  		if (strstr(line+45, "multi_ack"))
  			multi_ack = 1;
  		if (strstr(line+45, "thin-pack"))
@@ -208,7 +207,7 @@ static int receive_needs(void)
  		 */
  		o = lookup_object(sha1_buf);
  		if (!o || !(o->flags & OUR_REF))
-			die("git-upload-pack: not our ref %s", line+5);
+			die("not our ref %s", line+5);
  		if (!(o->flags & WANTED)) {
  			o->flags |= WANTED;
  			needs++;
@@ -222,7 +221,7 @@ static int send_ref(const char *refname,
  	struct object *o = parse_object(sha1);
  
  	if (!o)
-		die("git-upload-pack: cannot find object %s:", sha1_to_hex(sha1));
+		die("cannot find object %s:", sha1_to_hex(sha1));
  
  	if (capabilities)
  		packet_write(1, "%s %s%c%s\n", sha1_to_hex(sha1), refname,
@@ -261,6 +260,8 @@ int main(int argc, char **argv)
  	int i;
  	int strict = 0;
  
+	git_set_appname("git-upload-pack");
+
  	for (i = 1; i < argc; i++) {
  		char *arg = argv[i];
  
diff --git a/usage.c b/usage.c
index 1fa924c..bb89d66 100644
--- a/usage.c
+++ b/usage.c
@@ -5,8 +5,11 @@
   */
  #include "git-compat-util.h"
  
+static char appname[32+3]="";      /* +3 for ': \0' */
+
  static void report(const char *prefix, const char *err, va_list params)
  {
+	fputs(appname[0]?appname:"",stderr);
  	fputs(prefix, stderr);
  	vfprintf(stderr, err, params);
  	fputs("\n", stderr);
@@ -37,3 +40,14 @@ int error(const char *err, ...)
  	va_end(params);
  	return -1;
  }
+
+void git_set_appname(const char *name)
+{
+	size_t len=(name && *name)?strlen(name):0;
+	if (0==len)
+		return;
+	memcpy(appname,name,len>sizeof(appname)-3?sizeof(appname)-3:len);
+	appname[len++]=':';
+	appname[len++]=' ';
+	appname[len++]='\0';
+}
diff --git a/var.c b/var.c
index a57a33b..a816373 100644
--- a/var.c
+++ b/var.c
@@ -54,6 +54,9 @@ static int show_config(const char *var, 
  int main(int argc, char **argv)
  {
  	const char *val;
+
+	git_set_appname("git-var");
+
  	if (argc != 2) {
  		usage(var_usage);
  	}
diff --git a/verify-pack.c b/verify-pack.c
index c99db9d..e1b3b01 100644
--- a/verify-pack.c
+++ b/verify-pack.c
@@ -35,6 +35,8 @@ int main(int ac, char **av)
  	int verbose = 0;
  	int no_more_options = 0;
  
+	git_set_appname("git-verify-pack");
+
  	while (1 < ac) {
  		char path[PATH_MAX];
  
diff --git a/write-tree.c b/write-tree.c
index dcad6e6..9f68fda 100644
--- a/write-tree.c
+++ b/write-tree.c
@@ -92,6 +92,8 @@ int main(int argc, char **argv)
  	int entries;
  	unsigned char sha1[20];
  	
+	git_set_appname("git-write-tree");
+
  	setup_git_directory();
  
  	entries = read_cache();
@@ -106,7 +108,7 @@ int main(int argc, char **argv)
  		die("too many options");
  
  	if (entries < 0)
-		die("git-write-tree: error reading cache");
+		die("error reading cache");
  
  	/* Verify that the tree is merged */
  	funny = 0;
@@ -121,7 +123,7 @@ int main(int argc, char **argv)
  		}
  	}
  	if (funny)
-		die("git-write-tree: not able to write tree");
+		die("not able to write tree");
  
  	/* Also verify that the cache does not have path and path/file
  	 * at the same time.  At this point we know the cache has only
@@ -148,11 +150,11 @@ int main(int argc, char **argv)
  		}
  	}
  	if (funny)
-		die("git-write-tree: not able to write tree");
+		die("not able to write tree");
  
  	/* Ok, write it out */
  	if (write_tree(active_cache, entries, "", 0, sha1) != entries)
-		die("git-write-tree: internal error");
+		die("internal error");
  	printf("%s\n", sha1_to_hex(sha1));
  	return 0;
  }
-- 
1.3.0.g36932-dirty

^ permalink raw reply related

* Re: [PATCH] Make die() and error() prefix line with binary name if set
From: Rocco Rutte @ 2006-04-25 14:13 UTC (permalink / raw)
  To: git
In-Reply-To: <e2kt7h$o4a$1@sea.gmane.org>

* Jakub Narebski <jnareb@gmail.com>:

>Wouldn't it be easier (and less idiomatic) to just do

Oh, thanks for pointing it out. The second one I sent fixes it (and is 
against an updated master branch).

   bye, Rocco
-- 
:wq!

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links
From: Linus Torvalds @ 2006-04-25 15:10 UTC (permalink / raw)
  To: Sam Vilain; +Cc: git
In-Reply-To: <20060425035421.18382.51677.stgit@localhost.localdomain>



On Tue, 25 Apr 2006, Sam Vilain wrote:
>
> This patch series implements "prior" links in commit objects.  A
> 'prior' link on a commit represents its historical precedent, as
> opposed to the previous commit(s) that this commit builds upon.

I really don't think this is worth it.

We already have a very useful notion of "prior" commit that is used daily 
(well, weekly) for the Linux kernel, and it's used for one of the few 
places where this really makes unequivocal sense. "git revert".

It's also implemented in the only way that has clear and unambiguous 
semantics: by putting the prior link into the free-form part. The reason 
this is clear and unambiguous is that it makes it clear that it has no 
actual technical impact on any serious git strategy, ie there is never any 
question of "What does it _mean_?".

At the same time, it gives exactly what you actually _want_ for a prior 
link: it makes it easy to look up the commit that was replaced, or fixed, 
or that is related, or just any random semantics that you can explain 
easily in the text.

Both gitk and qgit already support it, and it's trivially 
cut-and-pasteable from any log message to see what it is when you work on 
the command line too.

In contrast, adding a new header is serious trouble:

 - What does it _mean_ from a technical angle? 

   Does it matter for merging? One of your patches seems to make it so, 
   which is _really_ confusing. Why should it? And does it affect anything 
   else that git does?

   Does "prior" have any meaning for "git-fsck-objects" and/or for object 
   pruning? For "git fetch/pull"?

 - What does it mean from a semantic standpoint?

   Is "prior" a note that something was reverted? Fixed? Changed? 
   Cherry-picked? And if it is Cherry-picked, than I would flat-out refuse 
   to ever merge with a tree that has it, because it pretty much by 
   definition means that the object that "prior" points to simply doesn't 
   _exist_ in my tree (since it was cherry-picked from somebody elses 
   tree). Or that it means that my history got tangled up with the history 
   of the failed branch that needed cherry-picking to clean up..

 - You say that there is just one "prior" parent, but why just one? 
   There's no way to even _think_ about this, since it seems to have no 
   actual semantic meaning.

I think all the problems really boil down to "What does this mean?"

Without an answer to that question, it's just a random feature. It's 
something that you can use and mis-use, but that has no "meaning". It only 
has whatever meaning you personally assign to it, but that implies that 
git shouldn't parse it, and shouldn't care about it.

Which again says that it should act like the current free-form thing does 
so well - it has no meaning, but it allows easy lookups.

		Linus

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Linus Torvalds @ 2006-04-25 15:21 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, jnareb
In-Reply-To: <7v7j5e2jv7.fsf@assigned-by-dhcp.cox.net>



On Tue, 25 Apr 2006, Junio C Hamano wrote:
> 
> How about an ability to "attach" arbitrary objects to commit
> objects?  The commit object would look like:
> 
>     tree 0aaa3fecff73ab428999cb9156f8abc075516abe
>     parent 5a6a8c0e012137a3f0059be40ec7b2f4aa614355
>     parent e1cbc46d12a0524fd5e710cbfaf3f178fc3da504
>     related a0e7d36193b96f552073558acf5fcc1f10528917 key
>     related 0032d548db56eac9ea09b4ba05843365f6325b85 cherrypick

This would at the face of it seem a bit better, but the fact is, it's not.

Without _semantics_ for the different cases, it's just random crud.

What does any of the fields _mean_ to git? In particular, if you cannot 
come up with an _exact_ definition of what they mean for fsck, pull, push, 
and any other random thing (how to show them for logging? How do they 
affect merge bases?), then it's still just random free-form text, and it 
should go into the random free-form section.

> The semantics I would attach to these "related" links are as
> follows:
> 
>  * To the "core" level git, they do not mean anything other than
>    "you must to have these objects, and objects reachable from
>    them, if you are going to have this commit and claim your
>    repository is without missing objects".

Ok, a real semantic meaning. However:

THAT IS COMPLETELY USELESS.

It sure isn't useful for cherry-picking, which so far is one of the only 
"real examples" of where this would actually be used. 

It isn't useful for much anything else either, because you really have two 
cases:

 - the "related" commit is an indirect parent _anyway_ (for things like 
   "revert", this would obviously be the case, since it doesn't generally 
   make a lot of sense to revert something that has never touched your 
   history). In this case, the git semantics end up being NULL, and you 
   just have another relationship that doesn't actually add any new 
   information to the tree.

 - the "related" commit is not actually in the set of _real_ parenthood at 
   all, and actually points to a different branch (or possibly even 
   different project).

   This case I'd sure as hell hate to have for the kernel, at least. I 
   would have to add crap to my workflow to make sure that people do _not_ 
   have these kinds of linkages that link in random parts of their project 
   that doesn't actually have anything to do with the history I'm pulling.

Those are the only two possible cases. Either it's an indirect parent, or 
it isn't. Neither one makes any sense: the first one is a no-op from your 
semantic definition, and the second one is just crazy and you'll just find 
that people have to protect themselves from other developers doing 
something crazy by mistake.

I want the git objects to have clear and unambiguous semantics. I want 
people to be able to explain exactly what the fields _mean_. No "this 
random field could be used this random way" crud, please.

			Linus

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Linus Torvalds @ 2006-04-25 15:40 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, jnareb
In-Reply-To: <Pine.LNX.4.64.0604250811230.3701@g5.osdl.org>



On Tue, 25 Apr 2006, Linus Torvalds wrote:
> 
> I want the git objects to have clear and unambiguous semantics. I want 
> people to be able to explain exactly what the fields _mean_. No "this 
> random field could be used this random way" crud, please.

Btw, if the whole point is a "leave random porcelain a field that they can 
use any way they want", then I say "Hell NO!".

Random porcelain can already just maintain their own lists of "related" 
stuff, any way they want: you can keep it in a file in ".git/porcelain", 
called "list-commit-relationships", or you could use a git blob for it and 
have a reference to it in .git/refs/porcelain/relationships or whatever. 

If it has no clear and real semantic meaning for core git, then it 
shouldn't be in the core git objects.

The absolute last thing we want is a "random out" that starts to mean 
different things to different people, groups and porcelains.

That's just crazy, and it's how you end up with a backwards compatibility 
mess five years from now that is totally unresolvable, because different 
projects end up having different meanings or uses for the fields, so 
converting the database (if we ever find a better format, or somebody 
notices that SHA1 can be broken by a five-year-old-with-a-crayon).

There's a reason "minimalist" actually ends up _working_. I'll take a UNIX 
"system calls have meanings" approach over a Windows "there's fifteen 
different flavors of 'open()', and we also support magic filenames with 
specific meaning" kind of thing.

			Linus

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: sean @ 2006-04-25 16:17 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: junkio, git, jnareb
In-Reply-To: <Pine.LNX.4.64.0604250833540.3701@g5.osdl.org>

On Tue, 25 Apr 2006 08:40:25 -0700 (PDT)
Linus Torvalds <torvalds@osdl.org> wrote:

> On Tue, 25 Apr 2006, Linus Torvalds wrote:
> > 
> > I want the git objects to have clear and unambiguous semantics. I want 
> > people to be able to explain exactly what the fields _mean_. No "this 
> > random field could be used this random way" crud, please.
> 
> Btw, if the whole point is a "leave random porcelain a field that they can 
> use any way they want", then I say "Hell NO!".
> 
> Random porcelain can already just maintain their own lists of "related" 
> stuff, any way they want: you can keep it in a file in ".git/porcelain", 
> called "list-commit-relationships", or you could use a git blob for it and 
> have a reference to it in .git/refs/porcelain/relationships or whatever. 
> 
> If it has no clear and real semantic meaning for core git, then it 
> shouldn't be in the core git objects.
> 
> The absolute last thing we want is a "random out" that starts to mean 
> different things to different people, groups and porcelains.
> 
> That's just crazy, and it's how you end up with a backwards compatibility 
> mess five years from now that is totally unresolvable, because different 
> projects end up having different meanings or uses for the fields, so 
> converting the database (if we ever find a better format, or somebody 
> notices that SHA1 can be broken by a five-year-old-with-a-crayon).
> 
> There's a reason "minimalist" actually ends up _working_. I'll take a UNIX 
> "system calls have meanings" approach over a Windows "there's fifteen 
> different flavors of 'open()', and we also support magic filenames with 
> specific meaning" kind of thing.
> 

It's a fair point.  But adding a separate database to augment the core 
information has some downsides.  That is, that information isn't pulled, 
cloned, or pushed automatically; it doesn't get to ride for free on top 
of the core.

Accommodating extra git headers (or "note"'s in Junio's example) would allow
a developer to record the fact that he is integrating a patch taken 
from a commit in the devel branch and backporting it to the release 
branch.   Either by adding a note that references the bug tracking #, or 
a commit sha1 from the devel branch that is already associated with the bug.

Of course that information could be embedded in the free text area, but 
you yourself have argued vigorously that it is brain damaged to try and rely
on parsing free form text for these types of situations.  Most of the potential 
uses aren't really meant for a human to read while looking at the log anyway, 
they just get in the way.  Another option that you alluded to, was to 
stuff the information in another git object.   But such an object would have 
to embed a reference to the original commit, thus you haven't really made 
changing the SHA1 algorithm any easier.  And then you also then have to jump 
through hoops to make sure that you pull the proper extra blobs that contain 
information about the real commits you just pulled.

But if the information is in the actual commit header it gets to tag along
for free with never any worry it will be separated from the commit in question.
So when the developer above updates his official repo the bug tracker system 
can notice that the bug referenced in its system has had a patch backported 
and take whatever action is desired.  

Of course there are other ways to do this, but integrating it into git means it
gets a free ride on the core, and it shouldn't really get in the way of core 
any more than email X- headers get in the way of email flowing.

Sean

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Jakub Narebski @ 2006-04-25 16:27 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.64.0604250833540.3701@g5.osdl.org>

Linus Torvalds wrote:

> On Tue, 25 Apr 2006, Linus Torvalds wrote:
>> 
>> I want the git objects to have clear and unambiguous semantics. I want
>> people to be able to explain exactly what the fields _mean_. No "this
>> random field could be used this random way" crud, please.
> 
> Btw, if the whole point is a "leave random porcelain a field that they can
> use any way they want", then I say "Hell NO!".

The generic commit links "related" which is fsck-able at least and "note"
which is not. It is idea somewhat on the level of providing _extended
attributes_ in VFS in Linux kernel, IMVHO.

"note" can be considere cruft, "related" is fsck-able and pull-able so has
meaning for core (even if not all "note" and/or "related" links have any
repercussion for merging for example).

So far there are following core git ideas of using this feature (akin to
using extended attributes for ACL, or SELinux properties):

1. "related" link "bind" for better support of subprojects. Useful if some
parts of project are developed independently (e.g. lm_sensors or ALSA was
in Linux kernel, xdiff for git, somelibrary or somemodule for someproject
etc.).
2. "note" link "cherrypicked" for cherry-picking, rebase etc., for example
to not apply the same commit twice. Useful in merging after cherry picking.

Additionally there are following less certain ideas

3. "prior" link in the sense of prior state of frequently rebased branch
like git's "pu" (case (1) in first post in this thread)
4. "depend" link for creating darc-esque dependency partial ordering of
commits (patches), for better merge perhaps
5. "note" link "rename" (or more generic "contents related") for remembering
renames/file moving, file splitting, contents moving and copying, including
correcting automatic "rename" detection at merge (i.e. remembering false
positives and false negatives). Useful in subsequent merges and information
commands (log, whatchanged, annotate/blame, diff).
6. "note" link "origin" to remember for where the commit was pulled.

Note that none of those are non-core Porcelain ideas.

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Linus Torvalds @ 2006-04-25 17:04 UTC (permalink / raw)
  To: sean; +Cc: junkio, git, jnareb
In-Reply-To: <BAYC1-PASMTP086A906CFB378AB229C2D8AEBF0@CEZ.ICE>



On Tue, 25 Apr 2006, sean wrote:
> 
> It's a fair point.  But adding a separate database to augment the core 
> information has some downsides.  That is, that information isn't pulled, 
> cloned, or pushed automatically; it doesn't get to ride for free on top 
> of the core.

But the point is, we don't generally _want_ to pull, push, or clone this 
crud.

I for one would literally have to add code to say "if any commit we poll 
has this random field, I refuse to pull". 

There's two ways to have true interoperability (and in a distributed 
system, that's the thing that matters):

 - keep on piling on the sh*t
 - keep it simple so that people know exactly what the rules are.

Guess which one I am religiously in favour of.

That's my whole point: the "rules" for this suggested "prior" or "related" 
field simply don't exist, and it doesn't even seem to be the case that 
people can agree what it _means_ in that nobody has actually explained 
what the thing would do and why you would use it.

If you cannot explain to the other side what a field is used for, then 
that field - by definition - is not useful for the other side. It will 
just result in confusion, because different users will have different 
notions of what to do with the field (if anything).

So some users might consider it to have meaning, and actually do different 
things when it exists. Others would ignore it entirely. Yet thirds would 
ignore it, but consider it a link that must exist - which would break 
whenever those people would interact with the people who ignore it, and 
think that it's superfluous.

This is why it has to have real meaning. If there are no rules, things 
will break. Some things will pull them, others won't, yet third things 
will do random things.

If you just want to have something that "follows" an archive, it's easy 
enough to do: have a totally separate ref, that is a real branch, but may 
not even contain any files at all. You can - perfectly validly - have a 
chain of commits where all the information is in the "free-form" text area 
as far as git is concerned, but where the trees are all empty.

You'll find that all git users can pull such a commit, and you can use all 
the normal git ops on them, and you can hide your own metadata in there. 
And it would still be a valid git tree - your metadata would be your 
private thing, and you can keep it along-side the "normal" git data, and 
you can have your own "extended fsck", and "git pull/push" still continues 
to work. 

Junio does something like that with the "todo" branch, for example (it's 
human-readable, not automated, but that doesn't really change anything). 
You can do

	git ls-tree todo
	git cat-file blob todo:Porcelainistas | less -S

and in general do anything you damn well please there. WITHOUT making 
up any new (and unnecessary) format semantics that nobody else cares 
about and that don't have very well-specified meaning.

		Linus

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Linus Torvalds @ 2006-04-25 17:11 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <e2lijt$aco$1@sea.gmane.org>



On Tue, 25 Apr 2006, Jakub Narebski wrote:
> 
> The generic commit links "related" which is fsck-able at least and "note"
> which is not. It is idea somewhat on the level of providing _extended
> attributes_ in VFS in Linux kernel, IMVHO.

And nobody actually uses extended attributes either, do they?

Plus it's _not_ fsck'able, since the thing doesn't even have any valid 
semantics. You guys can't even agree on whether the object must exist or 
not. 

Anyway, I'm not interested. I'm violently opposed to the mess that is 
darcs and other crapola. The WHOLE point of git is to have well-defined 
semantics and get away from the horrors that other systems have done, 
where they have allowed any random crap to "make sense". 

If you want darcs-like semantics where there are no rules, just use darcs, 
for chrissake! And if you want to base it on git because you've noticed 
that git is (a) stable, (b) fast and (c) has developed remarkably well, 
then think for a second _why_ git is stable, fast, and well-developed. 
It's that exactly because it has clear semantics, and no room for random 
crud.

Git tracks contents, and the well-defined history of how those contents 
came to be. Git does NOT track "additional notes" left by the developer 
that have weak semantics. Git does not track when a developer says "I 
renamed a file".

For exactly the same reason, git should not track it when a developer says 
"I think this commit is related to that commit". It's not hard data, that 
has hard and clear semantics.

Once you start adding data that has no clear semantics, you're screwed. At 
that point, it's a "track guesses" game, not a "track contents" game.

			Linus

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Jakub Narebski @ 2006-04-25 17:36 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.64.0604251004410.3701@g5.osdl.org>

Linus Torvalds wrote:

> On Tue, 25 Apr 2006, Jakub Narebski wrote:
>> 
>> The generic commit links "related" which is fsck-able at least and "note"
>> which is not. It is idea somewhat on the level of providing _extended
>> attributes_ in VFS in Linux kernel, IMVHO.
> 
> And nobody actually uses extended attributes either, do they?

Fedora's SELinux does use them, IIRC.

Well, people do use X-* headers in mail (sean's example), and some of them
got promoted from X-* to ordinary mail header status.

> Plus it's _not_ fsck'able, since the thing doesn't even have any valid
> semantics. You guys can't even agree on whether the object must exist or
> not.

Erm, further on we did agree 
  http://permalink.gmane.org/gmane.comp.version-control.git/19142
  (Message-Id: <7vmzeax9gj.fsf@assigned-by-dhcp.cox.net>). 
"related" links means that object must exist. "note" is what name says, just
note and doesn't even need to point to object.

> For exactly the same reason, git should not track it when a developer says
> "I think this commit is related to that commit". It's not hard data, that
> has hard and clear semantics.
> 
> Once you start adding data that has no clear semantics, you're screwed. At
> that point, it's a "track guesses" game, not a "track contents" game.

Well, the best example, i.e. remembering cherry picking has well defined
semantic (added when cherry-picking, used when merging, object does need
not to exist) but not well defined form. Currently the convention for
free-form is used, which has its advantages and disadvantages as pointed
out by Junio.


[somewhat unrelated note]
> Git tracks contents, and the well-defined history of how those contents
> came to be. Git does NOT track "additional notes" left by the developer
> that have weak semantics. Git does not track when a developer says "I
> renamed a file".

But I'd like Git to remember when I corrected false positives in "rename"
detection during merge, and added undetected automatically renames/file
contents copying and/or moving. Whether it would be done by saving the
information in commit header, commit free-for, or somewhere else...

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: sean @ 2006-04-25 17:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: jnareb, git
In-Reply-To: <Pine.LNX.4.64.0604251004410.3701@g5.osdl.org>

On Tue, 25 Apr 2006 10:11:13 -0700 (PDT)
Linus Torvalds <torvalds@osdl.org> wrote:

> Once you start adding data that has no clear semantics, you're screwed. At 
> that point, it's a "track guesses" game, not a "track contents" game.

Then shouldn't Git stop tracking commit comments; they're just developer
guesses. ;o)   Adding a free-form header is no different than adding a 
few more lines of free form text at the bottom of the commit message, in 
neither case does it change the nice clean git semantics.

Sean

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Linus Torvalds @ 2006-04-25 17:57 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <e2lmm3$rts$1@sea.gmane.org>



On Tue, 25 Apr 2006, Jakub Narebski wrote:
> 
> Erm, further on we did agree 

Hell no "we" didn't.

Since I totally refuse to touch anything like that.

I even told you exactly why, for things like the suggested "cherry-pick" 
thing.

Which still remains the "best" example. And I say "best", because as an 
example it totally sucks. Again, for reasons I made very clear.

The fact is, there is _zero_ reason for this field to exist. Nobody has 
actually mentioned a single use that is really valid and that people can 
agree on across different uses.

So here's the challenge: name _one_ thing that people actually can agree 
on, and that adds real measurable _value_ from a core git standpoint. 
Something where the semantics actually change what git does.

The "track it with pull/push" thing is NOT one such thing, however much 
you protest. We already _have_ that thing. It's called a "ref", and it's 
really really easy to create anywhere in .git/refs/, and the tools already 
know how to use it.

		Linus

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Linus Torvalds @ 2006-04-25 18:06 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0604251053100.3701@g5.osdl.org>



On Tue, 25 Apr 2006, Linus Torvalds wrote:
> 
> The "track it with pull/push" thing is NOT one such thing, however much 
> you protest. We already _have_ that thing. It's called a "ref", and it's 
> really really easy to create anywhere in .git/refs/, and the tools already 
> know how to use it.

Btw, there are other cases for that. For example, "parent" is a 
well-specified thing that actually has very clear and unambiguous meaning. 

And we had a much better proposals (in the sense that it had real 
suggested _meaning_ and semantics) over the last few months for things 
like sub-projects (trees that point to other commits) or last year a 
discussion about "container objects" (like the current tags, but listing 
multiple objects instead of just one).

All of which had clear and unambiguous semantics (but were not done for 
other reasons - maybe the sub-project still remains on the horizon, the 
"container objects" thing doesn't seem to have gone anywhere).

			Linus

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Linus Torvalds @ 2006-04-25 18:08 UTC (permalink / raw)
  To: sean; +Cc: jnareb, git
In-Reply-To: <BAYC1-PASMTP091348C4C33C5A0E83C012AEBF0@CEZ.ICE>



On Tue, 25 Apr 2006, sean wrote:

> On Tue, 25 Apr 2006 10:11:13 -0700 (PDT)
> Linus Torvalds <torvalds@osdl.org> wrote:
> 
> > Once you start adding data that has no clear semantics, you're screwed. At 
> > that point, it's a "track guesses" game, not a "track contents" game.
> 
> Then shouldn't Git stop tracking commit comments; they're just developer
> guesses. ;o)

No, they are pure content, and git doesn't actually give them any semantic 
meaning.

WHICH IS OK. I even suggested that you put this thing into that "pure 
content" part.

> Adding a free-form header is no different than adding a few more lines 
> of free form text at the bottom of the commit message, in neither case 
> does it change the nice clean git semantics.

Which is exactly what I told you to do. Just don't make it a git header. 

We do that already. Look at "git revert". Ooh. Aah. It works today.

Just don't make it something that changes semantics, and that git parses 
and "understands". Because git clearly doesn't understand it at all, since 
you didn't define it to have any meaning that _can_ be understood.

		Linus

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: sean @ 2006-04-25 18:14 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: jnareb, git
In-Reply-To: <Pine.LNX.4.64.0604251106400.3701@g5.osdl.org>

On Tue, 25 Apr 2006 11:08:31 -0700 (PDT)
Linus Torvalds <torvalds@osdl.org> wrote:

> Which is exactly what I told you to do. Just don't make it a git header. 

Well I just don't see how making it a header, or plopping it at the
end of a commit message makes an iota of difference to git, while it 
can help porcelain.

> We do that already. Look at "git revert". Ooh. Aah. It works today.

Nice.  Gotta love git.
 
> Just don't make it something that changes semantics, and that git parses 
> and "understands". Because git clearly doesn't understand it at all, since 
> you didn't define it to have any meaning that _can_ be understood.

But that's exactly the point, it's no different than extending git to be
able to store more than one comment.   Comment1 Comment2 Comment3.  
Pure content that git need not give any semantic meaning.  Git has a 
limitation of only a single comment today, there's no semantic damage
to extending git to allow multiple comments.   And there are a few 
applications, like bug tracking etc, which could use such a feature 
to good effect.

Sean

^ permalink raw reply

* Re: RFC: New diff-delta.c implementation
From: Rene Scharfe @ 2006-04-25 18:22 UTC (permalink / raw)
  To: Geert Bosch; +Cc: Git Mailing List, Junio C Hamano
In-Reply-To: <20060424025741.GA636@adacore.com>

Geert Bosch schrieb:
> On Sat, Apr 22, 2006 at 02:36:04PM +0200, Rene Scharfe wrote:
>> You can use "indent -npro -kr -i8 -ts8 -l80 -ss -ncs" to reformat your
>> code into a similar style as used in the rest of git (settings taken
>> from Lindent which is shipped with the Linux source).
> Although I cringe at 8-space indenting, and find much of the GIT
> code close to unreadable for lack of design-level comments, I'll
> gladly reformat any code to conform to existing code standards.
> Please let me know if you've got documentation on that, as it would
> be helpful for me to know what the standard is. (No flame intended. :-)

I'm not aware of a document mandating a certain formatting.  The output
of that indent call should come close to a "standard format", because
Linus followed this style from the beginning and Junio didn't go astray.

Don't worry too much about it.  I just wanted to point out an easy way
to reformat your code to use sane indenting. :->

René

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Jakub Narebski @ 2006-04-25 18:24 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.64.0604251058490.3701@g5.osdl.org>

Linus Torvalds wrote:

> On Tue, 25 Apr 2006, Linus Torvalds wrote:
>> 
>> The "track it with pull/push" thing is NOT one such thing, however much
>> you protest. We already _have_ that thing. It's called a "ref", and it's
>> really really easy to create anywhere in .git/refs/, and the tools
>> already know how to use it.

I agree(d) that tracking pull/push with extra commit header fields is not a
good example.
 
> Btw, there are other cases for that. For example, "parent" is a
> well-specified thing that actually has very clear and unambiguous meaning.

In single parent case, "parent" means that we modified tree pointed by the
parent. Multiple parent case suggests that we combined trees pointed by
parents, most probable by merge. I'd rather we not use parent for anything
else.

> And we had a much better proposals (in the sense that it had real
> suggested _meaning_ and semantics) over the last few months for things
> like sub-projects (trees that point to other commits)

Wasn't it commits pointing to other trees (or to commits)? "bind" field
proposal suggests it. And it could be implemented using 'X-*' "related"
headers in commit.

   related a0e7d36193b96f552073558acf5fcc1f10528917 bind linux-2.6

vs. proposed

   bind f6a8248420395bc9febd66194252fc9957b0052d linux/

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Linus Torvalds @ 2006-04-25 18:26 UTC (permalink / raw)
  To: sean; +Cc: jnareb, git
In-Reply-To: <BAYC1-PASMTP04D82622D9D5DA7E352079AEBF0@CEZ.ICE>



On Tue, 25 Apr 2006, sean wrote:

> On Tue, 25 Apr 2006 11:08:31 -0700 (PDT)
> Linus Torvalds <torvalds@osdl.org> wrote:
> 
> > Which is exactly what I told you to do. Just don't make it a git header. 
> 
> Well I just don't see how making it a header, or plopping it at the
> end of a commit message makes an iota of difference to git, while it 
> can help porcelain.

It can't help porcelain.

If we have undefined or bad semantics for it, the only thing it can do is 
_hurt_ porcelain, because it will cause confusion down the line.

Semantics for data objects are _the_ most important part of a SCM. Pretty 
much any project, in fact. 

And bad or weakly defined semantics will invariably cause problems later.

> But that's exactly the point, it's no different than extending git to be
> able to store more than one comment.

So why argue for it?

Just use the existing comment field.

		Linus

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Jakub Narebski @ 2006-04-25 18:34 UTC (permalink / raw)
  To: git
In-Reply-To: <BAYC1-PASMTP04D82622D9D5DA7E352079AEBF0@CEZ.ICE>

sean wrote:

> On Tue, 25 Apr 2006 11:08:31 -0700 (PDT)
> Linus Torvalds <torvalds@osdl.org> wrote:
> 
>> Which is exactly what I told you to do. Just don't make it a git header.
> 
> Well I just don't see how making it a header, or plopping it at the
> end of a commit message makes an iota of difference to git, while it 
> [storing information in X-* like header] can help porcelain.

And [graphical] history browsers like gitk or qgit.

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Jakub Narebski @ 2006-04-25 18:41 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.64.0604251125010.3701@g5.osdl.org>

Linus Torvalds wrote:

> So why argue for it?
> 
> Just use the existing comment field.

For the same reason there exist X-* _header_ fields in email.

Additionally, in "related" links we require that object exist (core git),
regardless of detailed semantics.

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: sean @ 2006-04-25 18:45 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: jnareb, git
In-Reply-To: <Pine.LNX.4.64.0604251125010.3701@g5.osdl.org>

On Tue, 25 Apr 2006 11:26:25 -0700 (PDT)
Linus Torvalds <torvalds@osdl.org> wrote:

> It can't help porcelain.
> 
> If we have undefined or bad semantics for it, the only thing it can do is 
> _hurt_ porcelain, because it will cause confusion down the line.
> 
> Semantics for data objects are _the_ most important part of a SCM. Pretty 
> much any project, in fact. 
> 
> And bad or weakly defined semantics will invariably cause problems later.

Take your example of how git-revert works today, it copies the comment from 
the original, thus keeping this semantic-free meta-data intact between
related commits.  However, you'd have to jump through hoops to accomplish
this same simple task with any third party meta data, unless it was 
burried inside the commit message text.
 
> So why argue for it?
> 
> Just use the existing comment field.

The last argument you and I had was me taking the other side, saying that 
it was fine for git to parse the free form text area to extract information; 
you rightfully showed me why that was wrong.

It's no different for a bug tracker or other 3rd party software that wants
to interface with git, it's bad design to force them to parse a single
free form text comment into individual pieces to extract their meta data.
Especially when git could easily add the ability to add multple comments
to each commit.  

Sean

^ permalink raw reply

* Re: [RFC] [PATCH 0/5] Implement 'prior' commit object links (and other commit links ideas)
From: Linus Torvalds @ 2006-04-25 18:52 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <e2lqf1$a5k$1@sea.gmane.org>



On Tue, 25 Apr 2006, Jakub Narebski wrote:
> 
> Additionally, in "related" links we require that object exist (core git),
> regardless of detailed semantics.

And as I've now mentioned a hundred times, that's just unacceptable to me. 
No suggested use of this has actually been useful, that I can tell.

		Linus

^ permalink raw reply


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