* [PATCH 0/6] External diff interface for diff-cache and friends.
@ 2005-04-27 6:19 Junio C Hamano
2005-04-27 6:24 ` [PATCH 1/6] Reworked external diff interface Junio C Hamano
` (6 more replies)
0 siblings, 7 replies; 9+ messages in thread
From: Junio C Hamano @ 2005-04-27 6:19 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
As discussed earlier, I am sending a series of patches to take
advantage of the simplified external diff interface you have
already merged. This series consists of the following:
[PATCH 1/6] Reworked external diff interface.
This patch introduces three public functions for diff-cache
and friends can use to call out to the GIT_EXTERNAL_DIFF
program when they wish to. A normal "add/remove/change"
entry is turned into 7-parameter process invocation of
GIT_EXTERNAL_DIFF program as before. In addition, the
program can now be called with a single parameter when
diff-cache and friends want to report an unmerged path.
[PATCH 2/6] Reactivate show-diff patch generation
This patch uses the reworked diff interface to generate
patches directly out of show-diff when -p is specified.
[PATCH 3/6] Add -p (patch) to diff-tree.
This patch uses the reworked diff interface to generate
patches directly out of diff-tree when -p is specified.
[PATCH 4/6] Add -p (patch) to diff-cache.
This patch uses the reworked diff interface to generate
patches directly out of diff-cache when -p is specified.
[PATCH 5/6] Teach diff-tree-helper to handle unmerged paths.
This patch teaches diff-tree-helper to call diff_unmreged()
so that it can report unmerged paths to GIT_EXTERNAL_DIFF.
[PATCH 6/6] Alternative patch to diff-cache.c
This is a replacement of PATCH 4, in case you have already
applied the "non-cached still looks only at cache" fix I
sent you earlier. If you took it, PATCH 4 may not apply
cleanly, in which case this should be easier to work with.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/6] Reworked external diff interface.
2005-04-27 6:19 [PATCH 0/6] External diff interface for diff-cache and friends Junio C Hamano
@ 2005-04-27 6:24 ` Junio C Hamano
2005-04-27 6:25 ` [PATCH 2/6] Reactivate show-diff patch generation Junio C Hamano
` (5 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2005-04-27 6:24 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
This patch introduces three public functions for diff-cache and
friends can use to call out to the GIT_EXTERNAL_DIFF program
when they wish to. A normal "add/remove/change" entry is turned
into 7-parameter process invocation of GIT_EXTERNAL_DIFF program
as before. In addition, the program can now be called with a
single parameter when diff-cache and friends want to report an
unmerged path.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
diff.c | 93 ++++++++++++++++++++++++++++++++++++++++-------------------------
diff.h | 19 +++++++++----
2 files changed, 72 insertions(+), 40 deletions(-)
To be tested with the following:
GIT_INDEX_FILE=junk
export GIT_INDEX_FILE
read-tree $(cat .git/HEAD)
t1=$(write-tree)
date >trash ; update-cache --add trash
t2=$(write-tree)
read-tree -m $(cat .git/HEAD) $t1 $t2
update-cache --refresh
./show-diff | GIT_EXTERNAL_DIFF=echo ./diff-tree-helper
--- k/diff.c
+++ l/diff.c
@@ -194,13 +194,15 @@ void run_external_diff(const char *name,
int pid, status;
static int atexit_asked = 0;
- prepare_temp_file(name, &temp[0], one);
- prepare_temp_file(name, &temp[1], two);
- if (! atexit_asked &&
- (temp[0].name == temp[0].tmp_path ||
- temp[1].name == temp[1].tmp_path)) {
- atexit_asked = 1;
- atexit(remove_tempfile);
+ if (one && two) {
+ prepare_temp_file(name, &temp[0], one);
+ prepare_temp_file(name, &temp[1], two);
+ if (! atexit_asked &&
+ (temp[0].name == temp[0].tmp_path ||
+ temp[1].name == temp[1].tmp_path)) {
+ atexit_asked = 1;
+ atexit(remove_tempfile);
+ }
}
fflush(NULL);
@@ -209,16 +211,23 @@ void run_external_diff(const char *name,
die("unable to fork");
if (!pid) {
const char *pgm = external_diff();
- if (pgm)
- execlp(pgm, pgm,
- name,
- temp[0].name, temp[0].hex, temp[0].mode,
- temp[1].name, temp[1].hex, temp[1].mode,
- NULL);
+ if (pgm) {
+ if (one && two)
+ execlp(pgm, pgm,
+ name,
+ temp[0].name, temp[0].hex, temp[0].mode,
+ temp[1].name, temp[1].hex, temp[1].mode,
+ NULL);
+ else
+ execlp(pgm, pgm, name, NULL);
+ }
/*
* otherwise we use the built-in one.
*/
- builtin_diff(name, temp);
+ if (one && two)
+ builtin_diff(name, temp);
+ else
+ printf("* Unmerged path %s\n", name);
exit(0);
}
if (waitpid(pid, &status, 0) < 0 || !WIFEXITED(status))
@@ -227,41 +236,55 @@ void run_external_diff(const char *name,
remove_tempfile();
}
-void show_diff_empty(const struct cache_entry *ce, int reverse)
+void diff_addremove(int addremove, unsigned mode,
+ const unsigned char *sha1,
+ const char *base, const char *path)
{
+ char concatpath[PATH_MAX];
struct diff_spec spec[2], *one, *two;
- memcpy(spec[0].u.sha1, ce->sha1, 20);
- spec[0].mode = ntohl(ce->ce_mode);
+ memcpy(spec[0].u.sha1, sha1, 20);
+ spec[0].mode = mode;
spec[0].sha1_valid = spec[0].file_valid = 1;
spec[1].file_valid = 0;
- if (reverse) {
+ if (addremove == '+') {
one = spec + 1; two = spec;
} else {
one = spec; two = one + 1;
}
-
- run_external_diff(ce->name, one, two);
+
+ if (path) {
+ strcpy(concatpath, base);
+ strcat(concatpath, "/");
+ strcat(concatpath, path);
+ }
+ run_external_diff(path ? concatpath : base, one, two);
}
-void show_differences(const struct cache_entry *ce, int reverse)
-{
- struct diff_spec spec[2], *one, *two;
-
- memcpy(spec[0].u.sha1, ce->sha1, 20);
- spec[0].mode = ntohl(ce->ce_mode);
+void diff_change(unsigned old_mode, unsigned new_mode,
+ const unsigned char *old_sha1,
+ const unsigned char *new_sha1,
+ const char *base, const char *path) {
+ char concatpath[PATH_MAX];
+ struct diff_spec spec[2];
+
+ memcpy(spec[0].u.sha1, old_sha1, 20);
+ spec[0].mode = old_mode;
+ memcpy(spec[1].u.sha1, new_sha1, 20);
+ spec[1].mode = new_mode;
spec[0].sha1_valid = spec[0].file_valid = 1;
+ spec[1].sha1_valid = spec[1].file_valid = 1;
- spec[1].u.name = ce->name; /* the name we stated */
- spec[1].sha1_valid = 0;
- spec[1].file_valid = 1;
-
- if (reverse) {
- one = spec + 1; two = spec;
- } else {
- one = spec; two = one + 1;
+ if (path) {
+ strcpy(concatpath, base);
+ strcat(concatpath, "/");
+ strcat(concatpath, path);
}
+ run_external_diff(path ? concatpath : base, &spec[0], &spec[1]);
+}
- run_external_diff(ce->name, one, two);
+void diff_unmerge(const char *path)
+{
+ run_external_diff(path, NULL, NULL);
}
--- k/diff.h
+++ l/diff.h
@@ -4,11 +4,20 @@
#ifndef DIFF_H
#define DIFF_H
-/* These two are for backward compatibility with show-diff;
- * new users should not use them.
- */
-extern void show_differences(const struct cache_entry *ce, int reverse);
-extern void show_diff_empty(const struct cache_entry *ce, int reverse);
+extern void diff_addremove(int addremove,
+ unsigned mode,
+ const unsigned char *sha1,
+ const char *base,
+ const char *path);
+
+extern void diff_change(unsigned mode1, unsigned mode2,
+ const unsigned char *sha1,
+ const unsigned char *sha2,
+ const char *base, const char *path);
+
+extern void diff_unmerge(const char *path);
+
+/* These are for diff-tree-helper */
struct diff_spec {
union {
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/6] Reactivate show-diff patch generation
2005-04-27 6:19 [PATCH 0/6] External diff interface for diff-cache and friends Junio C Hamano
2005-04-27 6:24 ` [PATCH 1/6] Reworked external diff interface Junio C Hamano
@ 2005-04-27 6:25 ` Junio C Hamano
2005-04-27 6:25 ` [PATCH 3/6] Add -p (patch) to diff-tree Junio C Hamano
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2005-04-27 6:25 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
This patch uses the reworked diff interface to generate patches
directly out of show-diff when -p is specified.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
show-diff.c | 56 ++++++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 42 insertions(+), 14 deletions(-)
To be tested with the following:
GIT_INDEX_FILE=junk
export GIT_INDEX_FILE
rm -f junk
date >trash ; update-cache --add trash
date >>trash;
GIT_EXTERNAL_DIFF=echo ./show-diff -p
update-cache --refresh
GIT_EXTERNAL_DIFF=echo ./show-diff -p
--- k/show-diff.c
+++ l/show-diff.c
@@ -4,10 +4,11 @@
* Copyright (C) Linus Torvalds, 2005
*/
#include "cache.h"
+#include "diff.h"
-static const char *show_diff_usage = "show-diff [-q] [-s] [-z] [paths...]";
+static const char *show_diff_usage = "show-diff [-q] [-s] [-z] [-p] [paths...]";
-static int recursive = 0;
+static int generate_patch = 0;
static int line_termination = '\n';
static int silent = 0;
static int silent_on_nonexisting_files = 0;
@@ -27,27 +28,57 @@ static int matches_pathspec(struct cache
return 0;
}
-static void show_file(const char *prefix, struct cache_entry *ce)
+static void show_unmerge(const char *path)
{
- printf("%s%o\t%s\t%s\t%s%c", prefix, ntohl(ce->ce_mode), "blob",
- sha1_to_hex(ce->sha1), ce->name, line_termination);
+ if (generate_patch)
+ diff_unmerge(path);
+ else
+ printf("U %s%c", path, line_termination);
+}
+
+static void show_file(int pfx, struct cache_entry *ce)
+{
+ if (generate_patch)
+ diff_addremove(pfx, ntohl(ce->ce_mode), ce->sha1,
+ ce->name, NULL);
+ else
+ printf("%c%06o\t%s\t%s\t%s%c",
+ pfx, ntohl(ce->ce_mode), "blob",
+ sha1_to_hex(ce->sha1), ce->name, line_termination);
+}
+
+static void show_modified(int oldmode, int mode,
+ const char *old_sha1, const char *sha1,
+ char *path)
+{
+ char old_sha1_hex[41];
+ strcpy(old_sha1_hex, sha1_to_hex(old_sha1));
+
+ if (generate_patch)
+ diff_change(oldmode, mode, old_sha1, sha1, path, NULL);
+ else
+ printf("*%06o->%06o\tblob\t%s->%s\t%s%c",
+ oldmode, mode, old_sha1_hex, sha1_to_hex(sha1), path,
+ line_termination);
}
int main(int argc, char **argv)
{
- static const char null_sha1_hex[] = "0000000000000000000000000000000000000000";
+ static const char null_sha1[20] = { 0, };
int entries = read_cache();
int i;
while (1 < argc && argv[1][0] == '-') {
if (!strcmp(argv[1], "-s"))
silent_on_nonexisting_files = silent = 1;
+ else if (!strcmp(argv[1], "-p"))
+ generate_patch = 1;
else if (!strcmp(argv[1], "-q"))
silent_on_nonexisting_files = 1;
else if (!strcmp(argv[1], "-z"))
line_termination = 0;
else if (!strcmp(argv[1], "-r"))
- recursive = 1; /* No-op */
+ ; /* no-op */
else
usage(show_diff_usage);
argv++; argc--;
@@ -72,8 +103,7 @@ int main(int argc, char **argv)
continue;
if (ce_stage(ce)) {
- printf("U %s%c", ce->name, line_termination);
-
+ show_unmerge(ce->name);
while (i < entries &&
!strcmp(ce->name, active_cache[i]->name))
i++;
@@ -88,7 +118,7 @@ int main(int argc, char **argv)
}
if (silent_on_nonexisting_files)
continue;
- show_file("-", ce);
+ show_file('-', ce);
continue;
}
changed = cache_match_stat(ce, &st);
@@ -98,10 +128,8 @@ int main(int argc, char **argv)
oldmode = ntohl(ce->ce_mode);
mode = S_IFREG | ce_permissions(st.st_mode);
- printf("*%o->%o\t%s\t%s->%s\t%s%c",
- oldmode, mode, "blob",
- sha1_to_hex(ce->sha1), null_sha1_hex,
- ce->name, line_termination);
+ show_modified(oldmode, mode, ce->sha1, null_sha1,
+ ce->name);
}
return 0;
}
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/6] Add -p (patch) to diff-tree.
2005-04-27 6:19 [PATCH 0/6] External diff interface for diff-cache and friends Junio C Hamano
2005-04-27 6:24 ` [PATCH 1/6] Reworked external diff interface Junio C Hamano
2005-04-27 6:25 ` [PATCH 2/6] Reactivate show-diff patch generation Junio C Hamano
@ 2005-04-27 6:25 ` Junio C Hamano
2005-04-27 6:26 ` [PATCH 4/6] Add -p (patch) to diff-cache Junio C Hamano
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2005-04-27 6:25 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
This patch uses the reworked diff interface to generate patches
directly out of diff-tree when -p is specified.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
diff-tree.c | 35 ++++++++++++++++++++++++++---------
1 files changed, 26 insertions(+), 9 deletions(-)
To be tested with the following:
GIT_INDEX_FILE=junk
export GIT_INDEX_FILE
rm -f junk
date >trash ; update-cache --add trash
t1=$(write-tree)
date >>trash; update-cache trash
t2=$(write-tree)
GIT_EXTERNAL_DIFF=echo ./diff-tree -p $t1 $t2
--- k/diff-tree.c
+++ l/diff-tree.c
@@ -1,7 +1,9 @@
#include "cache.h"
+#include "diff.h"
static int recursive = 0;
static int line_termination = '\n';
+static int generate_patch = 0;
// What paths are we interested in?
static int nr_paths = 0;
@@ -79,10 +81,15 @@ static void show_file(const char *prefix
return;
}
- printf("%s%o\t%s\t%s\t%s%s%c", prefix, mode,
- S_ISDIR(mode) ? "tree" : "blob",
- sha1_to_hex(sha1), base, path,
- line_termination);
+ if (generate_patch) {
+ if (!S_ISDIR(mode))
+ diff_addremove(prefix[0], mode, sha1, base, path);
+ }
+ else
+ printf("%s%06o\t%s\t%s\t%s%s%c", prefix, mode,
+ S_ISDIR(mode) ? "tree" : "blob",
+ sha1_to_hex(sha1), base, path,
+ line_termination);
}
static int compare_tree_entry(void *tree1, unsigned long size1, void *tree2, unsigned long size2, const char *base)
@@ -128,11 +135,17 @@ static int compare_tree_entry(void *tree
return retval;
}
- strcpy(old_sha1_hex, sha1_to_hex(sha1));
- printf("*%o->%o\t%s\t%s->%s\t%s%s%c", mode1, mode2,
- S_ISDIR(mode1) ? "tree" : "blob",
- old_sha1_hex, sha1_to_hex(sha2), base, path1,
- line_termination);
+ if (generate_patch) {
+ if (!S_ISDIR(mode1))
+ diff_change(mode1, mode2, sha1, sha2, base, path1);
+ }
+ else {
+ strcpy(old_sha1_hex, sha1_to_hex(sha1));
+ printf("*%06o->%06o\t%s\t%s->%s\t%s%s%c", mode1, mode2,
+ S_ISDIR(mode1) ? "tree" : "blob",
+ old_sha1_hex, sha1_to_hex(sha2), base, path1,
+ line_termination);
+ }
return 0;
}
@@ -255,6 +268,10 @@ int main(int argc, char **argv)
recursive = 1;
continue;
}
+ if (!strcmp(arg, "-p")) {
+ generate_patch = 1;
+ continue;
+ }
if (!strcmp(arg, "-z")) {
line_termination = '\0';
continue;
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/6] Add -p (patch) to diff-cache.
2005-04-27 6:19 [PATCH 0/6] External diff interface for diff-cache and friends Junio C Hamano
` (2 preceding siblings ...)
2005-04-27 6:25 ` [PATCH 3/6] Add -p (patch) to diff-tree Junio C Hamano
@ 2005-04-27 6:26 ` Junio C Hamano
2005-04-27 6:27 ` [PATCH 5/6] Teach diff-tree-helper to handle unmerged paths Junio C Hamano
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2005-04-27 6:26 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
This patch uses the reworked diff interface to generate patches
directly out of diff-cache when -p is specified.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
diff-cache.c | 37 ++++++++++++++++++++++++++++---------
1 files changed, 28 insertions(+), 9 deletions(-)
To be tested with the following:
GIT_INDEX_FILE=junk
export GIT_INDEX_FILE
rm -f junk
date >trash ; update-cache --add trash
t1=$(write-tree)
date >>trash;
GIT_EXTERNAL_DIFF=echo ./diff-cache -p $t1
GIT_EXTERNAL_DIFF=echo ./diff-cache -p --cached $t1
update-cache trash
GIT_EXTERNAL_DIFF=echo ./diff-cache -p --cached $t1
./diff-cache -p $(cat .git/HEAD) | filterdiff -i ?/diff-cache.c
--- k/diff-cache.c
+++ l/diff-cache.c
@@ -1,13 +1,20 @@
#include "cache.h"
+#include "diff.h"
static int cached_only = 0;
+static int generate_patch = 0;
static int line_termination = '\n';
/* A file entry went away or appeared */
static void show_file(const char *prefix, struct cache_entry *ce)
{
- printf("%s%o\t%s\t%s\t%s%c", prefix, ntohl(ce->ce_mode), "blob",
- sha1_to_hex(ce->sha1), ce->name, line_termination);
+ if (generate_patch)
+ diff_addremove(prefix[0], ntohl(ce->ce_mode),
+ ce->sha1, ce->name, NULL);
+ else
+ printf("%s%06o\tblob\t%s\t%s%c", prefix, ntohl(ce->ce_mode),
+ sha1_to_hex(ce->sha1), ce->name,
+ line_termination);
}
static int show_modified(struct cache_entry *old, struct cache_entry *new)
@@ -35,11 +42,15 @@ static int show_modified(struct cache_en
if (mode == oldmode && !memcmp(sha1, old->sha1, 20))
return 0;
- strcpy(old_sha1_hex, sha1_to_hex(old->sha1));
- printf("*%o->%o\t%s\t%s->%s\t%s%c", oldmode, mode,
- "blob",
- old_sha1_hex, sha1_to_hex(sha1),
- old->name, line_termination);
+ if (generate_patch)
+ diff_change(oldmode, mode,
+ old->sha1, sha1, old->name, NULL);
+ else {
+ strcpy(old_sha1_hex, sha1_to_hex(old->sha1));
+ printf("*%06o->%06o\tblob\t%s->%s\t%s%c", oldmode, mode,
+ old_sha1_hex, sha1_to_hex(sha1),
+ old->name, line_termination);
+ }
return 0;
}
@@ -67,7 +78,10 @@ static int diff_cache(struct cache_entry
}
/* Otherwise we fall through to the "unmerged" case */
case 3:
- printf("U %s%c", ce->name, line_termination);
+ if (generate_patch)
+ diff_unmerge(ce->name);
+ else
+ printf("U %s%c", ce->name, line_termination);
break;
default:
@@ -102,7 +116,8 @@ static void mark_merge_entries(void)
}
}
-static char *diff_cache_usage = "diff-cache [-r] [-z] [--cached] <tree sha1>";
+static char *diff_cache_usage =
+"diff-cache [-r] [-z] [-p] [--cached] <tree sha1>";
int main(int argc, char **argv)
{
@@ -119,6 +134,10 @@ int main(int argc, char **argv)
/* We accept the -r flag just to look like diff-tree */
continue;
}
+ if (!strcmp(arg, "-p")) {
+ generate_patch = 1;
+ continue;
+ }
if (!strcmp(arg, "-z")) {
line_termination = '\0';
continue;
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 5/6] Teach diff-tree-helper to handle unmerged paths.
2005-04-27 6:19 [PATCH 0/6] External diff interface for diff-cache and friends Junio C Hamano
` (3 preceding siblings ...)
2005-04-27 6:26 ` [PATCH 4/6] Add -p (patch) to diff-cache Junio C Hamano
@ 2005-04-27 6:27 ` Junio C Hamano
2005-04-27 6:28 ` [PATCH 6/6] Alternative patch to diff-cache.c Junio C Hamano
2005-04-27 8:17 ` [PATCH 7/6] Leftover bits Junio C Hamano
6 siblings, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2005-04-27 6:27 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
This patch teaches diff-tree-helper to call diff_unmrege() so
that it can report unmerged paths to GIT_EXTERNAL_DIFF, instead
of consuming it on its own.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
diff-tree-helper.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
To be tested with the following:
GIT_INDEX_FILE=junk
export GIT_INDEX_FILE
read-tree $(cat .git/HEAD)
t1=$(write-tree)
date >trash ; update-cache --add trash
t2=$(write-tree)
read-tree -m $(cat .git/HEAD) $t1 $t2
update-cache --refresh
./show-diff | GIT_EXTERNAL_DIFF=echo ./diff-tree-helper
--- k/diff-tree-helper.c
+++ l/diff-tree-helper.c
@@ -56,7 +56,7 @@ static int parse_diff_tree_output(const
switch (*cp++) {
case 'U':
- fprintf(stderr, "warning: unmerged path %s\n", cp+1);
+ diff_unmerge(cp + 1);
return WARNED_OURSELVES;
case '+':
old->file_valid = 0;
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 6/6] Alternative patch to diff-cache.c
2005-04-27 6:19 [PATCH 0/6] External diff interface for diff-cache and friends Junio C Hamano
` (4 preceding siblings ...)
2005-04-27 6:27 ` [PATCH 5/6] Teach diff-tree-helper to handle unmerged paths Junio C Hamano
@ 2005-04-27 6:28 ` Junio C Hamano
2005-04-27 8:17 ` [PATCH 7/6] Leftover bits Junio C Hamano
6 siblings, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2005-04-27 6:28 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
This is a replacement of PATCH 4, in case you have already
applied the "non-cached still looks only at cache" fix I
sent you earlier. If you took it, PATCH 4 may not apply
cleanly, in which case this should be easier to work with.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
diff-cache.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 63 insertions(+), 10 deletions(-)
--- k/diff-cache.c
+++ l/diff-cache.c
@@ -1,13 +1,41 @@
#include "cache.h"
+#include "diff.h"
static int cached_only = 0;
+static int generate_patch = 0;
static int line_termination = '\n';
/* A file entry went away or appeared */
static void show_file(const char *prefix, struct cache_entry *ce)
{
- printf("%s%o\t%s\t%s\t%s%c", prefix, ntohl(ce->ce_mode), "blob",
- sha1_to_hex(ce->sha1), ce->name, line_termination);
+ if (generate_patch)
+ diff_addremove(prefix[0], ntohl(ce->ce_mode),
+ ce->sha1, ce->name, NULL);
+ else
+ printf("%s%06o\tblob\t%s\t%s%c", prefix, ntohl(ce->ce_mode),
+ sha1_to_hex(ce->sha1), ce->name,
+ line_termination);
+}
+
+/* A file *may* have been added to the working tree */
+static void show_possible_local_add(struct cache_entry *new)
+{
+ static unsigned char no_sha1[20];
+ struct stat st;
+ if (stat(new->name, &st) < 0)
+ /* We signal the missing file by special mode 0 and
+ * let diff-tree-helper notice the missing file when it
+ * tries to open it by path. Sneaky but works.
+ */
+ st.st_mode = 0;
+ else if (cache_match_stat(new, &st))
+ return show_file("+", new);
+
+ if (generate_patch)
+ diff_addremove('+', st.st_mode, no_sha1, new->name, NULL);
+ else
+ printf("+%06o\tblob\t%s\t%s%c", st.st_mode,
+ sha1_to_hex(no_sha1), new->name, line_termination);
}
static int show_modified(struct cache_entry *old, struct cache_entry *new)
@@ -35,11 +63,15 @@ static int show_modified(struct cache_en
if (mode == oldmode && !memcmp(sha1, old->sha1, 20))
return 0;
- strcpy(old_sha1_hex, sha1_to_hex(old->sha1));
- printf("*%o->%o\t%s\t%s->%s\t%s%c", oldmode, mode,
- "blob",
- old_sha1_hex, sha1_to_hex(sha1),
- old->name, line_termination);
+ if (generate_patch)
+ diff_change(oldmode, mode,
+ old->sha1, sha1, old->name, NULL);
+ else {
+ strcpy(old_sha1_hex, sha1_to_hex(old->sha1));
+ printf("*%06o->%06o\tblob\t%s->%s\t%s%c", oldmode, mode,
+ old_sha1_hex, sha1_to_hex(sha1),
+ old->name, line_termination);
+ }
return 0;
}
@@ -54,20 +86,36 @@ static int diff_cache(struct cache_entry
/* No stage 1 entry? That means it's a new file */
if (!same) {
show_file("+", ce);
+ /* ... not so fast. The working tree may
+ * also not have it anymore.
+ */
+ if (cached_only)
+ show_file("+", ce);
+ else
+ show_possible_local_add(ce);
break;
}
/* Show difference between old and new */
show_modified(ac[1], ce);
break;
case 1:
- /* No stage 3 (merge) entry? That means it's been deleted */
+ /* No stage 3 (merge) entry? That means it's been
+ * deleted.
+ */
if (!same) {
+ /* The working tree may have it, but it does
+ * not matter. If you write-tree and commit
+ * you would lose that file, so take notice.
+ */
show_file("-", ce);
break;
}
/* Otherwise we fall through to the "unmerged" case */
case 3:
- printf("U %s%c", ce->name, line_termination);
+ if (generate_patch)
+ diff_unmerge(ce->name);
+ else
+ printf("U %s%c", ce->name, line_termination);
break;
default:
@@ -102,7 +150,8 @@ static void mark_merge_entries(void)
}
}
-static char *diff_cache_usage = "diff-cache [-r] [-z] [--cached] <tree sha1>";
+static char *diff_cache_usage =
+"diff-cache [-r] [-z] [-p] [--cached] <tree sha1>";
int main(int argc, char **argv)
{
@@ -119,6 +168,10 @@ int main(int argc, char **argv)
/* We accept the -r flag just to look like diff-tree */
continue;
}
+ if (!strcmp(arg, "-p")) {
+ generate_patch = 1;
+ continue;
+ }
if (!strcmp(arg, "-z")) {
line_termination = '\0';
continue;
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 7/6] Leftover bits.
2005-04-27 6:19 [PATCH 0/6] External diff interface for diff-cache and friends Junio C Hamano
` (5 preceding siblings ...)
2005-04-27 6:28 ` [PATCH 6/6] Alternative patch to diff-cache.c Junio C Hamano
@ 2005-04-27 8:17 ` Junio C Hamano
2005-04-27 17:37 ` Linus Torvalds
6 siblings, 1 reply; 9+ messages in thread
From: Junio C Hamano @ 2005-04-27 8:17 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
This is a minor cleanup to be applied on top of the last 6
patches (the 6th is an alternate so the count actually is five).
It makes sure that external diff interface functions are called
even when diff-tree detects directory changes. Since it is not
clear what to pass GIT_EXTERNAL_DIFF when we do see directory
changes, such calls are still currently dropped at the diff.c
interface function level, but whatever we will decide to do
later, the interface users should be cleaned up first anyway,
and that is primarily what this patch is about.
It also adds code to unlink temporary files used to call the
external diff command upon SIGNIT.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
diff-tree.c | 9 +++------
diff.c | 14 ++++++++++++++
2 files changed, 17 insertions(+), 6 deletions(-)
# - 04/26 23:58 Mark the last of '-p' (patch) work.
# + working tree
--- k/diff-tree.c
+++ l/diff-tree.c
@@ -82,8 +82,7 @@ static void show_file(const char *prefix
}
if (generate_patch) {
- if (!S_ISDIR(mode))
- diff_addremove(prefix[0], mode, sha1, base, path);
+ diff_addremove(prefix[0], mode, sha1, base, path);
}
else
printf("%s%06o\t%s\t%s\t%s%s%c", prefix, mode,
@@ -135,10 +134,8 @@ static int compare_tree_entry(void *tree
return retval;
}
- if (generate_patch) {
- if (!S_ISDIR(mode1))
- diff_change(mode1, mode2, sha1, sha2, base, path1);
- }
+ if (generate_patch)
+ diff_change(mode1, mode2, sha1, sha2, base, path1);
else {
strcpy(old_sha1_hex, sha1_to_hex(sha1));
printf("*%06o->%06o\t%s\t%s->%s\t%s%s%c", mode1, mode2,
--- k/diff.c
+++ l/diff.c
@@ -127,6 +127,7 @@ static void prepare_temp_file(const char
if (one->sha1_valid &&
!memcmp(one->u.sha1, null_sha1, sizeof(null_sha1))) {
+ /* "It is valid but please go to the filesystem." */
one->sha1_valid = 0;
one->u.name = name;
}
@@ -180,6 +181,11 @@ static void remove_tempfile(void)
}
}
+static void remove_tempfile_on_signal(int signo)
+{
+ remove_tempfile();
+}
+
/* An external diff command takes:
*
* diff-cmd name infile1 infile1-sha1 infile1-mode \
@@ -202,6 +208,7 @@ void run_external_diff(const char *name,
temp[1].name == temp[1].tmp_path)) {
atexit_asked = 1;
atexit(remove_tempfile);
+ signal(SIGINT, remove_tempfile_on_signal);
}
}
@@ -211,6 +218,7 @@ void run_external_diff(const char *name,
die("unable to fork");
if (!pid) {
const char *pgm = external_diff();
+
if (pgm) {
if (one && two)
execlp(pgm, pgm,
@@ -243,6 +251,9 @@ void diff_addremove(int addremove, unsig
char concatpath[PATH_MAX];
struct diff_spec spec[2], *one, *two;
+ if (S_ISDIR(mode))
+ return;
+
memcpy(spec[0].u.sha1, sha1, 20);
spec[0].mode = mode;
spec[0].sha1_valid = spec[0].file_valid = 1;
@@ -269,6 +280,9 @@ void diff_change(unsigned old_mode, unsi
char concatpath[PATH_MAX];
struct diff_spec spec[2];
+ if (S_ISDIR(old_mode) || S_ISDIR(new_mode))
+ return;
+
memcpy(spec[0].u.sha1, old_sha1, 20);
spec[0].mode = old_mode;
memcpy(spec[1].u.sha1, new_sha1, 20);
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 7/6] Leftover bits.
2005-04-27 8:17 ` [PATCH 7/6] Leftover bits Junio C Hamano
@ 2005-04-27 17:37 ` Linus Torvalds
0 siblings, 0 replies; 9+ messages in thread
From: Linus Torvalds @ 2005-04-27 17:37 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Wed, 27 Apr 2005, Junio C Hamano wrote:
>
> It also adds code to unlink temporary files used to call the
> external diff command upon SIGNIT.
Actually, you should probably do SIGPIPE too. I suspect that's the much
more common case (somebody does a "diff-tree | less", and then quits).
Linus
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2005-04-27 17:30 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-04-27 6:19 [PATCH 0/6] External diff interface for diff-cache and friends Junio C Hamano
2005-04-27 6:24 ` [PATCH 1/6] Reworked external diff interface Junio C Hamano
2005-04-27 6:25 ` [PATCH 2/6] Reactivate show-diff patch generation Junio C Hamano
2005-04-27 6:25 ` [PATCH 3/6] Add -p (patch) to diff-tree Junio C Hamano
2005-04-27 6:26 ` [PATCH 4/6] Add -p (patch) to diff-cache Junio C Hamano
2005-04-27 6:27 ` [PATCH 5/6] Teach diff-tree-helper to handle unmerged paths Junio C Hamano
2005-04-27 6:28 ` [PATCH 6/6] Alternative patch to diff-cache.c Junio C Hamano
2005-04-27 8:17 ` [PATCH 7/6] Leftover bits Junio C Hamano
2005-04-27 17:37 ` Linus Torvalds
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).