GitJournal / GitJournal

Mobile first Note Taking integrated with Git
https://gitjournal.io
GNU Affero General Public License v3.0
3.51k stars 239 forks source link

[Feature][Android] Don't commit changes if the content of note hasn't changed #615

Closed mnowotnik closed 2 years ago

mnowotnik commented 2 years ago

version of GitJournal on Android: 1.83.9+3526

What is happening ? When a user enters a note and then immediately exists the note widget using any of the provided editors (Markdown, raw, journal, checklist) or simply the View mode, the note is marked as changed, even though no changes have been performed by the user. Then, during the synchronization process one of two things will usually happen:

What should be happening? When a user enters a note via any mode and doesn't perform any changes, the GitJournal shouldn't update or change the note.

vHanda commented 2 years ago

Yup. I've noticed this happening lately. Clearly a regression. I'll look into it and write an automated test.

mnowotnik commented 2 years ago

Thanks for fast reply! Happy to support you! :smile:

vHanda commented 2 years ago

Sadly, I can't seem to reproduce it. Though I have seem empty commits in my git log. Can you reliably reproduce it? (Could you please try with 1.83.10?)

mnowotnik commented 2 years ago

Yes, I just rechecked with 1.83.10. I enter note. I press Android Back button. I sync notes. Empty commit is being made.

vHanda commented 2 years ago

Could you attach a copy of your debug logs, please?

(Settings -> Debug)

