Fossil SCM

Another attempt at addressing forum critiques about the gitusers doc's Case Study 1. Also had to update the example date we're searching for again, so I addeed a paragraph explaining why the example might break again.

wyoung 2020-11-05 03:08 trunk
Commit 278a2b7453a759b8036104ea48e3446265ee2f6ce13ade553a442ede7c2643d1
1 file changed +29 -22
+29 -22
--- www/gitusers.md
+++ www/gitusers.md
@@ -784,11 +784,11 @@
784784
My search engine’s first result for “git checkout by date” gives [a
785785
highly-upvoted accepted answer on Stack Overflow][gcod]. It gives two
786786
alternative commands, the first of which is based on Git’s [`rev-parse`
787787
feature][grp]:
788788
789
- git checkout master@{2020-03-12}
789
+ git checkout master@{2020-03-17}
790790
791791
It’s a bit cryptic, but that’s not its major flaw: it only works if the
792792
target commit is in Git’s [reflog], which Git [automatically
793793
prunes][gle] to 90 days of history, by default. Worse, the command won’t
794794
fail outright if the reflog can’t resolve the given date, it will
@@ -802,11 +802,11 @@
802802
from a purgeable and possibly-stale local cache.
803803
804804
That same Stack Overflow answer therefore goes on to recommend an
805805
entirely different command:
806806
807
- git checkout $(git rev-list -n 1 --first-parent --before="2020-03-12" master)
807
+ git checkout $(git rev-list -n 1 --first-parent --before="2020-03-17" master)
808808
809809
We believe you get such answers to Git help requests in part
810810
because of its lack of an always-up-to-date [index into its log](#log) and in
811811
part because of its “small tools loosely joined” design philosophy. This
812812
sort of command is therefore composed piece by piece:
@@ -819,35 +819,36 @@
819819
user.
820820
821821
“Oh, I know, I’ll search the rev-list, which outputs commit IDs by
822822
parsing the log backwards from `HEAD`! Easy!”
823823
824
- git rev-list --before=2020-03-12
824
+ git rev-list --before=2020-03-17
825825
826826
“Blast! Forgot the commit ID!”
827827
828
- git rev-list --before=2020-03-12 master
828
+ git rev-list --before=2020-03-17 master
829829
830830
“Double blast! It just spammed my terminal with revision IDs! I need to
831831
limit it to the single closest match:
832832
833
- git rev-list -n 1 --before=2020-03-12 master
833
+ git rev-list -n 1 --before=2020-03-17 master
834834
835835
“Okay, it gives me a single revision ID now, but is it what I’m after?
836836
Let’s take a look…”
837837
838
- git show $(git rev-list -n 1 --before=2020-03-12 master)
838
+ git show $(git rev-list -n 1 --before=2020-03-17 master)
839839
840840
“Oops, that’s giving me a merge commit, not what I want.
841
-Off to search the web… Okay, it says I need to give the
842
-`--no-merges` flag to show only regular commits, not merge-commits:”
841
+Off to search the web… Okay, it says I need to give either the
842
+`--first-parent` or `--no-merges` flag to show only regular commits,
843
+not merge-commits. Let’s try the first one:”
843844
844
- git show $(git rev-list -n 1 --no-merges --before=2020-03-12 master)
845
+ git show $(git rev-list -n 1 --first-parent --before=2020-03-17 master)
845846
846847
“Better. Let’s check it out:”
847848
848
- git checkout $(git rev-list -n 1 --no-merges --before=2020-03-12 master)
849
+ git checkout $(git rev-list -n 1 --first-parent --before=2020-03-17 master)
849850
850851
“Success, I guess?”
851852
852853
<center>◆  ◆  ◆</center>
853854
@@ -863,35 +864,41 @@
863864
All of the command examples above were done on [Git’s own
864865
repository][gitgh]. Your results with the first command — the one based
865866
on [Git’s `rev-parse` feature][grp] — will vary depending on the state
866867
of your local reflog.
867868
868
-You may have noticed the difference between my story’s final command and
869
-the one given on Stack Overflow: `--first-parent` versus `--no-merges`.
870
-As far as I can tell, the SO answer is wrong, a conclusion I came to
871
-while writing this case study and finding that the command didn’t do
872
-what the SO answer claimed it did. None of the other answers on that
873
-page give the `--no-merges` option, either. This is one of the sneaky
874
-problems with complicated commands: people copy them around from place
875
-to place without trying to understand them first, so errors propagate.
869
+The date we’re using is simply our attempt to produce an example that
870
+always points at the same merge commit. As I write this, it’s pointing
871
+at [this one][gmc], but this is my third attempt: prior examples
872
+(2020-04-12 and 2020-03-12) broke for no obvious reason, suggesting that
873
+a given date in the above command isn’t always guaranteed to give the
874
+same commit. These example dates are far enough back in history that I
875
+doubt this is due to history rewriting. My pet hypothesis is that Git
876
+isn’t always traversing the log strictly in date order, and the order of
877
+entries in the log can shift about from one clone to the next, so the
878
+commit “before” a given date might differ from one to the next. If
879
+that’s true, then even the second command isn’t wholly reliable.
876880
877881
You may be asking with an exasperated huff, “What is your *point*, man?”
878882
The point is that the equivalent in Fossil is simply:
879883
880
- fossil up 2020-03-12
884
+ fossil up 2020-03-17
881885
882
-…and the commit will *always* be the one closest to the 12th of March, 2020, no matter
883
-whether it’s a fresh clone or a stale one because of Fossil’s autosync
884
-feature.
886
+…which will *always* give the commit closest to the 17th of March, 2020,
887
+no matter whether you do it on a fresh clone or a stale one because of
888
+Fossil’s autosync feature. Because this uses a SQLite indexed
889
+“`ORDER BY`” query, the answer won’t shift about from one clone to the
890
+next.
885891
886892
In Git terms, Fossil’s “reflog” is always complete and up-to-date.
887893
888894
[gbash]: https://appuals.com/what-is-git-bash/
889895
[gcod]: https://stackoverflow.com/a/6990682/142454
890896
[gdh]: https://www.git-tower.com/learn/git/faq/detached-head-when-checkout-commit/
891897
[gitgh]: https://github.com/git/git/
892898
[gle]: https://git-scm.com/docs/git-reflog#_options_for_expire
899
+[gmc]: https://github.com/git/git/commit/67b0a24910fbb23c8f5e7a2c61c339818bc68296
893900
[grp]: https://git-scm.com/docs/git-rev-parse
894901
[reflog]: https://git-scm.com/docs/git-reflog
895902
896903
----
897904
898905
--- www/gitusers.md
+++ www/gitusers.md
@@ -784,11 +784,11 @@
784 My search engine’s first result for “git checkout by date” gives [a
785 highly-upvoted accepted answer on Stack Overflow][gcod]. It gives two
786 alternative commands, the first of which is based on Git’s [`rev-parse`
787 feature][grp]:
788
789 git checkout master@{2020-03-12}
790
791 It’s a bit cryptic, but that’s not its major flaw: it only works if the
792 target commit is in Git’s [reflog], which Git [automatically
793 prunes][gle] to 90 days of history, by default. Worse, the command won’t
794 fail outright if the reflog can’t resolve the given date, it will
@@ -802,11 +802,11 @@
802 from a purgeable and possibly-stale local cache.
803
804 That same Stack Overflow answer therefore goes on to recommend an
805 entirely different command:
806
807 git checkout $(git rev-list -n 1 --first-parent --before="2020-03-12" master)
808
809 We believe you get such answers to Git help requests in part
810 because of its lack of an always-up-to-date [index into its log](#log) and in
811 part because of its “small tools loosely joined” design philosophy. This
812 sort of command is therefore composed piece by piece:
@@ -819,35 +819,36 @@
819 user.
820
821 “Oh, I know, I’ll search the rev-list, which outputs commit IDs by
822 parsing the log backwards from `HEAD`! Easy!”
823
824 git rev-list --before=2020-03-12
825
826 “Blast! Forgot the commit ID!”
827
828 git rev-list --before=2020-03-12 master
829
830 “Double blast! It just spammed my terminal with revision IDs! I need to
831 limit it to the single closest match:
832
833 git rev-list -n 1 --before=2020-03-12 master
834
835 “Okay, it gives me a single revision ID now, but is it what I’m after?
836 Let’s take a look…”
837
838 git show $(git rev-list -n 1 --before=2020-03-12 master)
839
840 “Oops, that’s giving me a merge commit, not what I want.
841 Off to search the web… Okay, it says I need to give the
842 `--no-merges` flag to show only regular commits, not merge-commits:”
 
843
844 git show $(git rev-list -n 1 --no-merges --before=2020-03-12 master)
845
846 “Better. Let’s check it out:”
847
848 git checkout $(git rev-list -n 1 --no-merges --before=2020-03-12 master)
849
850 “Success, I guess?”
851
852 <center>◆  ◆  ◆</center>
853
@@ -863,35 +864,41 @@
863 All of the command examples above were done on [Git’s own
864 repository][gitgh]. Your results with the first command — the one based
865 on [Git’s `rev-parse` feature][grp] — will vary depending on the state
866 of your local reflog.
867
868 You may have noticed the difference between my story’s final command and
869 the one given on Stack Overflow: `--first-parent` versus `--no-merges`.
870 As far as I can tell, the SO answer is wrong, a conclusion I came to
871 while writing this case study and finding that the command didn’t do
872 what the SO answer claimed it did. None of the other answers on that
873 page give the `--no-merges` option, either. This is one of the sneaky
874 problems with complicated commands: people copy them around from place
875 to place without trying to understand them first, so errors propagate.
 
 
 
876
877 You may be asking with an exasperated huff, “What is your *point*, man?”
878 The point is that the equivalent in Fossil is simply:
879
880 fossil up 2020-03-12
881
882 …and the commit will *always* be the one closest to the 12th of March, 2020, no matter
883 whether it’s a fresh clone or a stale one because of Fossil’s autosync
884 feature.
 
 
885
886 In Git terms, Fossil’s “reflog” is always complete and up-to-date.
887
888 [gbash]: https://appuals.com/what-is-git-bash/
889 [gcod]: https://stackoverflow.com/a/6990682/142454
890 [gdh]: https://www.git-tower.com/learn/git/faq/detached-head-when-checkout-commit/
891 [gitgh]: https://github.com/git/git/
892 [gle]: https://git-scm.com/docs/git-reflog#_options_for_expire
 
893 [grp]: https://git-scm.com/docs/git-rev-parse
894 [reflog]: https://git-scm.com/docs/git-reflog
895
896 ----
897
898
--- www/gitusers.md
+++ www/gitusers.md
@@ -784,11 +784,11 @@
784 My search engine’s first result for “git checkout by date” gives [a
785 highly-upvoted accepted answer on Stack Overflow][gcod]. It gives two
786 alternative commands, the first of which is based on Git’s [`rev-parse`
787 feature][grp]:
788
789 git checkout master@{2020-03-17}
790
791 It’s a bit cryptic, but that’s not its major flaw: it only works if the
792 target commit is in Git’s [reflog], which Git [automatically
793 prunes][gle] to 90 days of history, by default. Worse, the command won’t
794 fail outright if the reflog can’t resolve the given date, it will
@@ -802,11 +802,11 @@
802 from a purgeable and possibly-stale local cache.
803
804 That same Stack Overflow answer therefore goes on to recommend an
805 entirely different command:
806
807 git checkout $(git rev-list -n 1 --first-parent --before="2020-03-17" master)
808
809 We believe you get such answers to Git help requests in part
810 because of its lack of an always-up-to-date [index into its log](#log) and in
811 part because of its “small tools loosely joined” design philosophy. This
812 sort of command is therefore composed piece by piece:
@@ -819,35 +819,36 @@
819 user.
820
821 “Oh, I know, I’ll search the rev-list, which outputs commit IDs by
822 parsing the log backwards from `HEAD`! Easy!”
823
824 git rev-list --before=2020-03-17
825
826 “Blast! Forgot the commit ID!”
827
828 git rev-list --before=2020-03-17 master
829
830 “Double blast! It just spammed my terminal with revision IDs! I need to
831 limit it to the single closest match:
832
833 git rev-list -n 1 --before=2020-03-17 master
834
835 “Okay, it gives me a single revision ID now, but is it what I’m after?
836 Let’s take a look…”
837
838 git show $(git rev-list -n 1 --before=2020-03-17 master)
839
840 “Oops, that’s giving me a merge commit, not what I want.
841 Off to search the web… Okay, it says I need to give either the
842 `--first-parent` or `--no-merges` flag to show only regular commits,
843 not merge-commits. Let’s try the first one:”
844
845 git show $(git rev-list -n 1 --first-parent --before=2020-03-17 master)
846
847 “Better. Let’s check it out:”
848
849 git checkout $(git rev-list -n 1 --first-parent --before=2020-03-17 master)
850
851 “Success, I guess?”
852
853 <center>◆  ◆  ◆</center>
854
@@ -863,35 +864,41 @@
864 All of the command examples above were done on [Git’s own
865 repository][gitgh]. Your results with the first command — the one based
866 on [Git’s `rev-parse` feature][grp] — will vary depending on the state
867 of your local reflog.
868
869 The date we’re using is simply our attempt to produce an example that
870 always points at the same merge commit. As I write this, it’s pointing
871 at [this one][gmc], but this is my third attempt: prior examples
872 (2020-04-12 and 2020-03-12) broke for no obvious reason, suggesting that
873 a given date in the above command isn’t always guaranteed to give the
874 same commit. These example dates are far enough back in history that I
875 doubt this is due to history rewriting. My pet hypothesis is that Git
876 isn’t always traversing the log strictly in date order, and the order of
877 entries in the log can shift about from one clone to the next, so the
878 commit “before” a given date might differ from one to the next. If
879 that’s true, then even the second command isn’t wholly reliable.
880
881 You may be asking with an exasperated huff, “What is your *point*, man?”
882 The point is that the equivalent in Fossil is simply:
883
884 fossil up 2020-03-17
885
886 …which will *always* give the commit closest to the 17th of March, 2020,
887 no matter whether you do it on a fresh clone or a stale one because of
888 Fossil’s autosync feature. Because this uses a SQLite indexed
889 “`ORDER BY`” query, the answer won’t shift about from one clone to the
890 next.
891
892 In Git terms, Fossil’s “reflog” is always complete and up-to-date.
893
894 [gbash]: https://appuals.com/what-is-git-bash/
895 [gcod]: https://stackoverflow.com/a/6990682/142454
896 [gdh]: https://www.git-tower.com/learn/git/faq/detached-head-when-checkout-commit/
897 [gitgh]: https://github.com/git/git/
898 [gle]: https://git-scm.com/docs/git-reflog#_options_for_expire
899 [gmc]: https://github.com/git/git/commit/67b0a24910fbb23c8f5e7a2c61c339818bc68296
900 [grp]: https://git-scm.com/docs/git-rev-parse
901 [reflog]: https://git-scm.com/docs/git-reflog
902
903 ----
904
905

Keyboard Shortcuts

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