Fossil Forum

The wrong way to close a branch
Login

The wrong way to close a branch

The wrong way to close a branch

(1) By Richard Hipp (drh) on 2020-08-16 16:22:09 [source]

If you have a branch in a Fossil repository and that branch is overcome by events so that it is no longer relevant, then you can "close" that branch. The right way to do that is to add a "closed" tag. From the web interface, you can do this by clicking on the "edit" page for the last check-in of the branch, selecting the "Leaf Closure" checkbox, and pressing Submit. You can also do this from the command-line using a command like:

fossil tag add --raw closed BRANCH

The wrong way to close a branch is to merge the branch into trunk, then undo all the changes associated with the branch prior to committing. Merging a branch and then reverting the changes is wrong because it makes it appear in the timeline as if the branch had actually merged. This is confusing and deceptive.

Recently, a branch in Fossil was closed in the wrong way → by merging, reverting changes, then committing. The offending check-in is 4c16a24995b48fbb. I had to go in afterwards and "fix" the problem by moving that check-in (and all of its successors) onto a new branch, closing the new branch, then cherry-picking the successors back onto trunk.

Had I not fixed this merge error, then the "history" of trunk (example) would have made it appears as if the changes of the abandoned branch had actually landed on trunk.

(2) By Richard Hipp (drh) on 2020-08-16 17:51:34 in reply to 1 [link] [source]

My "fix" created disruption for another developer who was working concurrently. In retrospect, I think a better fix would have been to add a "parent" tag to the 4c16a24995b48fbb check-in that caused it to ignore the incorrect merge-in arrow. The value of a "parent" tag is a list of (complete) hashes. The first hash is the primary parent and subsequent hashes are merge parents. In other words, the value for the "parent" tag should be the revised argument to the P-card of the manifest. The original P-card for the offending manifest is:

   P 9d2b7cab7ac64cf81eeab25698c6ee9ce2afa0e338ef5ca151e6372c6d464814 719dcd29cd8a99d592793211fe60f6c0d39a450087ab5aa440ed19

The primary parent (9d2b7ca...) is correct, but the merge parent (719dcd...) is wrong. So, if I had added a "parent" tag to the 4c16a24995b48fbb check-in that contained the string value

   9d2b7cab7ac64cf81eeab25698c6ee9ce2afa0e338ef5ca151e6372c6d464814

That would have cleared the problem without the need for rebranching. There is no way to add a parent tag using the web interface (that I know of). The way to have done this would have been a command like this:

fossil tag add --raw parent 4c16a24995b48fbb 9d2b7cab7ac64cf81eeab25698c6ee9ce2afa0e338ef5ca151e6372c6d464814

Except, when I tried that command (on a test copy of the Fossil repository) it did not work. I had to first make the bug fix of check-in 2bdbbc8a0ef84271. Apparently the "parent" tag has never been used before.

(4.1) By andygoth on 2020-08-17 00:47:59 edited from 4.0 in reply to 2 [link] [source]

Interestingly, reparenting was my request to begin with! See the implementation branch and the mailing list thread in which you first mentioned the idea of reparenting in response to my request.

I wonder if your correction fixes the intermittent problem I kept having but never could reproduce in a non-proprietary repository. There was also this thread which could be due to the same issue.

