blob: 884d45246f97a5276d6d5e83222427b83c35f69d [file] [log] [blame]
Linus Torvalds8bc9a0c2005-04-07 15:16:10 -07001/*
2 * GIT - The information manager from hell
3 *
4 * Copyright (C) Linus Torvalds, 2005
5 */
Linus Torvaldse83c5162005-04-07 15:13:13 -07006#include "cache.h"
Junio C Hamano4a6bf9e2005-04-27 09:21:00 -07007#include "diff.h"
Christopher Lic0fb9762005-04-12 02:04:44 -07008
Nicolas Pitre17710392005-04-30 13:59:38 -07009static const char *diff_files_usage =
Junio C Hamano52e95782005-05-21 02:40:01 -070010"git-diff-files [-p] [-q] [-r] [-z] [-M] [-C] [-R] [-S<string>] [paths...]";
Junio C Hamanob8f80922005-04-16 21:29:45 -070011
Junio C Hamano81e50ea2005-05-21 19:42:18 -070012static int diff_output_format = DIFF_FORMAT_HUMAN;
Junio C Hamano5c975582005-05-19 03:32:35 -070013static int detect_rename = 0;
Junio C Hamano57fe64a2005-05-19 19:00:36 -070014static int reverse_diff = 0;
15static int diff_score_opt = 0;
Junio C Hamano057c7d32005-05-21 15:02:51 -070016static const char *pickaxe = NULL;
Linus Torvalds0a7668e2005-04-26 17:17:36 -070017static int silent = 0;
Linus Torvalds0a7668e2005-04-26 17:17:36 -070018
Junio C Hamanob8f80922005-04-16 21:29:45 -070019static int matches_pathspec(struct cache_entry *ce, char **spec, int cnt)
20{
21 int i;
22 int namelen = ce_namelen(ce);
23 for (i = 0; i < cnt; i++) {
24 int speclen = strlen(spec[i]);
25 if (! strncmp(spec[i], ce->name, speclen) &&
26 speclen <= namelen &&
27 (ce->name[speclen] == 0 ||
28 ce->name[speclen] == '/'))
29 return 1;
30 }
31 return 0;
32}
33
Junio C Hamano4a6bf9e2005-04-27 09:21:00 -070034static void show_unmerge(const char *path)
Linus Torvalds0a7668e2005-04-26 17:17:36 -070035{
Junio C Hamano57fe64a2005-05-19 19:00:36 -070036 diff_unmerge(path);
Junio C Hamano4a6bf9e2005-04-27 09:21:00 -070037}
38
39static void show_file(int pfx, struct cache_entry *ce)
40{
Junio C Hamano57fe64a2005-05-19 19:00:36 -070041 diff_addremove(pfx, ntohl(ce->ce_mode), ce->sha1, ce->name, NULL);
Junio C Hamano4a6bf9e2005-04-27 09:21:00 -070042}
43
44static void show_modified(int oldmode, int mode,
Brian Gerstbf0f9102005-05-18 08:14:09 -040045 const unsigned char *old_sha1, const unsigned char *sha1,
Junio C Hamano4a6bf9e2005-04-27 09:21:00 -070046 char *path)
47{
Junio C Hamano57fe64a2005-05-19 19:00:36 -070048 diff_change(oldmode, mode, old_sha1, sha1, path, NULL);
Linus Torvalds0a7668e2005-04-26 17:17:36 -070049}
50
Linus Torvaldse83c5162005-04-07 15:13:13 -070051int main(int argc, char **argv)
52{
Brian Gerstbf0f9102005-05-18 08:14:09 -040053 static const unsigned char null_sha1[20] = { 0, };
Linus Torvaldse83c5162005-04-07 15:13:13 -070054 int entries = read_cache();
55 int i;
56
Junio C Hamanob8f80922005-04-16 21:29:45 -070057 while (1 < argc && argv[1][0] == '-') {
Junio C Hamanod15aa432005-04-27 15:22:02 -070058 if (!strcmp(argv[1], "-p"))
Junio C Hamano81e50ea2005-05-21 19:42:18 -070059 diff_output_format = DIFF_FORMAT_PATCH;
Junio C Hamanob8f80922005-04-16 21:29:45 -070060 else if (!strcmp(argv[1], "-q"))
Junio C Hamanod15aa432005-04-27 15:22:02 -070061 silent = 1;
Linus Torvalds0a7668e2005-04-26 17:17:36 -070062 else if (!strcmp(argv[1], "-r"))
Junio C Hamano4a6bf9e2005-04-27 09:21:00 -070063 ; /* no-op */
Junio C Hamanod15aa432005-04-27 15:22:02 -070064 else if (!strcmp(argv[1], "-s"))
65 ; /* no-op */
66 else if (!strcmp(argv[1], "-z"))
Junio C Hamano81e50ea2005-05-21 19:42:18 -070067 diff_output_format = DIFF_FORMAT_MACHINE;
Junio C Hamano57fe64a2005-05-19 19:00:36 -070068 else if (!strcmp(argv[1], "-R"))
69 reverse_diff = 1;
Junio C Hamano52e95782005-05-21 02:40:01 -070070 else if (!strcmp(argv[1], "-S"))
71 pickaxe = argv[1] + 2;
Junio C Hamano57fe64a2005-05-19 19:00:36 -070072 else if (!strncmp(argv[1], "-M", 2)) {
73 diff_score_opt = diff_scoreopt_parse(argv[1]);
Junio C Hamano81e50ea2005-05-21 19:42:18 -070074 detect_rename = 1;
Junio C Hamano5c975582005-05-19 03:32:35 -070075 }
Junio C Hamano427dcb42005-05-21 02:39:09 -070076 else if (!strncmp(argv[1], "-C", 2)) {
77 diff_score_opt = diff_scoreopt_parse(argv[1]);
78 detect_rename = 2;
Junio C Hamano427dcb42005-05-21 02:39:09 -070079 }
Junio C Hamanob8f80922005-04-16 21:29:45 -070080 else
Nicolas Pitre17710392005-04-30 13:59:38 -070081 usage(diff_files_usage);
Junio C Hamanob8f80922005-04-16 21:29:45 -070082 argv++; argc--;
Petr Baudise2e5e982005-04-13 01:40:09 -070083 }
84
Junio C Hamanob8f80922005-04-16 21:29:45 -070085 /* At this point, if argc == 1, then we are doing everything.
86 * Otherwise argv[1] .. argv[argc-1] have the explicit paths.
87 */
Linus Torvaldse83c5162005-04-07 15:13:13 -070088 if (entries < 0) {
89 perror("read_cache");
90 exit(1);
91 }
Junio C Hamanobe3cfa82005-04-26 09:25:05 -070092
Junio C Hamano81e50ea2005-05-21 19:42:18 -070093 diff_setup(reverse_diff, diff_output_format);
Junio C Hamano5c975582005-05-19 03:32:35 -070094
Linus Torvaldse83c5162005-04-07 15:13:13 -070095 for (i = 0; i < entries; i++) {
96 struct stat st;
Linus Torvalds0a7668e2005-04-26 17:17:36 -070097 unsigned int oldmode, mode;
Linus Torvaldse83c5162005-04-07 15:13:13 -070098 struct cache_entry *ce = active_cache[i];
Junio C Hamanod94c6122005-04-16 21:29:45 -070099 int changed;
Linus Torvaldse83c5162005-04-07 15:13:13 -0700100
Junio C Hamanod2522a62005-04-16 21:29:45 -0700101 if (1 < argc &&
Junio C Hamanob8f80922005-04-16 21:29:45 -0700102 ! matches_pathspec(ce, argv+1, argc-1))
103 continue;
104
Junio C Hamano9fec8b22005-04-16 21:29:45 -0700105 if (ce_stage(ce)) {
Junio C Hamano4a6bf9e2005-04-27 09:21:00 -0700106 show_unmerge(ce->name);
Junio C Hamano9fec8b22005-04-16 21:29:45 -0700107 while (i < entries &&
108 !strcmp(ce->name, active_cache[i]->name))
109 i++;
110 i--; /* compensate for loop control increments */
111 continue;
112 }
Junio C Hamano57fe64a2005-05-19 19:00:36 -0700113
Kay Sieversffbe1ad2005-05-06 15:45:01 +0200114 if (lstat(ce->name, &st) < 0) {
Junio C Hamano41174692005-05-20 09:48:38 -0700115 if (errno != ENOENT && errno != ENOTDIR) {
Linus Torvalds0a7668e2005-04-26 17:17:36 -0700116 perror(ce->name);
Junio C Hamanoca2a0792005-04-15 15:08:09 -0700117 continue;
Junio C Hamano57fe64a2005-05-19 19:00:36 -0700118 }
Junio C Hamanod15aa432005-04-27 15:22:02 -0700119 if (silent)
Linus Torvalds0a7668e2005-04-26 17:17:36 -0700120 continue;
Junio C Hamano4a6bf9e2005-04-27 09:21:00 -0700121 show_file('-', ce);
Linus Torvaldse83c5162005-04-07 15:13:13 -0700122 continue;
123 }
Brad Roberts5d728c82005-05-14 19:04:25 -0700124 changed = ce_match_stat(ce, &st);
Junio C Hamanoc3e7fbc2005-05-21 02:42:35 -0700125 if (!changed && detect_rename < 2)
Linus Torvaldse83c5162005-04-07 15:13:13 -0700126 continue;
Petr Baudise2e5e982005-04-13 01:40:09 -0700127
Linus Torvalds0a7668e2005-04-26 17:17:36 -0700128 oldmode = ntohl(ce->ce_mode);
Junio C Hamano95649d62005-05-12 16:51:08 -0700129 mode = (S_ISLNK(st.st_mode) ? S_IFLNK :
130 S_IFREG | ce_permissions(st.st_mode));
Linus Torvalds0a7668e2005-04-26 17:17:36 -0700131
Junio C Hamano4a6bf9e2005-04-27 09:21:00 -0700132 show_modified(oldmode, mode, ce->sha1, null_sha1,
133 ce->name);
Linus Torvaldse83c5162005-04-07 15:13:13 -0700134 }
Junio C Hamano38c6f782005-05-21 19:40:36 -0700135 if (detect_rename)
136 diff_detect_rename(detect_rename, diff_score_opt);
137 if (pickaxe)
138 diff_pickaxe(pickaxe);
139 diff_flush(NULL, 0);
Linus Torvaldse83c5162005-04-07 15:13:13 -0700140 return 0;
141}