langfield / ki

version control for Anki collections
https://langfield.github.io/ki/
GNU Affero General Public License v3.0
80 stars 3 forks source link

Merge conflict when pulling twice in a row #141

Closed langfield closed 1 year ago

langfield commented 1 year ago

Only thing that was changed in the collection between pulls was some reviews. It should be fairly clear this happens because we're autogenerating filenames based on the sort field, but the sort field is not unique in many cases. So if the order in which we generate cards is not deterministic (and apparently it is not), the contents of the cards gets churned, and we get a different guid for the same filename, causing a merge conflict. See the stack trace below.

(anki) user@computer:~/collection$ ki pull
Cloning into '/tmp/tmpd2nrenq3/ki-remote/524a4ea8ccc04a3850d7b2890fd95e48'...
Notes: 100%|███████████████████████████████| 516/516 [00:00<00:00, 10054.12it/s]
Media: 100%|████████████████████████████████| 516/516 [00:00<00:00, 8189.37it/s]
Fields: : 516it [00:00, 2312.16it/s]
Decks: 100%|████████████████████████████████████| 13/13 [00:00<00:00, 72.53it/s]
Auto-merging .ki/hashes
CONFLICT (content): Merge conflict in .ki/hashes
Auto-merging Decks/Meta/Anki Shortcuts/add-new-note-window_2.md
CONFLICT (content): Merge conflict in Decks/Meta/Anki Shortcuts/add-new-note-window_2.md
Auto-merging Decks/Meta/Anki Shortcuts/add-new-note-window_3.md
CONFLICT (content): Merge conflict in Decks/Meta/Anki Shortcuts/add-new-note-window_3.md
Auto-merging Decks/Meta/Anki Shortcuts/add-new-note-window_4.md
CONFLICT (content): Merge conflict in Decks/Meta/Anki Shortcuts/add-new-note-window_4.md
Auto-merging Decks/Meta/Anki Shortcuts/add-new-note-window_5.md
CONFLICT (content): Merge conflict in Decks/Meta/Anki Shortcuts/add-new-note-window_5.md
Auto-merging Decks/Meta/Anki Shortcuts/add-new-note-window_9.md
CONFLICT (content): Merge conflict in Decks/Meta/Anki Shortcuts/add-new-note-window_9.md
Auto-merging Decks/Meta/Anki Shortcuts/review-cards-window_1.md
CONFLICT (content): Merge conflict in Decks/Meta/Anki Shortcuts/review-cards-window_1.md
Auto-merging Decks/Meta/Anki Shortcuts/review-cards-window_3.md
CONFLICT (content): Merge conflict in Decks/Meta/Anki Shortcuts/review-cards-window_3.md
Auto-merging Decks/Meta/Anki Shortcuts/review-cards-window_5.md
CONFLICT (content): Merge conflict in Decks/Meta/Anki Shortcuts/review-cards-window_5.md
Auto-merging Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s.md
CONFLICT (content): Merge conflict in Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s.md
Auto-merging Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_1.md
CONFLICT (content): Merge conflict in Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_1.md
Auto-merging Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_10.md
CONFLICT (content): Merge conflict in Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_10.md
Auto-merging Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_2.md
CONFLICT (content): Merge conflict in Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_2.md
Auto-merging Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_3.md
CONFLICT (content): Merge conflict in Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_3.md
Auto-merging Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_4.md
CONFLICT (content): Merge conflict in Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_4.md
Auto-merging Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_5.md
CONFLICT (content): Merge conflict in Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_5.md
Auto-merging Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_6.md
CONFLICT (content): Merge conflict in Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_6.md
Auto-merging Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_7.md
CONFLICT (content): Merge conflict in Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_7.md
Auto-merging Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_8.md
CONFLICT (content): Merge conflict in Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_8.md
Auto-merging Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_9.md
CONFLICT (content): Merge conflict in Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_9.md
Automatic merge failed; fix conflicts and then commit the result.

From /tmp/tmpp7k21h22/ki-local-524a4ea8ccc04a3850d7b2890fd95e48/
 * branch            main       -> FETCH_HEAD
 * [new branch]      main       -> anki/main

Traceback (most recent call last):
  File "/home/mal/conda/envs/anki/bin/ki", line 33, in <module>
    sys.exit(load_entry_point('ki', 'console_scripts', 'ki')())
  File "/home/mal/conda/envs/anki/lib/python3.9/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/home/mal/conda/envs/anki/lib/python3.9/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/home/mal/conda/envs/anki/lib/python3.9/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/mal/conda/envs/anki/lib/python3.9/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/mal/conda/envs/anki/lib/python3.9/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "<@beartype(ki.pull) at 0x7f9769c41820>", line 10, in pull
  File "/home/mal/ki/ki/__init__.py", line 1733, in pull
    _pull(kirepo)
  File "<@beartype(ki._pull) at 0x7f9769c41700>", line 31, in _pull
  File "/home/mal/ki/ki/__init__.py", line 1889, in _pull
    commit_hashes_file(kirepo)
  File "<@beartype(ki.commit_hashes_file) at 0x7f9769cb7b80>", line 31, in commit_hashes_file
  File "/home/mal/ki/ki/__init__.py", line 1557, in commit_hashes_file
    kirepo.repo.index.commit("Update collection hashes file.")
  File "/home/mal/conda/envs/anki/lib/python3.9/site-packages/git/index/base.py", line 1055, in commit
    tree = self.write_tree()
  File "/home/mal/conda/envs/anki/lib/python3.9/site-packages/git/index/base.py", line 580, in write_tree
    binsha, tree_items = write_tree_from_cache(entries, mdb, slice(0, len(entries)))
  File "/home/mal/conda/envs/anki/lib/python3.9/site-packages/git/index/fun.py", line 324, in write_tree_from_cache
    sha, _tree_entry_list = write_tree_from_cache(entries, odb, slice(ci - 1, xi), rbound + 1)
  File "/home/mal/conda/envs/anki/lib/python3.9/site-packages/git/index/fun.py", line 324, in write_tree_from_cache
    sha, _tree_entry_list = write_tree_from_cache(entries, odb, slice(ci - 1, xi), rbound + 1)
  File "/home/mal/conda/envs/anki/lib/python3.9/site-packages/git/index/fun.py", line 324, in write_tree_from_cache
    sha, _tree_entry_list = write_tree_from_cache(entries, odb, slice(ci - 1, xi), rbound + 1)
  File "/home/mal/conda/envs/anki/lib/python3.9/site-packages/git/index/fun.py", line 302, in write_tree_from_cache
    raise UnmergedEntriesError(entry)
git.exc.UnmergedEntriesError: 100644 0006a9d89b6d2bde90e11bd9b19177d050bfb71b 1 Decks/Meta/Anki Shortcuts/add-new-note-window_2.md
(anki) mal@computer:~/collection$ ^C
(anki) mal@computer:~/collection$ git status
On branch main
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Changes to be committed:
        modified:   .ki/hashes
        modified:   Decks/Meta/Anki Shortcuts/review-cards-window_2.md
        modified:   Decks/Meta/Anki Shortcuts/review-cards-window_4.md

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   Decks/Meta/Anki Shortcuts/add-new-note-window_2.md
        both modified:   Decks/Meta/Anki Shortcuts/add-new-note-window_3.md
        both modified:   Decks/Meta/Anki Shortcuts/add-new-note-window_4.md
        both modified:   Decks/Meta/Anki Shortcuts/add-new-note-window_5.md
        both modified:   Decks/Meta/Anki Shortcuts/add-new-note-window_9.md
        both modified:   Decks/Meta/Anki Shortcuts/review-cards-window_1.md
        both modified:   Decks/Meta/Anki Shortcuts/review-cards-window_3.md
        both modified:   Decks/Meta/Anki Shortcuts/review-cards-window_5.md
        both modified:   Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s.md
        both modified:   Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_1.md
        both modified:   Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_10.md
        both modified:   Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_2.md
        both modified:   Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_3.md
        both modified:   Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_4.md
        both modified:   Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_5.md
        both modified:   Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_6.md
        both modified:   Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_7.md
        both modified:   Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_8.md
        both modified:   Decks/Programming/Haskell/Alphametics/write-a-function-to-solve-alphametics-puzzlesfor-example-s_9.md

(anki) user@computer:~/collection$ git diff
diff --cc Decks/Meta/Anki Shortcuts/add-new-note-window_2.md
index ac883eb,1e1b201..0000000
--- a/Decks/Meta/Anki Shortcuts/add-new-note-window_2.md
+++ b/Decks/Meta/Anki Shortcuts/add-new-note-window_2.md
@@@ -1,6 -1,6 +1,12 @@@
  # Note

++<<<<<<< HEAD +guid: KuLjX(pmWs ++||||||| 18f2b33 ++guid: qYyKt^B*76 ++=======

@@@ -12,7 -12,7 +18,19 @@@ 'Add New Note' window

action

++<<<<<<< HEAD +enter LaTeX math mode ++||||||| 18f2b33 ++attach pictures/audio/video ++=======

@@@ -12,7 -12,7 +18,19 @@@ 'Add New Note' window

action

++<<<<<<< HEAD +open field HTML editor ++||||||| 18f2b33 ++toggle superscript text ++=======

@@@ -12,7 -12,7 +18,19 @@@ 'Add New Note' window

action

++<<<<<<< HEAD +enter LaTeX math mode ++||||||| 18f2b33 ++attach pictures/audio/video ++=======

@@@ -12,7 -12,7 +18,19 @@@ 'Add New Note' window

action

++<<<<<<< HEAD +open field HTML editor ++||||||| 18f2b33 ++toggle superscript text ++=======

langfield commented 1 year ago

This can't happen (or at least is much less likely to happen) because we now disallow sibling cards in distinct decks, and so we now only have 1 file per note.