Also there's this problem I haven't seen lately (though it's been a few years since the last time I amended check-in times) which I suspected (perhaps incorrectly) was related. Just reminding you it might still be out there.

Thanks for looking into reparenting again. I may have need of it to stitch together some repositories I badly bungled in the past. I attempted such surgery before, but the patient died due to the sutures not withstanding a rebuild.

(3) By andygoth on 2020-08-17 00:03:04 in reply to 1 [link] [source]

Overview

I will use this space to explain myself and my actions, to put everything on record, and to write about my perspectives. If anyone actively wants to talk about it, reply here so that others may see and discuss. If for some reason you wish to communicate privately, email me.

Documented history

Initial check-in

The history of the multi-remote-fix branch is not straightforward. It began life as my check-in on trunk that backed out the multi-remote capability because it resulted in SQLITE_MISUSE when performing any clone operation. At the time, I figured we should not leave trunk in the condition of not being able to clone anything. To document the situation and make room for discussion, I created a forum thread, which I linked to from my check-in comment.

I hoped the correction would either be the immediate follow-up commit or would take place over the span of multiple commits to a branch (rooted at the predecessor to my backout commit) which would eventually be merged to trunk, replacing my backout commit. I also hoped for discussion on the forum thread I'd created, or at least a comment saying "it's fixed now."

Reaction to initial check-in

Indeed, drh's immediate follow-up commit corrected the problem, but there was no associated forum comment. So I made my own to say it's been fixed, with a link to drh's check-in that did the trick.

There was also something else I did not expect at all. My check-in was moved to a branch named "temporary-fix". I would have thought such an action should be accompanied by a comment in the forum thread, or an edit to my check-in comment, or an email, but there was nothing.

I visibly closed the branch by doing an integrate-merge to trunk. The assigned title of the branch was "temporary-fix" so it would make sense that the purpose of the branch was to fix something, and since that something is now fixed, it would also make sense to show that the fix has been put onto trunk, hence the merge. The fact that the merge commit didn't actually change any files was immaterial to me; the point was to show that trunk now has the correction the branch was supposed to make. To the best of my knowledge, this action elicited no comment on the forum or anywhere else.

Problem only half-solved

A couple weeks later, I discovered that cloning still did not work in the specific case of the source repository being a local file. Remembering that there appeared to be a preference for letting the correction process take place on a branch, even at the cost of leaving trunk unable to do a clone, I reopened the temporary-fix branch and merged in trunk. I also made another comment on my forum thread. My professional work needed the other improvements in Fossil without the loss of local filesystem cloning, so it made sense to capture this combination of functionalities. I wish I could have fixed it on the spot, but I cannot spend my time at the office working on Fossil.

Final correction

A couple weeks after that, i.e. today, I finally got a chance to dig in and debug. The first step was updating the branch so I could fairly compare the execution of trunk with and without multi-remote. This comparison uncovered the underlying problem, which I posted about in two comments. I also renamed the branch to "multi-remote-fix" to more specifically describe its purpose.

In the midst of my debugging, drh checked a correction into trunk. This action again surprised me because I would have thought a multi-remote fix would go onto the multi-remote-fix branch, preceded by (or combined with) restoring the multi-remote functionality. There was once again no comment on the forum thread. I will write one later but have been occupied between shortly after my commit and now.

Response to final correction

Within the half hour remaining to me after my commit before joining my family for Mass, I confirmed drh's correction worked for me, and indeed it did, so I decided to once again show that my branch is closed and the fix is incorporated. I did so by repeating what I had done previously without controversy. Specifically, I performed a no-op integrate-merge to trunk whose comment explains what had happened. (Though this time I gave more detail in the comment than before.)

I then proceeded to start looking into the segfault-on-manifest issue which I spotted earlier and was reported anonymously on the forum concurrent with me trying to report it myself. I didn't get to do more than post a backtrace before going to join my family. I am pleased to see that the problem has since been corrected, though haven't had a chance to myself see the fix in action.

While debugging the segfault, I saw my no-op commit was moved to a branch, much like my original commit that backed out multi-remote due to not being able to clone anything. Also like before, there was no forum post or email or other sort of communication to go along with it, so I didn't know what to make of it, why it should be wrong now to merge a no-op with an explanatory comment to trunk when previously it appeared to be fine to do so.

Then things got even more confusing due to there being two follow-up changes committed to trunk before my check-in was moved to this new "bad-merge" branch, then those two changes additionally had to be cherry-picked to trunk. stephan then was surprised to discover his check-out had silently migrated from trunk to bad-merge. At least that finally served as the catalyst for discussion on the forum.

Observations and commentary

So, now that I have documented the history and my perspective, let me step back from the specific timeline and comment on the situation.

(Non-)use of branches

Not once but twice I was surprised by the use or non-use of branches.

In the first case, the branch was created for me as a way to get my changes off to the side, which I found confusing because the changes themselves were obsoleted by the correction, so I don't see why it was necessary to make a branch at all. Just backout my backout, put in the correction, and be done with it. There's nothing wrong with "fossil merge -backout current". (Well, other than the fact that a dotted merge arrow isn't drawn between adjacent check-ins, but that's another matter.)

Reviewing everything now, I believe drh's intention was to use my predecessor version, i.e. the one with multi-remote capability, as his baseline. He must have considered it to be more straightforward to move my change to a branch than to backout a backout.

In the second case, now that we had a branch with the stated purpose of fixing multi-remote (I renamed it to be clear and explicitly stated my intentions on the forum), why not use that branch to perform the correction? As I said above and in my other forum posts, I needed to compare behaviors with and without multi-remote to find what was the matter, and what better place than my off-to-the-side branch to store the comparison version? Then when I'd figured it out, I would have done a "merge -backout" of my first branch check-in so as to put multi-remote back in, plus apply whatever fix was necessary. And then I'd have left it on a branch for others to review before integrate-merging to trunk.

But no, the correction was once again put straight to trunk, leaving it to me to attempt to retire the branch. So I just did what I had done before, i.e. no-op integrate-merge it to trunk, explaining myself in the check-in comment.

Once again, trunk already contained multi-remote, so surely drh wanted to use it directly as his baseline rather than making any changes on my branch in the name of being able to merge that branch to trunk.

(Non-)use of forums

Throughout this entire month-long process, I've been very nearly working in a bubble. The only outside comment on my forum thread was from richieadler expressing gratitude for multi-remote being fixed. (Though his wording "multi-remotes autosyncing all at once" appears to describe capability exceeding what the current incarnation of multi-remote actually does.) Aside from that comment, the only communication I've received was seeing drh's check-ins to trunk and his twice moving my check-ins to branches. The name of the branch is the only message I get, nothing else.

I am surprised the forum thread I created for the express purpose of discussing the multi-remote cloning issue went almost totally unused. To encourage its use, I linked to it not once but twice in my check-in comments. Granted, the title of the thread did not fit the second issue that was found, but that shouldn't have mattered given that I kept linking to it.

I would have thought the thread would be a good location to talk about not only the bug and its correction, but also how to handle checking in that correction. Instead, I felt like I was only talking to myself. That's not automatically a bad thing, since it's important to capture not only the code changes and a high-level description of what they accomplish (i.e. the check-in comment), but also the context and the debugging/testing process (i.e. the forum or perhaps a branch/check-in wiki). Indeed, Fossil is an indelible means of communicating with not only each other but our posterity. Nevertheless, it's not enough for us to develop excellent communication tools; we have to actively make use of them, or else we have to resort to mind-reading, i.e. guessing.

My suspicion is that drh felt the changes he was making to be simple and self-explanatory, which indeed they are, and furthermore he must have thought I had the forum thread well-in-hand so there was no real need for him to comment.

The problem, then, was his decision to move my no-op integrate merge to a new branch when previously he did not. That I did not anticipate.

Putting changes back in the oven

(Please bear with me as I appear to go off on three tangents at once.)

Rework can be tough regardless of the SCM. When a new feature introduces a bug, what do you do? The obvious answer is to fix it. But how? Pull the original change and correct it on a branch? Leave it be but put the fix straight into trunk? Develop the fix on a branch? The options have varying degrees of invasiveness, and decision turns on the severity of the bug, the value of the feature, and how much time and effort it will take to fix. These measures are subjective and speculative, and reasonable people can disagree on the best path forward. Further complicating matters: What if the bug isn't found until some time after its introduction? What if other changes built on top of the change that broke something? Furthermore, what if the correction is later discovered to be incomplete? What if it takes a month to get everything working again? What if some people need the new feature immediately and aren't even affected by the bug even if that bug is fatal to others? All these questions came up over the course of dealing with the multi-remote issue, but none of them were actually addressed in the forum or (to my knowledge) private email. Hence, we ended up in a mind-reader situation, which inevitably caused different people to move in conflicting directions despite sharing a common goal.

On the one large group project I was lucky enough to have been allowed to use Fossil to manage (I'm normally required to use non-UCM ClearCase), we found the best policy was to reserve trunk for integrating changes first introduced on branches. We required every check-in to trunk to be a merge. (The only exception was purely administrative changes modifying Fossil's own configuration or a special file which associated branch names with customer requirement identifiers, external ticket tracking identifiers, internal/customer release identifiers, and the name of the primary responsible engineer.) This allowed engineers to check in their work frequently without worrying about destabilizing trunk. This also kept trunk relatively uncluttered, consisting almost entirely of completed activities, as well as easily amenable to bisection with a good expectation that each version is stable enough to at least compile and run. In short, we had continuous integration. I could go on about the benefits, but I'm already straying from my point, being that for group projects my team and I found branches to be a great way to coordinate.

Nowadays I mostly use Fossil for individual projects, where I find the opposite to be true. I rarely use branches to organize my separate development projects, since I rarely even have separate development projects. (Well, there are often many things I want to work on, but I mostly start and finish coding them one at a time.) Typically I'll focus on one thing, make a few check-ins, get it done, then move on. I'll certainly use branches when an effort becomes protracted or far-flung to the point where I can't let it stall more pressing matters, but that accounts for a dozen cases amidst my hundreds of one-and-done changes. I also use branches to manage the organizational hurdle posed by having multiple disconnected quasi-mirrors of the repository which can only be sync'ed via intermittent snapshots and diffs (don't ask), so branches are useful to store imported snapshots before merging them, or for later comparison when preparing a diff to export. But other than that, making a branch for each task would clutter my tree far beyond any supposed benefit, because for an individual project, I rarely need branches to avoid tripping over my own shoelaces.

What do these last three paragraphs have to do with each other and with Fossil development? I think the conflict between them is what led to us having the trouble we did today.

Sometimes Fossil is approached as an individual project, sometimes as a group project. Sometimes we have voluminous communication, sometimes an individual goes it alone. Even after all this time, we're still experiencing growing pains sussing out our development and administration policies, and it typically comes down to everyone using their best judgment. Obviously that can lead to disagreement, and when discussion is limited, the disagreement will take the form of one user suddenly reverting the work of another.

For my part, aside from obvious documentation, typo, and bug fixes, I preferred to put my changes on branches until I had favorable discussion on the mailing list or someone was brave enough to merge my work to trunk. But a couple times when I was bold enough to go straight to trunk, my changes were pulled without explanation or discussion. (Example 1, 2.) So that left me with the feeling I should stick with branches. But today when I tried to work on a branch only to see that the necessary change had quietly gone straight to trunk, and I tried close that branch because its goal was met, that became a problem too. At least an explanation did come, but only in response to explaining what happened to stephan.

Conflicting visions

Going back to my very first commit, the one where I backed out multi-remote, what I was hoping for was that a branch be made rooted at the predecessor to that commit (i.e. the last trunk version that had multi-remote), and on that branch fixes would be made. Then once sorted, the branch would be merged to trunk, wholly replacing the commit I'd made. This way, we'd atomically switch over from my version (which had working clone but no multi-remote) to the merged version (which would have working clone and working multi-remote), without any intermediate versions that lacked cloning. My view was formed by my branch-centric, process-driven mindset that I found useful in large group projects.

drh, on the other hand, took the very straightforward and pragmatic approach of simply basing his check-ins on the version that had the code that needed fixing, subtracting later, no-longer-needed commits by pushing them to a branch. I'd be a fool to say there's anything wrong with that, but nevertheless it surprised me and I didn't anticipate it. drh absolutely has the right to treat Fossil as an individual project, because it belongs to him and I'm just happy that he lets me play in his sandbox. Just like with my own individual projects, when there's no technical justification for branches, we don't bother making them.

In my process-oriented view, once the goal of a branch addressing an activity has been met, it should show as merged into trunk to show where said activity ended up being incorporated. Ideally, the merge itself would accomplish that goal, but here, it was done by a direct commit to trunk.

In drh's straightforward view, there was no reason to have a spurious no-op merge which risked confusing a casual observer into thinking that the change actually on the branch (i.e. removing multi-remotes) was merged.

Conclusion

It's not that anybody did anything wrong. The problem was a lack of communication. Neither party knew what the other was doing or why. Thus, I took it upon myself to write out in detail my side of things as my way of reversing the communication problem.

I am also now taking advantage of the new(ish) check-in/branch/tag wiki feature to revisit my old branches that weren't merged and explain their circumstances so that perhaps we might be able to come to an agreement and someday get the needed functionality into trunk.

All of this activity now has me wanting to get more involved with Fossil. Truth be told, my desire to spend my free time on Fossil has been hampered of late, and not just because of my many obligations. For one, Fossil was doing what I needed it to do, so obviously I'm going to just coast along and let others drive for as long as my needs are met. But also, I was discouraged by the previous incidents of changes being pulled without explanation. Rather than let that turn into hard feelings or confusion, I'm doing my part to restore communication lines and become more involved.

(5.1) By Stephan Beal (stephan) on 2020-08-17 02:44:54 edited from 5.0 in reply to 3 [link] [source]

i can't comment on much of that exception post, except for these few bits...

Throughout this entire month-long process, I've been very nearly working in a bubble. The only outside comment on my forum thread was from richieadler expressing gratitude for multi-remote being fixed.

My impression (without having looked closely) was the multi-sync was "your baby." It's not a feature i need, so didn't follow those posts, other than to mentally note that they'd been made, should i never need such a feature. My assumption is that that was the reason others didn't get involved in the discussion.

Aside from that comment, the only communication I've received was seeing drh's check-ins to trunk...

In his defense, if i may, there were extenuating higher-priority circumstances the past couple of weeks which had him focused (as it were) elsewhere.

My suspicion is that drh felt the changes he was making to be simple and self-explanatory, which indeed they are, and furthermore he must have thought I had the forum thread well-in-hand so there was no real need for him to comment.

FWIW, that's was my impression. Richard has never been one to announce every merge or every fix for a problem reported on the forum, aside from the commit showing that it had been done.

We required every check-in to trunk to be a merge.

FWIW again, i would not at all be bothered by such a policy.

What do these last three paragraphs have to do with each other and with Fossil development? I think the conflict between them is what led to us having the trouble we did today. ... Sometimes Fossil is approached as an individual project, sometimes as a group project. Sometimes we have voluminous communication, sometimes an individual goes it alone.

i'll agree with that and also admit some guilt in the matter.

drh, on the other hand, took the very straightforward and pragmatic approach of simply basing his check-ins on the version that had the code that needed fixing, subtracting later, no-longer-needed commits by pushing them to a branch.

This particular case went sidewise because of plain bad timing with me in the middle. i made a commit which was intended for trunk, but my timeline had been moved without my realizing it, and my instinctive response was to panic, fearing i'd triggered a serious latent bug, so then escalated it. Had i not accidentally stepped in it and squawked, or had i reacted with a cooler head, it would possibly have ended up as another "silent branch/merge action."

It's not that anybody did anything wrong. The problem was a lack of communication. Neither party knew what the other was doing or why. Thus, I took it upon myself to write out in detail my side of things as my way of reversing the communication problem.

Just coincidentally, the topic of a developer-only repo+forum for more focused discussions popped up again due to an unrelated situation, so it seems likely that this point that that will soon become a thing.

For one, Fossil was doing what I needed it to do, so obviously I'm going to just coast along and let others drive for as long as my needs are met.

Its already been doing all i really needed since 2008 ;).

But also, I was discouraged by the previous incidents of changes being pulled without explanation. Rather than let that turn into hard feelings or confusion, I'm doing my part to restore communication lines and become more involved.

Thank you :).

