Fossil SCM
Fix segfault and add message for ambiguous checkins.
Commit
e501d74440abc5e6affbb0c58d31c5a8810b53e6080ef7518313fce5a634e5a6
Parent
40de2cd9c3273f1…
1 file changed
+15
-6
+15
-6
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -3698,10 +3698,16 @@ | ||
| 3698 | 3698 | ** relative to an earlier, tagged checkin. Use 'descr' for the output. |
| 3699 | 3699 | ** |
| 3700 | 3700 | ** Finds the closest ancestor (ignoring merge-ins) that has a non-propagating |
| 3701 | 3701 | ** label tag and the number of steps backwards that we had to search in |
| 3702 | 3702 | ** order to find that tag. |
| 3703 | +** | |
| 3704 | +** Return values: | |
| 3705 | +** 0: ok | |
| 3706 | +** -1: zName does not resolve to a commit | |
| 3707 | +** -2: zName resolves to more than a commit | |
| 3708 | +** -3: no ancestor commit with a fitting non-propagating tag found | |
| 3703 | 3709 | */ |
| 3704 | 3710 | int describe_commit(const char *zName, const char *matchGlob, |
| 3705 | 3711 | CommitDescr *descr){ |
| 3706 | 3712 | int rid; /* rid for zName */ |
| 3707 | 3713 | const char *zUuid; /* Hash of rid */ |
| @@ -3709,16 +3715,16 @@ | ||
| 3709 | 3715 | Stmt q; /* Query for tagged ancestors */ |
| 3710 | 3716 | |
| 3711 | 3717 | rid = symbolic_name_to_rid(zName, "ci"); /* only commits */ |
| 3712 | 3718 | |
| 3713 | 3719 | if( rid<=0 ){ |
| 3714 | - /* Commit does not exist */ | |
| 3715 | - *(descr->zRelTagname) = 0; | |
| 3720 | + /* Commit does not exist or is ambiguous */ | |
| 3721 | + descr->zRelTagname = mprintf(""); | |
| 3716 | 3722 | descr->nCommitsSince = -1; |
| 3717 | - *(descr->zCommitHash) = 0; | |
| 3723 | + descr->zCommitHash = mprintf(""); | |
| 3718 | 3724 | descr->isDirty = -1; |
| 3719 | - return -1; | |
| 3725 | + return (rid-1); | |
| 3720 | 3726 | } |
| 3721 | 3727 | |
| 3722 | 3728 | zUuid = rid_to_uuid(rid); |
| 3723 | 3729 | descr->zCommitHash = mprintf("%s", zUuid); |
| 3724 | 3730 | descr->isDirty = unsaved_changes(0); |
| @@ -3778,13 +3784,13 @@ | ||
| 3778 | 3784 | descr->zRelTagname = mprintf("%s", lastTag); |
| 3779 | 3785 | descr->nCommitsSince = db_column_int(&q, 2)-1; |
| 3780 | 3786 | nRet = 0; |
| 3781 | 3787 | }else{ |
| 3782 | 3788 | /* no ancestor commit with a fitting singleton tag found */ |
| 3783 | - *(descr->zRelTagname) = 0; | |
| 3789 | + descr->zRelTagname = mprintf(""); | |
| 3784 | 3790 | descr->nCommitsSince = -1; |
| 3785 | - nRet = -2; | |
| 3791 | + nRet = -3; | |
| 3786 | 3792 | } |
| 3787 | 3793 | |
| 3788 | 3794 | db_finalize(&q); |
| 3789 | 3795 | return nRet; |
| 3790 | 3796 | } |
| @@ -3844,10 +3850,13 @@ | ||
| 3844 | 3850 | switch( describe_commit(zName, zMatchGlob, &descr) ){ |
| 3845 | 3851 | case -1: |
| 3846 | 3852 | fossil_fatal("commit %s does not exist", zName); |
| 3847 | 3853 | break; |
| 3848 | 3854 | case -2: |
| 3855 | + fossil_fatal("commit %s is ambiguous", zName); | |
| 3856 | + break; | |
| 3857 | + case -3: | |
| 3849 | 3858 | fossil_print("%.*s%s\n", nDigits, descr.zCommitHash, |
| 3850 | 3859 | bDirtyFlag ? (descr.isDirty ? "-dirty" : "") : ""); |
| 3851 | 3860 | break; |
| 3852 | 3861 | case 0: |
| 3853 | 3862 | if( descr.nCommitsSince==0 && !bLongFlag ){ |
| 3854 | 3863 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -3698,10 +3698,16 @@ | |
| 3698 | ** relative to an earlier, tagged checkin. Use 'descr' for the output. |
| 3699 | ** |
| 3700 | ** Finds the closest ancestor (ignoring merge-ins) that has a non-propagating |
| 3701 | ** label tag and the number of steps backwards that we had to search in |
| 3702 | ** order to find that tag. |
| 3703 | */ |
| 3704 | int describe_commit(const char *zName, const char *matchGlob, |
| 3705 | CommitDescr *descr){ |
| 3706 | int rid; /* rid for zName */ |
| 3707 | const char *zUuid; /* Hash of rid */ |
| @@ -3709,16 +3715,16 @@ | |
| 3709 | Stmt q; /* Query for tagged ancestors */ |
| 3710 | |
| 3711 | rid = symbolic_name_to_rid(zName, "ci"); /* only commits */ |
| 3712 | |
| 3713 | if( rid<=0 ){ |
| 3714 | /* Commit does not exist */ |
| 3715 | *(descr->zRelTagname) = 0; |
| 3716 | descr->nCommitsSince = -1; |
| 3717 | *(descr->zCommitHash) = 0; |
| 3718 | descr->isDirty = -1; |
| 3719 | return -1; |
| 3720 | } |
| 3721 | |
| 3722 | zUuid = rid_to_uuid(rid); |
| 3723 | descr->zCommitHash = mprintf("%s", zUuid); |
| 3724 | descr->isDirty = unsaved_changes(0); |
| @@ -3778,13 +3784,13 @@ | |
| 3778 | descr->zRelTagname = mprintf("%s", lastTag); |
| 3779 | descr->nCommitsSince = db_column_int(&q, 2)-1; |
| 3780 | nRet = 0; |
| 3781 | }else{ |
| 3782 | /* no ancestor commit with a fitting singleton tag found */ |
| 3783 | *(descr->zRelTagname) = 0; |
| 3784 | descr->nCommitsSince = -1; |
| 3785 | nRet = -2; |
| 3786 | } |
| 3787 | |
| 3788 | db_finalize(&q); |
| 3789 | return nRet; |
| 3790 | } |
| @@ -3844,10 +3850,13 @@ | |
| 3844 | switch( describe_commit(zName, zMatchGlob, &descr) ){ |
| 3845 | case -1: |
| 3846 | fossil_fatal("commit %s does not exist", zName); |
| 3847 | break; |
| 3848 | case -2: |
| 3849 | fossil_print("%.*s%s\n", nDigits, descr.zCommitHash, |
| 3850 | bDirtyFlag ? (descr.isDirty ? "-dirty" : "") : ""); |
| 3851 | break; |
| 3852 | case 0: |
| 3853 | if( descr.nCommitsSince==0 && !bLongFlag ){ |
| 3854 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -3698,10 +3698,16 @@ | |
| 3698 | ** relative to an earlier, tagged checkin. Use 'descr' for the output. |
| 3699 | ** |
| 3700 | ** Finds the closest ancestor (ignoring merge-ins) that has a non-propagating |
| 3701 | ** label tag and the number of steps backwards that we had to search in |
| 3702 | ** order to find that tag. |
| 3703 | ** |
| 3704 | ** Return values: |
| 3705 | ** 0: ok |
| 3706 | ** -1: zName does not resolve to a commit |
| 3707 | ** -2: zName resolves to more than a commit |
| 3708 | ** -3: no ancestor commit with a fitting non-propagating tag found |
| 3709 | */ |
| 3710 | int describe_commit(const char *zName, const char *matchGlob, |
| 3711 | CommitDescr *descr){ |
| 3712 | int rid; /* rid for zName */ |
| 3713 | const char *zUuid; /* Hash of rid */ |
| @@ -3709,16 +3715,16 @@ | |
| 3715 | Stmt q; /* Query for tagged ancestors */ |
| 3716 | |
| 3717 | rid = symbolic_name_to_rid(zName, "ci"); /* only commits */ |
| 3718 | |
| 3719 | if( rid<=0 ){ |
| 3720 | /* Commit does not exist or is ambiguous */ |
| 3721 | descr->zRelTagname = mprintf(""); |
| 3722 | descr->nCommitsSince = -1; |
| 3723 | descr->zCommitHash = mprintf(""); |
| 3724 | descr->isDirty = -1; |
| 3725 | return (rid-1); |
| 3726 | } |
| 3727 | |
| 3728 | zUuid = rid_to_uuid(rid); |
| 3729 | descr->zCommitHash = mprintf("%s", zUuid); |
| 3730 | descr->isDirty = unsaved_changes(0); |
| @@ -3778,13 +3784,13 @@ | |
| 3784 | descr->zRelTagname = mprintf("%s", lastTag); |
| 3785 | descr->nCommitsSince = db_column_int(&q, 2)-1; |
| 3786 | nRet = 0; |
| 3787 | }else{ |
| 3788 | /* no ancestor commit with a fitting singleton tag found */ |
| 3789 | descr->zRelTagname = mprintf(""); |
| 3790 | descr->nCommitsSince = -1; |
| 3791 | nRet = -3; |
| 3792 | } |
| 3793 | |
| 3794 | db_finalize(&q); |
| 3795 | return nRet; |
| 3796 | } |
| @@ -3844,10 +3850,13 @@ | |
| 3850 | switch( describe_commit(zName, zMatchGlob, &descr) ){ |
| 3851 | case -1: |
| 3852 | fossil_fatal("commit %s does not exist", zName); |
| 3853 | break; |
| 3854 | case -2: |
| 3855 | fossil_fatal("commit %s is ambiguous", zName); |
| 3856 | break; |
| 3857 | case -3: |
| 3858 | fossil_print("%.*s%s\n", nDigits, descr.zCommitHash, |
| 3859 | bDirtyFlag ? (descr.isDirty ? "-dirty" : "") : ""); |
| 3860 | break; |
| 3861 | case 0: |
| 3862 | if( descr.nCommitsSince==0 && !bLongFlag ){ |
| 3863 |