Fossil User Forum

advice on a couple of changes
Login

advice on a couple of changes

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.

(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.

(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.

(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).

(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.