add --path option to git hash-object
The --path option allows us to pretend as if the contents being hashed came from the specified path, and affects which input filter is used via the attributes mechanism. This is useful for hashing a temporary file whose name is different from the path that is meant to have the hashed contents. Signed-off-by: Dmitry Potapov <dpotapov@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Dmitry Potapov committed
Aug 3, 2008 at 18:36 UTC
39702431500b76425f047209c9e9b2aae7e92b00
3 files changed
+48
-7
Documentation/git-hash-object.txt
+11
-1
@@ -9,7 +9,7 @@ git-hash-object - Compute object ID and optionally creates a blob from a file
9
SYNOPSIS
10
--------
11
[verse]
12
-'git hash-object' [-t <type>] [-w] [--stdin] [--] <file>...
12
+'git hash-object' [-t <type>] [-w] [--path=<file>] [--stdin] [--] <file>...
13
'git hash-object' [-t <type>] [-w] --stdin-paths < <list-of-paths>
14
15
DESCRIPTION
@@ -37,6 +37,16 @@ OPTIONS
37
--stdin-paths::
38
Read file names from stdin instead of from the command-line.
39
40
+--path::
41
+ Hash object as it were located at the given path. The location of
42
+ file does not directly influence on the hash value, but path is
43
+ used to determine what git filters should be applied to the object
44
+ before it can be placed to the object database, and, as result of
45
+ applying filters, the actual blob put into the object database may
46
+ differ from the given file. This option is mainly useful for hashing
47
+ temporary files located outside of the working directory or files
48
+ read from stdin.
49
+
50
Author
51
------
52
Written by Junio C Hamano <gitster@pobox.com>
hash-object.c
+13
-6
@@ -22,13 +22,14 @@ static void hash_fd(int fd, const char *type, int write_object, const char *path
22
maybe_flush_or_die(stdout, "hash to stdout");
23
}
24
25
-static void hash_object(const char *path, const char *type, int write_object)
25
+static void hash_object(const char *path, const char *type, int write_object,
26
+ const char *vpath)
27
{
28
int fd;
29
fd = open(path, O_RDONLY);
30
if (fd < 0)
31
die("Cannot open %s", path);
31
- hash_fd(fd, type, write_object, path);
32
+ hash_fd(fd, type, write_object, vpath);
33
}
34
35
static void hash_stdin_paths(const char *type, int write_objects)
@@ -44,14 +45,14 @@ static void hash_stdin_paths(const char *type, int write_objects)
45
die("line is badly quoted");
46
strbuf_swap(&buf, &nbuf);
47
}
47
- hash_object(buf.buf, type, write_objects);
48
+ hash_object(buf.buf, type, write_objects, buf.buf);
49
}
50
strbuf_release(&buf);
51
strbuf_release(&nbuf);
52
}
53
54
static const char * const hash_object_usage[] = {
54
- "git hash-object [-t <type>] [-w] [--stdin] [--] <file>...",
55
+ "git hash-object [-t <type>] [-w] [--path=<file>] [--stdin] [--] <file>...",
56
"git hash-object --stdin-paths < <list-of-paths>",
57
NULL
58
};
@@ -60,12 +61,14 @@ static const char *type;
61
static int write_object;
62
static int hashstdin;
63
static int stdin_paths;
64
+static const char *vpath;
65
66
static const struct option hash_object_options[] = {
67
OPT_STRING('t', NULL, &type, "type", "object type"),
68
OPT_BOOLEAN('w', NULL, &write_object, "write the object into the object database"),
69
OPT_BOOLEAN( 0 , "stdin", &hashstdin, "read the object from stdin"),
70
OPT_BOOLEAN( 0 , "stdin-paths", &stdin_paths, "read file names from stdin"),
71
+ OPT_STRING( 0 , "path", &vpath, "file", "process file as it were from this path"),
72
OPT_END()
73
};
74
@@ -85,6 +88,8 @@ int main(int argc, const char **argv)
88
if (write_object) {
89
prefix = setup_git_directory();
90
prefix_length = prefix ? strlen(prefix) : 0;
91
+ if (vpath && prefix)
92
+ vpath = prefix_filename(prefix, prefix_length, vpath);
93
}
94
95
if (stdin_paths) {
@@ -92,6 +97,8 @@ int main(int argc, const char **argv)
97
errstr = "Can't use --stdin-paths with --stdin";
98
else if (argc)
99
errstr = "Can't specify files with --stdin-paths";
100
+ else if (vpath)
101
+ errstr = "Can't use --stdin-paths with --path";
102
}
103
else if (hashstdin > 1)
104
errstr = "Multiple --stdin arguments are not supported";
@@ -102,14 +109,14 @@ int main(int argc, const char **argv)
109
}
110
111
if (hashstdin)
105
- hash_fd(0, type, write_object, NULL);
112
+ hash_fd(0, type, write_object, vpath);
113
114
for (i = 0 ; i < argc; i++) {
115
const char *arg = argv[i];
116
117
if (0 <= prefix_length)
118
arg = prefix_filename(prefix, prefix_length, arg);
112
- hash_object(arg, type, write_object);
119
+ hash_object(arg, type, write_object, vpath ? vpath : arg);
120
}
121
122
if (stdin_paths)
t/t1007-hash-object.sh
+24
@@ -61,6 +61,10 @@ test_expect_success "Can't pass filenames as arguments with --stdin-paths" '
61
echo example | test_must_fail git hash-object --stdin-paths hello
62
'
63
64
+test_expect_success "Can't use --path with --stdin-paths" '
65
+ echo example | test_must_fail git hash-object --stdin-paths --path=foo
66
+'
67
+
68
# Behavior
69
70
push_repo
@@ -93,6 +97,26 @@ test_expect_success 'git hash-object --stdin file1 <file0 first operates on file
97
test "$obname1" = "$obname1new"
98
'
99
100
+test_expect_success 'check that appropriate filter is invoke when --path is used' '
101
+ echo fooQ | tr Q "\\015" >file0 &&
102
+ cp file0 file1 &&
103
+ echo "file0 -crlf" >.gitattributes &&
104
+ echo "file1 crlf" >>.gitattributes &&
105
+ git config core.autocrlf true &&
106
+ file0_sha=$(git hash-object file0) &&
107
+ file1_sha=$(git hash-object file1) &&
108
+ test "$file0_sha" != "$file1_sha" &&
109
+ path1_sha=$(git hash-object --path=file1 file0) &&
110
+ path0_sha=$(git hash-object --path=file0 file1) &&
111
+ test "$file0_sha" = "$path0_sha" &&
112
+ test "$file1_sha" = "$path1_sha" &&
113
+ path1_sha=$(cat file0 | git hash-object --path=file1 --stdin) &&
114
+ path0_sha=$(cat file1 | git hash-object --path=file0 --stdin) &&
115
+ test "$file0_sha" = "$path0_sha" &&
116
+ test "$file1_sha" = "$path1_sha" &&
117
+ git config --unset core.autocrlf
118
+'
119
+
120
pop_repo
121
122
for args in "-w --stdin" "--stdin -w"; do