mnowotnik commented 2 years ago
Show log {"t":1647946073011,"l":"d","msg":"Note modified"} {"t":1647946073011,"l":"e","msg":"AutoCompleter","ex":"RangeError: Invalid value: Not in inclusive range 0..264: -1","stack":[{"uri":"dart:core","member":"_StringBase.lastIndexOf","isCore":true,"library":"dart:core","location":"dart:core"},{"uri":"package:gitjournal/editors/autocompletion_widget.dart","line":280,"member":"TagsAutoCompleter.textChanged","isCore":false,"library":"package:gitjournal/editors/autocompletion_widget.dart","location":"package:gitjournal/editors/autocompletion_widget.dart 280","package":"gitjournal"},{"uri":"package:gitjournal/editors/autocompletion_widget.dart","line":69,"member":"_AutoCompletionWidgetState._textChanged","isCore":false,"library":"package:gitjournal/editors/autocompletion_widget.dart","location":"package:gitjournal/editors/autocompletion_widget.dart 69","package":"gitjournal"},{"uri":"package:flutter/src/foundation/change_notifier.dart","line":308,"member":"ChangeNotifier.notifyListeners","isCore":false,"library":"package:flutter/src/foundation/change_notifier.dart","location":"package:flutter/src/foundation/change_notifier.dart 308","package":"flutter"},{"uri":"package:flutter/src/foundation/change_notifier.dart","line":412,"member":"ValueNotifier.value=","isCore":false,"library":"package:flutter/src/foundation/change_notifier.dart","location":"package:flutter/src/foundation/change_notifier.dart 412","package":"flutter"},{"uri":"package:flutter/src/widgets/editable_text.dart","line":151,"member":"TextEditingController.value=","isCore":false,"library":"package:flutter/src/widgets/editable_text.dart","location":"package:flutter/src/widgets/editable_text.dart 151","package":"flutter"},{"uri":"package:flutter/src/widgets/editable_text.dart","line":136,"member":"TextEditingController.text=","isCore":false,"library":"package:flutter/src/widgets/editable_text.dart","location":"package:flutter/src/widgets/editable_text.dart 136","package":"flutter"},{"uri":"package:gitjournal/editors/raw_editor.dart","line":105,"member":"RawEditorState.didUpdateWidget","isCore":false,"library":"package:gitjournal/editors/raw_editor.dart","location":"package:gitjournal/editors/raw_editor.dart 105","package":"gitjournal"},{"uri":"package:flutter/src/widgets/framework.dart","line":4778,"member":"StatefulElement.update","isCore":false,"library":"package:flutter/src/widgets/framework.dart","location":"package:flutter/src/widgets/framework.dart 4778","package":"flutter"},{"uri":"package:flutter/src/widgets/framework.dart","line":3370,"member":"Element.updateChild","isCore":false,"library":"package:flutter/src/widgets/framework.dart","location":"package:flutter/src/widgets/framework.dart 3370","package":"flutter"},{"uri":"package:flutter/src/widgets/framework.dart","line":4613,"member":"ComponentElement.performRebuild","isCore":false,"library":"package:flutter/src/widgets/framework.dart","location":"package:flutter/src/widgets/framework.dart 4613","package":"flutter"},{"uri":"package:flutter/src/widgets/framework.dart","line":4763,"member":"StatefulElement.performRebuild","isCore":false,"library":"package:flutter/src/widgets/framework.dart","location":"package:flutter/src/widgets/framework.dart 4763","package":"flutter"},{"uri":"package:flutter/src/widgets/framework.dart","line":4311,"member":"Element.rebuild","isCore":false,"library":"package:flutter/src/widgets/framework.dart","location":"package:flutter/src/widgets/framework.dart 4311","package":"flutter"},{"uri":"package:flutter/src/widgets/framework.dart","line":4795,"member":"StatefulElement.update","isCore":false,"library":"package:flutter/src/widgets/framework.dart","location":"package:flutter/src/widgets/framework.dart 4795","package":"flutter"},{"uri":"package:flutter/src/widgets/framework.dart","line":3370,"member":"Element.updateChild","isCore":false,"library":"package:flutter/src/widgets/framework.dart","location":"package:flutter/src/widgets/framework.dart 3370","package":"flutter"},{"uri":"package:flutter/src/widgets/framework.dart","line":4613,"member":"ComponentElement.performRebuild","isCore":false,"library":"package:flutter/src/widgets/framework.dart","location":"package:flutter/src/widgets/framework.dart 4613","package":"flutter"},{"uri":"package:flutter/src/widgets/framework.dart","line":4763,"member":"StatefulElement.performRebuild","isCore":false,"library":"package:flutter/src/widgets/framework.dart","location":"package:flutter/src/widgets/framework.dart 4763","package":"flutter"},{"uri":"package:flutter/src/widgets/framework.dart","line":4311,"member":"Element.rebuild","isCore":false,"library":"package:flutter/src/widgets/framework.dart","location":"package:flutter/src/widgets/framework.dart 4311","package":"flutter"},{"uri":"package:flutter/src/widgets/framework.dart","line":2578,"member":"BuildOwner.buildScope","isCore":false,"library":"package:flutter/src/widgets/framework.dart","location":"package:flutter/src/widgets/framework.dart 2578","package":"flutter"},{"uri":"package:flutter/src/widgets/binding.dart","line":882,"member":"WidgetsBinding.drawFrame","isCore":false,"library":"package:flutter/src/widgets/binding.dart","location":"package:flutter/src/widgets/binding.dart 882","package":"flutter"},{"uri":"package:flutter/src/rendering/binding.dart","line":363,"member":"RendererBinding._handlePersistentFrameCallback","isCore":false,"library":"package:flutter/src/rendering/binding.dart","location":"package:flutter/src/rendering/binding.dart 363","package":"flutter"},{"uri":"package:flutter/src/scheduler/binding.dart","line":1145,"member":"SchedulerBinding._invokeFrameCallback","isCore":false,"library":"package:flutter/src/scheduler/binding.dart","location":"package:flutter/src/scheduler/binding.dart 1145","package":"flutter"},{"uri":"package:flutter/src/scheduler/binding.dart","line":1082,"member":"SchedulerBinding.handleDrawFrame","isCore":false,"library":"package:flutter/src/scheduler/binding.dart","location":"package:flutter/src/scheduler/binding.dart 1082","package":"flutter"},{"uri":"package:flutter/src/scheduler/binding.dart","line":996,"member":"SchedulerBinding._handleDrawFrame","isCore":false,"library":"package:flutter/src/scheduler/binding.dart","location":"package:flutter/src/scheduler/binding.dart 996","package":"flutter"}]} {"t":1647946073035,"l":"d","msg":"Building autocompleter with { REDACTED }"} {"t":1647946073040,"l":"d","msg":"Note modified: REDACTED.md"} {"t":1647946074700,"l":"d","msg":"Event.RepoSynced"} {"t":1647946077718,"l":"d","msg":"Synced!"}
vHanda commented 2 years ago

