Fossil SCM

Merge again checkout_on_root_fix. Fix more cases when working from '/', should not affect when working normally.

mgagnon 2014-01-09 11:24 trunk merge
Commit af194dbb16b74d8b6b3e9b4731fc48a57788d617
3 files changed +31 -24 +31 -24 +1 -1
+31 -24
--- src/file.c
+++ src/file.c
@@ -703,11 +703,11 @@
703703
}
704704
}
705705
if( j>=0 ) z[j] = z[i];
706706
j++;
707707
}
708
- if( j==0 ) z[j++] = '.';
708
+ if( j==0 ) z[j++] = '/';
709709
z[j] = 0;
710710
return j;
711711
}
712712
713713
/*
@@ -777,39 +777,40 @@
777777
** Convert /A/../ to just /
778778
** If the slash parameter is non-zero, the trailing slash, if any,
779779
** is retained.
780780
*/
781781
void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
782
+ blob_zero(pOut);
782783
if( file_is_absolute_path(zOrigName) ){
783
-#if defined(_WIN32) || defined(__CYGWIN__)
784
- char *zOut;
785
-#endif
786
- blob_set(pOut, zOrigName);
787
- blob_materialize(pOut);
784
+ blob_appendf(pOut, "%/", zOrigName);
785
+ }else{
786
+ char zPwd[2000];
787
+ file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
788
+ if( zPwd[0]=='/' && strlen(zPwd)==1 ){
789
+ // when on '/', don't add an extra '/'
790
+ if( zOrigName[0]=='.' && strlen(zOrigName)==1 ){
791
+ // '.' when on '/' mean '/'
792
+ blob_appendf(pOut, "%/", zPwd);
793
+ }else{
794
+ blob_appendf(pOut, "%/%/", zPwd, zOrigName);
795
+ }
796
+ }else{
797
+ blob_appendf(pOut, "%//%/", zPwd, zOrigName);
798
+ }
799
+ }
788800
#if defined(_WIN32) || defined(__CYGWIN__)
801
+ {
802
+ char *zOut;
789803
/*
790804
** On Windows/cygwin, normalize the drive letter to upper case.
791805
*/
792806
zOut = blob_str(pOut);
793
- if( fossil_islower(zOut[0]) && zOut[1]==':' ){
807
+ if( fossil_islower(zOut[0]) && zOut[1]==':' && zOut[2]=='/' ){
794808
zOut[0] = fossil_toupper(zOut[0]);
795809
}
796
-#endif
797
- }else{
798
- char zPwd[2000];
799
- file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
800
-#if defined(_WIN32)
801
- /*
802
- ** On Windows, normalize the drive letter to upper case.
803
- */
804
- if( fossil_islower(zPwd[0]) && zPwd[1]==':' ){
805
- zPwd[0] = fossil_toupper(zPwd[0]);
806
- }
807
-#endif
808
- blob_zero(pOut);
809
- blob_appendf(pOut, "%//%/", zPwd, zOrigName);
810
- }
810
+ }
811
+#endif
811812
blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
812813
blob_size(pOut), slash));
813814
}
814815
815816
/*
@@ -928,11 +929,16 @@
928929
blob_append(pOut, &zPath[i+1], -1);
929930
blob_reset(&tmp);
930931
return;
931932
}
932933
while( zPath[i-1]!='/' ){ i--; }
933
- blob_set(&tmp, "../");
934
+ if( zPwd[0]=='/' && strlen(zPwd)==1 ){
935
+ // If on '/', don't go to higher level
936
+ blob_zero(&tmp);
937
+ }else{
938
+ blob_set(&tmp, "../");
939
+ }
934940
for(j=i; zPwd[j]; j++){
935941
if( zPwd[j]=='/' ){
936942
blob_append(&tmp, "../", 3);
937943
}
938944
}
@@ -990,11 +996,12 @@
990996
}else{
991997
xCmp = fossil_strnicmp;
992998
}
993999
9941000
/* Special case. zOrigName refers to g.zLocalRoot directory. */
995
- if( nFull==nLocalRoot-1 && xCmp(zLocalRoot, zFull, nFull)==0 ){
1001
+ if( (nFull==nLocalRoot-1 && xCmp(zLocalRoot, zFull, nFull)==0)
1002
+ || (nFull==1 && zFull[0]=='/' && nLocalRoot==1 && zLocalRoot[0]=='/') ){
9961003
blob_append(pOut, ".", 1);
9971004
blob_reset(&localRoot);
9981005
blob_reset(&full);
9991006
return 1;
10001007
}
10011008
--- src/file.c
+++ src/file.c
@@ -703,11 +703,11 @@
703 }
704 }
705 if( j>=0 ) z[j] = z[i];
706 j++;
707 }
708 if( j==0 ) z[j++] = '.';
709 z[j] = 0;
710 return j;
711 }
712
713 /*
@@ -777,39 +777,40 @@
777 ** Convert /A/../ to just /
778 ** If the slash parameter is non-zero, the trailing slash, if any,
779 ** is retained.
780 */
781 void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
 
