* Re: [PATCH] diff-options: add --stat
From: Junio C Hamano @ 2006-04-13 4:54 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.63.0604130301240.28688@wbgn013.biozentrum.uni-wuerzburg.de>
Interesting.
I wonder if you can also make this an independent option that
prepends diffstat in front of the patch, just like the way the
new flag --patch-with-raw flag prepends raw output in front of
the patch.
By the way, I've been wondering if anybody uses the
GIT_EXTERNAL_DIFF interface. Does anybody miss it if we did so?
^ permalink raw reply
* Common option parsing..
From: Linus Torvalds @ 2006-04-13 1:48 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
Junio,
right now we actually haev very consistent command line options for git,
but we have two (and in your "next" branch, three) different structures
that they get parsed into, and lots of it is duplicated. We have
"diff_options", "rev_info" and now "log_info".
To make matters worse, some things aren't actually in any of them, ie
"--cc", "--abbrev" and friends actually end up being parsed into their own
private flags in diff-files. Some are in _both_ rev_info and diff_options
(the "--pretty" parsing), because both diff and rev-parse supported that
option set.
And almost all commands that take any of those options at all end up
actually taking the combination of them these days. Yeah, git-rev-parse
doesn't, but quite frankly, with your "git log --diff" changes, that's
actually the odd man out, and I think we should just make git-rev-parse
basically do it too.
And some things, like doing a builtin "git diff" would actually be quite
easy to do, except for the fact that having three different option parsers
_and_ having some options you parse by hand on top of that is just crazy
("git diff" wants even the stage diff flags that git-diff-files takes).
The easiest way to just solve all this mess would be to
- add the diff-options into "struct rev_list" and make the
"setup_revisions()" parser parse the diff flags too.
- get rid of "log_info" and "diff_options"
- possibly rename the resulting super-options structure as "struct
git_options" or something if we want to.
At that point, it would become a lot easier to do things like a built-in
"git diff", where command line parsing really is the biggest deal. It
would become something like this:
struct rev_info revs;
struct commit *src, *dst;
if (setup_revisions(&revs))
die(git_diff_usage);
/* No revision arguments: git-diff-files */
if (!revs->commits)
return diff_files(&revs);
src = revs->commits->item;
revs->commits = revs->commits->next;
/* Just one rev: git-diff-index against that */
if (!revs->commits)
return diff_index(&revs, src);
dst = revs->commits->item;
revs->commits = revs->commits->next;
/*
* More than two revs? Maybe that means a combined diff?
* Some day.. In the meantime, just make it an error.
*/
if (revs->commits->next)
die(git_diff_usage);
/*
* If it was "a..b" using git-rev-parse, the second commit
* on the list is the initial (and uninteresting) one, we
* need to make that the source..
*/
if (dst->object.flags & UNINTERESTING) {
struct commit *tmp = dst;
dst = src;
src = tmp;
}
return diff_trees(&revs, src, dst);
where obviously we'd need to do some minor moving-around to make
"diff_files()" be a function interface, but I actually did that, and it
was really trivial. The bigger part would be to just change the structures
around (which could be done first as a fairly big but trivial patch, kind
of the same way the initial "struct rev_info" was done when the
"revision.c" file was split away).
What do you think?
Linus
^ permalink raw reply
* Re: [PATCH] diff-options: add --stat
From: Johannes Schindelin @ 2006-04-13 1:32 UTC (permalink / raw)
To: git, junkio
In-Reply-To: <Pine.LNX.4.63.0604130308150.11360@wbgn013.biozentrum.uni-wuerzburg.de>
Hi,
On Thu, 13 Apr 2006, Johannes Schindelin wrote:
> I just realized that something is wrong with this patch: the first file
> of the patchset seems to be ignored. I'll fix it tomorrow.
Okay, so I lied: I fixed it today.
diff --git a/diff-tree.c b/diff-tree.c
index 2b79dd0..536da8e 100644
--- a/diff-tree.c
+++ b/diff-tree.c
@@ -117,7 +117,8 @@ int main(int argc, const char **argv)
if (opt->dense_combined_merges)
opt->diffopt.output_format = DIFF_FORMAT_PATCH;
- if (opt->diffopt.output_format == DIFF_FORMAT_PATCH)
+ if (opt->diffopt.output_format == DIFF_FORMAT_DIFFSTAT ||
+ opt->diffopt.output_format == DIFF_FORMAT_PATCH)
opt->diffopt.recursive = 1;
diff_tree_setup_paths(get_pathspec(prefix, argv), opt);
diff --git a/git.c b/git.c
index 5cb0d32..e4fcf92 100644
--- a/git.c
+++ b/git.c
@@ -344,7 +344,8 @@ static int cmd_log(int argc, const char
opt.ignore_merges = 0;
if (opt.dense_combined_merges)
opt.diffopt.output_format = DIFF_FORMAT_PATCH;
- if (opt.diffopt.output_format == DIFF_FORMAT_PATCH)
+ if (opt.diffopt.output_format == DIFF_FORMAT_DIFFSTAT ||
+ opt.diffopt.output_format == DIFF_FORMAT_PATCH)
opt.diffopt.recursive = 1;
if (!full_diff && rev.prune_data)
diff_tree_setup_paths(rev.prune_data, &opt.diffopt);
^ permalink raw reply related
* Re: [PATCH] diff-options: add --stat
From: Johannes Schindelin @ 2006-04-13 1:15 UTC (permalink / raw)
To: git, junkio
In-Reply-To: <Pine.LNX.4.63.0604130301240.28688@wbgn013.biozentrum.uni-wuerzburg.de>
Hi,
I just realized that something is wrong with this patch: the first file
of the patchset seems to be ignored. I'll fix it tomorrow.
Ciao,
Dscho
^ permalink raw reply
* [PATCH] diff-options: add --stat
From: Johannes Schindelin @ 2006-04-13 1:02 UTC (permalink / raw)
To: git, junkio
Now you can say "git diff --stat" (to get an idea how many changes are
uncommitted), or "git log --stat" (to get an idea how many changes were
committed).
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---
Probably it would be nicer to pass down the diff_options to
builtin_diff(), run_diff() and run_diff_cmd(), but I am *way*
too tired to change that now.
It would have been nice to not just rip out and modify the diffstat
code from apply.c, but I did not want to fake patch structures.
Maybe someone more intelligent than me wants to fix this...
Documentation/diff-options.txt | 3
diff.c | 250 ++++++++++++++++++++++++++++++++++------
diff.h | 3
git-diff.sh | 6 +
4 files changed, 222 insertions(+), 40 deletions(-)
c706aa10bc5e2e2e22fb07aeaff1418f3d4caee0
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 338014c..447e522 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -7,6 +7,9 @@
--patch-with-raw::
Generate patch but keep also the default raw diff output.
+--stat::
+ Generate a diffstat instead of a patch.
+
-z::
\0 line termination on output
diff --git a/diff.c b/diff.c
index a14e664..7f2b652 100644
--- a/diff.c
+++ b/diff.c
@@ -177,6 +177,7 @@ static int fill_mmfile(mmfile_t *mf, str
struct emit_callback {
const char **label_path;
+ struct diffstat_t *diffstat;
};
static int fn_out(void *priv, mmbuffer_t *mb, int nbuf)
@@ -195,6 +196,150 @@ static int fn_out(void *priv, mmbuffer_t
return 0;
}
+struct diffstat_t {
+ int nr;
+ int alloc;
+ struct diffstat_file {
+ char *name;
+ unsigned int added, deleted;
+ } **files;
+};
+
+static int fn_diffstat(void *priv, mmbuffer_t *mb, int nbuf)
+{
+ int i;
+ struct emit_callback *data = priv;
+ struct diffstat_file *x;
+ struct diffstat_t *diffstat = data->diffstat;
+
+ if (data->label_path[0]) {
+ x = xcalloc(sizeof (*x), 1);
+ if (diffstat->nr == diffstat->alloc) {
+ diffstat->alloc = alloc_nr(diffstat->alloc);
+ diffstat->files = xrealloc(diffstat->files,
+ diffstat->alloc * sizeof(x));
+ }
+ diffstat->files[diffstat->nr++] = x;
+ x->name = strdup(data->label_path[0] + 2);
+ data->label_path[0] = data->label_path[1] = NULL;
+ } else
+ x = diffstat->files[diffstat->nr - 1];
+
+ for (i = 0; i < nbuf; i++)
+ if (mb[i].ptr[0] == '+')
+ x->added++;
+ else if (mb[i].ptr[0] == '-')
+ x->deleted++;
+ return 0;
+}
+
+static void diffstat_binary(struct diffstat_t *diffstat, const char *name)
+{
+ struct diffstat_file *x = xcalloc(sizeof (*x), 1);
+ if (diffstat->nr == diffstat->alloc) {
+ diffstat->alloc = alloc_nr(diffstat->alloc);
+ diffstat->files = xrealloc(diffstat->files,
+ diffstat->alloc * sizeof(x));
+ }
+ diffstat->files[diffstat->nr++] = x;
+ x->name = strdup(name + 2);
+ x->added = -1;
+}
+
+static const char pluses[] = "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
+static const char minuses[]= "----------------------------------------------------------------------";
+
+static void show_stats(struct diffstat_t* data)
+{
+ char *prefix = "";
+ int i, len, add, del, total, adds = 0, dels = 0;
+ int max, max_change = 0, max_len = 0;
+ int total_files = data->nr;
+
+ if (data->nr == 0)
+ return;
+
+ printf("---\n");
+
+ for (i = 0; i < data->nr; i++) {
+ struct diffstat_file *file = data->files[i];
+
+ if (max_change < file->added + file->deleted)
+ max_change = file->added + file->deleted;
+ len = strlen(file->name);
+ if (max_len < len)
+ max_len = len;
+ }
+
+ for (i = 0; i < data->nr; i++) {
+ char *name = data->files[i]->name;
+ int added = data->files[i]->added;
+ int deleted = data->files[i]->deleted;
+
+ if (0 < (len = quote_c_style(name, NULL, NULL, 0))) {
+ char *qname = xmalloc(len + 1);
+ quote_c_style(name, qname, NULL, 0);
+ free(name);
+ name = qname;
+ }
+
+ /*
+ * "scale" the filename
+ */
+ len = strlen(name);
+ max = max_len;
+ if (max > 50)
+ max = 50;
+ if (len > max) {
+ char *slash;
+ prefix = "...";
+ max -= 3;
+ name += len - max;
+ slash = strchr(name, '/');
+ if (slash)
+ name = slash;
+ }
+ len = max;
+
+ /*
+ * scale the add/delete
+ */
+ max = max_change;
+ if (max + len > 70)
+ max = 70 - len;
+
+ if (added < 0) {
+ /* binary file */
+ printf(" %s%-*s | Bin\n", prefix, len, name);
+ continue;
+ } else if (added + deleted == 0) {
+ total_files--;
+ continue;
+ }
+
+ add = added;
+ del = deleted;
+ total = add + del;
+ adds += add;
+ dels += del;
+
+ if (max_change > 0) {
+ total = (total * max + max_change / 2) / max_change;
+ add = (add * max + max_change / 2) / max_change;
+ del = total - add;
+ }
+ /* TODO: binary */
+ printf(" %s%-*s |%5d %.*s%.*s\n", prefix,
+ len, name, added + deleted,
+ add, pluses, del, minuses);
+ free(name);
+ free(data->files[i]);
+ }
+ free(data->files);
+ printf(" %d files changed, %d insertions(+), %d deletions(-)\n",
+ total_files, adds, dels);
+}
+
#define FIRST_FEW_BYTES 8000
static int mmfile_is_binary(mmfile_t *mf)
{
@@ -211,7 +356,8 @@ static void builtin_diff(const char *nam
struct diff_filespec *one,
struct diff_filespec *two,
const char *xfrm_msg,
- int complete_rewrite)
+ int complete_rewrite,
+ struct diffstat_t* diffstat)
{
mmfile_t mf1, mf2;
const char *lbl[2];
@@ -221,43 +367,49 @@ static void builtin_diff(const char *nam
b_two = quote_two("b/", name_b);
lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null";
- printf("diff --git %s %s\n", a_one, b_two);
- if (lbl[0][0] == '/') {
- /* /dev/null */
- printf("new file mode %06o\n", two->mode);
- if (xfrm_msg && xfrm_msg[0])
- puts(xfrm_msg);
- }
- else if (lbl[1][0] == '/') {
- printf("deleted file mode %06o\n", one->mode);
- if (xfrm_msg && xfrm_msg[0])
- puts(xfrm_msg);
- }
- else {
- if (one->mode != two->mode) {
- printf("old mode %06o\n", one->mode);
- printf("new mode %06o\n", two->mode);
+ if (!diffstat) {
+ printf("diff --git %s %s\n", a_one, b_two);
+ if (lbl[0][0] == '/') {
+ /* /dev/null */
+ printf("new file mode %06o\n", two->mode);
+ if (xfrm_msg && xfrm_msg[0])
+ puts(xfrm_msg);
}
- if (xfrm_msg && xfrm_msg[0])
- puts(xfrm_msg);
- /*
- * we do not run diff between different kind
- * of objects.
- */
- if ((one->mode ^ two->mode) & S_IFMT)
- goto free_ab_and_return;
- if (complete_rewrite) {
- emit_rewrite_diff(name_a, name_b, one, two);
- goto free_ab_and_return;
+ else if (lbl[1][0] == '/') {
+ printf("deleted file mode %06o\n", one->mode);
+ if (xfrm_msg && xfrm_msg[0])
+ puts(xfrm_msg);
}
+ else {
+ if (one->mode != two->mode) {
+ printf("old mode %06o\n", one->mode);
+ printf("new mode %06o\n", two->mode);
+ }
+ if (xfrm_msg && xfrm_msg[0])
+ puts(xfrm_msg);
+ /*
+ * we do not run diff between different kind
+ * of objects.
+ */
+ if ((one->mode ^ two->mode) & S_IFMT)
+ goto free_ab_and_return;
+ if (complete_rewrite) {
+ emit_rewrite_diff(name_a, name_b, one, two);
+ goto free_ab_and_return;
+ }
+ }
}
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
die("unable to read files to diff");
- if (mmfile_is_binary(&mf1) || mmfile_is_binary(&mf2))
- printf("Binary files %s and %s differ\n", lbl[0], lbl[1]);
- else {
+ if (mmfile_is_binary(&mf1) || mmfile_is_binary(&mf2)) {
+ if (diffstat)
+ diffstat_binary(diffstat, lbl[0]);
+ else
+ printf("Binary files %s and %s differ\n",
+ lbl[0], lbl[1]);
+ } else {
/* Crazy xdl interfaces.. */
const char *diffopts = getenv("GIT_DIFF_OPTS");
xpparam_t xpp;
@@ -266,6 +418,7 @@ static void builtin_diff(const char *nam
struct emit_callback ecbdata;
ecbdata.label_path = lbl;
+ ecbdata.diffstat = diffstat;
xpp.flags = XDF_NEED_MINIMAL;
xecfg.ctxlen = 3;
xecfg.flags = XDL_EMIT_FUNCNAMES;
@@ -275,7 +428,7 @@ static void builtin_diff(const char *nam
xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
else if (!strncmp(diffopts, "-u", 2))
xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
- ecb.outf = fn_out;
+ ecb.outf = diffstat ? fn_diffstat : fn_out;
ecb.priv = &ecbdata;
xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);
}
@@ -690,16 +843,19 @@ static void run_diff_cmd(const char *pgm
struct diff_filespec *one,
struct diff_filespec *two,
const char *xfrm_msg,
- int complete_rewrite)
+ int complete_rewrite,
+ struct diffstat_t *diffstat)
{
if (pgm) {
+ if (diffstat)
+ die ("Cannot use diffstat with external diff");
run_external_diff(pgm, name, other, one, two, xfrm_msg,
complete_rewrite);
return;
}
if (one && two)
builtin_diff(name, other ? other : name,
- one, two, xfrm_msg, complete_rewrite);
+ one, two, xfrm_msg, complete_rewrite, diffstat);
else
printf("* Unmerged path %s\n", name);
}
@@ -733,7 +889,8 @@ static void run_diff(struct diff_filepai
if (DIFF_PAIR_UNMERGED(p)) {
/* unmerged */
- run_diff_cmd(pgm, p->one->path, NULL, NULL, NULL, NULL, 0);
+ run_diff_cmd(pgm, p->one->path, NULL, NULL, NULL, NULL, 0,
+ o->diffstat);
return;
}
@@ -805,15 +962,17 @@ static void run_diff(struct diff_filepai
* needs to be split into deletion and creation.
*/
struct diff_filespec *null = alloc_filespec(two->path);
- run_diff_cmd(NULL, name, other, one, null, xfrm_msg, 0);
+ run_diff_cmd(NULL, name, other, one, null, xfrm_msg, 0,
+ o->diffstat);
free(null);
null = alloc_filespec(one->path);
- run_diff_cmd(NULL, name, other, null, two, xfrm_msg, 0);
+ run_diff_cmd(NULL, name, other, null, two, xfrm_msg, 0,
+ o->diffstat);
free(null);
}
else
run_diff_cmd(pgm, name, other, one, two, xfrm_msg,
- complete_rewrite);
+ complete_rewrite, o->diffstat);
free(name_munged);
free(other_munged);
@@ -866,6 +1025,8 @@ int diff_opt_parse(struct diff_options *
options->output_format = DIFF_FORMAT_PATCH;
options->with_raw = 1;
}
+ else if (!strcmp(arg, "--stat"))
+ options->output_format = DIFF_FORMAT_DIFFSTAT;
else if (!strcmp(arg, "-z"))
options->line_termination = 0;
else if (!strncmp(arg, "-l", 2))
@@ -1291,6 +1452,7 @@ static void flush_one_pair(struct diff_f
break;
default:
switch (diff_output_format) {
+ case DIFF_FORMAT_DIFFSTAT:
case DIFF_FORMAT_PATCH:
diff_flush_patch(p, options);
break;
@@ -1316,6 +1478,12 @@ void diff_flush(struct diff_options *opt
struct diff_queue_struct *q = &diff_queued_diff;
int i;
int diff_output_format = options->output_format;
+ struct diffstat_t *diffstat = NULL;
+
+ if (diff_output_format == DIFF_FORMAT_DIFFSTAT) {
+ diffstat = xcalloc(sizeof (struct diffstat_t), 1);
+ options->diffstat = diffstat;
+ }
if (options->with_raw) {
for (i = 0; i < q->nr; i++) {
@@ -1329,6 +1497,12 @@ void diff_flush(struct diff_options *opt
flush_one_pair(p, diff_output_format, options);
diff_free_filepair(p);
}
+
+ if (diffstat) {
+ show_stats(diffstat);
+ free(diffstat);
+ }
+
free(q->queue);
q->queue = NULL;
q->nr = q->alloc = 0;
diff --git a/diff.h b/diff.h
index 236095f..5c1526c 100644
--- a/diff.h
+++ b/diff.h
@@ -44,6 +44,7 @@ struct diff_options {
int *pathlens;
change_fn_t change;
add_remove_fn_t add_remove;
+ struct diffstat_t *diffstat;
};
extern void diff_tree_setup_paths(const char **paths, struct diff_options *);
@@ -119,6 +120,7 @@ #define COMMON_DIFF_OPTIONS_HELP \
" -u synonym for -p.\n" \
" --patch-with-raw\n" \
" output both a patch and the diff-raw format.\n" \
+" --stat show diffstat instead of patch.\n" \
" --name-only show only names of changed files.\n" \
" --name-status show names and status of changed files.\n" \
" --full-index show full object name on index lines.\n" \
@@ -142,6 +144,7 @@ #define DIFF_FORMAT_PATCH 2
#define DIFF_FORMAT_NO_OUTPUT 3
#define DIFF_FORMAT_NAME 4
#define DIFF_FORMAT_NAME_STATUS 5
+#define DIFF_FORMAT_DIFFSTAT 6
extern void diff_flush(struct diff_options*);
diff --git a/git-diff.sh b/git-diff.sh
index dc0dd31..0fe6770 100755
--- a/git-diff.sh
+++ b/git-diff.sh
@@ -30,9 +30,11 @@ case " $flags " in
cc_or_p=--cc ;;
esac
-# If we do not have --name-status, --name-only, -r, or -c default to --cc.
+# If we do not have --name-status, --name-only, -r, -c or --stat,
+# default to --cc.
case " $flags " in
-*" '--name-status' "* | *" '--name-only' "* | *" '-r' "* | *" '-c' "* )
+*" '--name-status' "* | *" '--name-only' "* | *" '-r' "* | *" '-c' "* | \
+*" '--stat' "*)
;;
*)
flags="$flags'$cc_or_p' " ;;
--
1.2.0.gd507-dirty
^ permalink raw reply related
* [PATCH 1/3] Add a testsuite framework copied from git-core
From: Yann Dirson @ 2006-04-12 21:21 UTC (permalink / raw)
To: git
In-Reply-To: <20060412211633.14579.98008.stgit@gandelf.nowhere.earth>
From: <>
---
t/Makefile | 25 ++++++
t/t0000-dummy.sh | 17 ++++
t/test-lib.sh | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 251 insertions(+), 0 deletions(-)
diff --git a/t/Makefile b/t/Makefile
new file mode 100644
index 0000000..d5d7b6f
--- /dev/null
+++ b/t/Makefile
@@ -0,0 +1,25 @@
+# Run tests
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+
+#GIT_TEST_OPTS=--verbose --debug
+SHELL_PATH ?= $(SHELL)
+TAR ?= $(TAR)
+
+# Shell quote;
+SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
+
+T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
+
+all: $(T) clean
+
+$(T):
+ @echo "*** $@ ***"; '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
+
+clean:
+ rm -fr trash
+
+.PHONY: $(T) clean
+.NOPARALLEL:
+
diff --git a/t/t0000-dummy.sh b/t/t0000-dummy.sh
new file mode 100755
index 0000000..ae4f838
--- /dev/null
+++ b/t/t0000-dummy.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Yann Dirson
+#
+
+test_description='dummy test.
+
+Only to test the testing environment.
+'
+
+. ./test-lib.sh
+
+test_expect_success \
+ 'check stgit can be run' \
+ 'stg version'
+
+test_done
diff --git a/t/test-lib.sh b/t/test-lib.sh
new file mode 100755
index 0000000..b1ac350
--- /dev/null
+++ b/t/test-lib.sh
@@ -0,0 +1,209 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+# Copyright (c) 2006 Yann Dirson
+#
+
+# For repeatability, reset the environment to known value.
+LANG=C
+LC_ALL=C
+PAGER=cat
+TZ=UTC
+export LANG LC_ALL PAGER TZ
+unset AUTHOR_DATE
+unset AUTHOR_EMAIL
+unset AUTHOR_NAME
+unset COMMIT_AUTHOR_EMAIL
+unset COMMIT_AUTHOR_NAME
+unset GIT_ALTERNATE_OBJECT_DIRECTORIES
+unset GIT_AUTHOR_DATE
+GIT_AUTHOR_EMAIL=author@example.com
+GIT_AUTHOR_NAME='A U Thor'
+unset GIT_COMMITTER_DATE
+GIT_COMMITTER_EMAIL=committer@example.com
+GIT_COMMITTER_NAME='C O Mitter'
+unset GIT_DIFF_OPTS
+unset GIT_DIR
+unset GIT_EXTERNAL_DIFF
+unset GIT_INDEX_FILE
+unset GIT_OBJECT_DIRECTORY
+unset SHA1_FILE_DIRECTORIES
+unset SHA1_FILE_DIRECTORY
+export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
+export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
+
+# Each test should start with something like this, after copyright notices:
+#
+# test_description='Description of this test...
+# This test checks if command xyzzy does the right thing...
+# '
+# . ./test-lib.sh
+
+error () {
+ echo "* error: $*"
+ trap - exit
+ exit 1
+}
+
+say () {
+ echo "* $*"
+}
+
+test "${test_description}" != "" ||
+error "Test script did not set test_description."
+
+while test "$#" -ne 0
+do
+ case "$1" in
+ -d|--d|--de|--deb|--debu|--debug)
+ debug=t; shift ;;
+ -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)
+ immediate=t; shift ;;
+ -h|--h|--he|--hel|--help)
+ echo "$test_description"
+ exit 0 ;;
+ -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
+ verbose=t; shift ;;
+ *)
+ break ;;
+ esac
+done
+
+exec 5>&1
+if test "$verbose" = "t"
+then
+ exec 4>&2 3>&1
+else
+ exec 4>/dev/null 3>/dev/null
+fi
+
+test_failure=0
+test_count=0
+
+trap 'echo >&5 "FATAL: Unexpected exit with code $?"; exit 1' exit
+
+
+# You are not expected to call test_ok_ and test_failure_ directly, use
+# the text_expect_* functions instead.
+
+test_ok_ () {
+ test_count=$(expr "$test_count" + 1)
+ say " ok $test_count: $@"
+}
+
+test_failure_ () {
+ test_count=$(expr "$test_count" + 1)
+ test_failure=$(expr "$test_failure" + 1);
+ say "FAIL $test_count: $1"
+ shift
+ echo "$@" | sed -e 's/^/ /'
+ test "$immediate" = "" || { trap - exit; exit 1; }
+}
+
+
+test_debug () {
+ test "$debug" = "" || eval "$1"
+}
+
+test_run_ () {
+ eval >&3 2>&4 "$1"
+ eval_ret="$?"
+ return 0
+}
+
+test_expect_failure () {
+ test "$#" = 2 ||
+ error "bug in the test script: not 2 parameters to test-expect-failure"
+ say >&3 "expecting failure: $2"
+ test_run_ "$2"
+ if [ "$?" = 0 -a "$eval_ret" != 0 ]
+ then
+ test_ok_ "$1"
+ else
+ test_failure_ "$@"
+ fi
+}
+
+test_expect_success () {
+ test "$#" = 2 ||
+ error "bug in the test script: not 2 parameters to test-expect-success"
+ say >&3 "expecting success: $2"
+ test_run_ "$2"
+ if [ "$?" = 0 -a "$eval_ret" = 0 ]
+ then
+ test_ok_ "$1"
+ else
+ test_failure_ "$@"
+ fi
+}
+
+test_expect_code () {
+ test "$#" = 3 ||
+ error "bug in the test script: not 3 parameters to test-expect-code"
+ say >&3 "expecting exit code $1: $3"
+ test_run_ "$3"
+ if [ "$?" = 0 -a "$eval_ret" = "$1" ]
+ then
+ test_ok_ "$2"
+ else
+ test_failure_ "$@"
+ fi
+}
+
+# Most tests can use the created repository, but some amy need to create more.
+# Usage: test_create_repo <directory>
+test_create_repo () {
+ test "$#" = 1 ||
+ error "bug in the test script: not 1 parameter to test-create-repo"
+ owd=`pwd`
+ repo="$1"
+ mkdir "$repo"
+ cd "$repo" || error "Cannot setup test environment"
+ git-init-db 2>/dev/null ||
+ error "cannot run git-init-db -- have you installed git-core?"
+ mv .git/hooks .git/hooks-disabled
+ cd "$owd"
+}
+
+test_stg_init () {
+ touch .empty
+ git-update-index --add .empty
+ git-commit -m "nearly empty start" 2>/dev/null ||
+ error "cannot run git-commit -- is your git-core funtionning?"
+ stg init ||
+ error "cannot run stg init -- have you built things yet?"
+}
+
+test_done () {
+ trap - exit
+ case "$test_failure" in
+ 0)
+ # We could:
+ # cd .. && rm -fr trash
+ # but that means we forbid any tests that use their own
+ # subdirectory from calling test_done without coming back
+ # to where they started from.
+ # The Makefile provided will clean this test area so
+ # we will leave things as they are.
+
+ say "passed all $test_count test(s)"
+ exit 0 ;;
+
+ *)
+ say "failed $test_failure among $test_count test(s)"
+ exit 1 ;;
+
+ esac
+}
+
+# Test the binaries we have just built. The tests are kept in
+# t/ subdirectory and are run in trash subdirectory.
+PATH=$(pwd)/..:$PATH
+export PATH
+
+
+# Test repository
+test=trash
+rm -fr "$test"
+test_create_repo $test
+cd "$test"
^ permalink raw reply related
* [PATCH 3/3] Add testcase for branch -r problem
From: Yann Dirson @ 2006-04-12 21:21 UTC (permalink / raw)
To: git
In-Reply-To: <20060412211633.14579.98008.stgit@gandelf.nowhere.earth>
From: <>
---
TODO | 1 +
t/t1000-branch.sh | 33 +++++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/TODO b/TODO
index a9a8b1f..365ecd4 100644
--- a/TODO
+++ b/TODO
@@ -26,3 +26,4 @@ Bugs:
- the following commands break in subdirs:
- refresh (ml: "Running StGIT in subdirectories")
+- branch renaming leaves junk behind
diff --git a/t/t1000-branch.sh b/t/t1000-branch.sh
new file mode 100755
index 0000000..4c790f5
--- /dev/null
+++ b/t/t1000-branch.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Yann Dirson
+#
+
+test_description='dummy test.
+
+Only to test the testing environment.
+'
+
+. ./test-lib.sh
+
+test_stg_init
+
+test_expect_success \
+ 'Create an stgit branch from scratch' \
+ 'stg branch -c foo &&
+ stg new p1 -m "p1"
+'
+
+test_expect_failure \
+ 'Rename the current stgit branch' \
+ 'stg branch -r foo bar
+'
+
+test_expect_success \
+ 'Rename an stgit branch' \
+ 'stg branch -c buz &&
+ stg branch -r foo bar &&
+ test -z `find .git -name foo`
+'
+
+test_done
^ permalink raw reply related
* [PATCH 2/3] Add list of bugs to TODO
From: Yann Dirson @ 2006-04-12 21:21 UTC (permalink / raw)
To: git
In-Reply-To: <20060412211633.14579.98008.stgit@gandelf.nowhere.earth>
From: <>
---
TODO | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/TODO b/TODO
index e5affe0..a9a8b1f 100644
--- a/TODO
+++ b/TODO
@@ -17,3 +17,12 @@ The future, when time allows or if someo
synchronising with other patches (diff format or in other
repositories)
- write bash-completion script for the StGIT commands
+- support for branches with / in names
+ (ml: "Handle branch names with slashes")
+- "pull" argument should default to a sane value, "origin" is wrong in
+ many cases
+
+Bugs:
+
+- the following commands break in subdirs:
+ - refresh (ml: "Running StGIT in subdirectories")
^ permalink raw reply related
* [PATCH 0/3] Add a testsuite to stgit
From: Yann Dirson @ 2006-04-12 21:16 UTC (permalink / raw)
To: git
The following steals the testsuite system from git-core and adapts it to stgit,
adds a couple of items to the TODO file, and adds a first testsuite to
demonstrate a problem with branch renaming, to serve as a non-reg test.
To run the testsuite, just "make -C t", there is no integration in the python-generated
toplevel Makefile.
--
Yann Dirson <ydirson@altern.org> |
Debian-related: <dirson@debian.org> | Support Debian GNU/Linux:
| Freedom, Power, Stability, Gratis
http://ydirson.free.fr/ | Check <http://www.debian.org/>
^ permalink raw reply
* Re: Some Commit Messages Scare git-rev-list
From: Linus Torvalds @ 2006-04-12 20:04 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Darrin Thompson
In-Reply-To: <7vy7ya37o2.fsf@assigned-by-dhcp.cox.net>
On Wed, 12 Apr 2006, Junio C Hamano wrote:
>
> [PATCH] stripspace: make sure not to leave an incomplete line.
Ack.
Linus
^ permalink raw reply
* Re: Some Commit Messages Scare git-rev-list
From: Junio C Hamano @ 2006-04-12 19:39 UTC (permalink / raw)
To: git; +Cc: Darrin Thompson, Linus Torvalds
In-Reply-To: <7v3bgi4op7.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> writes:
> We still need the "do we have anything to commit?" check by
> running "status" (which has to know what to do in different
> cases with -i/-o/-a), but there is no point appending its output
> to the proposed commit message given by the user.
BTW, this does not quite work as expected if you did something
like this:
echo -n 'incomplete line' | git commit -a -s -F -
because we would want to append the Signed-off-by: line. I am
almost tempted to say "then do not do it", but it might make
sense to do this as well.
-- >8 --
[PATCH] stripspace: make sure not to leave an incomplete line.
When dealing with a commit log message for human consumption, it
never makes sense to keep a log that ends with an incomplete
line, so make it a part of the clean-up process done with
git-stripspace.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
diff --git a/stripspace.c b/stripspace.c
index 96cd0a8..dee1ef0 100644
--- a/stripspace.c
+++ b/stripspace.c
@@ -6,9 +6,9 @@ #include <ctype.h>
* Remove empty lines from the beginning and end.
*
* Turn multiple consecutive empty lines into just one
- * empty line.
+ * empty line. Return true if it is an incomplete line.
*/
-static void cleanup(char *line)
+static int cleanup(char *line)
{
int len = strlen(line);
@@ -21,16 +21,19 @@ static void cleanup(char *line)
len--;
line[len] = 0;
} while (len > 1);
+ return 0;
}
+ return 1;
}
int main(int argc, char **argv)
{
int empties = -1;
+ int incomplete = 0;
char line[1024];
while (fgets(line, sizeof(line), stdin)) {
- cleanup(line);
+ incomplete = cleanup(line);
/* Not just an empty line? */
if (line[0] != '\n') {
@@ -44,5 +47,7 @@ int main(int argc, char **argv)
continue;
empties++;
}
+ if (incomplete)
+ putchar('\n');
return 0;
}
^ permalink raw reply related
* Re: [PATCH] Handle branch names with slashes
From: Yann Dirson @ 2006-04-12 19:16 UTC (permalink / raw)
To: Catalin Marinas; +Cc: Karl Hasselström, git
In-Reply-To: <tnxbqx6z592.fsf@arm.com>
On Fri, Feb 17, 2006 at 09:47:21AM +0000, Catalin Marinas wrote:
> Karl Hasselström <kha@treskal.com> wrote:
> > Let StGIT grok branch names with slashes in them. It used to fall flat
> > on its face when confronted with them.
>
> Thanks for the patches you sent. I'll have a look at them tomorrow.
Is this still being worked on ?
--
Yann Dirson <ydirson@altern.org> |
Debian-related: <dirson@debian.org> | Support Debian GNU/Linux:
| Freedom, Power, Stability, Gratis
http://ydirson.free.fr/ | Check <http://www.debian.org/>
^ permalink raw reply
* Re: Some Commit Messages Scare git-rev-list
From: Junio C Hamano @ 2006-04-12 18:46 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Darrin Thompson, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0604121002220.14565@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> Fixed like so..
Thanks.
> However, your script shows another problem: the "#" added at the end of
> the line for a
>
> echo -n "duh" | git-commit -F - -a
>
> seems to be because we append the "git status" output to it, and then we
> drop the lines that start with a '#', but due to the "-n", the first #
> ends up being at the end of the line.
>
> I suspect that when we get the commit message like that, we should _not_
> do any of the commit message editing at all.
True.
-- >8 --
[PATCH] git-commit: do not muck with commit message when no_edit is set.
Spotted by Linus and Darrin Thompson. When we took a commit
message from -F <file> with an incomplete line, we appended "git
status" output, which ended up attaching a lone "#" at the end.
We still need the "do we have anything to commit?" check by
running "status" (which has to know what to do in different
cases with -i/-o/-a), but there is no point appending its output
to the proposed commit message given by the user.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
git-commit.sh | 17 ++++++++++++-----
1 files changed, 12 insertions(+), 5 deletions(-)
475443c8489d9167b944367d8ec8bfef77bee0a5
diff --git a/git-commit.sh b/git-commit.sh
index 1e7c09e..bd3dc71 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -537,7 +537,7 @@ t)
;;
esac
-if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
+if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
echo "#"
echo "# It looks like you may be committing a MERGE."
echo "# If this is not correct, please remove the file"
@@ -605,16 +605,23 @@ else
current=
fi
-{
- test -z "$only_include_assumed" || echo "$only_include_assumed"
- run_status
-} >>"$GIT_DIR"/COMMIT_EDITMSG
+if test -z "$no_edit"
+then
+ {
+ test -z "$only_include_assumed" || echo "$only_include_assumed"
+ run_status
+ } >>"$GIT_DIR"/COMMIT_EDITMSG
+else
+ # we need to check if there is anything to commit
+ run_status >/dev/null
+fi
if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" -a -z "$amend" ]
then
rm -f "$GIT_DIR/COMMIT_EDITMSG"
run_status
exit 1
fi
+
case "$no_edit" in
'')
case "${VISUAL:-$EDITOR},$TERM" in
--
1.3.0.rc3.g72c1
^ permalink raw reply related
* Re: Some Commit Messages Scare git-rev-list
From: Linus Torvalds @ 2006-04-12 17:23 UTC (permalink / raw)
To: Darrin Thompson; +Cc: Git Mailing List, Junio C Hamano
In-Reply-To: <1144847462.5213.6.camel@localhost.localdomain>
On Wed, 12 Apr 2006, Darrin Thompson wrote:
>
> This scripts exhibits some odd behavior. Apparently git-rev-list
> mishandles commit messages which do not end in a newline. This as best I
> can tell this is a problem introduced since 1.1.5.
Fixed like so..
However, your script shows another problem: the "#" added at the end of
the line for a
echo -n "duh" | git-commit -F - -a
seems to be because we append the "git status" output to it, and then we
drop the lines that start with a '#', but due to the "-n", the first #
ends up being at the end of the line.
I suspect that when we get the commit message like that, we should _not_
do any of the commit message editing at all.
That's a separate issue, though, and not fixed by this patch.
Linus
---
diff --git a/commit.c b/commit.c
index d534c9b..c7bb8db 100644
--- a/commit.c
+++ b/commit.c
@@ -400,11 +400,11 @@ static int get_one_line(const char *msg,
while (len--) {
char c = *msg++;
+ if (!c)
+ break;
ret++;
if (c == '\n')
break;
- if (!c)
- return 0;
}
return ret;
}
^ permalink raw reply related
* Re: Adding color to git diff output.
From: Alex Riesen @ 2006-04-12 15:52 UTC (permalink / raw)
To: Linus Torvalds; +Cc: sean, junkio, git
In-Reply-To: <Pine.LNX.4.64.0604120846000.14565@g5.osdl.org>
On 4/12/06, Linus Torvalds <torvalds@osdl.org> wrote:
> >
> > Maybe use "-t" here? I have at least one system which has no tty installed.
> > Like this:
> >
> > if [ -n "$GIT_DIFF_PAGER" -a -t ]; then
>
> I assume you mean "-t 1". It needs the FD number. But yes.
>
yes, tpyo
(bash doesn't give an error here, btw. Just always 0)
^ permalink raw reply
* Re: Adding color to git diff output.
From: Linus Torvalds @ 2006-04-12 15:46 UTC (permalink / raw)
To: Alex Riesen; +Cc: sean, junkio, git
In-Reply-To: <81b0412b0604120038q2e4aef8cn55ba4cfa68e18b34@mail.gmail.com>
On Wed, 12 Apr 2006, Alex Riesen wrote:
>
> Maybe use "-t" here? I have at least one system which has no tty installed.
> Like this:
>
> if [ -n "$GIT_DIFF_PAGER" -a -t ]; then
I assume you mean "-t 1". It needs the FD number. But yes.
Linus
^ permalink raw reply
* Re: how to make a git-format patch
From: Mathieu Chouquet-Stringer @ 2006-04-12 14:04 UTC (permalink / raw)
To: Aubrey; +Cc: git
In-Reply-To: <6d6a94c50604120328ufa09f0do76c04472206ae15f@mail.gmail.com>
aubreylee@gmail.com (Aubrey) writes:
> But I saw most of the git-format patches have a header in the front of
> the patch file, like:
I believe you're talking about 'git whatchanged -p' which not only displays
the diffs but also the commit comments.
--
Mathieu Chouquet-Stringer
^ permalink raw reply
* Some Commit Messages Scare git-rev-list
From: Darrin Thompson @ 2006-04-12 13:11 UTC (permalink / raw)
To: git
This scripts exhibits some odd behavior. Apparently git-rev-list
mishandles commit messages which do not end in a newline. This as best I
can tell this is a problem introduced since 1.1.5.
Here is a script to reproduce the problem:
rm -rf git-test
mkdir git-test
cd git-test
git-init-db
echo hello > hello
git-add hello
# send scary message to git-commit -F -
echo -n "test commit" | git-commit -F - -a
echo world > world
git-add world
git-update-index --add world
treeid=$(git-write-tree)
# send scary message directly to git-commit-tree
commitid=$(echo -n "another-test" | git-commit-tree $treeid -p HEAD)
git-update-ref HEAD $commitid
# see the wreckage
git-rev-list --pretty HEAD
Running gitk will also show the problem.
--
Darrin
^ permalink raw reply
* Re: how to make a git-format patch
From: Jakub Narebski @ 2006-04-12 11:12 UTC (permalink / raw)
To: git
In-Reply-To: <6d6a94c50604120328ufa09f0do76c04472206ae15f@mail.gmail.com>
Aubrey wrote:
> But I saw most of the git-format patches have a header in the front of
> the patch file, like:
> =================================
> * Added xxxxxx support
>
> Signed-off-by: xxxxxxxx <xxxxxxx@email.com>
> ---
>
> net/packet/Kconfig | 11 ++++++++++-
> 1 files changed, 10 insertions(+), 1 deletions(-)
>
> diff --git a/net/packet/Kconfig b/net/packet/Kconfig
> index 34ff93f..959c272 100644
> --- a/net/packet/Kconfig
> +++ b/net/packet/Kconfig
>
> ----snip----
> =================================
>
> Just want to know how this kind of patch format generated.
> Thanks for any hints.
Perhaps git-format-patch(1) is what you want?
--
Jakub Narebski
Warsaw, Poland
^ permalink raw reply
* how to make a git-format patch
From: Aubrey @ 2006-04-12 10:28 UTC (permalink / raw)
To: git
Hi list,
When I use GIT to generate a patch, I can use git-diff, if one file
changed, I can get the following patch:
=================================
diff --git a/net/packet/Kconfig b/net/packet/Kconfig
index 34ff93f..959c272 100644
--- a/net/packet/Kconfig
+++ b/net/packet/Kconfig
@@ -17,7 +17,7 @@ config PACKET
config PACKET_MMAP
bool "Packet socket: mmapped IO"
- depends on PACKET
+ depends on PACKET && MMU
help
If you say Y here, the Packet protocol driver will use an IO
mechanism that results in faster communication.
=================================
But I saw most of the git-format patches have a header in the front of
the patch file, like:
=================================
* Added xxxxxx support
Signed-off-by: xxxxxxxx <xxxxxxx@email.com>
---
net/packet/Kconfig | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/net/packet/Kconfig b/net/packet/Kconfig
index 34ff93f..959c272 100644
--- a/net/packet/Kconfig
+++ b/net/packet/Kconfig
----snip----
=================================
Just want to know how this kind of patch format generated.
Thanks for any hints.
Regards,
-Aubrey
^ permalink raw reply related
* Re: Adding color to git diff output.
From: Alex Riesen @ 2006-04-12 7:38 UTC (permalink / raw)
To: Linus Torvalds; +Cc: sean, junkio, git
In-Reply-To: <Pine.LNX.4.64.0604111801270.14565@g5.osdl.org>
On 4/12/06, Linus Torvalds <torvalds@osdl.org> wrote:
> +if [ "$GIT_DIFF_PAGER" ] && tty -s <&1; then
Maybe use "-t" here? I have at least one system which has no tty installed.
Like this:
if [ -n "$GIT_DIFF_PAGER" -a -t ]; then
...
^ permalink raw reply
* Re: Adding color to git diff output.
From: Junio C Hamano @ 2006-04-12 6:19 UTC (permalink / raw)
To: sean; +Cc: Linus Torvalds, git
In-Reply-To: <BAYC1-PASMTP119CAD2588D00764DB3EA3AEC20@CEZ.ICE>
sean <seanlkml@sympatico.ca> writes:
> What I have is a script ~/bin/gitcdiff:
>
> #!/bin/sh
> tty -s <&1 || exec cat
> colordiff | less -RS
>
> And then setting GIT_DIFF_PAGER="~/bin/gitcdiff". When piping to a file
> it just uses cat, but when the output is a terminal device it uses the
> colordiff.
>
> I thought about integrating that logic into git-diff.sh, but i'm not sure
> it's always appropriate.
What Linus posted seems sensible. And here is a hacked version
that is git-aware ;-).
-- >8 --
Subject: [PATCH] Add colordiff for git to contrib/colordiff.
I hacked it up to teach it the git extended diff headers, made
it not to read the whole patch in the array.
Also, the original program, when arguments are given, ran "diff"
with the given arguments and showed the output from it. Of
course, I changed it to run "git diff" ;-).
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
contrib/colordiff/README | 2
contrib/colordiff/colordiff.perl | 196 ++++++++++++++++++++++++++++++++++++++
2 files changed, 198 insertions(+), 0 deletions(-)
create mode 100644 contrib/colordiff/README
create mode 100755 contrib/colordiff/colordiff.perl
2ee04989119dd5c00e066f740efb8f2155d81ede
diff --git a/contrib/colordiff/README b/contrib/colordiff/README
new file mode 100644
index 0000000..2678fdf
--- /dev/null
+++ b/contrib/colordiff/README
@@ -0,0 +1,2 @@
+This is "colordiff" (http://colordiff.sourceforge.net/) by Dave
+Ewart <davee@sungate.co.uk>, modified specifically for git.
diff --git a/contrib/colordiff/colordiff.perl b/contrib/colordiff/colordiff.perl
new file mode 100755
index 0000000..37c3559
--- /dev/null
+++ b/contrib/colordiff/colordiff.perl
@@ -0,0 +1,196 @@
+#!/usr/bin/perl -w
+#
+# $Id: colordiff.pl,v 1.4.2.10 2004/01/04 15:02:59 daveewart Exp $
+
+########################################################################
+# #
+# ColorDiff - a wrapper/replacment for 'diff' producing #
+# colourful output #
+# #
+# Copyright (C)2002-2004 Dave Ewart (davee@sungate.co.uk) #
+# #
+########################################################################
+# #
+# This program is free software; you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the Free Software #
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #
+# #
+########################################################################
+
+use strict;
+use Getopt::Long qw(:config pass_through);
+use IPC::Open2;
+
+my $app_name = 'colordiff';
+my $version = '1.0.4';
+my $author = 'Dave Ewart';
+my $author_email = 'davee@sungate.co.uk';
+my $app_www = 'http://colordiff.sourceforge.net/';
+my $copyright = '(C)2002-2004';
+my $show_banner = 1;
+
+# ANSI sequences for colours
+my %colour;
+$colour{white} = "\033[1;37m";
+$colour{yellow} = "\033[1;33m";
+$colour{green} = "\033[1;32m";
+$colour{blue} = "\033[1;34m";
+$colour{cyan} = "\033[1;36m";
+$colour{red} = "\033[1;31m";
+$colour{magenta} = "\033[1;35m";
+$colour{black} = "\033[1;30m";
+$colour{darkwhite} = "\033[0;37m";
+$colour{darkyellow} = "\033[0;33m";
+$colour{darkgreen} = "\033[0;32m";
+$colour{darkblue} = "\033[0;34m";
+$colour{darkcyan} = "\033[0;36m";
+$colour{darkred} = "\033[0;31m";
+$colour{darkmagenta} = "\033[0;35m";
+$colour{darkblack} = "\033[0;30m";
+$colour{OFF} = "\033[0;0m";
+
+# Default colours if /etc/colordiffrc or ~/.colordiffrc do not exist
+my $plain_text = $colour{OFF};
+my $file_old = $colour{red};
+my $file_new = $colour{blue};
+my $diff_stuff = $colour{magenta};
+
+# Locations for personal and system-wide colour configurations
+my $HOME = $ENV{HOME};
+my $etcdir = '/etc';
+
+my ($setting, $value);
+my @config_files = ("$etcdir/colordiffrc", "$HOME/.colordiffrc");
+my $config_file;
+
+foreach $config_file (@config_files) {
+ if (open(COLORDIFFRC, "<$config_file")) {
+ while (<COLORDIFFRC>) {
+ chop;
+ next if (/^#/ || /^$/);
+ s/\s+//g;
+ ($setting, $value) = split ('=');
+ if ($setting eq 'banner') {
+ if ($value eq 'no') {
+ $show_banner = 0;
+ }
+ next;
+ }
+ if (!defined $colour{$value}) {
+ print "Invalid colour specification ($value) in $config_file\n";
+ next;
+ }
+ if ($setting eq 'plain') {
+ $plain_text = $colour{$value};
+ }
+ elsif ($setting eq 'oldtext') {
+ $file_old = $colour{$value};
+ }
+ elsif ($setting eq 'newtext') {
+ $file_new = $colour{$value};
+ }
+ elsif ($setting eq 'diffstuff') {
+ $diff_stuff = $colour{$value};
+ }
+ else {
+ print "Unknown option in $etcdir/colordiffrc: $setting\n";
+ }
+ }
+ close COLORDIFFRC;
+ }
+}
+
+# colordiff specfic options here. Need to pre-declare if using variables
+GetOptions(
+ "no-banner" => sub { $show_banner = 0 },
+ "plain-text=s" => \&set_color,
+ "file-old=s" => \&set_color,
+ "file-new=s" => \&set_color,
+ "diff-stuff=s" => \&set_color
+);
+
+if ($show_banner == 1) {
+ print STDERR "$app_name $version ($app_www)\n";
+ print STDERR "$copyright $author, $author_email\n\n";
+}
+
+if (defined $ARGV[0]) {
+ # More reliable way of pulling in arguments
+ open2(\*INPUTSTREAM, undef, "git", "diff", @ARGV);
+}
+else {
+ *INPUTSTREAM = \*STDIN;
+}
+
+my $record;
+my $nrecs = 0;
+my $inside_file_old = 1;
+my $nparents = undef;
+
+while (<INPUTSTREAM>) {
+ $nrecs++;
+ if (/^(\@\@+) -[-+0-9, ]+ \1/) {
+ print "$diff_stuff";
+ $nparents = length($1) - 1;
+ }
+ elsif (/^diff -/ || /^index / ||
+ /^old mode / || /^new mode / ||
+ /^deleted file mode / || /^new file mode / ||
+ /^similarity index / || /^dissimilarity index / ||
+ /^copy from / || /^copy to / ||
+ /^rename from / || /^rename to /) {
+ $nparents = undef;
+ print "$diff_stuff";
+ }
+ elsif (defined $nparents) {
+ if ($nparents == 1) {
+ if (/^\+/) {
+ print $file_new;
+ }
+ elsif (/^-/) {
+ print $file_old;
+ }
+ else {
+ print $plain_text;
+ }
+ }
+ elsif (/^ {$nparents}/) {
+ print "$plain_text";
+ }
+ elsif (/^[+ ]{$nparents}/) {
+ print "$file_new";
+ }
+ elsif (/^[- ]{$nparents}/) {
+ print "$file_old";
+ }
+ else {
+ print $plain_text;
+ }
+ }
+ elsif (/^--- / || /^\+\+\+ /) {
+ print $diff_stuff;
+ }
+ else {
+ print "$plain_text";
+ }
+ s/$/$colour{OFF}/;
+ print "$_";
+}
+close INPUTSTREAM;
+
+sub set_color {
+ my ($type, $color) = @_;
+
+ $type =~ s/-/_/;
+ eval "\$$type = \$colour{$color}";
+}
--
1.3.0.rc3.g72c1
^ permalink raw reply related
* Re: Adding color to git diff output.
From: Linus Torvalds @ 2006-04-12 1:03 UTC (permalink / raw)
To: sean; +Cc: junkio, git
In-Reply-To: <BAYC1-PASMTP119CAD2588D00764DB3EA3AEC20@CEZ.ICE>
On Tue, 11 Apr 2006, sean wrote:
>
> What I have is a script ~/bin/gitcdiff:
>
> #!/bin/sh
> tty -s <&1 || exec cat
> colordiff | less -RS
>
> And then setting GIT_DIFF_PAGER="~/bin/gitcdiff". When piping to a file
> it just uses cat, but when the output is a terminal device it uses the
> colordiff.
>
> I thought about integrating that logic into git-diff.sh, but i'm not sure
> it's always appropriate.
Yeah, that's close to what I'd have suggested:
Linus
----
diff --git a/git-diff.sh b/git-diff.sh
index dc0dd31..f0bea80 100755
--- a/git-diff.sh
+++ b/git-diff.sh
@@ -69,4 +69,8 @@ case "$rev" in
;;
esac
+if [ "$GIT_DIFF_PAGER" ] && tty -s <&1; then
+ cmd="$cmd | $GIT_DIFF_PAGER"
+fi
+
eval "$cmd"
^ permalink raw reply related
* Re: Adding color to git diff output.
From: sean @ 2006-04-12 0:38 UTC (permalink / raw)
To: Linus Torvalds; +Cc: junkio, git
In-Reply-To: <Pine.LNX.4.64.0604111725590.14565@g5.osdl.org>
On Tue, 11 Apr 2006 17:34:10 -0700 (PDT)
Linus Torvalds <torvalds@osdl.org> wrote:
> On Tue, 11 Apr 2006, Junio C Hamano wrote:
>
> > sean <seanlkml@sympatico.ca> writes:
> >
> > > Linus posted a colorize program a while back[1] but it wasn't taken into git.
> > > The patch below takes a different approach, adding a GIT_DIFF_PAGER variable.
> > > You can use it by assigning a filter to the environment variable, like so:
> > >
> > > export GIT_DIFF_PAGER="colordiff | less -RS"
> >
> > Sounds like a nice idea, even maybe suitable in a FAQ.
> > Unfortunately colordiff does not seem to grok diff --cc output,
> > but that is fine ;-).
>
> Well, the real problem - at least as far as my usage is concerned - is
> that I'd want colorization to be more integrated so that it can be turned
> off when not appropriate.
>
> Think "colorized 'ls'", where if you enable colorization by default, it
> only colorizes when the output is a tty, so that you can still script
> things and output things to a file or so, without it getting colorized.
>
> Because most "patch" programs (git-apply included) do not want to see
> colorization ;)
>
> So I'd suggest that the "git diff" script at a minimum first check whether
> the output is to a tty before it decides to use GIT_DIFF_PAGER. With
> perhaps an option to _force_ colorization if you want to.
>
> Now, I don't actually enable ls-colorization by default, and I probably
> wouldn't do it for git diff either, but at least for diffs I _might_. But
> I'd definitely want it to be turned off automatically so that I can do
>
> git diff .. > ~/patch-file
>
> without having to remember to turn it off explicitly.
>
What I have is a script ~/bin/gitcdiff:
#!/bin/sh
tty -s <&1 || exec cat
colordiff | less -RS
And then setting GIT_DIFF_PAGER="~/bin/gitcdiff". When piping to a file
it just uses cat, but when the output is a terminal device it uses the
colordiff.
I thought about integrating that logic into git-diff.sh, but i'm not sure
it's always appropriate.
Sean
^ permalink raw reply
* Re: Adding color to git diff output.
From: Linus Torvalds @ 2006-04-12 0:34 UTC (permalink / raw)
To: Junio C Hamano; +Cc: sean, git
In-Reply-To: <7virpf4sg4.fsf@assigned-by-dhcp.cox.net>
On Tue, 11 Apr 2006, Junio C Hamano wrote:
> sean <seanlkml@sympatico.ca> writes:
>
> > Linus posted a colorize program a while back[1] but it wasn't taken into git.
> > The patch below takes a different approach, adding a GIT_DIFF_PAGER variable.
> > You can use it by assigning a filter to the environment variable, like so:
> >
> > export GIT_DIFF_PAGER="colordiff | less -RS"
>
> Sounds like a nice idea, even maybe suitable in a FAQ.
> Unfortunately colordiff does not seem to grok diff --cc output,
> but that is fine ;-).
Well, the real problem - at least as far as my usage is concerned - is
that I'd want colorization to be more integrated so that it can be turned
off when not appropriate.
Think "colorized 'ls'", where if you enable colorization by default, it
only colorizes when the output is a tty, so that you can still script
things and output things to a file or so, without it getting colorized.
Because most "patch" programs (git-apply included) do not want to see
colorization ;)
So I'd suggest that the "git diff" script at a minimum first check whether
the output is to a tty before it decides to use GIT_DIFF_PAGER. With
perhaps an option to _force_ colorization if you want to.
Now, I don't actually enable ls-colorization by default, and I probably
wouldn't do it for git diff either, but at least for diffs I _might_. But
I'd definitely want it to be turned off automatically so that I can do
git diff .. > ~/patch-file
without having to remember to turn it off explicitly.
Linus
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox