Fossil SCM
More gitusers.md doc improvements: promoted the "detached HEAD state" paragraph in Case Study 1 to a new section; clarified "fossil update" vs "fossil checkout" in relation to "git checkout"; applied forum feedback on Case Study 1.
Commit
7e03f7b4d87418ad445c5b783b5d4ea431b4c018427375a4bed1c18028bfc0a1
Parent
03f0a4950ccf45e…
1 file changed
+48
-39
+48
-39
| --- www/gitusers.md | ||
| +++ www/gitusers.md | ||
| @@ -46,13 +46,12 @@ | ||
| 46 | 46 | |
| 47 | 47 | |
| 48 | 48 | #### <a id="cwork" name="scw"></a> Checkout Workflows |
| 49 | 49 | |
| 50 | 50 | A Fossil repository is a SQLite database storing the entire history of a |
| 51 | -project. It is not normally stored inside the working tree, as with Git. | |
| 52 | - | |
| 53 | -The working tree — also called a check-out in Fossil — is a directory | |
| 51 | +project. It is not normally stored inside the working tree. | |
| 52 | +A Fossil working tree — also called a check-out — is a directory | |
| 54 | 53 | that contains a snapshot of your project that you are currently working |
| 55 | 54 | on, extracted for you from the repository database file by the `fossil` |
| 56 | 55 | program. |
| 57 | 56 | |
| 58 | 57 | Git commingles these two by default, with the repository stored in a |
| @@ -61,30 +60,37 @@ | ||
| 61 | 60 | designed into the core concept of the tool, Git tutorials usually |
| 62 | 61 | advocate a switch-in-place working mode instead, so that is how most |
| 63 | 62 | users end up working with Git. Contrast [Fossil’s check-out workflow |
| 64 | 63 | document][ckwf] to see the practical differences. |
| 65 | 64 | |
| 66 | -There are two key Git-specific things to add to that document. | |
| 67 | - | |
| 68 | -First, this: | |
| 65 | +There is one Git-specific detail we wish to add beyond what that | |
| 66 | +document already covers. This command: | |
| 69 | 67 | |
| 70 | 68 | git checkout some-branch |
| 71 | 69 | |
| 72 | -…is spelled: | |
| 70 | +…is best given as: | |
| 73 | 71 | |
| 74 | 72 | fossil update some-branch |
| 75 | 73 | |
| 76 | -…in Fossil. | |
| 77 | - | |
| 78 | -Second, as of Fossil 2.14, we now have Git-style clone-and-open: | |
| 79 | - | |
| 80 | - fossil clone https://example.com/repo | |
| 81 | - | |
| 82 | -That gets you a `repo.fossil` file, opened into a `repo/` working | |
| 83 | -directory alongside it. Note that we do not commingle the repo and | |
| 84 | -working directory even in this case. See [the workflows doc][ckwf] | |
| 85 | -for more detail on this and related topics. | |
| 74 | +…in Fossil. There is a `fossil checkout` command, but it has two | |
| 75 | +restrictions that push you toward using `fossil update` instead: | |
| 76 | + | |
| 77 | +1. Several features in `fossil update` do not exist in | |
| 78 | + `fossil checkout`. | |
| 79 | + | |
| 80 | +2. The lone exception is `fossil checkout --keep`, a rarely-needed | |
| 81 | + operation. | |
| 82 | + | |
| 83 | +3. Fossil will have you typing “`fossil up`” frequently anyway to pull | |
| 84 | + remote changes and merge them into the local check-out directory. | |
| 85 | + Adding a `VERSION` string for the cases where you mean something | |
| 86 | + other than “tip of the current branch” is an easy habit to develop. | |
| 87 | + | |
| 88 | +Neither command is an alias for the other. They overlap enough that they | |
| 89 | +can be used interchangeably for everyday use cases, but since `update` | |
| 90 | +is more powerful, we recommend that you break the habit of typing | |
| 91 | +`checkout`. | |
| 86 | 92 | |
| 87 | 93 | [ckwf]: ./ckout-workflows.md |
| 88 | 94 | |
| 89 | 95 | |
| 90 | 96 | #### <a id="rname"></a> Naming Repositories |
| @@ -417,10 +423,19 @@ | ||
| 417 | 423 | [tlc]: /help?cmd=timeline |
| 418 | 424 | [tlw]: /help?cmd=/timeline |
| 419 | 425 | [up]: /help?cmd=update |
| 420 | 426 | [wdm]: ./fossil-v-git.wiki#durable |
| 421 | 427 | |
| 428 | + | |
| 429 | +## <a id="dhead"></a> Detached HEAD State | |
| 430 | + | |
| 431 | +The SQL indexes in Fossil which we brought up above have a very useful | |
| 432 | +side benefit: you cannot have a [detached HEAD state][gdh] in Fossil, | |
| 433 | +the source of untold pain and data loss in Git. It simply cannot be done | |
| 434 | +in Fossil, because the indexes always let us find our way back into the | |
| 435 | +hash tree. | |
| 436 | + | |
| 422 | 437 | |
| 423 | 438 | ## <a id="slcom"></a> Summary Line Convention In Commit Comments |
| 424 | 439 | |
| 425 | 440 | The Git convention of a [length-limited summary line][lsl] at the start |
| 426 | 441 | of commit comments has no equivalent in Fossil. You’re welcome to style |
| @@ -475,14 +490,10 @@ | ||
| 475 | 490 | |
| 476 | 491 | To switch back to the parent branch, say something like: |
| 477 | 492 | |
| 478 | 493 | fossil update trunk # ≅ git checkout master |
| 479 | 494 | |
| 480 | -(There is also `fossil checkout trunk`, but it’s a 2nd-tier command | |
| 481 | -meant for more specialized purposes. Almost always, you want to use | |
| 482 | -`update` instead.) | |
| 483 | - | |
| 484 | 495 | Fossil does also support the Git style, creating the branch ahead of |
| 485 | 496 | need: |
| 486 | 497 | |
| 487 | 498 | fossil branch new my-new-branch |
| 488 | 499 | fossil update my-new-branch |
| @@ -764,25 +775,25 @@ | ||
| 764 | 775 | |
| 765 | 776 | Let’s get into something a bit more complicated: a case study showing |
| 766 | 777 | how the concepts lined out above cause Fossil to materially differ in |
| 767 | 778 | day-to-day operation from Git. |
| 768 | 779 | |
| 769 | -A common thing to need to do in a version control system is to check out | |
| 770 | -a version by date. Perhaps this is because your customer gave you a | |
| 771 | -vague bug report — “I think it broke on a Wednesday… Yes, there was a | |
| 772 | -full moon, and the Dodgers were playing in Boston…” — or perhaps you’re | |
| 773 | -poking semi-randomly through history to find a “good” version to set up | |
| 780 | +You may need to check out | |
| 781 | +a version of a project by date. Perhaps your customer gave you a | |
| 782 | +vague bug report referencing only a date rather than a version, or perhaps you’re | |
| 783 | +poking semi-randomly through history to find a “good” version to anchor | |
| 774 | 784 | the start point of a [`bisect`][bis] operation. |
| 775 | 785 | |
| 776 | 786 | Because Git doesn’t maintain comprehensive lookup tables into its log — |
| 777 | 787 | [as detailed above](#log) — you will find pages online recommending |
| 778 | -horror-show commands like this: | |
| 788 | +long, nested commands like this: | |
| 779 | 789 | |
| 780 | 790 | git checkout $(git rev-list -n 1 --first-parent --before="2020-04-12" master) |
| 781 | 791 | |
| 782 | -That’s [the top answer on Stack Overflow][gcod] for the first hit on | |
| 783 | -“git checkout by date” in the web search engine I used. | |
| 792 | +That’s [the top answer on Stack Overflow][gcod] for | |
| 793 | +“git checkout by date” as surfaced by the web search engine I used, | |
| 794 | +its first search result. | |
| 784 | 795 | |
| 785 | 796 | We believe you get such answers to Git help requests in part |
| 786 | 797 | because of its lack of an always-up-to-date index into its log and in |
| 787 | 798 | part because of its “small tools loosely joined” design philosophy. This |
| 788 | 799 | sort of command is therefore composed piece by piece: |
| @@ -789,11 +800,12 @@ | ||
| 789 | 800 | |
| 790 | 801 | <center>◆ ◆ ◆</center> |
| 791 | 802 | |
| 792 | 803 | **Given:** Git lacks a reliable lookup-by-date index into its log. |
| 793 | 804 | |
| 794 | -**Goal:** Find the commit ID nearest a given date, you poor sod. | |
| 805 | +**Goal:** Find the commit ID nearest a given date, you poor unfortunate | |
| 806 | +user. | |
| 795 | 807 | |
| 796 | 808 | “Oh, I know, I’ll search the rev-list, which outputs commit IDs by |
| 797 | 809 | parsing the log backwards from `HEAD`! Easy!” |
| 798 | 810 | |
| 799 | 811 | git rev-list --before=2020-04-12 |
| @@ -822,11 +834,11 @@ | ||
| 822 | 834 | “Well poop: it shows the same commit! Eff it; let’s just try it and hope |
| 823 | 835 | it’s close enough.” |
| 824 | 836 | |
| 825 | 837 | git checkout $(git rev-list -n 1 --no-merges --before=2020-04-12 master) |
| 826 | 838 | |
| 827 | -“Success! Just so easy!” | |
| 839 | +“Success, I guess?” | |
| 828 | 840 | |
| 829 | 841 | <center>◆ ◆ ◆</center> |
| 830 | 842 | |
| 831 | 843 | This vignette is meant to explain some of Git’s popularity: it rewards |
| 832 | 844 | the sort of people who enjoy puzzles, many of whom are software |
| @@ -835,14 +847,10 @@ | ||
| 835 | 847 | |
| 836 | 848 | And too bad if you’re a Windows user who doesn’t want to use [Git |
| 837 | 849 | Bash][gbash], since neither of the stock OS command shells have a |
| 838 | 850 | command interpolation feature needed to run that horrid command. |
| 839 | 851 | |
| 840 | -By the way, congratulations, you just created a [detached head][gdh] | |
| 841 | -along with all of its attendant risks. There’s no such state in Fossil | |
| 842 | -due to its robust commit history indexing. | |
| 843 | - | |
| 844 | 852 | If you think the bit about “a commit from 2019-12-15” in my |
| 845 | 853 | little story above is made up, try `git rev-parse master@{2020-04-12}` |
| 846 | 854 | on [Git’s own repository][gitgh]: it gives [this commit][grpgh]! Though |
| 847 | 855 | GitHub shows the date we asked for, the `git show` command above gives |
| 848 | 856 | the confusing result referenced in the story. |
| @@ -864,26 +872,26 @@ | ||
| 864 | 872 | git checkout master@{2020-04-12} |
| 865 | 873 | |
| 866 | 874 | It’s a bit cryptic, but it’s much nicer than the prior command. |
| 867 | 875 | |
| 868 | 876 | Too bad it only works if the target commit is in Git’s [reflog], which |
| 869 | -Git automatically prunes to 90 days of history from time to time. But | |
| 877 | +Git [automatically prunes][gle] to 90 days of history from time to time. But | |
| 870 | 878 | the above command won’t fail outright if the reflog can’t resolve the |
| 871 | 879 | given date, it will instead give an *incorrect* result on `stdout`, |
| 872 | 880 | *possibly* accompanied by a warning on *stderr!* While I was writing |
| 873 | 881 | this, it happily gave me a commit from 2019-07-19 until I nuked the |
| 874 | 882 | repository and re-cloned, after which it at least warned me that the |
| 875 | 883 | reflog didn’t go back that far… But it still gave me an answer: a wrong |
| 876 | 884 | one! |
| 877 | 885 | |
| 878 | 886 | Why? Because Git lacks comprehensive up-to-date indices into its log, |
| 879 | -and my clone was stale. | |
| 887 | +and my clone was stale, apparently last updated in July of 2019. | |
| 880 | 888 | When I nuked my stale clone and re-cloned, my |
| 881 | 889 | command above started giving me today’s latest commit, that being as far |
| 882 | 890 | back in history as it could dig. Who wants this behavior? |
| 883 | 891 | |
| 884 | -Well, at least it works on Windows! That’s something! | |
| 892 | +Well, at least it works on Windows… That’s something! | |
| 885 | 893 | |
| 886 | 894 | But woe betide you if you leave off the `master` bit. Or forget some bit |
| 887 | 895 | of the cryptic punctuation. |
| 888 | 896 | |
| 889 | 897 | You may be asking with an exasperated huff, “What is your *point*, man?” |
| @@ -890,16 +898,17 @@ | ||
| 890 | 898 | The point is that the equivalent in Fossil is simply: |
| 891 | 899 | |
| 892 | 900 | fossil up 2020-04-12 |
| 893 | 901 | |
| 894 | 902 | …and the commit will *always* be the one closest to the 12th of April, 2020, no matter |
| 895 | -whether it’s a fresh clone or a stale one, praise be Ritchie! | |
| 903 | +whether it’s a fresh clone or a stale one. | |
| 896 | 904 | |
| 897 | 905 | [gbash]: https://appuals.com/what-is-git-bash/ |
| 898 | 906 | [gcod]: https://stackoverflow.com/a/6990682/142454 |
| 899 | 907 | [gdh]: https://www.git-tower.com/learn/git/faq/detached-head-when-checkout-commit/ |
| 900 | 908 | [gitgh]: https://github.com/git/git/ |
| 909 | +[gle]: https://git-scm.com/docs/git-reflog#_options_for_expire | |
| 901 | 910 | [grp]: https://git-scm.com/docs/git-rev-parse |
| 902 | 911 | [grpgh]: https://github.com/git/git/commit/a99bc27aec74071aa1 |
| 903 | 912 | [reflog]: https://git-scm.com/docs/git-reflog |
| 904 | 913 | |
| 905 | 914 | ---- |
| 906 | 915 |
| --- www/gitusers.md | |
| +++ www/gitusers.md | |
| @@ -46,13 +46,12 @@ | |
| 46 | |
| 47 | |
| 48 | #### <a id="cwork" name="scw"></a> Checkout Workflows |
| 49 | |
| 50 | A Fossil repository is a SQLite database storing the entire history of a |
| 51 | project. It is not normally stored inside the working tree, as with Git. |
| 52 | |
| 53 | The working tree — also called a check-out in Fossil — is a directory |
| 54 | that contains a snapshot of your project that you are currently working |
| 55 | on, extracted for you from the repository database file by the `fossil` |
| 56 | program. |
| 57 | |
| 58 | Git commingles these two by default, with the repository stored in a |
| @@ -61,30 +60,37 @@ | |
| 61 | designed into the core concept of the tool, Git tutorials usually |
| 62 | advocate a switch-in-place working mode instead, so that is how most |
| 63 | users end up working with Git. Contrast [Fossil’s check-out workflow |
| 64 | document][ckwf] to see the practical differences. |
| 65 | |
| 66 | There are two key Git-specific things to add to that document. |
| 67 | |
| 68 | First, this: |
| 69 | |
| 70 | git checkout some-branch |
| 71 | |
| 72 | …is spelled: |
| 73 | |
| 74 | fossil update some-branch |
| 75 | |
| 76 | …in Fossil. |
| 77 | |
| 78 | Second, as of Fossil 2.14, we now have Git-style clone-and-open: |
| 79 | |
| 80 | fossil clone https://example.com/repo |
| 81 | |
| 82 | That gets you a `repo.fossil` file, opened into a `repo/` working |
| 83 | directory alongside it. Note that we do not commingle the repo and |
| 84 | working directory even in this case. See [the workflows doc][ckwf] |
| 85 | for more detail on this and related topics. |
| 86 | |
| 87 | [ckwf]: ./ckout-workflows.md |
| 88 | |
| 89 | |
| 90 | #### <a id="rname"></a> Naming Repositories |
| @@ -417,10 +423,19 @@ | |
| 417 | [tlc]: /help?cmd=timeline |
| 418 | [tlw]: /help?cmd=/timeline |
| 419 | [up]: /help?cmd=update |
| 420 | [wdm]: ./fossil-v-git.wiki#durable |
| 421 | |
| 422 | |
| 423 | ## <a id="slcom"></a> Summary Line Convention In Commit Comments |
| 424 | |
| 425 | The Git convention of a [length-limited summary line][lsl] at the start |
| 426 | of commit comments has no equivalent in Fossil. You’re welcome to style |
| @@ -475,14 +490,10 @@ | |
| 475 | |
| 476 | To switch back to the parent branch, say something like: |
| 477 | |
| 478 | fossil update trunk # ≅ git checkout master |
| 479 | |
| 480 | (There is also `fossil checkout trunk`, but it’s a 2nd-tier command |
| 481 | meant for more specialized purposes. Almost always, you want to use |
| 482 | `update` instead.) |
| 483 | |
| 484 | Fossil does also support the Git style, creating the branch ahead of |
| 485 | need: |
| 486 | |
| 487 | fossil branch new my-new-branch |
| 488 | fossil update my-new-branch |
| @@ -764,25 +775,25 @@ | |
| 764 | |
| 765 | Let’s get into something a bit more complicated: a case study showing |
| 766 | how the concepts lined out above cause Fossil to materially differ in |
| 767 | day-to-day operation from Git. |
| 768 | |
| 769 | A common thing to need to do in a version control system is to check out |
| 770 | a version by date. Perhaps this is because your customer gave you a |
| 771 | vague bug report — “I think it broke on a Wednesday… Yes, there was a |
| 772 | full moon, and the Dodgers were playing in Boston…” — or perhaps you’re |
| 773 | poking semi-randomly through history to find a “good” version to set up |
| 774 | the start point of a [`bisect`][bis] operation. |
| 775 | |
| 776 | Because Git doesn’t maintain comprehensive lookup tables into its log — |
| 777 | [as detailed above](#log) — you will find pages online recommending |
| 778 | horror-show commands like this: |
| 779 | |
| 780 | git checkout $(git rev-list -n 1 --first-parent --before="2020-04-12" master) |
| 781 | |
| 782 | That’s [the top answer on Stack Overflow][gcod] for the first hit on |
| 783 | “git checkout by date” in the web search engine I used. |
| 784 | |
| 785 | We believe you get such answers to Git help requests in part |
| 786 | because of its lack of an always-up-to-date index into its log and in |
| 787 | part because of its “small tools loosely joined” design philosophy. This |
| 788 | sort of command is therefore composed piece by piece: |
| @@ -789,11 +800,12 @@ | |
| 789 | |
| 790 | <center>◆ ◆ ◆</center> |
| 791 | |
| 792 | **Given:** Git lacks a reliable lookup-by-date index into its log. |
| 793 | |
| 794 | **Goal:** Find the commit ID nearest a given date, you poor sod. |
| 795 | |
| 796 | “Oh, I know, I’ll search the rev-list, which outputs commit IDs by |
| 797 | parsing the log backwards from `HEAD`! Easy!” |
| 798 | |
| 799 | git rev-list --before=2020-04-12 |
| @@ -822,11 +834,11 @@ | |
| 822 | “Well poop: it shows the same commit! Eff it; let’s just try it and hope |
| 823 | it’s close enough.” |
| 824 | |
| 825 | git checkout $(git rev-list -n 1 --no-merges --before=2020-04-12 master) |
| 826 | |
| 827 | “Success! Just so easy!” |
| 828 | |
| 829 | <center>◆ ◆ ◆</center> |
| 830 | |
| 831 | This vignette is meant to explain some of Git’s popularity: it rewards |
| 832 | the sort of people who enjoy puzzles, many of whom are software |
| @@ -835,14 +847,10 @@ | |
| 835 | |
| 836 | And too bad if you’re a Windows user who doesn’t want to use [Git |
| 837 | Bash][gbash], since neither of the stock OS command shells have a |
| 838 | command interpolation feature needed to run that horrid command. |
| 839 | |
| 840 | By the way, congratulations, you just created a [detached head][gdh] |
| 841 | along with all of its attendant risks. There’s no such state in Fossil |
| 842 | due to its robust commit history indexing. |
| 843 | |
| 844 | If you think the bit about “a commit from 2019-12-15” in my |
| 845 | little story above is made up, try `git rev-parse master@{2020-04-12}` |
| 846 | on [Git’s own repository][gitgh]: it gives [this commit][grpgh]! Though |
| 847 | GitHub shows the date we asked for, the `git show` command above gives |
| 848 | the confusing result referenced in the story. |
| @@ -864,26 +872,26 @@ | |
| 864 | git checkout master@{2020-04-12} |
| 865 | |
| 866 | It’s a bit cryptic, but it’s much nicer than the prior command. |
| 867 | |
| 868 | Too bad it only works if the target commit is in Git’s [reflog], which |
| 869 | Git automatically prunes to 90 days of history from time to time. But |
| 870 | the above command won’t fail outright if the reflog can’t resolve the |
| 871 | given date, it will instead give an *incorrect* result on `stdout`, |
| 872 | *possibly* accompanied by a warning on *stderr!* While I was writing |
| 873 | this, it happily gave me a commit from 2019-07-19 until I nuked the |
| 874 | repository and re-cloned, after which it at least warned me that the |
| 875 | reflog didn’t go back that far… But it still gave me an answer: a wrong |
| 876 | one! |
| 877 | |
| 878 | Why? Because Git lacks comprehensive up-to-date indices into its log, |
| 879 | and my clone was stale. |
| 880 | When I nuked my stale clone and re-cloned, my |
| 881 | command above started giving me today’s latest commit, that being as far |
| 882 | back in history as it could dig. Who wants this behavior? |
| 883 | |
| 884 | Well, at least it works on Windows! That’s something! |
| 885 | |
| 886 | But woe betide you if you leave off the `master` bit. Or forget some bit |
| 887 | of the cryptic punctuation. |
| 888 | |
| 889 | You may be asking with an exasperated huff, “What is your *point*, man?” |
| @@ -890,16 +898,17 @@ | |
| 890 | The point is that the equivalent in Fossil is simply: |
| 891 | |
| 892 | fossil up 2020-04-12 |
| 893 | |
| 894 | …and the commit will *always* be the one closest to the 12th of April, 2020, no matter |
| 895 | whether it’s a fresh clone or a stale one, praise be Ritchie! |
| 896 | |
| 897 | [gbash]: https://appuals.com/what-is-git-bash/ |
| 898 | [gcod]: https://stackoverflow.com/a/6990682/142454 |
| 899 | [gdh]: https://www.git-tower.com/learn/git/faq/detached-head-when-checkout-commit/ |
| 900 | [gitgh]: https://github.com/git/git/ |
| 901 | [grp]: https://git-scm.com/docs/git-rev-parse |
| 902 | [grpgh]: https://github.com/git/git/commit/a99bc27aec74071aa1 |
| 903 | [reflog]: https://git-scm.com/docs/git-reflog |
| 904 | |
| 905 | ---- |
| 906 |
| --- www/gitusers.md | |
| +++ www/gitusers.md | |
| @@ -46,13 +46,12 @@ | |
| 46 | |
| 47 | |
| 48 | #### <a id="cwork" name="scw"></a> Checkout Workflows |
| 49 | |
| 50 | A Fossil repository is a SQLite database storing the entire history of a |
| 51 | project. It is not normally stored inside the working tree. |
| 52 | A Fossil working tree — also called a check-out — is a directory |
| 53 | that contains a snapshot of your project that you are currently working |
| 54 | on, extracted for you from the repository database file by the `fossil` |
| 55 | program. |
| 56 | |
| 57 | Git commingles these two by default, with the repository stored in a |
| @@ -61,30 +60,37 @@ | |
| 60 | designed into the core concept of the tool, Git tutorials usually |
| 61 | advocate a switch-in-place working mode instead, so that is how most |
| 62 | users end up working with Git. Contrast [Fossil’s check-out workflow |
| 63 | document][ckwf] to see the practical differences. |
| 64 | |
| 65 | There is one Git-specific detail we wish to add beyond what that |
| 66 | document already covers. This command: |
| 67 | |
| 68 | git checkout some-branch |
| 69 | |
| 70 | …is best given as: |
| 71 | |
| 72 | fossil update some-branch |
| 73 | |
| 74 | …in Fossil. There is a `fossil checkout` command, but it has two |
| 75 | restrictions that push you toward using `fossil update` instead: |
| 76 | |
| 77 | 1. Several features in `fossil update` do not exist in |
| 78 | `fossil checkout`. |
| 79 | |
| 80 | 2. The lone exception is `fossil checkout --keep`, a rarely-needed |
| 81 | operation. |
| 82 | |
| 83 | 3. Fossil will have you typing “`fossil up`” frequently anyway to pull |
| 84 | remote changes and merge them into the local check-out directory. |
| 85 | Adding a `VERSION` string for the cases where you mean something |
| 86 | other than “tip of the current branch” is an easy habit to develop. |
| 87 | |
| 88 | Neither command is an alias for the other. They overlap enough that they |
| 89 | can be used interchangeably for everyday use cases, but since `update` |
| 90 | is more powerful, we recommend that you break the habit of typing |
| 91 | `checkout`. |
| 92 | |
| 93 | [ckwf]: ./ckout-workflows.md |
| 94 | |
| 95 | |
| 96 | #### <a id="rname"></a> Naming Repositories |
| @@ -417,10 +423,19 @@ | |
| 423 | [tlc]: /help?cmd=timeline |
| 424 | [tlw]: /help?cmd=/timeline |
| 425 | [up]: /help?cmd=update |
| 426 | [wdm]: ./fossil-v-git.wiki#durable |
| 427 | |
| 428 | |
| 429 | ## <a id="dhead"></a> Detached HEAD State |
| 430 | |
| 431 | The SQL indexes in Fossil which we brought up above have a very useful |
| 432 | side benefit: you cannot have a [detached HEAD state][gdh] in Fossil, |
| 433 | the source of untold pain and data loss in Git. It simply cannot be done |
| 434 | in Fossil, because the indexes always let us find our way back into the |
| 435 | hash tree. |
| 436 | |
| 437 | |
| 438 | ## <a id="slcom"></a> Summary Line Convention In Commit Comments |
| 439 | |
| 440 | The Git convention of a [length-limited summary line][lsl] at the start |
| 441 | of commit comments has no equivalent in Fossil. You’re welcome to style |
| @@ -475,14 +490,10 @@ | |
| 490 | |
| 491 | To switch back to the parent branch, say something like: |
| 492 | |
| 493 | fossil update trunk # ≅ git checkout master |
| 494 | |
| 495 | Fossil does also support the Git style, creating the branch ahead of |
| 496 | need: |
| 497 | |
| 498 | fossil branch new my-new-branch |
| 499 | fossil update my-new-branch |
| @@ -764,25 +775,25 @@ | |
| 775 | |
| 776 | Let’s get into something a bit more complicated: a case study showing |
| 777 | how the concepts lined out above cause Fossil to materially differ in |
| 778 | day-to-day operation from Git. |
| 779 | |
| 780 | You may need to check out |
| 781 | a version of a project by date. Perhaps your customer gave you a |
| 782 | vague bug report referencing only a date rather than a version, or perhaps you’re |
| 783 | poking semi-randomly through history to find a “good” version to anchor |
| 784 | the start point of a [`bisect`][bis] operation. |
| 785 | |
| 786 | Because Git doesn’t maintain comprehensive lookup tables into its log — |
| 787 | [as detailed above](#log) — you will find pages online recommending |
| 788 | long, nested commands like this: |
| 789 | |
| 790 | git checkout $(git rev-list -n 1 --first-parent --before="2020-04-12" master) |
| 791 | |
| 792 | That’s [the top answer on Stack Overflow][gcod] for |
| 793 | “git checkout by date” as surfaced by the web search engine I used, |
| 794 | its first search result. |
| 795 | |
| 796 | We believe you get such answers to Git help requests in part |
| 797 | because of its lack of an always-up-to-date index into its log and in |
| 798 | part because of its “small tools loosely joined” design philosophy. This |
| 799 | sort of command is therefore composed piece by piece: |
| @@ -789,11 +800,12 @@ | |
| 800 | |
| 801 | <center>◆ ◆ ◆</center> |
| 802 | |
| 803 | **Given:** Git lacks a reliable lookup-by-date index into its log. |
| 804 | |
| 805 | **Goal:** Find the commit ID nearest a given date, you poor unfortunate |
| 806 | user. |
| 807 | |
| 808 | “Oh, I know, I’ll search the rev-list, which outputs commit IDs by |
| 809 | parsing the log backwards from `HEAD`! Easy!” |
| 810 | |
| 811 | git rev-list --before=2020-04-12 |
| @@ -822,11 +834,11 @@ | |
| 834 | “Well poop: it shows the same commit! Eff it; let’s just try it and hope |
| 835 | it’s close enough.” |
| 836 | |
| 837 | git checkout $(git rev-list -n 1 --no-merges --before=2020-04-12 master) |
| 838 | |
| 839 | “Success, I guess?” |
| 840 | |
| 841 | <center>◆ ◆ ◆</center> |
| 842 | |
| 843 | This vignette is meant to explain some of Git’s popularity: it rewards |
| 844 | the sort of people who enjoy puzzles, many of whom are software |
| @@ -835,14 +847,10 @@ | |
| 847 | |
| 848 | And too bad if you’re a Windows user who doesn’t want to use [Git |
| 849 | Bash][gbash], since neither of the stock OS command shells have a |
| 850 | command interpolation feature needed to run that horrid command. |
| 851 | |
| 852 | If you think the bit about “a commit from 2019-12-15” in my |
| 853 | little story above is made up, try `git rev-parse master@{2020-04-12}` |
| 854 | on [Git’s own repository][gitgh]: it gives [this commit][grpgh]! Though |
| 855 | GitHub shows the date we asked for, the `git show` command above gives |
| 856 | the confusing result referenced in the story. |
| @@ -864,26 +872,26 @@ | |
| 872 | git checkout master@{2020-04-12} |
| 873 | |
| 874 | It’s a bit cryptic, but it’s much nicer than the prior command. |
| 875 | |
| 876 | Too bad it only works if the target commit is in Git’s [reflog], which |
| 877 | Git [automatically prunes][gle] to 90 days of history from time to time. But |
| 878 | the above command won’t fail outright if the reflog can’t resolve the |
| 879 | given date, it will instead give an *incorrect* result on `stdout`, |
| 880 | *possibly* accompanied by a warning on *stderr!* While I was writing |
| 881 | this, it happily gave me a commit from 2019-07-19 until I nuked the |
| 882 | repository and re-cloned, after which it at least warned me that the |
| 883 | reflog didn’t go back that far… But it still gave me an answer: a wrong |
| 884 | one! |
| 885 | |
| 886 | Why? Because Git lacks comprehensive up-to-date indices into its log, |
| 887 | and my clone was stale, apparently last updated in July of 2019. |
| 888 | When I nuked my stale clone and re-cloned, my |
| 889 | command above started giving me today’s latest commit, that being as far |
| 890 | back in history as it could dig. Who wants this behavior? |
| 891 | |
| 892 | Well, at least it works on Windows… That’s something! |
| 893 | |
| 894 | But woe betide you if you leave off the `master` bit. Or forget some bit |
| 895 | of the cryptic punctuation. |
| 896 | |
| 897 | You may be asking with an exasperated huff, “What is your *point*, man?” |
| @@ -890,16 +898,17 @@ | |
| 898 | The point is that the equivalent in Fossil is simply: |
| 899 | |
| 900 | fossil up 2020-04-12 |
| 901 | |
| 902 | …and the commit will *always* be the one closest to the 12th of April, 2020, no matter |
| 903 | whether it’s a fresh clone or a stale one. |
| 904 | |
| 905 | [gbash]: https://appuals.com/what-is-git-bash/ |
| 906 | [gcod]: https://stackoverflow.com/a/6990682/142454 |
| 907 | [gdh]: https://www.git-tower.com/learn/git/faq/detached-head-when-checkout-commit/ |
| 908 | [gitgh]: https://github.com/git/git/ |
| 909 | [gle]: https://git-scm.com/docs/git-reflog#_options_for_expire |
| 910 | [grp]: https://git-scm.com/docs/git-rev-parse |
| 911 | [grpgh]: https://github.com/git/git/commit/a99bc27aec74071aa1 |
| 912 | [reflog]: https://git-scm.com/docs/git-reflog |
| 913 | |
| 914 | ---- |
| 915 |