782 if( file_is_absolute_path(zOrigName) ){
783 #if defined(_WIN32) || defined(__CYGWIN__)
784 char *zOut;
785 #endif
786 blob_set(pOut, zOrigName);
787 blob_materialize(pOut);
 
 
 
 
 
 
 
 
 
 
 
788 #if defined(_WIN32) || defined(__CYGWIN__)
 
 
789 /*
790 ** On Windows/cygwin, normalize the drive letter to upper case.
791 */
792 zOut = blob_str(pOut);
793 if( fossil_islower(zOut[0]) && zOut[1]==':' ){
794 zOut[0] = fossil_toupper(zOut[0]);
795 }
796 #endif
797 }else{
798 char zPwd[2000];
799 file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
800 #if defined(_WIN32)
801 /*
802 ** On Windows, normalize the drive letter to upper case.
803 */
804 if( fossil_islower(zPwd[0]) && zPwd[1]==':' ){
805 zPwd[0] = fossil_toupper(zPwd[0]);
806 }
807 #endif
808 blob_zero(pOut);
809 blob_appendf(pOut, "%//%/", zPwd, zOrigName);
810 }
811 blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
812 blob_size(pOut), slash));
813 }
814
815 /*
@@ -928,11 +929,16 @@
928 blob_append(pOut, &zPath[i+1], -1);
929 blob_reset(&tmp);
930 return;
931 }
932 while( zPath[i-1]!='/' ){ i--; }
933 blob_set(&tmp, "../");
 
 
 
 
 
934 for(j=i; zPwd[j]; j++){
935 if( zPwd[j]=='/' ){
936 blob_append(&tmp, "../", 3);
937 }
938 }
@@ -990,11 +996,12 @@
990 }else{
991 xCmp = fossil_strnicmp;
992 }
993
994 /* Special case. zOrigName refers to g.zLocalRoot directory. */
995 if( nFull==nLocalRoot-1 && xCmp(zLocalRoot, zFull, nFull)==0 ){
 
996 blob_append(pOut, ".", 1);
997 blob_reset(&localRoot);
998 blob_reset(&full);
999 return 1;
1000 }
1001
--- src/file.c
+++ src/file.c
@@ -703,11 +703,11 @@
703 }
704 }
705 if( j>=0 ) z[j] = z[i];
706 j++;
707 }
708 if( j==0 ) z[j++] = '/';
709 z[j] = 0;
710 return j;
711 }
712
713 /*
@@ -777,39 +777,40 @@
777 ** Convert /A/../ to just /
778 ** If the slash parameter is non-zero, the trailing slash, if any,
779 ** is retained.
780 */
781 void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
782 blob_zero(pOut);
783 if( file_is_absolute_path(zOrigName) ){
784 blob_appendf(pOut, "%/", zOrigName);
785 }else{
786 char zPwd[2000];
787 file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
788 if( zPwd[0]=='/' && strlen(zPwd)==1 ){
789 // when on '/', don't add an extra '/'
790 if( zOrigName[0]=='.' && strlen(zOrigName)==1 ){
791 // '.' when on '/' mean '/'
792 blob_appendf(pOut, "%/", zPwd);
793 }else{
794 blob_appendf(pOut, "%/%/", zPwd, zOrigName);
795 }
796 }else{
797 blob_appendf(pOut, "%//%/", zPwd, zOrigName);
798 }
799 }
800 #if defined(_WIN32) || defined(__CYGWIN__)
801 {
802 char *zOut;
803 /*
804 ** On Windows/cygwin, normalize the drive letter to upper case.
805 */
806 zOut = blob_str(pOut);
807 if( fossil_islower(zOut[0]) && zOut[1]==':' && zOut[2]=='/' ){
808 zOut[0] = fossil_toupper(zOut[0]);
809 }
810 }
811 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
812 blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
813 blob_size(pOut), slash));
814 }
815
816 /*
@@ -928,11 +929,16 @@
929 blob_append(pOut, &zPath[i+1], -1);
930 blob_reset(&tmp);
931 return;
932 }
933 while( zPath[i-1]!='/' ){ i--; }
934 if( zPwd[0]=='/' && strlen(zPwd)==1 ){
935 // If on '/', don't go to higher level
936 blob_zero(&tmp);
937 }else{
938 blob_set(&tmp, "../");
939 }
940 for(j=i; zPwd[j]; j++){
941 if( zPwd[j]=='/' ){
942 blob_append(&tmp, "../", 3);
943 }
944 }
@@ -990,11 +996,12 @@
996 }else{
997 xCmp = fossil_strnicmp;
998 }
999
1000 /* Special case. zOrigName refers to g.zLocalRoot directory. */
1001 if( (nFull==nLocalRoot-1 && xCmp(zLocalRoot, zFull, nFull)==0)
1002 || (nFull==1 && zFull[0]=='/' && nLocalRoot==1 && zLocalRoot[0]=='/') ){
1003 blob_append(pOut, ".", 1);
1004 blob_reset(&localRoot);
1005 blob_reset(&full);
1006 return 1;
1007 }
1008
+31 -24
--- src/file.c
+++ src/file.c
@@ -703,11 +703,11 @@
703703
}
704704
}
705705
if( j>=0 ) z[j] = z[i];
706706
j++;
707707
}
708
- if( j==0 ) z[j++] = '.';
708
+ if( j==0 ) z[j++] = '/';
709709
z[j] = 0;
710710
return j;
711711
}
712712
713713
/*
@@ -777,39 +777,40 @@
777777
** Convert /A/../ to just /
778778
** If the slash parameter is non-zero, the trailing slash, if any,
779779
** is retained.
780780
*/
781781
void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
782
+ blob_zero(pOut);
782783
if( file_is_absolute_path(zOrigName) ){
783
-#if defined(_WIN32) || defined(__CYGWIN__)
784
- char *zOut;
785
-#endif
786
- blob_set(pOut, zOrigName);
787
- blob_materialize(pOut);
784
+ blob_appendf(pOut, "%/", zOrigName);
785
+ }else{
786
+ char zPwd[2000];
787
+ file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
788
+ if( zPwd[0]=='/' && strlen(zPwd)==1 ){
789
+ // when on '/', don't add an extra '/'
790
+ if( zOrigName[0]=='.' && strlen(zOrigName)==1 ){
791
+ // '.' when on '/' mean '/'
792
+ blob_appendf(pOut, "%/", zPwd);
793
+ }else{
794
+ blob_appendf(pOut, "%/%/", zPwd, zOrigName);
795
+ }
796
+ }else{
797
+ blob_appendf(pOut, "%//%/", zPwd, zOrigName);
798
+ }
799
+ }
788800
#if defined(_WIN32) || defined(__CYGWIN__)
801
+ {
802
+ char *zOut;
789803
/*
790804
** On Windows/cygwin, normalize the drive letter to upper case.
791805
*/
792806
zOut = blob_str(pOut);
793
- if( fossil_islower(zOut[0]) && zOut[1]==':' ){
807
+ if( fossil_islower(zOut[0]) && zOut[1]==':' && zOut[2]=='/' ){
794808
zOut[0] = fossil_toupper(zOut[0]);
795809
}
796
-#endif
797
- }else{
798
- char zPwd[2000];
799
- file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
800
-#if defined(_WIN32)
801
- /*
802
- ** On Windows, normalize the drive letter to upper case.
803
- */
804
- if( fossil_islower(zPwd[0]) && zPwd[1]==':' ){
805
- zPwd[0] = fossil_toupper(zPwd[0]);
806
- }
807
-#endif
808
- blob_zero(pOut);
809
- blob_appendf(pOut, "%//%/", zPwd, zOrigName);
810
- }
810
+ }
811
+#endif
811812
blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
812813
blob_size(pOut), slash));
813814
}
814815
815816
/*
@@ -928,11 +929,16 @@
928929
blob_append(pOut, &zPath[i+1], -1);
929930
blob_reset(&tmp);
930931
return;
931932
}
932933
while( zPath[i-1]!='/' ){ i--; }
933
- blob_set(&tmp, "../");
934
+ if( zPwd[0]=='/' && strlen(zPwd)==1 ){
935
+ // If on '/', don't go to higher level
936
+ blob_zero(&tmp);
937
+ }else{
938
+ blob_set(&tmp, "../");
939
+ }
934940
for(j=i; zPwd[j]; j++){
935941
if( zPwd[j]=='/' ){
936942
blob_append(&tmp, "../", 3);
937943
}
938944
}
@@ -990,11 +996,12 @@
990996
}else{
991997
xCmp = fossil_strnicmp;
992998
}
993999
9941000
/* Special case. zOrigName refers to g.zLocalRoot directory. */
995
- if( nFull==nLocalRoot-1 && xCmp(zLocalRoot, zFull, nFull)==0 ){
1001
+ if( (nFull==nLocalRoot-1 && xCmp(zLocalRoot, zFull, nFull)==0)
1002
+ || (nFull==1 && zFull[0]=='/' && nLocalRoot==1 && zLocalRoot[0]=='/') ){
9961003
blob_append(pOut, ".", 1);
9971004
blob_reset(&localRoot);
9981005
blob_reset(&full);
9991006
return 1;
10001007
}
10011008
--- src/file.c
+++ src/file.c
@@ -703,11 +703,11 @@
703 }
704 }
705 if( j>=0 ) z[j] = z[i];
706 j++;
707 }
708 if( j==0 ) z[j++] = '.';
709 z[j] = 0;
710 return j;
711 }
712
713 /*
@@ -777,39 +777,40 @@
777 ** Convert /A/../ to just /
778 ** If the slash parameter is non-zero, the trailing slash, if any,
779 ** is retained.
780 */
781 void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
 
