Fossil Forum

Merging binary files... ***** Cannot merge binary file
Login

Merging binary files... ***** Cannot merge binary file

Merging binary files... ***** Cannot merge binary file

(1) By decuser on 2023-01-20 20:14:59 [link] [source]

I'm trying out stuff from the docs in order to learn more about fossil...

I created a repo and added a binary file DEMO to it as user Jim. I then tweaked the binary file as Marilyn and committed my changes. I then tweaked the binary file as JIM.

At this point

  • The central repo, marilyn's repo, and marilyn's working files are in sync with her tweaked DEMO.

  • Jim's repo doesn't have her DEMO or his tweaked DEMO, it has the original DEMO. His working files have his tweaked DEMO.

Jim then adds his DEMO and tries to commit it:

fossil commit -m "commit that might fork"
Pull from http://Jim@fossil:8080/testrepo
Round-trips: 1   Artifacts sent: 0  received: 0
Pull done, wire bytes sent: 439  received: 721  ip: 192.168.254.24
Would fork.  "update" first or use --branch or --allow-fork.

a look at the timeline shows:

=== 2023-01-20 ===
19:48:16 [3490d997b4] m's third (user: Marilyn tags: trunk)
19:45:43 [61f01dcac4] M's second (user: Marilyn tags: trunk)
19:42:51 [9cd18cce0a] *CURRENT* marilyn's first commit (user: Marilyn tags: trunk)
19:41:56 [83a6b1ae5e] first real commit (user: Jim tags: trunk)
19:30:29 [19118005cd] initial empty check-in (user: wsenn tags: trunk)
+++ no more data (5) +++

And a dry run shows:

MERGE DEMO
***** Cannot merge binary file DEMO
UNCHANGED make
-------------------------------------------------------------------------------
updated-from: 9cd18cce0a446b95365b4e197dd9fa1a63ac126b 2023-01-20 19:42:51 UTC
updated-to:   3490d997b47770ae053c7a4f4122be4bf6aae472 2023-01-20 19:48:16 UTC
tags:         trunk
comment:      m's third (user: Marilyn)
changes:      1 files modified.

What I would like to do is just take Marilyn's third version of DEMO. Following the docs (as best I can), it seemed like this would call for:

fossil update trunk DEMO

but this results in:

MERGE DEMO
***** Cannot merge binary file DEMO

and seemingly has no effect.

How do I update to Marilyn's committed DEMO version? and how do I commit my version (the flip side of the problem)?

Will

(2) By decuser on 2023-01-20 20:17:22 in reply to 1 [link] [source]

This is fossil version 2.20 [210e89a059] 2022-11-16 18:46:32 UTC

(3) By Stephan Beal (stephan) on 2023-01-20 23:05:06 in reply to 1 [link] [source]

How do I update to Marilyn's committed DEMO version? and how do I commit my version (the flip side of the problem)?

Unlike line-based text documents, there are no generic algorithms for merging binary files. The only options are to throw away the most recent changes altogether or to check them in over the prior version. i'm on a tablet, so can't demonstrate, but hopefully that hint will help you proceed.

(4) By decuser on 2023-01-21 02:52:45 in reply to 3 [link] [source]

OK. It seems like option 1 is to throw away the changes...

fossil update 3490d997b4 DEMO

Then I'm on Marilyn's commit.

and option 2 is to check them in over the prior version... this I'm not real clear on. Is the only way to --branch or --allow-fork and then do cleanup of the fork somehow. I'm off to investigating, but if somebody knows, I'd appreciate the tip. There doesn't appear to be a force option.

(5) By Warren Young (wyoung) on 2023-01-21 04:41:05 in reply to 4 [link] [source]

There doesn't appear to be a force option.

That would be almost certain to corrupt a good many binary file types. Compressed images, Word DOCX files (being Zip files internally), SQLite DBs, etc.

What file types are we talking about here? There are sometimes smart ways around this class of problem.

(7.1) By decuser on 2023-01-21 16:30:57 edited from 7.0 in reply to 5 [link] [source]

Hi Warren. I don’t want to ‘merge’ the binary. I want to overwrite it one of two ways - with Jim’s version or, alternatively with Marilyn’s and I’m not yet able to figure out the ‘right way’ to do it. I did figure out how to get Marilyn’s by having Jim revert to it. Dunno about if it’s the right way or not and haven’t been able to get Jim’s version to win.

