Fossil SCM

Added revision support to diff and revert

jnc 2007-09-26 03:37 trunk
Commit 574763bab9eb73a4cdf733c331bc596866d53c7c
3 files changed +26 +38 -54 +18 -10
--- src/content.c
+++ src/content.c
@@ -74,10 +74,36 @@
7474
}
7575
db_finalize(&q);
7676
}
7777
return rc;
7878
}
79
+
80
+/*
81
+** Get the contents of a file within a given revision.
82
+*/
83
+int content_get_historical_file(const char *revision, const char *file, Blob *content){
84
+ Blob mfile;
85
+ Manifest m;
86
+ int i, rid=0;
87
+
88
+ rid = name_to_rid(revision);
89
+ content_get(rid, &mfile);
90
+
91
+ if( manifest_parse(&m, &mfile) ){
92
+ for(i=0; i<m.nFile; i++){
93
+ if( strcmp(m.aFile[i].zName, file)==0 ){
94
+ rid = uuid_to_rid(m.aFile[i].zUuid, 0);
95
+ return content_get(rid, content);
96
+ }
97
+ }
98
+ fossil_panic("file: %s does not exist in revision: %s", file, revision);
99
+ }else{
100
+ fossil_panic("could not parse manifest for revision: %s", revision);
101
+ }
102
+
103
+ return 0;
104
+}
79105
80106
/*
81107
** COMMAND: test-content-get
82108
**
83109
** Extract a blob from the database and write it into a file.
84110
--- src/content.c
+++ src/content.c
@@ -74,10 +74,36 @@
74 }
75 db_finalize(&q);
76 }
77 return rc;
78 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
80 /*
81 ** COMMAND: test-content-get
82 **
83 ** Extract a blob from the database and write it into a file.
84
--- src/content.c
+++ src/content.c
@@ -74,10 +74,36 @@
74 }
75 db_finalize(&q);
76 }
77 return rc;
78 }
79
80 /*
81 ** Get the contents of a file within a given revision.
82 */
83 int content_get_historical_file(const char *revision, const char *file, Blob *content){
84 Blob mfile;
85 Manifest m;
86 int i, rid=0;
87
88 rid = name_to_rid(revision);
89 content_get(rid, &mfile);
90
91 if( manifest_parse(&m, &mfile) ){
92 for(i=0; i<m.nFile; i++){
93 if( strcmp(m.aFile[i].zName, file)==0 ){
94 rid = uuid_to_rid(m.aFile[i].zUuid, 0);
95 return content_get(rid, content);
96 }
97 }
98 fossil_panic("file: %s does not exist in revision: %s", file, revision);
99 }else{
100 fossil_panic("could not parse manifest for revision: %s", revision);
101 }
102
103 return 0;
104 }
105
106 /*
107 ** COMMAND: test-content-get
108 **
109 ** Extract a blob from the database and write it into a file.
110
+38 -54
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -44,11 +44,11 @@
4444
4545
/*
4646
** COMMAND: diff
4747
** COMMAND: gdiff
4848
**
49
-** Usage: %fossil diff|gdiff ?-i FILE...
49
+** Usage: %fossil diff|gdiff ?-i ?-r REVISION FILE...
5050
**
5151
** Show the difference between the current version of a file (as it
5252
** exists on disk) and that same file as it was checked out.
5353
**
5454
** diff will show a textual diff while gdiff will attempt to run a
@@ -69,18 +69,20 @@
6969
** %fossil config gdiff-command=meld
7070
** %fossil config gdiff-command=xxdiff
7171
** %fossil config gdiff-command=kdiff3
7272
*/
7373
void diff_cmd(void){
74
- const char *zFile;
74
+ const char *zFile, *zRevision;
7575
Blob cmd;
7676
Blob fname;
77
- int i, internalDiff;
78
- char *zV1 = 0;
79
- char *zV2 = 0;
77
+ Blob vname;
78
+ Blob record;
79
+ int cnt=0,internalDiff;
8080
8181
internalDiff = find_option("internal","i",0)!=0;
82
+ zRevision = find_option("revision", "r", 1);
83
+ verify_all_options();
8284
8385
if( g.argc<3 ){
8486
usage("?OPTIONS? FILE");
8587
}
8688
db_must_be_within_tree();
@@ -96,66 +98,48 @@
9698
internalDiff=1;
9799
}
98100
blob_zero(&cmd);
99101
blob_appendf(&cmd, "%s ", zExternalCommand);
100102
}
101
- for(i=2; i<g.argc-1; i++){
102
- const char *z = g.argv[i];
103
- if( (strcmp(z,"-v")==0 || strcmp(z,"--version")==0) && i<g.argc-2 ){
104
- if( zV1==0 ){
105
- zV1 = g.argv[i+1];
106
- }else if( zV2==0 ){
107
- zV2 = g.argv[i+1];
108
- }else{
109
- fossil_panic("too many versions");
110
- }
111
- }else{
112
- if( internalDiff==0 ){
113
- blob_appendf(&cmd, "%s ", z);
114
- }
115
- }
116
- }
117103
zFile = g.argv[g.argc-1];
118104
if( !file_tree_name(zFile, &fname) ){
119105
fossil_panic("unknown file: %s", zFile);
120106
}
121
- if( zV1==0 ){
107
+
108
+ blob_zero(&vname);
109
+ do{
110
+ blob_reset(&vname);
111
+ blob_appendf(&vname, "%s~%d", zFile, cnt++);
112
+ }while( access(blob_str(&vname),0)==0 );
113
+
114
+ if( zRevision==0 ){
122115
int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname);
123
- Blob record;
124
- Blob vname;
125
- int cnt = 0;
126
-
127116
if( rid==0 ){
128117
fossil_panic("no history for file: %b", &fname);
129118
}
130
- blob_zero(&vname);
131
- do{
132
- blob_reset(&vname);
133
- blob_appendf(&vname, "%s~%d", zFile, cnt++);
134
- }while( access(blob_str(&vname),0)==0 );
135119
content_get(rid, &record);
136
- if( internalDiff==1 ){
137
- Blob current;
138
- Blob out;
139
- blob_zero(&current);
140
- blob_read_from_file(&current, zFile);
141
- blob_zero(&out);
142
- unified_diff(&record, &current, 5, &out);
143
- printf("%s\n", blob_str(&out));
144
- blob_reset(&current);
145
- blob_reset(&out);
146
- }else{
147
- blob_write_to_file(&record, blob_str(&vname));
148
- blob_reset(&record);
149
- shell_escape(&cmd, blob_str(&vname));
150
- blob_appendf(&cmd, " ");
151
- shell_escape(&cmd, zFile);
152
- system(blob_str(&cmd));
153
- unlink(blob_str(&vname));
154
- blob_reset(&vname);
155
- blob_reset(&cmd);
156
- }
157
- }else{
158
- fossil_panic("not yet implemented");
120
+ }else{
121
+ content_get_historical_file(zRevision, zFile, &record);
122
+ }
123
+ if( internalDiff==1 ){
124
+ Blob out;
125
+ Blob current;
126
+ blob_zero(&current);
127
+ blob_read_from_file(&current, zFile);
128
+ blob_zero(&out);
129
+ unified_diff(&record, &current, 5, &out);
130
+ printf("%s\n", blob_str(&out));
131
+ blob_reset(&current);
132
+ blob_reset(&out);
133
+ }else{
134
+ blob_write_to_file(&record, blob_str(&vname));
135
+ blob_reset(&record);
136
+ shell_escape(&cmd, blob_str(&vname));
137
+ blob_appendf(&cmd, " ");
138
+ shell_escape(&cmd, zFile);
139
+ system(blob_str(&cmd));
140
+ unlink(blob_str(&vname));
141
+ blob_reset(&vname);
142
+ blob_reset(&cmd);
159143
}
160144
blob_reset(&fname);
161145
}
162146
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -44,11 +44,11 @@
44
45 /*
46 ** COMMAND: diff
47 ** COMMAND: gdiff
48 **
49 ** Usage: %fossil diff|gdiff ?-i FILE...
50 **
51 ** Show the difference between the current version of a file (as it
52 ** exists on disk) and that same file as it was checked out.
53 **
54 ** diff will show a textual diff while gdiff will attempt to run a
@@ -69,18 +69,20 @@
69 ** %fossil config gdiff-command=meld
70 ** %fossil config gdiff-command=xxdiff
71 ** %fossil config gdiff-command=kdiff3
72 */
73 void diff_cmd(void){
74 const char *zFile;
75 Blob cmd;
76 Blob fname;
77 int i, internalDiff;
78 char *zV1 = 0;
79 char *zV2 = 0;
80
81 internalDiff = find_option("internal","i",0)!=0;
 
 
82
83 if( g.argc<3 ){
84 usage("?OPTIONS? FILE");
85 }
86 db_must_be_within_tree();
@@ -96,66 +98,48 @@
96 internalDiff=1;
97 }
98 blob_zero(&cmd);
99 blob_appendf(&cmd, "%s ", zExternalCommand);
100 }
101 for(i=2; i<g.argc-1; i++){
102 const char *z = g.argv[i];
103 if( (strcmp(z,"-v")==0 || strcmp(z,"--version")==0) && i<g.argc-2 ){
104 if( zV1==0 ){
105 zV1 = g.argv[i+1];
106 }else if( zV2==0 ){
107 zV2 = g.argv[i+1];
108 }else{
109 fossil_panic("too many versions");
110 }
111 }else{
112 if( internalDiff==0 ){
113 blob_appendf(&cmd, "%s ", z);
114 }
115 }
116 }
117 zFile = g.argv[g.argc-1];
118 if( !file_tree_name(zFile, &fname) ){
119 fossil_panic("unknown file: %s", zFile);
120 }
121 if( zV1==0 ){
 
 
 
 
 
 
 
122 int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname);
123 Blob record;
124 Blob vname;
125 int cnt = 0;
126
127 if( rid==0 ){
128 fossil_panic("no history for file: %b", &fname);
129 }
130 blob_zero(&vname);
131 do{
132 blob_reset(&vname);
133 blob_appendf(&vname, "%s~%d", zFile, cnt++);
134 }while( access(blob_str(&vname),0)==0 );
135 content_get(rid, &record);
136 if( internalDiff==1 ){
137 Blob current;
138 Blob out;
139 blob_zero(&current);
140 blob_read_from_file(&current, zFile);
141 blob_zero(&out);
142 unified_diff(&record, &current, 5, &out);
143 printf("%s\n", blob_str(&out));
144 blob_reset(&current);
145 blob_reset(&out);
146 }else{
147 blob_write_to_file(&record, blob_str(&vname));
148 blob_reset(&record);
149 shell_escape(&cmd, blob_str(&vname));
150 blob_appendf(&cmd, " ");
151 shell_escape(&cmd, zFile);
152 system(blob_str(&cmd));
153 unlink(blob_str(&vname));
154 blob_reset(&vname);
155 blob_reset(&cmd);
156 }
157 }else{
158 fossil_panic("not yet implemented");
159 }
160 blob_reset(&fname);
161 }
162
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -44,11 +44,11 @@
44
45 /*
46 ** COMMAND: diff
47 ** COMMAND: gdiff
48 **
49 ** Usage: %fossil diff|gdiff ?-i ?-r REVISION FILE...
50 **
51 ** Show the difference between the current version of a file (as it
52 ** exists on disk) and that same file as it was checked out.
53 **
54 ** diff will show a textual diff while gdiff will attempt to run a
@@ -69,18 +69,20 @@
69 ** %fossil config gdiff-command=meld
70 ** %fossil config gdiff-command=xxdiff
71 ** %fossil config gdiff-command=kdiff3
72 */
73 void diff_cmd(void){
74 const char *zFile, *zRevision;
75 Blob cmd;
76 Blob fname;
77 Blob vname;
78 Blob record;
79 int cnt=0,internalDiff;
80
81 internalDiff = find_option("internal","i",0)!=0;
82 zRevision = find_option("revision", "r", 1);
83 verify_all_options();
84
85 if( g.argc<3 ){
86 usage("?OPTIONS? FILE");
87 }
88 db_must_be_within_tree();
@@ -96,66 +98,48 @@
98 internalDiff=1;
99 }
100 blob_zero(&cmd);
101 blob_appendf(&cmd, "%s ", zExternalCommand);
102 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103 zFile = g.argv[g.argc-1];
104 if( !file_tree_name(zFile, &fname) ){
105 fossil_panic("unknown file: %s", zFile);
106 }
107
108 blob_zero(&vname);
109 do{
110 blob_reset(&vname);
111 blob_appendf(&vname, "%s~%d", zFile, cnt++);
112 }while( access(blob_str(&vname),0)==0 );
113
114 if( zRevision==0 ){
115 int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname);
 
 
 
 
116 if( rid==0 ){
117 fossil_panic("no history for file: %b", &fname);
118 }
 
 
 
 
 
