The average git command is along the lines of "git ph-nglui --mglw=nafh Cthulhu...R'lyeh -- wgah^nagl fhtagn"
The average git command is along the lines of "git ph-nglui --mglw=nafh Cthulhu...R'lyeh -- wgah^nagl fhtagn"
git diff
git commit -p
git rebase -i HEAD~3
The command quoted in my original comment is just this we strip away the SHA256 garbage: git log abac87a..f787cac
(Or maybe it is: git log abac87a^..f787cac^
I cannot guess whether the ^ operator still has the same meaning or whether it is part of this ^{sha...} notation.)The hashes will typically be copy and pasted, so you type just the git log, .. and spaces.
The fixed parts of convoluted git syntax can be hidden behind shell functions and aliases. But notations for referencing objects are not fixed; they will end up as arguments.
This isn't the first ^{...} notation. The manpage gitrevisions(7) also mentions <rev>^{/<text>} for referencing a commit based on a regular expression of its commit message, like
git checkout 'add-search^{/finished query builder}'
Though, this new notation is probably more in-line with the notation <rev>^{<type>}, which lets you disambiguate what you put in <rev> as in deadbeef^{tag}, so that it's not confused with deadbeef^{commit}.EDIT: The article doesn't mention it, but I imagine one interpretation would take precedence and cause git to issue a warning when it's ambiguous. Right now, if I tag a commit with the hash of another commit, its interpretation as a tag takes precedence and I get a warning at the top, "warning: refname '368bc6e' is ambiguous." That would mean you'd only ever write ^{sha256} when the provided part of a sha256 hash is ambiguous with an existing sha1 hash or something else like a tag. That's also vice versa with ^{sha1}.
> 'For a Git user interface this is relatively straightforward and concise'.
It kinda looks like you missed the joke and are now doubling-down on your disagreement.
The author does not think the proposed example is reasonable. You're in agreement.
But unless you're going to take this up with Linus, you're just yelling at your fellow disappointed spectators.
Anyone who compares the git CLI to being driven insane by Elder Gods is not defending the git CLI.
I know he's not defending it.
What I said is that he (kazinator) is inadvertently attacking somebody that's also not defending it (the author).
Well, let's see, the Fossil equivalents are:
1. Do nothing at all for a conversion from the SHA-1 to SHA-3 — yes, 3, not 2 as in Git! — because it's automatic for months now and dead easy going back 3 years now. (https://www.fossil-scm.org/fossil/doc/trunk/www/hashpolicy.w...)
2. "fossil diff"
3. "fossil ci"
4. Why are you rebasing in the first place, again? https://www.fossil-scm.org/fossil/doc/trunk/www/rebaseharm.m...
> Rebasing is the same as lying
And I think, "Holy crud do I not want to be part of this community."
The nice thing about Git is that (within reason) once I understood it, I was able to use it in very flexible ways.
It's really common for different projects I manage to range all over the place from the extreme "commits as literal history" perspective all the way to the "commits as literature/guide" perspective. Sometimes I don't rebase at all, sometimes I rebase a lot. Sometimes I commit everything, all the time, sometimes I refuse to commit any code that isn't a deployable feature. Sometimes I leave branches as historical artifacts, sometimes I don't care about history and I'm just trying to coordinate developers across timelines.
That's not to say that Git isn't opinionated about some things -- nearly all good tools have at least a few strong opinions. But Git passes the (IMO extremely low) bar of not conflating a workflow decision with a moral failing. Over the years as a software engineer, I've learned to be somewhat skeptical of programming/workflow heuristics advertised as rules, and to be very skeptical of heuristics advertised as ideologies.
I really don't understand the perspective of someone who can't think of even one good reason why they would ever want to edit history. You've never accidentally committed a password to repo, or had to respond to a takedown request?
The fact that Fossil preserves history does not prevent you from coordinating with people across timelines. It is rather the whole point of a DVCS.
> conflating a workflow decision with a moral failing
I think it's fairer to say that we don't think a data repository is any place for lies of any sort, even white lies.
> I've learned to be somewhat skeptical of programming/workflow heuristics advertised as rules, and to be very skeptical of heuristics advertised as ideologies.
Sure, flexible tools are often better than inflexible ones, but you also have to consider the cost of the flexibility. Here, it means someone can say "this happened at some point in the past," and it's just plain wrong.
That isn't always an important thing. Most filesystems and databases operate on the same principle, presenting only the current truth, not any past truth.
Yet, we also have snapshotting in DBMSes and filesystems, because it's often very useful to be able to say, "This was the state of the system as of 2020.02.04."
You don't need a snapshotting filesystem for everything, and you don't need Fossil for everything, but it sure is nice to have ready access to both when needed.
> You've never accidentally committed a password to repo, or had to respond to a takedown request?
Fossil has shunning for that: https://fossil-scm.org/fossil/doc/trunk/www/shunning.wiki
And no, shunning is nothing at all like rebase, which should be clear from the article.
Fossil also has the `amend` command: http://fossil-scm.org/fossil/help?cmd=amend
And no, it is also not like rebase, because it only adds to the project history, it never destroys information.
I, too, wish this extreme hyperbole would be just left out of the discussion completely. It is offputting, and I think it's intentionally a bad faith argument, it fails to acknowledge the utility, the design intent, and the context behind rebase, which has been talked about at length by Linus and others.
When rebase is used as designed, according to the golden rule, it's not modifying published history, so it's not "lying". Whether rebase has safety problems is a separate issue from whether it's use as designed amounts to being "dishonest".
I'm all in favor of improved design choices, and if Fossil is making those better design choices, let them stand on their own without intentionally denigrating git and every user of git through utter exaggeration.
When I revise history in Git, even if it's just doing something as simple as removing sensitive information, I often need to replace that information, either through new commits, or by introducing minor edits to surrounding commits. I could add those changes on top of my current HEAD, but then checkouts of old versions would be broken. On the other hand, if I can just replay my commits while inserting extra code, I'll end up with something that's pretty close to my original history, with just the offending information excluded/replaced.
That carries the cost that people will need to force pull my repo, but at least the repo history will still roughly correspond to what development looked like, rather than being out-of-order and mostly impossible to build except for at my current HEAD.
As a followup question, what do you do if the sensitive information you need to exclude is in a commit message? `amend` won't help you, since it's not destroying information. Do you shun that commit and then... what?
It just seems like destroying information isn't enough unless you can also replace it?
> Sure, flexible tools are often better than inflexible ones, but you also have to consider the cost of the flexibility.
I appreciate this -- I like having multiple tools for different purposes. I don't see a problem with having a VC that focuses on auditability, or having one that goes in a radically different direction from Git. Fossil has very interesting ideas, which is why I try to pay it some attention whenever I see it mentioned or linked to.
However, whenever I follow those links and start digging deeper into the philosophy behind its design decisions, inevitably the conversation changes from, "here's our alternative approach to Git" to "what Git does is fundamentally wrong". It's not, "Fossil doesn't have this problem because we eschew rebasing", it's "why would anyone rebase?"
(Nearly) all architectural decisions have good and bad consequences. Sometimes those consequences are imbalanced, so we have heuristics that can say things like, "often X is a bad idea." That's fine.
More harmfully, sometimes people extend heuristics into rules that say, "it's never a good idea to do X". Programming rules are usually wrong.
But programming ideologies the worst, because they say, "there is something mentally or morally wrong with a person who would do X". This is toxic for the reasons that Fossil devs already mention in their documentation:
> programmers should avoid linking their code with their sense of self
Programming ideologies explicitly encourage developers to have egos, because ideology conflates architectural decisions and workflow processes with individual worth. Programming ideologies make it harder for people to grow as programmers, because they tie intellectual growth to fears about being wrong. They're completely toxic.
And is Fossil's documentation promoting an ideology? I'm guessing that you'd disagree with me on this, but my take is that when Fossil's official documentation says things like:
> Honorable writers adjust their narrative to fit history. Rebase adjusts history to fit the narrative.
or
> It is dishonest. It deliberately omits historical information. It causes problems for collaboration. And it has no offsetting benefits.
That's not designing a focused tool to support specific heuristics, or making a case that, "sometimes strict auditability is important". That's just trolling for fights.
No. You start with the ideology based on your local culture and project needs, then you pick the tool that supports your project's needs.
This is why we spend so much time talking about philosophy in the Fossil vs. Git article, particularly this section: https://fossil-scm.org/fossil/doc/trunk/www/fossil-v-git.wik...
Which of the two philosophies matches better with the way your project works? That alone is a pretty good guide to whether you want Fossil or Git. (Or something else!)
A foobar is an assertion that there is a single right or wrong way to look at the world. Not even just a single correct or incorrect way, but a right way -- a proper way. If the problem with a rule is that it overgeneralizes what the world is, the problem with a foobar is that it generalizes what the world ought to be. To the extent that a foobar allows space for deviation or alternate approaches to architecture, it's only with the implicit understanding that those deviations are on some level, a kind of small sin.
Not all foobars are necessarily wrong, but in the world of software, they are particularly dangerous, and should be approached with caution. Under a foobar, a rebase isn't an organization strategy, it's a "white lie". A writer isn't optimizing for a specific audience or purpose, they're "honerable". An agreed-upon set of rules for everyone accessing a repo can be "dishonest".
Different people have different standards for this kind of thing -- but is it really all that weird or abnormal to worry that this kind of language can encourage toxicity in a community, or that it could encourage developers to think of architectural outcomes as personal validations or attacks? To me, that language sounds very foobar, and it makes me nervous about what experience I'm going to have if I adopt Fossil and then start asking questions to the community about how to use it in unconventional ways.
To be clear, there are other pages in Fossil's documentation that are much, much better about this kind of thing (particularly the Fossil vs Git page).
But even on those pages, the thing is: I use Git constantly. I am intimately familiar with its strengths and flaws. I really don't need the documentation to tell me that Git's storage is an "ad-hock pile-of-files", because I've worked with those files before and built 3rd-party tools to manipulate them, and while there are flaws, sometimes being able to do a completely dependency-free read on any OS/platform to find the current HEAD is quite useful.
When I read the docs, I just want to know what makes your software different. You're not going to convince me that actually all of my experiences were wrong, and everything I like about Git is secretly terrible. You might be able to convince me that there are specific problems Git isn't optimized for, and that Fossil can solve them.
When Fossil is talking about Bazaar and Cathedral development, I'm really interested in learning more. When Fossil is taking cheap shots at purposeful design decisions in Git that are actually really good for certain classes of problems, I lose confidence that the docs know what they're talking about.
If I were to attempt to help with the terminology, instead of sorting out the definition of ideology, I might say you’re talking about dogma and wyoung2 was referring to philosophy most directly above, but indirectly using philosophy to justify dogma.
There’s a fairly stark irony here in using words like ‘lie’ and ‘dishonest’ to judge this git workflow while at the same time taking cheap shots... but in the end I suppose the Fossil devs can describe things any way they want, and I don’t have to like it or use Fossil.
If you think your filesystem-based Git repo is easy to manipulate, go poking around in there, and what you'll find is a bespoke one-off pile-of-files database! Given a choice between Git's DB and SQLite, I put more trust into SQLite.
> I just want a C program in /usr/bin that does version control.
...which Git doesn't provide. Git is hundreds of files scattered all over your filesystem, a large number of which aren't C binaries anyway, and of those that are, only one of them is the front-end program sitting in /usr/bin, whereas Fossil can be built to a single static executable in /usr/bin.
And if you can't build Fossil statically on your system, it's likely due to an OS limitation rather than something about Fossil itself, as on RHEL where they've made fully static linking rather difficult in the past few releases.
Getting back to Git, large chunks of Git are written in POSIX shell, Perl, Python, and Tcl/Tk. Almost all of Fossil is written in C, and the rest of the code is embedded within that binary running under built-in interpreters rather than depending on platform interpreters.
This has nice knock-on effects, one of which is that Fossil is truly native on Windows, whereas you have to drag along a Linux portability environment to run Git on Windows. Another is that Fossil plays nicely with chroot/jail/container technology.
> I'm also not interested in version control systems that are dragging along a wiki and bug tracker.
Not a GitHub or GitLab user, then, I'm guessing?
> Not a GitHub or GitLab user, then, I'm guessing?
Absolutely not.
You mean your password is something funny? In that case random.org can help you with password generation.
The point is valid that when we rebase, we are losing history: the context of where that change was originally parented.
However, (1) the history does not matter if the change was parented in some temporary context, like your unpublished changes and (2) the information can be tracked in other ways, such as a Gerrit Change-Id (or something like it) in the commit message.
Regarding (1) the extra parent pointers in a merge commit cause retention of garbage. If we do everything with merge instead of rebase, we will never lose any of the temporary commits. If we prepare an unpublished change through numerous rebase operations, all that temporary crap will stay referenced from the head, waste space and confuse other people with irrelevant information when they try to navigate the history.
It does if it means a big ball o' hackage lands on the public working branch, since it complicates merges, backouts, cherrypicks, and bisects.
Git users can also hide individual commit messages behind one big combined message, losing part of the project's development history and logical progression.
When I pull your repo and build it, and I find that it doesn't build on my system, I don't want to dig through a 500-line merge commit to figure out why you changed this one line from the one that used to build last week, I want the 14-line diff it was part of so I can begin to understand what you were thinking when you committed it. If I later find out that that 14-line change was wrong but the rest of your 500-line merge was fine, I want to be able to back it out with a single command. (In Fossil, it's `fossil merge --backout abcd1234`.)
> confuse other people with irrelevant information when they try to navigate the history.
How much time do you spend navigating the project's history vs looking at the tip of the current branch?
I'd wager that the times you dig back into the history, it's because you are in fact trying to figure out why you got here, which means a trail of detailed breadcrumbs will be more likely helpful than "...and between one week and the next, something changed in commit abcd1234, but we've lost all of its internal context, so we'll be spending next week reconstructing it because Angie's on vacation now."
It's reasonably common for me to start exploring a problem space, stub out a concept, and have a long drawn-out conversation with the compiler that touches many files, before finally reaching a point that is working enough to be interesting.
At that point, I can take a step back and note that actually, not all of those changes have to be made all at once, and I can break that patch up into a bunch of simpler pieces.
In Git, I have two essentially-equivalent choices:
1. stage the commit in small chunks, adding a separate descriptive comment for each.
2. commit everything as a WIP commit so this working state is in the reflog, then break it up into smaller commits with interactive rebase.
In either process, I'm able to get a better comprehension of my own thoughts along the way.
Fossil, refusing both staging would force me to commit the proverbial 500-line blob all at once, which is less helpful to the reviewer trying to discern my thought process.
If rebasing isn't important to your workflow, Fossil probably is a better choice for you than Git. It has a lot of comforts that I really appreciated even eight years ago when I did frequently use Fossil (distributed wiki and tickets are really nice, the web interface serving raw artifacts from any point in time is great for HTML5 game jams, SQLite is a very portable repository format, etc. etc. etc.), and I'm sure it's only improved in that regard. The only reason I use Git for personal projects is because rebase is that helpful to my process.
Nope.
If it were me doing such a thing as you describe, I'd start the work on a feature branch. If I'm working on that repo with other active developers, this lets them see what I'm up to and possibly help; and if not help, then at least be aware about where my head's at, so they can better predict what's likely to land on the shared working branch later.
If I got to a point where only part of the branch needed to be applied, I could cherrypick those individual changes, either down to the parent branch or up to a higher-level feature branch.
All of this happens in public, with the work fully recorded, so someone doesn't have to reconstruct the development history after the fact later.
This mode of development helps keep your project's bus factor above 1.
To be clear, my typical approach is certainly to commit every time I return to a working state. But in more experimental modes, I often reach that the long-way-around and have ended up with multiple semantic changes I wish to break apart for study.
Unless I'm missing something and Fossil has gained the ability to cherry-pick selective lines from a commit.
The connection between the two is that git has a script called git rebase, which has an interactive mode, and that can squash commits.
git merge has squash functionality also (git merge --squash).
Rebase on a local working copy is normally used for cleaning up a string of commits that is messy and/or separating commits that mixed multiple logical changes together.
Local commit history before push is arbitrary. There’s nothing sacred that needs to be preserved about the exact order I typed things into each file, that’s not what I want from a version control system.
Personally, I haven’t really seen use of rebase complicating merges, reverts, cherry picks, or bisects. I can imagine ways it can happen, but I haven’t seen it be a problem in practice. However, I have seen cases where failing to rebase caused problems. Allowing build breakage between two commits is an example where bisect is affected, and squashing the fix into the first commit before push is much preferred.
So, anyway, your example feels totally contrived.
> How much time do you spend navigating the project’s history vs looking at the tip of the current branch?
This is a false dichotomy. I need both. I happen to navigate project history quite a lot, like multiple times per day. In addition to how I got here I usually need to know who changed it, so I can talk to them.
What happens if a Fossil repo that has had SHA3 commits written to it is accessed by old Fossil software before that change was introduced?
If you have an old clone made from before the transition and try to update it, I'm not sure what it says, since I don't have any of those around any more. It has, after all, been three years since Fossil began to move on this problem, so that it's largely a past issue for us now.
This transition time was indeed annoying for us over in Fossil land, but Git's going to have to go through a transition like this, too. The question isn't whether but how long we'll have to wait for it to begin and how long it'll take to complete.
The moment I can't read new repos with an installation of git 1.6 or 1.7, I'm ditching the garbage and finding something else.
Forward and backward compatibility, forever, please!
Beyond about 10 years, you usually end up freezing old binaries in place along with old data in order to continue manipulating it anyway.