(9) By Martin Gagnon (mgagnon) on 2023-01-21 16:44:51 in reply to 7.1 [link] [source]

For what I remember doing an update with a specific version will overwrite the binary file and in case of conflict it will back up the local copy. I cannot test right now because I am on mobile, maybe it doesn’t do that in your particular case? I’ll try to experiment when I’ll be at my computer.

(10) By Martin Gagnon (mgagnon) on 2023-01-21 17:19:32 in reply to 7.1 [link] [source]

Just experiment, and for the test case I tried, "fossil up ABCD binary-file" where binary-file is modified locally, it will overwrite with the ABCD version and keep a local copy of the local file.

$ fossil up d6b008d0b1 network_diagram.pdf
MERGE network_diagram.pdf
***** Cannot merge binary file network_diagram.pdf, original copy backed up locally
-------------------------------------------------------------------------------
updated-from: e06afea26498654629938c2c3fc2d08c861aca24 2022-07-01 13:47:45 UTC
updated-to:   d6b008d0b13182288714010c32385c4666442246 2021-12-05 23:06:32 UTC
tags:         trunk
comment:      edit of bin file (user: mgagnon)
changes:      1 file modified.
WARNING: 1 merge conflicts
 "fossil undo" is available to undo changes to the working checkout.

It's not what happens in your case ?

(11) By decuser on 2023-01-21 23:06:52 in reply to 10 [link] [source]

I found this https://fossil-scm.org/home/doc/trunk/www/branching.wiki and will use the method described in it :)

(12) By decuser on 2023-01-22 14:53:28 in reply to 11 [link] [source]

After much ado and experimentation, I've figured out the best approach to resolving this issue... there are many other ways, but these are the cleanest.

Review of Scenario to test

Two users Marilyn and Jim update to latest and begin working on their versions of the repository. Marilyn, changes a binary file called DEMO and commits her changes. Meanwhile, Jim changes his DEMO and tries to commit his changes. When he does so, he is warned that a fork would result from his commit. He has two options at this point:

  1. Revert his changes and update to the latest before editing again (preferred).
  2. Commit his changes and ask Marilyn to update to his and merge the resulting fork.

Option 1) Jim fixes

fossil revert DEMO
fossil update
fossil status

Jim sees that he's on m's changes and can carry on. There's a linear timeline at this point.

Option 2) Marilyn fixes

fossil update
WARNING: multiple open leaf check-ins on trunk:
  (1) 2023-01-22 13:53:19 [995eb89bff]
  (2) 2023-01-22 13:52:56 [6ca07d2507] (current)

fossil diff -r 995eb89bff
... The DEMO file has changed.

fossil update trunk DEMO
...
updated-from: 6ca07d2507346ac7670f374ce164c9007f4aac6a 2023-01-22 13:52:56 UTC
updated-to:   995eb89bff227d813a5d8a17267de7cd82baf5b3 2023-01-22 13:53:19 UTC
...

fossil merge
fossil add .
fossil commit -m "merging j's fork"

She tells Jim it's all good again and there's a fork and merge in the timeline.

(13.1) By decuser on 2023-01-22 15:05:20 edited from 13.0 in reply to 12 [link] [source]

Or, I suppose Jim could fix it himself by changing to her branch and doing the stuff she would do. I just don't know how to switch branches :).

(14) By Warren Young (wyoung) on 2023-01-22 17:51:59 in reply to 13.1 [link] [source]

Info.

(15) By decuser on 2023-01-22 23:37:33 in reply to 14 [link] [source]

Nice!

