advice on a couple of changes
(1) By Kartik Agaram (akkartik) on 2024-04-26 05:29:18 [source]
Coming from git, I found a few things confusing just now. Let me lay them out, and I'd appreciate someone pointing out where my mental model needs updating for fossil.
I have two branches in a fossil repo. Let's call them A and B.
I made a commit in branch A. There were no outstanding diffs. I wanted to copy just that one commit over to B, but not other commits in A. So I switched opened branch A in a new directory and initiated a cherrypick:
$ mkdir ../B
$ cd ../B
$ fossil open ../repo.fossil B
$ fossil merge --cherrypick <versionid>
UPDATE score.c
"fossil undo" is available to undo changes to the working checkout.
Coming from git
and after reading fossil help merge
, I expected <versionid>
to now be committed in the new branch. But I see the changes uncommitted when I run fossil diff
.
So I ran fossil commit
. I saw the commit message prepopulated in my editor. When I exited, I saw this:
unchanged check-in comment. continue (y/N)? y
New_Version: c3a969bdf2c464454cc176120793e0e24ef682419a0ec49fb263720e04408d65
WARNING: multiple open leaf check-ins on A:
(1) 2024-04-26 05:13:57 [c3a969bdf2] (current)
(2) 2024-04-26 00:04:00 [2ab3f7bace]
$
Does all this seem expected? Or does it seem like my repo is messed up somehow? Thanks in advance.
(2.1) By hanche on 2024-04-26 08:56:24 edited from 2.0 in reply to 1 [link] [source]
Okay, I'll give it a try.
First of all, yes, fossil merge
just updates the working tree and makes a note of the merge. It does not commit anything. So it's normal to have to commit after the merge. I think that is so that you can further modify your working tree first. (Edit: And to give you a chance to check that the merge did what you expected it to, so you can fix it or back out if not.)
Second, running fossil commit
should never create a fork unless you give it the --allow-fork
argument. And even then, the created fork only affects the current branch.
Third, once a fork exists, many fossil commands will issue the “multiple open leaf check-ins” warning. (That is what a fork is, in fossil terminology.)
Therefore, I conlcude that the fork in A most likely already existed before you did these steps.
I highly recommend using the fossil ui
command to get a nice graphical view of the current state of your repository. It might help you figure out what happened, perhaps even why.
(3) By Stephan Beal (stephan) on 2024-04-26 12:38:30 in reply to 2.1 [link] [source]
Second, running fossil commit should never create a fork unless you give it the --allow-fork argument.
Just to clarify: that's mostly true, and it's the ideal situation, but it is possible to end up with multiple unintended forks when either (A) autosync is off and multiple clones are being used or (B) two developers hit a very tiny race condition when autosync is on and both try to commit at precisely the same moment.
In the first case, both clones can commit freely, but the forks won't show up until they have both shared their work with each other. It doesn't break anything, it just means that the new forks need to be merged back into one.
The second case is extremely rare but did happen to us once in this project sometime in the past year.
(4) By Richard Hipp (drh) on 2024-04-26 12:44:22 in reply to 3 [link] [source]
Even more clarification: Forks are completely harmless, at least from Fossil's point of view. The only downside of forks is that they can be confusing to human readers, especially humans with prior exposure to Git. Fossil itself is not the least bit bothered by forks and will continue happily along with a repository full of them.
All these warnings about Forks and all the extra code added to detect and report them are purely for the benefit of human readers. These warnings do not indicate any logic problems in the underlying repository.
(12) By Kartik Agaram (akkartik) on 2024-04-27 23:20:46 in reply to 4 [link] [source]
Thanks all. I think I've figured out how I ended up in this situation. I'm using git and fossil side by side, and I created a couple of manual commits on both git and fossil, and then reran git fast-export ... | fossil import ...
(to import a new branch).
(5) By Andy Bradford (andybradford) on 2024-04-26 13:51:02 in reply to 1 [link] [source]
> Coming from git and after reading fossil help merge, I expected > <versionid> to now be committed in the new branch. But I see the > changes uncommitted when I run fossil diff. This is one of those differences where I think Fossil gets it right. When you cherrypick a commit, why should it be automatically committed? What if you decide that you didn't really want it because maybe it was the wrong hash? Furthermore, have you tested the code after the cherrypick and before it is committed? Yes, this is working properly. When you cherrypick in Fossil, it simply updates your working directory and prepares some information that will be used to make a permanent record once you actually do commit the change. You must then follow up with "fossil commit". Regarding the fork, if you did not see at the time of "fossil commit" output suggesting a new fork was created, then it must have existed prior to this commit. If you really want the fork then do nothing, otherwise, you can just run "fossil merge" [literally] and it will attempt to automatically merge the two. You may have to resolve conflicts if any, but you will then have to "fossil commit" the result because as mentioned before [and as you have discovered], merges do not get automatically committed to the repository. Andy
(6) By Richard Hipp (drh) on 2024-04-26 14:30:05 in reply to 5 [link] [source]
Yeah. I didn't even realize that Git automatically commits a cherry-pick.
Another downside of auto-commit after cherry-pick is that you can only cherry-pick once per check-in. In Fossil, you can cherry-pick two or more changes, plus make manual edits, plus resolve any merge conflicts, all before you commit. https://sqlite.org/src/info/7a3d0027f81e8def is an example of where I cherry-picked three separate fixes into a single check-in.
(7.1) By Marcelo Huerta (richieadler) on 2024-04-26 15:08:07 edited from 7.0 in reply to 6 [link] [source]
You can add a -n | --no-commit
flag to the git cherry-pick
command, but the default is committing, yes.
(13) By Konstantin Khomutov (kostix) on 2024-04-29 10:04:48 in reply to 6 [link] [source]
As Marcelo suggested, you can tell Git not to automatically commit a cherry-pick, and you can also tell it to cherry-pick any number of commits in a single run.
It's also possible to git show <commitish> | git apply
any commit which would work like git cherry-pick -nc
by basically producing a textual patch out of a commit and then applying it.
(14) By Warren Young (wyoung) on 2024-04-29 19:24:21 in reply to 13 [link] [source]
Yes, I was aware of these options before you replied, which is why I put “by default” into the new doc section.
Defaults matter. People tend to accept them blindly, as advice from above on “best practices”. This new section of the docs gives our position that autocommit is an objectively bad practice, at least in conjunction with autosync and no rebase.
(8) By Warren Young (wyoung) on 2024-04-26 15:36:53 in reply to 1 [link] [source]
I've summarized this thread's responses into a new section in the Git to Fossil Translation Guide. The ideas were there before, but not as clearly expressed.
Does this help?
(9) By Andy Bradford (andybradford) on 2024-04-27 00:54:25 in reply to 8 [link] [source]
> I've summarized this thread's responses into a new section in the Git > to Fossil Translation Guide. The statement that "fossil timeline" cannot show commits from just a single branch is no longer accurate. This functionality was added here: https://www.fossil-scm.org/home/info/213ca339c2951ad1 I've updated the documentation but feel free to alter if it doesn't make sense the way I wrote it. Andy
(10) By Warren Young (wyoung) on 2024-04-27 01:13:49 in reply to 9 [link] [source]
TIL; thank you!
(11.1) By Kartik Agaram (akkartik) on 2024-04-27 22:44:16 edited from 11.0 in reply to 8 [link] [source]
Thank you! This is enormously helpful. Particularly the pointer to the Translation Guide I had somehow missed thus far.