(6) By andygoth on 2020-08-17 07:52:52 in reply to 5.1 [link] [source]

My impression (without having looked closely) was the multi-sync was "your baby."

It was never mine, rather drh's innovation. All I did was notice the two cases where it interfered with cloning. Like richieadler, I also had high hopes that it might support automatically sync'ing with multiple remotes, but that is not yet the case.

This particular case went sidewise because of plain bad timing with me in the middle. i made a commit which was intended for trunk, but my timeline had been moved without my realizing it, and my instinctive response was to panic, fearing i'd triggered a serious latent bug, so then escalated it. Had i not accidentally stepped in it and squawked, or had i reacted with a cooler head, it would possibly have ended up as another "silent branch/merge action."

Thank you for forcing communication to take place! This has done a lot to reinvigorate me.

(7) By John Rouillard (rouilj) on 2020-08-17 16:52:33 in reply to 5.1 [link] [source]

Just coincidentally, the topic of a developer-only repo+forum for more focused discussions popped up again due to an unrelated situation, so it seems likely that this point that that will soon become a thing.

Why not just use the forum native to the fossil repo on fossil-scm.org since the forum i am viewing is a different fossil repo?

That way links to artifacts in fossil will work which is more likely to be needed by the devs.

(8) By Stephan Beal (stephan) on 2020-08-17 17:42:48 in reply to 7 [link] [source]