782 if( file_is_absolute_path(zOrigName) ){
783 #if defined(_WIN32) || defined(__CYGWIN__)
784 char *zOut;
785 #endif
786 blob_set(pOut, zOrigName);
787 blob_materialize(pOut);
 
 
 
 
 
 
 
 
 
 
 
788 #if defined(_WIN32) || defined(__CYGWIN__)
 
 
789 /*
790 ** On Windows/cygwin, normalize the drive letter to upper case.
791 */
792 zOut = blob_str(pOut);
793 if( fossil_islower(zOut[0]) && zOut[1]==':' ){
794 zOut[0] = fossil_toupper(zOut[0]);
795 }
796 #endif
797 }else{
798 char zPwd[2000];
799 file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
800 #if defined(_WIN32)
801 /*
802 ** On Windows, normalize the drive letter to upper case.
803 */
804 if( fossil_islower(zPwd[0]) && zPwd[1]==':' ){
805 zPwd[0] = fossil_toupper(zPwd[0]);
806 }
807 #endif
808 blob_zero(pOut);
809 blob_appendf(pOut, "%//%/", zPwd, zOrigName);
810 }
811 blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
812 blob_size(pOut), slash));
813 }
814
815 /*
@@ -928,11 +929,16 @@
928 blob_append(pOut, &zPath[i+1], -1);
929 blob_reset(&tmp);
930 return;
931 }
932 while( zPath[i-1]!='/' ){ i--; }
933 blob_set(&tmp, "../");
 
 
 
 
 
934 for(j=i; zPwd[j]; j++){
935 if( zPwd[j]=='/' ){
936 blob_append(&tmp, "../", 3);
937 }
938 }
@@ -990,11 +996,12 @@
990 }else{
991 xCmp = fossil_strnicmp;
992 }
993
994 /* Special case. zOrigName refers to g.zLocalRoot directory. */
995 if( nFull==nLocalRoot-1 && xCmp(zLocalRoot, zFull, nFull)==0 ){
 
996 blob_append(pOut, ".", 1);
997 blob_reset(&localRoot);
998 blob_reset(&full);
999 return 1;
1000 }
1001
--- src/file.c
+++ src/file.c
@@ -703,11 +703,11 @@
703 }
704 }
705 if( j>=0 ) z[j] = z[i];
706 j++;
707 }
708 if( j==0 ) z[j++] = '/';
709 z[j] = 0;
710 return j;
711 }
712
713 /*
@@ -777,39 +777,40 @@
777 ** Convert /A/../ to just /
778 ** If the slash parameter is non-zero, the trailing slash, if any,
779 ** is retained.
780 */
781 void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
782 blob_zero(pOut);
783 if( file_is_absolute_path(zOrigName) ){
784 blob_appendf(pOut, "%/", zOrigName);
785 }else{
786 char zPwd[2000];
787 file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
788 if( zPwd[0]=='/' && strlen(zPwd)==1 ){
789 // when on '/', don't add an extra '/'
790 if( zOrigName[0]=='.' && strlen(zOrigName)==1 ){
791 // '.' when on '/' mean '/'
792 blob_appendf(pOut, "%/", zPwd);
793 }else{
794 blob_appendf(pOut, "%/%/", zPwd, zOrigName);
795 }
796 }else{
797 blob_appendf(pOut, "%//%/", zPwd, zOrigName);
798 }
799 }
800 #if defined(_WIN32) || defined(__CYGWIN__)
801 {
802 char *zOut;
803 /*
804 ** On Windows/cygwin, normalize the drive letter to upper case.
805 */
806 zOut = blob_str(pOut);
807 if( fossil_islower(zOut[0]) && zOut[1]==':' && zOut[2]=='/' ){
808 zOut[0] = fossil_toupper(zOut[0]);
809 }
810 }
811 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
812 blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
813 blob_size(pOut), slash));
814 }
815
816 /*
@@ -928,11 +929,16 @@
929 blob_append(pOut, &zPath[i+1], -1);
930 blob_reset(&tmp);
931 return;
932 }
933 while( zPath[i-1]!='/' ){ i--; }
934 if( zPwd[0]=='/' && strlen(zPwd)==1 ){
935 // If on '/', don't go to higher level
936 blob_zero(&tmp);
937 }else{
938 blob_set(&tmp, "../");
939 }
940 for(j=i; zPwd[j]; j++){
941 if( zPwd[j]=='/' ){
942 blob_append(&tmp, "../", 3);
943 }
944 }
@@ -990,11 +996,12 @@
996 }else{
997 xCmp = fossil_strnicmp;
998 }
999
1000 /* Special case. zOrigName refers to g.zLocalRoot directory. */
1001 if( (nFull==nLocalRoot-1 && xCmp(zLocalRoot, zFull, nFull)==0)
1002 || (nFull==1 && zFull[0]=='/' && nLocalRoot==1 && zLocalRoot[0]=='/') ){
1003 blob_append(pOut, ".", 1);
1004 blob_reset(&localRoot);
1005 blob_reset(&full);
1006 return 1;
1007 }
1008
+1 -1
--- src/update.c
+++ src/update.c
@@ -353,11 +353,11 @@
353353
db_prepare(&mtimeXfer,
354354
"UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)"
355355
" WHERE id=:idt"
356356
);
357357
assert( g.zLocalRoot!=0 );
358
- assert( strlen(g.zLocalRoot)>1 );
358
+ assert( strlen(g.zLocalRoot)>0 );
359359
assert( g.zLocalRoot[strlen(g.zLocalRoot)-1]=='/' );
360360
while( db_step(&q)==SQLITE_ROW ){
361361
const char *zName = db_column_text(&q, 0); /* The filename from root */
362362
int idv = db_column_int(&q, 1); /* VFILE entry for current */
363363
int ridv = db_column_int(&q, 2); /* RecordID for current */
364364
--- src/update.c
+++ src/update.c
@@ -353,11 +353,11 @@
353 db_prepare(&mtimeXfer,
354 "UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)"
355 " WHERE id=:idt"
356 );
357 assert( g.zLocalRoot!=0 );
358 assert( strlen(g.zLocalRoot)>1 );
359 assert( g.zLocalRoot[strlen(g.zLocalRoot)-1]=='/' );
360 while( db_step(&q)==SQLITE_ROW ){
361 const char *zName = db_column_text(&q, 0); /* The filename from root */
362 int idv = db_column_int(&q, 1); /* VFILE entry for current */
363 int ridv = db_column_int(&q, 2); /* RecordID for current */
364
--- src/update.c
+++ src/update.c
@@ -353,11 +353,11 @@
353 db_prepare(&mtimeXfer,
354 "UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)"
355 " WHERE id=:idt"
356 );
357 assert( g.zLocalRoot!=0 );
358 assert( strlen(g.zLocalRoot)>0 );
359 assert( g.zLocalRoot[strlen(g.zLocalRoot)-1]=='/' );
360 while( db_step(&q)==SQLITE_ROW ){
361 const char *zName = db_column_text(&q, 0); /* The filename from root */
362 int idv = db_column_int(&q, 1); /* VFILE entry for current */
363 int ridv = db_column_int(&q, 2); /* RecordID for current */
364

Keyboard Shortcuts

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