Jim commits with --allow-fork, but wants to clean up the mess by merging the fork. Since it's a binary, merge isn't a real option. So, he checks out out the soon to be defunct Marilyn branch, updates the binary from trunk (with Jim's changes), does the merge, adds and commits and his changes are on top. Marilyn's aren't lost, they're just sidelined.

fossil commit --allow-fork -m "j's change"
***** WARNING: a fork has occurred *****

fossil timeline
23:24:27 [b9d532045a] *CURRENT* j's change (user: Jim tags: trunk)
23:23:29 [f9416b4ea5] m's change (user: marilyn tags: trunk)

# checkout marilyn's branch 
fossil checkout f9416b4ea5
DEMO

# get j's changed DEMO
fossil update b9d532045a DEMO

updated-from: f9416b4ea5143dba93edcd6855c4535257453ee5 2023-01-22 23:23:29 UTC
updated-to:   b9d532045a16a7a64dcc60c2ea1d95707e962916 2023-01-22 23:24:27 UTC

# merge
fossil merge

Merging fork [b9d532045a] at 2023-01-22 23:24:27 by Jim: "j's change"
MERGE DEMO
***** Cannot merge binary file DEMO
WARNING: 1 merge conflicts

fossil add .
fossil commit -m "merging m and j lines"

Lines get merged, history preserved, rational so far as I can tell.

(17) By Stephan Beal (stephan) on 2023-01-23 00:03:13 in reply to 15 [link] [source]

Lines get merged, history preserved, rational so far as I can tell.

One additional detail which is often needed is to "close" the merged-in branch. That can be done in several different ways:

  • Browse to that checkin in the UI, tap "edit", and one of the options is "close".

  • When merging, using "fossil merge --integrate THAT_BRANCH". When you check in, THAT_BRANCH will automatically be closed due to the --integrate flag.

  • The "fossil branch close THAT_BRANCH" command, noting that THAT_BRANCH can be any symbolic name, including a hash.

"Closing" is just a hint to fossil that you no longer intend to make any changes in that branch, and it will forbid checkins to that branch by default if the branch is locally closed. (If, however, it was closed on a remote copy but the closing not yet synced to yours, the closed flag has no effect on you even when you eventually push your changes to that remote.)

(19) By decuser on 2023-01-23 00:57:27 in reply to 17 [source]

Thanks, Stephan. After being pointed to the docs section a couple of times, I figured out that the 'book' isn't really sufficient on its own. The docs section is quite helpful and includes much of the info I was missing. I was wondering about the closed branches and such and am reading up on it now. --integrate - got it :).

(16) By decuser on 2023-01-22 23:52:47 in reply to 10 [link] [source]

OK. I get it now. Yes it works as you said, but I didn't understand what was happening. Now, I do. So, when I try to commit and get the warning:

Would fork. "update" first or use --branch or --allow-fork.

If I do:

fossil timeline
23:46:21 [9477c0eb2d] m's change (user: marilyn tags: trunk)

A simple fossil update (or fossil update 9477c0eb2d) will get the version m checked in and make a copy of j's version as DEMO-Original.

To 'resolve', I just get rid of the copy and I'm at m's change in the timeline.

No revert needed.

(6) By skywalk on 2023-01-21 15:50:50 in reply to 3 [link] [source]

I read Google improved their Play Store update process by merging smaller binary chunks with the resident installed binary. Thereby reducing data charges for millions of users. https://github.com/mendsley/bsdiff Is this applicable to any binary file or just the patterns of executables?

(8.1) By Martin Gagnon (mgagnon) on 2023-01-21 16:58:30 edited from 8.0 in reply to 6 [link] [source]

A tool like this would work to optimize transfer and avoid sending the complete binary to move from one version to another.

But while in theory it could successfully resolve a merge from two version branch or from local change and an upstream version, the resultant binary file would probably be unusable. This depends on the nature of the binary file. In other word, for some type of file, Even if modified chunk from two different version are not conflicting, it can produce an invalid binary file.
(Anyway as I understood, OP want to replace with one of the versions in your case, so what this tool does is probably irrelevant)

By the way, Fossil do somethings similar to store files across version in the repertory to save space: see Fossil Delta Encoding

(18) By decuser on 2023-01-23 00:53:28 in reply to 1 [link] [source]

Talk about overcomplicating things :). After even more discussion and investigation, this is what I came to:

Does Jim want his changes to be taken over Marilyn's? If so, he can stash his changes, update to her commit, pop his changes, add them and commit them:

fossil stash save -m "stashing j's changes"
fossil update
fossil stash pop
fossil add .
fossil commit -m "j's changes"

Does Jim want to just take Marilyn's changes? If so, he can just revert his changes and update to her commit:

fossil revert
fossil update

If he wants to allow the fork, he can and proceed apace, merging at a later time. If that floats your boat, the other parts of this discussion are prolly interesting.

(20) By decuser on 2023-01-23 20:33:09 in reply to 18 [link] [source]

I did a blog post to capture the essence of what I learned over on my blog https://decuser.github.io/fossil/merging/2023/01/23/fossil-merging-binary-files.html. I thought this was a good use of my newly deployed mermaid stuff.