Why not just use the forum native to the fossil repo on fossil-scm.org since the forum i am viewing is a different fossil repo?

That's a potential option, with the down-side of adding weight to the repo clone.

No decision has been made at this point, but it will probably either come up for discussion "real soon now," maybe here on this forum, or the decision will simply be made by Richard, who'll then point the devs to the appropriate forum.

That way links to artifacts in fossil will work which is more likely to be needed by the devs.

That would indeed be convenient, but whether that outweighs other factors is up for discussion. (i'm not strongly attached to either point of view.)

(9) By Warren Young (wyoung) on 2020-08-17 20:19:36 in reply to 8 [link] [source]

adding weight to the repo clone.

The Fossil forum repo is about 1/6 the age of the source code repo, but it is closer to 1/10 the size.

One way to view that is that if we merged the repos, we'd grow the source repo by only about 10%.

The other is that the forum traffic seems to be growing faster than the source repo size. This makes sense to me since, absent a major shift in priority of features and dependencies, Fossil is approaching "completion", so its growth is slowing. The appetite for discussion will only drop off once its audience drops off, so as long as we gain users, we can expect these two curves to cross eventually, with more content going into the forum repo than into the source repo.

I advocated from the start that the forum and source be co-hosted, since a large part of the value of Fossil is cross-linking between artifacts. I'm not wild about having to use full URLs on the forum to point at the timeline, or to a checkin, or to a source file, or...

And vice versa: a commit message should be able to reference a relevant forum post by just giving a prefix of its artifact ID in square brackets.

That aside, we know for a fact from the mailing list days that the -dev list carried much less traffic than the user list, so I'd expect enabling the forum feature on the source repo to add negligible size to it.

Having said all of that, I don't like splitting a community this way. Few users list track the dev list, so the users get annoyed when "surprises" land which they weren't consulted on. Then some of those users go and join the developer list and post things that shouldn't be there, causing traffic about "You should post this on the users list." Seen it all before.

Splitting the community into multiple discussion lists can be required in bigger communities, but Fossil just isn't that big.

(10) By John Rouillard (rouilj) on 2020-08-18 01:45:26 in reply to 9 [link] [source]

I'm not wild about having to use full URLs on the forum to point at the timeline, or to a checkin, or to a source file, or...

Would adding interwiki style markup be helpful?

  fcheckin:abcdef4578

  fwiki:some_wiki_page_in_fossil_repo

  fticket:1234567890

  fforum:abcdef12345

etc. (initial f for fossil, if you wanted you could add swiki to point to the sqlite wiki for example) to link to artifacts in another fossil repo? This could be useful to provide low cost linkage. Also it could be used in described/labeled url links:

  [this checkin fixes x](fcheckin:a703b4ce25)

would result in a link to https://fossil-scm.org/fossil/info/a703b4ce25c29cd9.

(11) By Warren Young (wyoung) on 2020-08-18 05:49:56 in reply to 10 [link] [source]

Sure, though I don't see why the tag would vary based on the artifact type, since they're statistically guaranteed to be unique across types. Instead, I'd suggest "code" or "src".

We could make a useful restriction on the feature that it only works among repos on the same server to start with, so the remote Fossil server can do a SQL ATTACH on the other repo to quickly look up the artifact type when resolving the artifact ID to a URL.

Interwiki syntax.

(12) By John Rouillard (rouilj) on 2020-08-18 18:07:33 in reply to 11 [link] [source]

I was suggesting different interwiki names because people may want to use different endpoints for wiki display (page name) vs code (artifact/checkin id) vs. forum (where you want the entire thread not the single artifact at the top of the thread). All of these would use the argument to the interwiki located after the : in a different URL.

Interwiki could also be used to shorten other external links (e.g. a mailing list url associated with a project, or an irc log entry).

As you mention, you need to have an ATTACH or some other mechanism to make sense of the artifact ID and create logic on how to display it if you only have one form of interwiki name.

For implementation, you could commit an actual artifact wiki page InterWiki that has string substitution in the URL to allow people to add new links. This makes it much more general that something tied to an ATTACHable fossil repo.

If you didn't want to use the InterWiki page (lack of ACL's becomes an issue) It Could be part of syncable config state (fossil config pull interwiki)and settable by an admin user.

