summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2012-06-28 03:14:47 (GMT)
committerJunio C Hamano <gitster@pobox.com>2012-06-28 23:18:19 (GMT)
commit4682d8521c3ce9d722bd214fd7d5fc92063fdacb (patch)
tree1d3030f460c38d95eec40bc80d162acfa54a592a
parent3b069b1beba6d851401032260a8030448637ece5 (diff)
downloadgit-4682d8521c3ce9d722bd214fd7d5fc92063fdacb.zip
git-4682d8521c3ce9d722bd214fd7d5fc92063fdacb.tar.gz
git-4682d8521c3ce9d722bd214fd7d5fc92063fdacb.tar.bz2
diff-index.c: "git diff" has no need to read blob from the standard input
Only "diff --no-index -" does. Bolting the logic into the low-level function diff_populate_filespec() was a layering violation from day one. Move populate_from_stdin() function out of the generic diff.c to its only user, diff-index.c. Also make sure "-" from the command line stays a special token "read from the standard input", even if we later decide to sanitize the result from prefix_filename() function in a few obvious ways, e.g. removing unnecessary "./" prefix, duplicated slashes "//" in the middle, etc. Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--diff-no-index.c52
-rw-r--r--diff.c21
-rw-r--r--diffcore.h1
-rwxr-xr-xt/t7501-commit.sh12
4 files changed, 55 insertions, 31 deletions
diff --git a/diff-no-index.c b/diff-no-index.c
index ac41b68..09656bc 100644
--- a/diff-no-index.c
+++ b/diff-no-index.c
@@ -32,6 +32,13 @@ static int read_directory(const char *path, struct string_list *list)
return 0;
}
+/*
+ * This should be "(standard input)" or something, but it will
+ * probably expose many more breakages in the way no-index code
+ * is bolted onto the diff callchain.
+ */
+static const char file_from_standard_input[] = "-";
+
static int get_mode(const char *path, int *mode)
{
struct stat st;
@@ -42,7 +49,7 @@ static int get_mode(const char *path, int *mode)
else if (!strcasecmp(path, "nul"))
*mode = 0;
#endif
- else if (!strcmp(path, "-"))
+ else if (path == file_from_standard_input)
*mode = create_ce_mode(0666);
else if (lstat(path, &st))
return error("Could not access '%s'", path);
@@ -51,6 +58,36 @@ static int get_mode(const char *path, int *mode)
return 0;
}
+static int populate_from_stdin(struct diff_filespec *s)
+{
+ struct strbuf buf = STRBUF_INIT;
+ size_t size = 0;
+
+ if (strbuf_read(&buf, 0, 0) < 0)
+ return error("error while reading from stdin %s",
+ strerror(errno));
+
+ s->should_munmap = 0;
+ s->data = strbuf_detach(&buf, &size);
+ s->size = size;
+ s->should_free = 1;
+ s->is_stdin = 1;
+ return 0;
+}
+
+static struct diff_filespec *noindex_filespec(const char *name, int mode)
+{
+ struct diff_filespec *s;
+
+ if (!name)
+ name = "/dev/null";
+ s = alloc_filespec(name);
+ fill_filespec(s, null_sha1, mode);
+ if (name == file_from_standard_input)
+ populate_from_stdin(s);
+ return s;
+}
+
static int queue_diff(struct diff_options *o,
const char *name1, const char *name2)
{
@@ -135,15 +172,8 @@ static int queue_diff(struct diff_options *o,
tmp_c = name1; name1 = name2; name2 = tmp_c;
}
- if (!name1)
- name1 = "/dev/null";
- if (!name2)
- name2 = "/dev/null";
- d1 = alloc_filespec(name1);
- d2 = alloc_filespec(name2);
- fill_filespec(d1, null_sha1, mode1);
- fill_filespec(d2, null_sha1, mode2);
-
+ d1 = noindex_filespec(name1, mode1);
+ d2 = noindex_filespec(name2, mode2);
diff_queue(&diff_queued_diff, d1, d2);
return 0;
}
@@ -238,7 +268,7 @@ void diff_no_index(struct rev_info *revs,
* stdin should be spelled as "-"; if you have
* path that is "-", spell it as "./-".
*/
- p = p;
+ p = file_from_standard_input;
else if (prefixlen)
p = xstrdup(prefix_filename(prefix, prefixlen, p));
paths[i] = p;
diff --git a/diff.c b/diff.c
index 9038f19..d6fdb8e 100644
--- a/diff.c
+++ b/diff.c
@@ -2426,22 +2426,6 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
return 0;
}
-static int populate_from_stdin(struct diff_filespec *s)
-{
- struct strbuf buf = STRBUF_INIT;
- size_t size = 0;
-
- if (strbuf_read(&buf, 0, 0) < 0)
- return error("error while reading from stdin %s",
- strerror(errno));
-
- s->should_munmap = 0;
- s->data = strbuf_detach(&buf, &size);
- s->size = size;
- s->should_free = 1;
- return 0;
-}
-
static int diff_populate_gitlink(struct diff_filespec *s, int size_only)
{
int len;
@@ -2491,9 +2475,6 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
struct stat st;
int fd;
- if (!strcmp(s->path, "-"))
- return populate_from_stdin(s);
-
if (lstat(s->path, &st) < 0) {
if (errno == ENOENT) {
err_empty:
@@ -2855,7 +2836,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
if (DIFF_FILE_VALID(one)) {
if (!one->sha1_valid) {
struct stat st;
- if (!strcmp(one->path, "-")) {
+ if (one->is_stdin) {
hashcpy(one->sha1, null_sha1);
return;
}
diff --git a/diffcore.h b/diffcore.h
index b8f1fde..ae43149 100644
--- a/diffcore.h
+++ b/diffcore.h
@@ -43,6 +43,7 @@ struct diff_filespec {
unsigned should_free : 1; /* data should be free()'ed */
unsigned should_munmap : 1; /* data should be munmap()'ed */
unsigned dirty_submodule : 2; /* For submodules: its work tree is dirty */
+ unsigned is_stdin : 1;
#define DIRTY_SUBMODULE_UNTRACKED 1
#define DIRTY_SUBMODULE_MODIFIED 2
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index 3ad0436..e6cf6ee 100755
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -458,4 +458,16 @@ test_expect_success 'amend can copy notes' '
'
+test_expect_success 'commit a file whose name is a dash' '
+ git reset --hard &&
+ for i in 1 2 3 4 5
+ do
+ echo $i
+ done >./- &&
+ git add ./- &&
+ test_tick &&
+ git commit -m "add dash" >output </dev/null &&
+ test_i18ngrep " changed, 5 insertions" output
+'
+
test_done