119 content_get(rid, &record);
120 }else{
121 content_get_historical_file(zRevision, zFile, &record);
122 }
123 if( internalDiff==1 ){
124 Blob out;
125 Blob current;
126 blob_zero(&current);
127 blob_read_from_file(&current, zFile);
128 blob_zero(&out);
129 unified_diff(&record, &current, 5, &out);
130 printf("%s\n", blob_str(&out));
131 blob_reset(&current);
132 blob_reset(&out);
133 }else{
134 blob_write_to_file(&record, blob_str(&vname));
135 blob_reset(&record);
136 shell_escape(&cmd, blob_str(&vname));
137 blob_appendf(&cmd, " ");
138 shell_escape(&cmd, zFile);
139 system(blob_str(&cmd));
140 unlink(blob_str(&vname));
141 blob_reset(&vname);
142 blob_reset(&cmd);
143 }
144 blob_reset(&fname);
145 }
146
+18 -10
--- src/update.c
+++ src/update.c
@@ -221,52 +221,60 @@
221221
}
222222
223223
/*
224224
** COMMAND: revert
225225
**
226
-** Usage: %fossil revert ?-yes FILE
226
+** Usage: %fossil revert ?-yes ?-r REVISION FILE
227227
**
228228
** Revert to the current repository version of FILE. This
229229
** command will confirm your operation, unless you do so
230230
** at the command line via the -yes option.
231231
**/
232232
void revert_cmd(void){
233233
const char *zFile;
234
+ const char *zRevision;
234235
Blob fname;
235236
Blob record;
236237
Blob ans;
237
- int rid, yesRevert;
238
+ int rid = 0, yesRevert;
238239
239
- yesRevert = find_option("yes","y", 0)!=0;
240
+ yesRevert = find_option("yes", "y", 0)!=0;
241
+ zRevision = find_option("revision", "r", 1);
240242
verify_all_options();
241243
242244
if( g.argc<3 ){
243245
usage("?OPTIONS FILE");
244246
}
245247
db_must_be_within_tree();
246248
247249
zFile = g.argv[g.argc-1];
250
+
248251
if( !file_tree_name(zFile, &fname) ){
249252
fossil_panic("unknown file: %s", zFile);
250253
}
251
- rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname);
252
-
253
- if( rid==0 ){
254
- fossil_panic("no history for file: %b", &fname);
255
- }
256
-
254
+
257255
if( yesRevert==0 ){
258256
char *prompt = mprintf("revert file %B? this will destroy local changes [y/N]? ",
259257
&fname);
260258
blob_zero(&ans);
261259
prompt_user(prompt, &ans);
262260
if( blob_str(&ans)[0]=='y' ){
263261
yesRevert = 1;
264262
}
265263
}
266
- if( yesRevert==1 ){
264
+
265
+ if( yesRevert==1 && zRevision!=0 ){
266
+ content_get_historical_file(zRevision, zFile, &record);
267
+ }else if( yesRevert==1 ){
268
+ rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname);
269
+ if( rid==0 ){
270
+ fossil_panic("no history for file: %b", &fname);
271
+ }
267272
content_get(rid, &record);
273
+ }
274
+
275
+ if( yesRevert==1 ){
268276
blob_write_to_file(&record, blob_str(&fname));
269277
printf("%s reverted\n", blob_str(&fname));
270278
blob_reset(&record);
271279
blob_reset(&fname);
272280
}else{
273281
--- src/update.c
+++ src/update.c
@@ -221,52 +221,60 @@
221 }
222
223 /*
224 ** COMMAND: revert
225 **
226 ** Usage: %fossil revert ?-yes FILE
227 **
228 ** Revert to the current repository version of FILE. This
229 ** command will confirm your operation, unless you do so
230 ** at the command line via the -yes option.
231 **/
232 void revert_cmd(void){
233 const char *zFile;
 
234 Blob fname;
235 Blob record;
236 Blob ans;
237 int rid, yesRevert;
238
239 yesRevert = find_option("yes","y", 0)!=0;
 
240 verify_all_options();
241
242 if( g.argc<3 ){
243 usage("?OPTIONS FILE");
244 }
245 db_must_be_within_tree();
246
247 zFile = g.argv[g.argc-1];
 
248 if( !file_tree_name(zFile, &fname) ){
249 fossil_panic("unknown file: %s", zFile);
250 }
251 rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname);
252
253 if( rid==0 ){
254 fossil_panic("no history for file: %b", &fname);
255 }
256
257 if( yesRevert==0 ){
258 char *prompt = mprintf("revert file %B? this will destroy local changes [y/N]? ",
259 &fname);
260 blob_zero(&ans);
261 prompt_user(prompt, &ans);
262 if( blob_str(&ans)[0]=='y' ){
263 yesRevert = 1;
264 }
265 }
266 if( yesRevert==1 ){
 
 
 
 
 
 
 
267 content_get(rid, &record);
 
 
 
268 blob_write_to_file(&record, blob_str(&fname));
269 printf("%s reverted\n", blob_str(&fname));
270 blob_reset(&record);
271 blob_reset(&fname);
272 }else{
273
--- src/update.c
+++ src/update.c
@@ -221,52 +221,60 @@
221 }
222
223 /*
224 ** COMMAND: revert
225 **
226 ** Usage: %fossil revert ?-yes ?-r REVISION FILE
227 **
228 ** Revert to the current repository version of FILE. This
229 ** command will confirm your operation, unless you do so
230 ** at the command line via the -yes option.
231 **/
232 void revert_cmd(void){
233 const char *zFile;
234 const char *zRevision;
235 Blob fname;
236 Blob record;
237 Blob ans;
238 int rid = 0, yesRevert;
239
240 yesRevert = find_option("yes", "y", 0)!=0;
241 zRevision = find_option("revision", "r", 1);
242 verify_all_options();
243
244 if( g.argc<3 ){
245 usage("?OPTIONS FILE");
246 }
247 db_must_be_within_tree();
248
249 zFile = g.argv[g.argc-1];
250
251 if( !file_tree_name(zFile, &fname) ){
252 fossil_panic("unknown file: %s", zFile);
253 }
254
 
 
 
 
 
255 if( yesRevert==0 ){
256 char *prompt = mprintf("revert file %B? this will destroy local changes [y/N]? ",
257 &fname);
258 blob_zero(&ans);
259 prompt_user(prompt, &ans);
260 if( blob_str(&ans)[0]=='y' ){
261 yesRevert = 1;
262 }
263 }
264
265 if( yesRevert==1 && zRevision!=0 ){
266 content_get_historical_file(zRevision, zFile, &record);
267 }else if( yesRevert==1 ){
268 rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B", &fname);
269 if( rid==0 ){
270 fossil_panic("no history for file: %b", &fname);
271 }
272 content_get(rid, &record);
273 }
274
275 if( yesRevert==1 ){
276 blob_write_to_file(&record, blob_str(&fname));
277 printf("%s reverted\n", blob_str(&fname));
278 blob_reset(&record);
279 blob_reset(&fname);
280 }else{
281

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button