(13.1) By Richard Hipp (drh) on 2020-08-22 20:40:54 edited from 13.0 in reply to 11 [link] [source]

See check-in 3ca23edc8fe05300 for a preliminary implementation of interwiki links in Fossil. Note that the check-in comment uses a interwiki link to Wikipedia. The link to the check-in in this forum post is also an interwiki link.

See code comments for additional information about how interwiki links are enabled and how they work.

All links on this post are interwiki links, of course...

To Do:

  1. Provide an "Interwiki" choice on the Admin menu that allows the administrator to easily add, delete, or edit the CONFIG table entries that control interwiki links.

  2. Automatically propagate interwiki CONFIG settings on a clone, or on "fossil config pull".

  3. A mechanism (possibly a test command) that scans all artifacts in a repository looking for interwiki links, and prints them out, for debugging purposes.

(14) By Warren Young (wyoung) on 2020-08-23 00:50:45 in reply to 13.1 [link] [source]

To-Do 4: Document which codes are available on each repo in an easy-to-find place, so users don't have to go digging in the repo config tables to assemble that list. Such links are resolved before presentation to users, so most readers won't even realize when they're in use, reducing the speed of percolation through any given user community subset if they're not made explicit somewhere.

Do you have stats on the fetch rate on the "source" links on posts, as compared to rendered HTML fetches? I'd guess it's rare for one forum user to study how another marked up a given post, particularly when it appears to be rendering as intended.