I'm mostly interested in the parts which print out all your settings. So I can configure GitJournal in the same way. it's printed in the log each time the app loads.

mnowotnik commented 2 years ago
Show log {"t":1647953592075,"l":"i","msg":"--------------------------------"} {"t":1647953592075,"l":"i","msg":"--------------------------------"} {"t":1647953592075,"l":"i","msg":"--------------------------------"} {"t":1647953592075,"l":"i","msg":"--------- App Launched ---------"} {"t":1647953592075,"l":"i","msg":"--------------------------------"} {"t":1647953592075,"l":"i","msg":"--------------------------------"} {"t":1647953592075,"l":"i","msg":"--------------------------------"} {"t":1647953592075,"l":"i","msg":"AppConfig","p":{"onBoardingCompleted":"true","collectCrashReports":"true","version":"0","validateProMode":"true","proExpirationDate":"2022-03-12 01:26:23.000","debugLogLevel":"v","experimentalMarkdownToolbar":"true","experimentalGraphView":"true","experimentalAccounts":"false","experimentalGitMerge":"false","experimentalGitOps":"false","experimentalTagAutoCompletion":"false","experimentalHistory":"false"}} {"t":1647953592124,"l":"d","msg":"Analytics Collection: true"} {"t":1647953592124,"l":"d","msg":"Analytics Storage: /data/user/0/io.gitjournal.gitjournal/files/analytics"} {"t":1647953592142,"l":"i","msg":"Repo Ids [0]"} {"t":1647953592142,"l":"i","msg":"Current Id 0"} {"t":1647953592144,"l":"d","msg":"Event.StorageConfig","p":{"folderName":"other","storeInternally":"true","storageLocation":"","id":"0"}} {"t":1647953592145,"l":"d","msg":"Event.FolderConfig","p":{"noteFileNameFormat":"FromTitle","journalNoteFileNameFormat":"DateOnly","yamlModifiedKey":"modified","yamlCreatedKey":"created","yamlTagsKey":"tags","yamlEditorTypeKey":"type","yamlHeaderEnabled":"true","defaultEditor":"Raw","defaultView":"Standard","defaultFileFormat":"Markdown","sortingField":"Modified","sortingOrder":"desc","showNoteSummary":"true","folderViewHeaderType":"TitleOrFileName","imageLocationSpec":"assets","titleSettings":"h1","inlineTagPrefixes":"#","emojify":"false","allowedFileExts":".md .txt .org","id":"0"}} {"t":1647953592145,"l":"d","msg":"Event.GitConfig","p":{"gitAuthor":"true","gitAuthorEmail":"true","sshPublicKey":"true","sshPrivateKey":"true","sshPassword":"false","id":"0"}} {"t":1647953592146,"l":"d","msg":"Event.Settings","p":{"customMetaData":"","defaultNewNoteFolderSpec":"false","journalEditordefaultNewNoteFolderSpec":"","journalEditorSingleNote":"true","remoteSyncFrequency":"automatic","version":"3","markdownDefaultView":"Last Used","markdownLastUsedView":"Edit","homeScreen":"all_notes","theme":"dark","lightTheme":"LightDefault","darkTheme":"DarkDefault","zenMode":"false","swipeToDelete":"true","emojiParser":"true","bottomMenuBar":"true","confirmDelete":"true","id":"0"}} {"t":1647953592146,"l":"i","msg":"Loading Repo at path /data/user/0/io.gitjournal.gitjournal/app_flutter/Notes/"} {"t":1647953592147,"l":"i","msg":"App Version: 1.83.10"} {"t":1647953592147,"l":"i","msg":"App Build Number: 3533"} {"t":1647953592147,"l":"d","msg":"Event.AppUpdate","p":{"version":"1.83.10","previous_app_version":"1.83.5","app_name":"GitJournal","package_name":"io.gitjournal.gitjournal","build_number":"3533"}} {"t":1647953592151,"l":"d","msg":"BlobCTimeBuilder Cache Size: 23.88 Kb"} {"t":1647953592156,"l":"d","msg":"FileMTimeBuilder Cache Size: 25.74 Kb"} {"t":1647953592164,"l":"d","msg":"Loading MTimeCache: 220 items"} {"t":1647953592164,"l":"d","msg":"Loading CTimeCache: 273 items"} {"t":1647953592166,"l":"i","msg":"Branch master"} {"t":1647953592166,"l":"i","msg":"Cache Directory: /data/user/0/io.gitjournal.gitjournal/files/0"} {"t":1647953592167,"l":"d","msg":"Event.RepoSynced"} {"t":1647953592167,"l":"i","msg":"confirmProPurchaseBoot: Pro Mode is false"} {"t":1647953592199,"l":"d","msg":"Received MediaFile Share with App (media): []"} {"t":1647953592224,"l":"i","msg":"Notes Cache Loaded: 20 items"} {"t":1647953592227,"l":"i","msg":"Finished loading the notes cache - 0:00:00.060922"} {"t":1647953592231,"l":"i","msg":"Built Git Time Cache - 0:00:00.003748"} {"t":1647953592278,"l":"e","msg":"parseDateTime - '2020-02-17T13:21:00:Z'","ex":"FormatException: Invalid date format 2020-02-17T13:21:00:Z"} {"t":1647953592297,"l":"i","msg":"Sending 170 events"} {"t":1647953592302,"l":"e","msg":"parseDateTime - '${modified}'","ex":"FormatException: Invalid date format ${modified}"} {"t":1647953592302,"l":"e","msg":"parseDateTime - '${created}'","ex":"FormatException: Invalid date format ${created}"} {"t":1647953592303,"l":"e","msg":"parseDateTime - '${modified}'","ex":"FormatException: Invalid date format ${modified}"} {"t":1647953592303,"l":"e","msg":"parseDateTime - '${created}'","ex":"FormatException: Invalid date format ${created}"} {"t":1647953592332,"l":"e","msg":"parseDateTime - '15-02-20202T15:47:00Z'","ex":"FormatException: Invalid date format 15-02-20202T15:47:00Z"} {"t":1647953592361,"l":"i","msg":"Finished loading all the notes - 0:00:00.133390"} {"t":1647953592456,"l":"i","msg":"Loading View 0_summary_v2: 0:00:00.010968"} {"t":1647953593904,"l":"d","msg":"Synced!"} {"t":1647953594017,"l":"d","msg":"Saving MTimeCache: 225 items"} {"t":1647953594017,"l":"d","msg":"Saving CTimeCache: 326 items"} {"t":1647953594721,"l":"i","msg":"Sent 170 Analytics Events"} {"t":1647953594736,"l":"i","msg":"Sending 2 events"} {"t":1647953594995,"l":"i","msg":"Sent 2 Analytics Events"} {"t":1647953595008,"l":"i","msg":"Sending 0 events"} {"t":1647953595255,"l":"i","msg":"Sent 0 Analytics Events"} {"t":1647953595268,"l":"i","msg":"Sending 0 events"} {"t":1647953595492,"l":"i","msg":"Sent 0 Analytics Events"} {"t":1647953596725,"l":"d","msg":"Event.PurchaseScreenOpen","p":{"from":"drawer"}} {"t":1647953597968,"l":"i","msg":"Restoring Purchases"} {"t":1647953597968,"l":"i","msg":"Trying to confirmProPurchase"} {"t":1647953597976,"l":"i","msg":"Number of Past Purchases: 1"} {"t":1647953598806,"l":"i","msg":"IAP Verify body: {\"expiry_date\":1649723183323}"} {"t":1647953598806,"l":"i","msg":"--> SubscriptionStatus{isActive: true, expiryDate: 2022-04-12 00:26:23.323Z}"} {"t":1647953598807,"l":"i","msg":"Number of SubscriptionStatus: 1"} {"t":1647953598807,"l":"i","msg":"SubscriptionState: SubscriptionStatus{isActive: true, expiryDate: 2022-04-12 00:26:23.323Z}"} {"t":1647953598807,"l":"i","msg":"Pro ExpiryDate: 2022-04-12 00:26:23.323Z"} {"t":1647953602095,"l":"d","msg":"Event.DrawerSettings"} {"t":1647953628224,"l":"d","msg":"Event.DrawerSettings"}