1 //
2 // aegis - project change supervisor
3 // Copyright (C) 2005-2009, 2011, 2012 Peter Miller
4 // Copyright (C) 2006, 2008 Walter Franzini
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or (at
9 // your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 //
19
20 #include <common/ac/assert.h>
21
22 #include <common/nstring.h>
23 #include <libaegis/change/branch.h>
24 #include <libaegis/change/file.h>
25 #include <libaegis/file.h>
26 #include <libaegis/os.h>
27 #include <libaegis/project/file.h>
28 #include <libaegis/user.h>
29
30
31 bool
file_unchanged(fstate_src_ty * src_data,user_ty::pointer up)32 change::file_unchanged(fstate_src_ty *src_data, user_ty::pointer up)
33 {
34 //
35 // The policy only applies to simple change sets, not to branches.
36 //
37 if (was_a_branch())
38 return false;
39
40 //
41 // Leave cross branch merges alone, even if they
42 // don't change anything. The information is
43 // about the merge, not the file contents.
44 //
45 if (src_data->edit_origin_new)
46 {
47 assert(src_data->edit_origin_new->revision);
48 return false;
49 }
50
51 //
52 // Only modified files are of interest.
53 //
54 switch (src_data->action)
55 {
56 case file_action_modify:
57 case file_action_insulate:
58 break;
59
60 case file_action_create:
61 if (src_data->move)
62 break;
63 return false;
64
65 case file_action_remove:
66 case file_action_transparent:
67 return false;
68 }
69 switch (src_data->usage)
70 {
71 case file_usage_build:
72 return false;
73
74 case file_usage_config:
75 case file_usage_source:
76 case file_usage_test:
77 case file_usage_manual_test:
78 break;
79 }
80
81 //
82 // The file could have vanished from under us,
83 // so make sure this is sensable.
84 //
85 fstate_src_ty *psrc_data = pp->file_find(src_data, view_path_extreme);
86 if (!psrc_data)
87 return false;
88
89 //
90 // Get the path of the project file to be compared against.
91 //
92 int blf_unlink = 0;
93 string_ty *tmp = project_file_path(pp, psrc_data->file_name);
94 nstring blf(tmp);
95 str_free(tmp);
96 assert(!blf.empty());
97 up->become_begin();
98 int blf_exists = os_exists(blf);
99 up->become_end();
100 assert(blf_exists);
101 if (!blf_exists)
102 {
103 blf = nstring(project_file_version_path(pp, src_data, &blf_unlink));
104 assert(!blf.empty());
105 }
106
107 //
108 // Get the path of the change file to be compared against.
109 //
110 nstring cfp(file_path(src_data->file_name));
111 assert(cfp);
112 if (!cfp)
113 return false;
114
115 //
116 // If any of the file's attributes have changed, the file is
117 // different, too.
118 //
119 if (!str_equal(src_data->file_name, psrc_data->file_name))
120 return false;
121 if (src_data->usage != psrc_data->usage)
122 return false;
123 if
124 (
125 (src_data->attribute ? src_data->attribute->length : 0)
126 !=
127 (psrc_data->attribute ? psrc_data->attribute->length : 0)
128 )
129 return false;
130 if (src_data->attribute && src_data->attribute->length)
131 {
132 assert(psrc_data->attribute);
133 for (size_t j = 0; j < src_data->attribute->length; ++j)
134 {
135 attributes_ty *p1 = src_data->attribute->list[j];
136 attributes_ty *p2 = psrc_data->attribute->list[j];
137 if (p1 && p2)
138 {
139 if (p1->name && p2->name && !str_equal(p1->name, p2->name))
140 return false;
141 if (p1->value && p2->value && !str_equal(p1->value, p2->value))
142 return false;
143 }
144 }
145 }
146
147 //
148 // Perform the comparison.
149 //
150 up->become_begin();
151 bool different = files_are_different(cfp, blf);
152 up->become_end();
153 if (blf_unlink)
154 {
155 os_become_orig();
156 os_unlink(blf);
157 os_become_undo();
158 }
159 return !different;
160 }
161
162
163 // vim: set ts=8 sw=4 et :
164