I suppose the least surprising place to find this would be in /wiki_rules and md_rules. (I see that despite the feature's name, this does seem to work in Markdown as well.) This does mean the page will need to be dynamically-generated now.

You could also write it statically into an About page somewhere, but that feels more surprising here.

To-Do 5: Make this config info pullable? I've spent a fair bit of time trying to find what intermap entries you've defined on this repo, and I've come to the conclusion that they're either not syncing, or I'm looking in the wrong place for them. I had to do a "source" view on your post to find that fossil is currently so-defined. Are there more? Wikipedia would be nice, for example.

(15) By Richard Hipp (drh) on 2020-08-23 01:12:11 in reply to 14 [link] [source]

The feature should be pullable now using "fossil config pull interwiki". It should pull automatically on clone, of course.

(16) By Ilya (phobos) on 2021-07-21 17:25:39 in reply to 1 [link] [source]

Why there are not alias command like

fossil branch close BRANCH-NAME

or even simplier

fossil close BRANCH-NAME

and closing should be over tag?

Because branches are closed rarely, it's hard to remember what command should do and I always did it by search.

(17) By Stephan Beal (stephan) on 2021-07-21 23:48:40 in reply to 16 [link] [source]

Why there are not alias command like ...

Because it's never bothered anyone enough to prompt them to implement it. In practice, branches are normally closed while browsing through the UI and an errant open branch is noticed or via the merge --integrate flag.

This:

Because branches are closed rarely...

is probably a big part of why it hasn't bothered anyone enough to want to implement it.

(Note that "fossil close" does something completely unrelated to branching, so that one isn't a suitable option.)

(18) By Ilya (phobos) on 2021-07-22 05:57:13 in reply to 1 [link] [source]

Because it's never bothered anyone enough to prompt them to implement it. In practice, branches are normally closed while browsing through the UI and an errant open branch is noticed or via the merge --integrate flag.

This makes sense, but I'm prefer CLI and not use UI a lot for my purposes yet and most branches eliminated by merge --integrate, but sometimes can forgot add integrate in merging and also should close with tag.

As I understood correctly it's open for implementation by anyone?

(Note that "fossil close" does something completely unrelated to branching, so that one isn't a suitable option.)

Thank you for you answer, actually first variant is more close to my expectation and this one was provided just as "food" for discussions.

(19) By Stephan Beal (stephan) on 2021-07-22 06:01:31 in reply to 18 [link] [source]

As I understood correctly it's open for implementation by anyone?

Yes, but too late ;).

[stephan@nuc:~/tmp/br]$ f branch close b-one b-two ffa9e32dbde952 -v -n
Closing branch [b-one] f4952c810d703c65d0bd39a742f2e0ee35bfa47fa83bccbfde8f24a15df46f19
Closing branch [b-two] ec9511c8f01ac00f4ee63d0cc4dc0e0c10ab906673f79cfd26393d2c997e1eb1
Skipping non-leaf [ffa9e32dbde952] ffa9e32dbde95226300e1851841cc96ef1b2332b18b53a5baff61ba46a732370
Dry-run mode. Not saving control artifact:
D 2021-07-22T05:57:59.651
T +closed ec9511c8f01ac00f4ee63d0cc4dc0e0c10ab906673f79cfd26393d2c997e1eb1
T +closed f4952c810d703c65d0bd39a742f2e0ee35bfa47fa83bccbfde8f24a15df46f19
U stephan
Z 147627fa6394d838b5aed19914734601

[stephan@nuc:~/tmp/br]$ f branch close b-one b-two ffa9e32dbde952 -v 
Closing branch [b-one] f4952c810d703c65d0bd39a742f2e0ee35bfa47fa83bccbfde8f24a15df46f19
Closing branch [b-two] ec9511c8f01ac00f4ee63d0cc4dc0e0c10ab906673f79cfd26393d2c997e1eb1
Skipping non-leaf [ffa9e32dbde952] ffa9e32dbde95226300e1851841cc96ef1b2332b18b53a5baff61ba46a732370
Saved new control artifact (RID 6)

[stephan@nuc:~/tmp/br]$ f-acat rid:6
D 2021-07-22T05:58:11.810
T +closed ec9511c8f01ac00f4ee63d0cc4dc0e0c10ab906673f79cfd26393d2c997e1eb1
T +closed f4952c810d703c65d0bd39a742f2e0ee35bfa47fa83bccbfde8f24a15df46f19
U stephan
Z 06a9f7dc10e5d474c3ddd31afd5e888a

That's not currently in trunk, but will be shortly unless significant problems are found.

(20) By Florian Balmer (florian.balmer) on 2021-07-22 06:50:52 in reply to 19 [link] [source]

Just a minor nitpick: commands to create manifests and/or control artifacts usually support the --user-override and --date-override flags. Maybe (internally) redirecting branch close to amend --close would be much simpler, and more consistent with regard to the supported options?

(21) By Stephan Beal (stephan) on 2021-07-22 07:20:51 in reply to 20 [link] [source]

Just a minor nitpick: commands to create manifests and/or control artifacts usually support the --user-override and --date-override flags.

That's true but...

The user can still be set with the global --user flag, should it be necessary (the new command will fail if it cannot determine the correct user). i'm not currently convinced that --user-override is relevant for tag changes, especially since the --user flag is globally available.

--date-override seems like overkill for branch closing because the time of the closing is not technically relevant. For fossil a branch is either closed or not, but the timeline will not (unless i am sorely mistaken!) show it in both states depending on the timeframe being viewed. That is, if a branch is closed at Time X and re-opened at Time (X + 10), the timeline will show it as opened even when browsing at Time (X - 1) because the last "closed" tag was cancelled (at X + 10). (Again, i might be wrong on that point but believe that to be the case.)

The only(?) thing the closed-tag timestamp is relevant for is determining what order to apply tags in, with the latest one being applied. It would never(?) make sense to retroactively apply a close tag to a branch which had previously be closed, then re-opened, giving the tag a timestamp which preceded the re-opening. That would functionally be a no-op.

Thus i'm not currently convinced that date-override is useful for this particular case, but am willing to accept arguments to the contrary.

My current preference is to leave those options out until/unless a genuine use is found for them.

Maybe (internally) redirecting branch close to amend --close would be much simpler, and more consistent with regard to the supported options?

That's an idea which i didn't consider because i never use amend and didn't remember that a branch can be closed that way :/, but this implementation supports something which i occasionally do in the fossil main repo which no commands currently support: closing multiple branches at once.

Once or twice a year i go through and close many "stale" branches in the main fossil repo. In the past i've had to script it or create a single mass-close artifact by hand. This new branch close accepts any number of branches, simplifying that greatly, and that capability does not easily fit into the amend command because it doesn't make much sense for most of amend's options.

(22) By Stephan Beal (stephan) on 2021-07-22 07:49:46 in reply to 21 [link] [source]

My current preference is to leave those options out until/unless a genuine use is found for them.

Nonethess, they were trivial to add, so they're supported now.

The --user-override flag has one capability which --user does not: the latter requires a known/valid user name whereas the former accepts whatever value is passed to it. Feature or bug, i'm not sure, but that's how the other APIs which support that flag do it.

(24) By Florian Balmer (florian.balmer) on 2021-07-22 10:51:06 in reply to 22 [link] [source]

Thanks for adding the options!

I'm often using --date-override (with small deltas) to group or move tagging operations outside of a series of check-ins (as my default timeline view filter is set to "Any Type").

I don't think --user and --user-override are the same.

The first is to simplify the following sequence of commands:

fossil user default otheruser
fossil command ...
fossil user default florian

To:

fossil command ... --user otheruser

It's true that this also changes the U card in the control artifact generated by fossil branch close, but in addition, this also sets the username shown in the Artifact Receipts Log, for example.

On the other hand, --user-override changes just the U card, and nothing more, so the username can be arbitrary and doesn't need to "exist" -- even fossil sync doesn't care and accepts arbitrary usernames in received check-in manifests and control artifacts.

So, definitely feature, not bug -- maximum simplicity and flexibility for Fossil users!

P.S. Even if --user-override accepted only "existing" usernames, temporarily forging an arbitrary username in a local repository is easy:

fossil user new otheruser
...
fossil sql "delete from user where login='otheruser'"

(25) By Andy Bradford (andybradford) on 2021-07-22 19:28:44 in reply to 21 [link] [source]

> That's an idea  which i didn't consider because i  never use amend and
> didn't remember that a branch can be closed that way

Just keep  in mind that  the "fossil amend"  command is pretty  much the
command-line equivalent  to editing  a commit in  the "fossil  ui". This
includes renaming  the branch,  closing the  branch, hiding  the branch,
etc.


> this implementation supports something which  i occasionally do in the
> fossil main repo which no commands currently support: closing multiple
> branches at once.

And  this  functionality definitely  sets  it  apart  from what  can  be
accomplished via "fossil  amend" so it definitely belongs  as a separate
command. I've never had the need  to close multiple branches before, but
I can certainly see how it would be useful.

Looks good.

Thanks,

Andy

(23) By Ilya (phobos) on 2021-07-22 08:27:40 in reply to 19 [link] [source]

It's superiour and superfast! Thank you Stephan!

That's not currently in trunk, but will be shortly unless significant problems are found.

It's clear too me and I already viewed and a bit understand your commits.

(26) By sean (jungleboogie) on 2021-07-22 21:06:30 in reply to 19 [link] [source]

I like it!

While we're aliasing commands, what about something for fossil tag add --raw hidden e9d6469edb605d? :)

Discussed by Andy in this thread

(27) By Stephan Beal (stephan) on 2021-07-22 22:31:07 in reply to 26 [link] [source]

While we're aliasing commands, what about something for fossil tag add --raw hidden e9d6469edb605d? :)

That's a good idea. Funnily enough, an early copy of this new impl was over-engeneered and would have supported that already, but then i simplified it :/. i'll get that reworked after work today.

Any other branch/checkin features which make sense for this?

(32) By Florian Balmer (florian.balmer) on 2021-07-23 05:49:01 in reply to 27 [link] [source]

Any other branch/checkin features which make sense for this?

Well, reopen, the counterpart to close, in symmetry to hide and unhide?

P.S. Also make sure to mention hide and unhide (and probably reopen) in the quick help?

P.P.S. Maybe also change (or not) this hint on fossil amend --close to fossil branch close?

(33) By Stephan Beal (stephan) on 2021-07-23 05:56:51 in reply to 32 [link] [source]

Well, reopen, the counterpart to close, in symmetry to hide and unhide?

Good point. Should it be called open, reopen, or (for symmetry) unclose?

P.S. Also make sure to mention hide and unhide (and probably reopen) in the quick help?

Fixed locally. Will commit soon.

P.P.S. Maybe also change (or not) this hint on fossil amend --close to fossil branch close?

That one i'll leave as is for now. It's not wrong and that option for closing branches isn't going away.

(34) By Florian Balmer (florian.balmer) on 2021-07-23 11:42:14 in reply to 33 [link] [source]

Good point. Should it be called open, reopen, or (for symmetry) unclose?

As long as you don't call it "ununopen" ... ;-)

It's just that "unclose" and "unhide" sound funny in my non-English ears.

Also, I think "reopen" is better than "open", as it emphasizes more that the branch has already been closed before. And for non-programmers, "opening" a branch may mean the same as "creating" it. (Or, maybe we need another command-line switch to allow creating a closed branch.)

(28) By Stephan Beal (stephan) on 2021-07-23 02:46:08 in reply to 26 [link] [source]

While we're aliasing commands, what about something for fossil tag add --raw hidden...

Done: branch hide/unhide are now a real thing in the the branch-close-subcommand branch, and adding that same support for similar cases is easy to do. This feature adds or cancels the "hidden" tag identically to how the /ci_edit page does it except that it permits an arbitrary number of branch/checkin names and it checks for the tag first and skips the entry if already has (or, as appropriate, doesn't have) the "hidden" tag.

Trivia: unless i'm sorely mistaken (which might be the case), Sean holds the record for the number of implemented feature suggestions which came from a non-committer. Thank you, Sean, for your continued stream of interesting feature ideas!

(29) By Andy Bradford (andybradford) on 2021-07-23 03:46:27 in reply to 28 [link] [source]

> Done: branch hide/unhide are now a real thing

I haven't  looked at  the implementation, but  branch hiding  was always
possible with "fossil  amend" though it wasn't possible  to "unhide" and
in retrospect that  was probably a missed feature that  should have been
done.

Does your implementation hide the entire  branch or just a single commit
in the  branch (e.g. difference between  propagating and non-propagating
hidden tag)?

Thanks,

Andy

(30) By Andy Bradford (andybradford) on 2021-07-23 03:48:55 in reply to 29 [link] [source]

> Does your implementation hide the entire  branch [snip]

The  reason I  ask  is  because there's  a  distinction between  "branch
hiding"  and "commit  hiding", the  latter having  never been  a feature
except as I mentioned using the "fossil tag" command.

Andy

(31) By Stephan Beal (stephan) on 2021-07-23 03:53:57 in reply to 29 [link] [source]

Does your implementation hide the entire branch or just a single commit in the branch (e.g. difference between propagating and non-propagating hidden tag)?

Hiding is a feature i've never used, so modeled it 100% after the ci_edit page: it adds a propagating hidden tag or a cancel tag (for unhiding), as appropriate.

The main difference from the amend command is that it accepts an arbitrary number of branch names/symbolic names. It's not strictly limited to branches.

(35) By Stephan Beal (stephan) on 2021-07-25 03:07:53 in reply to 18 [link] [source]

As I understood correctly it's open for implementation by anyone?

The branch close/reopen/hide/unhide subcommands are now in trunk. Please report any problems with them (or patches for them!) here or in a new thread.

i'm tempted to add "unclose" as an undocumented alias for "reopen", but will, for now, resist that temptation :).

One thing to note is that, though this is part of the branch command, these new subcommands actually accept any symbolic checkin names, be they branches, hash IDs, or any of the other diverse forms fossil accepts. They will fail if a name is ambiguous, but all unambiguous checkin names are valid. Thus it's possible, but not recommended, to do:

fossil branch hide rid:1

(RID 1 is almost always the "initial empty commit" which fossil seeds the database with.)

(36) By John Rouillard (rouilj) on 2021-07-25 14:21:44 in reply to 35 [link] [source]

Hi Stephan:

One thing to note is that, though this is part of the branch command, these new subcommands actually accept any symbolic checkin names, be they branches, hash IDs, or any of the other diverse forms fossil accepts.

Hmm,what happens if I fossil branch close ID where the ID is 1/2 way up a branch? Does it act the same as thought I had done a close on the tip of the branch? (IIUC close is non-propigating tag right?)

Just trying to figure out the implications should I mess up using it.

-- rouilj

(37) By Stephan Beal (stephan) on 2021-07-25 22:01:04 in reply to 36 [link] [source]

Hmm,what happens if I fossil branch close ID where the ID is 1/2 way up a branch? Does it act the same as thought I had done a close on the tip of the branch? (IIUC close is non-propigating tag right?)

That would add a non-propagating close tag to that specific checkin but have no real effect. A closing is not "absolute," it's just a hint that fossil should ideally not allow, in interactive mode, further commits directly from that checkin. It is possible, via two developers overlapping each other while working offline, to check in to a closed leaf. That won't break anything, it just might confuse the person who closed the branch (the branch will no longer be marked as closed). No harm done, though.

(38) By Stephan Beal (stephan) on 2021-07-25 22:06:38 in reply to 37 [link] [source]

That would add a non-propagating close tag to that specific checkin but have no real effect.

Correction: it actually checks for that case and skips non-leaf checkins. If it did not do that check, though, it would behave as described in my previous response.