Fossil SCM

Make sure that symlinks to directories are honored when dealing with checkout files.

mistachkin 2016-10-04 04:49 trunk merge
Commit 912a0d500884dff12593880b7f76b1283c2e14ee
+1 -1
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -922,11 +922,11 @@
922922
if( pFileDir ){
923923
int i;
924924
for(i=0; pFileDir[i].zName; i++){
925925
if( pFileDir[i].nUsed==0
926926
&& strcmp(pFileDir[0].zName,".")!=0
927
- && !file_isdir(g.argv[i+2])
927
+ && !file_wd_isdir(g.argv[i+2])
928928
){
929929
fossil_fatal("not found: '%s'", g.argv[i+2]);
930930
}
931931
fossil_free(pFileDir[i].zName);
932932
}
933933
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -922,11 +922,11 @@
922 if( pFileDir ){
923 int i;
924 for(i=0; pFileDir[i].zName; i++){
925 if( pFileDir[i].nUsed==0
926 && strcmp(pFileDir[0].zName,".")!=0
927 && !file_isdir(g.argv[i+2])
928 ){
929 fossil_fatal("not found: '%s'", g.argv[i+2]);
930 }
931 fossil_free(pFileDir[i].zName);
932 }
933
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -922,11 +922,11 @@
922 if( pFileDir ){
923 int i;
924 for(i=0; pFileDir[i].zName; i++){
925 if( pFileDir[i].nUsed==0
926 && strcmp(pFileDir[0].zName,".")!=0
927 && !file_wd_isdir(g.argv[i+2])
928 ){
929 fossil_fatal("not found: '%s'", g.argv[i+2]);
930 }
931 fossil_free(pFileDir[i].zName);
932 }
933
+21 -9
--- src/file.c
+++ src/file.c
@@ -293,24 +293,36 @@
293293
}
294294
return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
295295
}
296296
297297
/*
298
-** Same as file_isdir(), but takes into account symlinks.
298
+** Same as file_isdir(), but takes into account symlinks. Return 1 if
299
+** zFilename is a directory -OR- a symlink that points to a directory.
300
+** Return 0 if zFilename does not exist. Return 2 if zFilename exists
301
+** but is something other than a directory.
299302
*/
300303
int file_wd_isdir(const char *zFilename){
301304
int rc;
305
+ char *zFN;
302306
303
- if( zFilename ){
304
- char *zFN = mprintf("%s", zFilename);
305
- file_simplify_name(zFN, -1, 0);
306
- rc = getStat(zFN, 1);
307
- free(zFN);
307
+ zFN = mprintf("%s", zFilename);
308
+ file_simplify_name(zFN, -1, 0);
309
+ rc = getStat(zFN, 1);
310
+ if( rc ){
311
+ rc = 0; /* It does not exist at all. */
312
+ }else if( S_ISDIR(fileStat.st_mode) ){
313
+ rc = 1; /* It exists and is a real directory. */
314
+ }else if( S_ISLNK(fileStat.st_mode) ){
315
+ Blob content;
316
+ blob_read_link(&content, zFN); /* It exists and is a link. */
317
+ rc = file_wd_isdir(blob_str(&content)); /* Points to directory? */
318
+ blob_reset(&content);
308319
}else{
309
- rc = getStat(0, 1);
320
+ rc = 2; /* It exists and is something else. */
310321
}
311
- return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
322
+ free(zFN);
323
+ return rc;
312324
}
313325
314326
315327
/*
316328
** Wrapper around the access() system call.
@@ -600,11 +612,11 @@
600612
** The if stops us from trying to create a directory of a drive letter
601613
** C: in this example.
602614
*/
603615
if( !(i==2 && zName[1]==':') ){
604616
#endif
605
- if( file_mkdir(zName, forceFlag) && file_isdir(zName)!=1 ){
617
+ if( file_mkdir(zName, forceFlag) && file_wd_isdir(zName)!=1 ){
606618
if (errorReturn <= 0) {
607619
fossil_fatal_recursive("unable to create directory %s", zName);
608620
}
609621
rc = errorReturn;
610622
break;
611623
612624
ADDED test/symlinks.test
--- src/file.c
+++ src/file.c
@@ -293,24 +293,36 @@
293 }
294 return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
295 }
296
297 /*
298 ** Same as file_isdir(), but takes into account symlinks.
 
 
 
299 */
300 int file_wd_isdir(const char *zFilename){
301 int rc;
 
302
303 if( zFilename ){
304 char *zFN = mprintf("%s", zFilename);
305 file_simplify_name(zFN, -1, 0);
306 rc = getStat(zFN, 1);
307 free(zFN);
 
 
 
 
 
 
 
308 }else{
309 rc = getStat(0, 1);
310 }
311 return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
 
312 }
313
314
315 /*
316 ** Wrapper around the access() system call.
@@ -600,11 +612,11 @@
600 ** The if stops us from trying to create a directory of a drive letter
601 ** C: in this example.
602 */
603 if( !(i==2 && zName[1]==':') ){
604 #endif
605 if( file_mkdir(zName, forceFlag) && file_isdir(zName)!=1 ){
606 if (errorReturn <= 0) {
607 fossil_fatal_recursive("unable to create directory %s", zName);
608 }
609 rc = errorReturn;
610 break;
611
612 DDED test/symlinks.test
--- src/file.c
+++ src/file.c
@@ -293,24 +293,36 @@
293 }
294 return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
295 }
296
297 /*
298 ** Same as file_isdir(), but takes into account symlinks. Return 1 if
299 ** zFilename is a directory -OR- a symlink that points to a directory.
300 ** Return 0 if zFilename does not exist. Return 2 if zFilename exists
301 ** but is something other than a directory.
302 */
303 int file_wd_isdir(const char *zFilename){
304 int rc;
305 char *zFN;
306
307 zFN = mprintf("%s", zFilename);
308 file_simplify_name(zFN, -1, 0);
309 rc = getStat(zFN, 1);
310 if( rc ){
311 rc = 0; /* It does not exist at all. */
312 }else if( S_ISDIR(fileStat.st_mode) ){
313 rc = 1; /* It exists and is a real directory. */
314 }else if( S_ISLNK(fileStat.st_mode) ){
315 Blob content;
316 blob_read_link(&content, zFN); /* It exists and is a link. */
317 rc = file_wd_isdir(blob_str(&content)); /* Points to directory? */
318 blob_reset(&content);
319 }else{
320 rc = 2; /* It exists and is something else. */
321 }
322 free(zFN);
323 return rc;
324 }
325
326
327 /*
328 ** Wrapper around the access() system call.
@@ -600,11 +612,11 @@
612 ** The if stops us from trying to create a directory of a drive letter
613 ** C: in this example.
614 */
615 if( !(i==2 && zName[1]==':') ){
616 #endif
617 if( file_mkdir(zName, forceFlag) && file_wd_isdir(zName)!=1 ){
618 if (errorReturn <= 0) {
619 fossil_fatal_recursive("unable to create directory %s", zName);
620 }
621 rc = errorReturn;
622 break;
623
624 DDED test/symlinks.test
--- a/test/symlinks.test
+++ b/test/symlinks.test
@@ -0,0 +1,66 @@
1
+#
2
+# Copyright (c) 2016 D. Richard Hipp
3
+#
4
+# This program is free software; you can redistribute it and/or
5
+# modify it under the terms of the Simplified BSD License (also
6
+# known as the "2-Clause License" or "FreeBSD License".)
7
+#
8
+# This program is distributed in the hope that it will be useful,
9
+# but without any warranty; without even the implied warranty of
10
+# merchantability or fitness for a particular purpose.
11
+#
12
+# Author contact information:
13
+# [email protected]
14
+# http://www.hwaci.com/drh/
15
+#
16
+############################################################################
17
+#
18
+# Symbolic link tests.
19
+#
20
+
21
+if {$tcl_platform(platform) eq "windows"allow
22
+puts $RESULTmlinks are not supported on Windows."
23
+ test_cleanup_then_returnon
24
+
25
+fossil test-th-eval --open-con"setting allow-symlinks"
26
+
27
+itory [normalize_result]
28
+
29
+if {[string length $repository] == 0} {
30
+ puts "Detection of the open repository file failed."
31
+ test_cleanup_then_return
32
+}
33
+
34
+#######################################
35
+# Use symbolic link to a directory... #
36
+##############fossil commit -m "c1"_then_returnon
37
+
38
+fossil test-th-eval --open-con"setting allow-symlinks"
39
+
40
+itory [normalize_rght (c) 2016 D. Rich#
41
+# Copyright up_then_returnon
42
+
43
+fossil test-th-eval --open-con"setting allow-symlinks"
44
+
45
+itory [normalize_result]
46
+
47
+if {[string length $repository] == 0} {
48
+ puts "Detection of the open repository file failed."
49
+ test_cleanup_then_return
50
+}
51
+
52
+#######################################
53
+# Use symbolic link to a directory... #
54
+#######################################
55
+
56
+file mkdir [file join $rootDir subdirA]
57
+exec ln -s [file join $rootDir subdirA] symdirA
58
+
59
+###############################################################################
60
+
61
+write_file [file join $rootDir subdirA f1.txt] "f1"
62
+write_file [file join $rootDir subdirA f2.txt] "f2"
63
+
64
+test symlinks-dir-1 {[file exists [file join $rootDir subdirA f1.txt]] eq 1}
65
+test symlinks-dir-2 {[file exists [file join $rootDir symdirA f1.txt]] eq 1}
66
+test symlinks-di
--- a/test/symlinks.test
+++ b/test/symlinks.test
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/test/symlinks.test
+++ b/test/symlinks.test
@@ -0,0 +1,66 @@
1 #
2 # Copyright (c) 2016 D. Richard Hipp
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the Simplified BSD License (also
6 # known as the "2-Clause License" or "FreeBSD License".)
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but without any warranty; without even the implied warranty of
10 # merchantability or fitness for a particular purpose.
11 #
12 # Author contact information:
13 # [email protected]
14 # http://www.hwaci.com/drh/
15 #
16 ############################################################################
17 #
18 # Symbolic link tests.
19 #
20
21 if {$tcl_platform(platform) eq "windows"allow
22 puts $RESULTmlinks are not supported on Windows."
23 test_cleanup_then_returnon
24
25 fossil test-th-eval --open-con"setting allow-symlinks"
26
27 itory [normalize_result]
28
29 if {[string length $repository] == 0} {
30 puts "Detection of the open repository file failed."
31 test_cleanup_then_return
32 }
33
34 #######################################
35 # Use symbolic link to a directory... #
36 ##############fossil commit -m "c1"_then_returnon
37
38 fossil test-th-eval --open-con"setting allow-symlinks"
39
40 itory [normalize_rght (c) 2016 D. Rich#
41 # Copyright up_then_returnon
42
43 fossil test-th-eval --open-con"setting allow-symlinks"
44
45 itory [normalize_result]
46
47 if {[string length $repository] == 0} {
48 puts "Detection of the open repository file failed."
49 test_cleanup_then_return
50 }
51
52 #######################################
53 # Use symbolic link to a directory... #
54 #######################################
55
56 file mkdir [file join $rootDir subdirA]
57 exec ln -s [file join $rootDir subdirA] symdirA
58
59 ###############################################################################
60
61 write_file [file join $rootDir subdirA f1.txt] "f1"
62 write_file [file join $rootDir subdirA f2.txt] "f2"
63
64 test symlinks-dir-1 {[file exists [file join $rootDir subdirA f1.txt]] eq 1}
65 test symlinks-dir-2 {[file exists [file join $rootDir symdirA f1.txt]] eq 1}
66 test symlinks-di

Keyboard Shortcuts

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