Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Git Synchronization #173

Merged
merged 23 commits into from
May 21, 2018
Merged

Conversation

colonelpanic8
Copy link
Contributor

Fixes #24

@colonelpanic8
Copy link
Contributor Author

This is just a work in progress for the time being, but I wanted to put this up just in case anyone wants to take a look at the approach I am taking.

@colonelpanic8
Copy link
Contributor Author

@nevenz This is getting pretty close, although it's not quite there. Do you want to take a look at what I did with the UI and see if it's in line with what you would like? I had to make some changes to the existing code to make file browsing work that you might want to take a look at.

@nevenz
Copy link
Member

nevenz commented Sep 28, 2017

I tried it and for now just took a quick look a the code...

This is getting pretty close, although it's not quite there.

Should cloning work already? I'm getting InvalidRemoteException (I've added some logging, so lines might not match):

09-28 02:01:46.111 21800 21800 D RepoFactory: 1#main: ensureRepositoryExists: git@bitbucket.org:nevenz/foo.git file:/storage/emulated/0/Download/git-sync-test
09-28 02:01:46.111 21800 21800 W System.err: org.eclipse.jgit.api.errors.InvalidRemoteException: Invalid remote: origin
09-28 02:01:46.111 21800 21800 W System.err:    at org.eclipse.jgit.api.CloneCommand.call(CloneCommand.java:140)
09-28 02:01:46.111 21800 21800 W System.err:    at com.orgzly.android.repos.RepoFactory.ensureRepositoryExists(RepoFactory.java:102)

Might be what you mean by "not quite there", but since I tried it, I might as well report.

I get the same when I try to open the fragment to edit the repo (from the list of repositories). I don't think anything serious (like cloning) should happen at that point. BTW, all that code should probably be moved from RepoFactory to GitRepo itself.

Apart from few smaller UI stuff which I'm not going to mention now - when checkmark is clicked, repos are being created (looking at the logs), but fragment is not closed. Also, it would be helpful displaying some error messages (even in this early stage) if repo is not created due to missing data or whatever.

Do you want to take a look at what I did with the UI and see if it's in line with what you would like? I had to make some changes to the existing code to make file browsing work that you might want to take a look at.

I like it, FileSelectionFragment could be used for DirectoryRepo too, or anything else in the future.

I can't select the key though. I had to select a directory, then type the file name.

@colonelpanic8
Copy link
Contributor Author

I can't select the key though. I had to select a directory, then type the file name.

Oh oops, I guess maybe we should make it so that the browser can select a file?

Should cloning work already?

No, not quite yet, I need to fiddle with where it actually puts the stuff, and how it provides credentials

BTW, all that code should probably be moved from RepoFactory to GitRepo itself.

Yeah, actually I plan on doing the clone when the repo is created, to validate that all of the settings work as well, so I want to share the code somehow. I agree that it should be moved out of factory though.

Also, it would be helpful displaying some error messages (even in this early stage) if repo is not created due to missing data or whatever.

Yeah agreed, thats another thing I need to get to.

I mostly just wanted to get feedback on whether the changes to the starting of the browser okay.

My main concern (and the reason I wanted to have you look at the UI stuff) is actually with the BrowserResultHandler browserResultHandler instance variable. I haven't really done any android development before this, but my understanding is that fragments can be destroyed at any time by the runtime if they aren't displayed. Could something weird happen here where that variable points to a dead fragment or something like that? I'm not 100% clear on the conditions under which fragments/activity can be destroyed/created.

@nevenz
Copy link
Member

nevenz commented Sep 28, 2017

Oh oops, I guess maybe we should make it so that the browser can select a file?

My idea with browser is to be reused for something like notes browsing too. For example for refiling when you have to choose the target note. So there could be implementation of BrowserFragment for that too.

Now, we either rename FileBrowserFragment to DirectoryBrowserFragment and create new FileBrowserFragment that would call onBrowserUse in onListItemClick, or improve current implementation to accept option whether to allow selecting files or not.

It's probably easier to just create a new implementation which would inherit the existing one, for now?

My main concern (and the reason I wanted to have you look at the UI stuff) is actually with the BrowserResultHandler browserResultHandler instance variable.

It should be OK. Activity can killed by the system if it's not displayed, but as long as there is a fragment displayed and others are in the backstack, they should be fine.

BTW, looking at all those interfaces/listeners (and more coming in the future), I'm thinking we should switch to using activities per repo at one point (probably something I should have done from the start). It's getting confusing now who calls what etc. Maybe after this is released, I'll take a shot at that and see if it's worth it.

@colonelpanic8
Copy link
Contributor Author

implementation to accept option whether to allow selecting files or not.

Yeah that seems like the most reasonable approach to me.

using activities per repo at one point

Yes, definitely. The current setup is way too complicated.

@nevenz It would really make the rest of the work for this pull request a lot easier if we could move to storing repository type in the database instead of relying on uris to determine repo type. What is the advantage of doing things that way?

@nevenz
Copy link
Member

nevenz commented Sep 30, 2017

It would really make the rest of the work for this pull request a lot easier if we could move to storing repository type in the database instead of relying on uris to determine repo type.

Sounds good to me. Are you suggesting we do this before this PR, or as a part of it?

Which places besides getFromUri would that make things easier BTW?

@colonelpanic8
Copy link
Contributor Author

@nevenz git synchronization should be able to handle the case where there are both local and remote modifications. How would you refactor things to allow this?

@colonelpanic8
Copy link
Contributor Author

colonelpanic8 commented Oct 2, 2017

@nevenz @tulth I would like to pursue a much more aggresive refactor of syncing that gives a bit more control to the particular sync types implementation. The current implementation makes quite a few assumptions that seem tightly coupled to current implementations.

The idea would be to have the current code in Shelf.java to be one of multiple sync "strategies" that could be used. I think that at the very least, it should be up to the repo implementation to decide what the status of the sync is. The fact that this is not abstract causes a lot of issues.

The ideal interface for git synchronization would combine book storage and retrieval:

VersionedRook syncBook(Uri uri, File source, File destination, VersionedRook current) throws IOException;

Repo repo = getRepo(rook.getRepoUri());
Repo.TwoWaySync sync = repo.getSync();
if (sync != null) {
handleTwoWaySync(sync, namesake);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nevenz I expect that this is probably not the way you would like me to handle this, but I need an interface like this to handle git synchronization properly.

Do you have ideas/feelings about how this should be done?

BookAction.Type.INFO,
namesake.getStatus().msg(UriUtils.friendlyUri(repo.getUri().toString())));
}

switch (namesake.getStatus()) {
case NO_CHANGE:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like all of this should not be required of all synchronization strategies i.e. it should belong in its own class that CAN be used for some of the repos, but not others.

@@ -42,4 +42,12 @@
void delete(Uri uri) throws IOException;

String toString();

TwoWaySync getSync();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is obviously hideous, I have a few ideas about how to get around it, but they require a lot of changes in Shelf.java

@colonelpanic8
Copy link
Contributor Author

Synchronization sort of works now if anyone would like to try this. Some things (ssh key selection, directory naming, overlapping filenames across repositories) might be weird.

@jgkamat
Copy link

jgkamat commented Oct 2, 2017

Hi! I'm trying to test this out, and I'm having a bit of a problem building it, and I'm not exactly sure whats going on. Could someone take a look at my build? The full output is here.

Otherwise, can someone provide me with an APK so I can try this out! I'm super excited for this, I've been waiting for it for a long time!

@colonelpanic8
Copy link
Contributor Author

colonelpanic8 commented Oct 2, 2017

@jgkamat Not sure what is going on there. Here's an apk: https://nofile.io/f/tdSBOAeOzS1/orgzly-git-sync.apk

not that only ssh key support is added

@jgkamat
Copy link

jgkamat commented Oct 2, 2017

Im getting a crash on startup with the version you gave, the version from fdroid seems fine.

I/ActivityManager( 5140): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10300000 pkg=com.orgzly cmp=com.orgzly/.android.ui.MainActivity} from uid 1000 on display 0
I/ActivityManager( 5140): Start proc 29047:com.orgzly/u0a609 for activity com.orgzly/.android.ui.MainActivity
W/System  (29047): ClassLoader referenced unknown path: /data/app/com.orgzly-1/lib/arm
D/com.orgzly.android.provider.Provider(29047): 1#main: onCreate
D/com.orgzly.android.provider.Database(29047): 1#main: <init>: orgzly.db 143
D/com.orgzly.android.ui.MainActivity(29047): 1#main: onCreate: null
D/com.orgzly.android.ui.CommonActivity(29047): 1#main: onCreate: null
D/com.orgzly.android.ui.MainActivity(29047): 1#main: setupDrawer
D/com.orgzly.android.ui.MainActivity(29047): 1#main: addSyncFragment
D/com.orgzly.android.ui.fragments.SyncFragment(29047): 1#main: <init>
D/com.orgzly.android.ui.fragments.DrawerFragment(29047): 1#main: <init>
D/com.orgzly.android.ui.MainActivity(29047): 1#main: setupDisplay: null
D/com.orgzly.android.ui.DisplayManager(29047): 1#main: isFragmentDisplayed: tag:com.orgzly.android.ui.fragments.BooksFragment fragment:null isVisible:no
D/com.orgzly.android.ui.fragments.BooksFragment(29047): 1#main: <init>
D/com.orgzly.android.ui.fragments.SyncFragment(29047): 1#main: onAttach: com.orgzly.android.ui.MainActivity@e88da65
D/com.orgzly.android.ui.MainActivity(29047): 1#main: onAttachFragment: SyncFragment{fa7f01c #0 id=0x7f1000ac com.orgzly.android.ui.fragments.SyncFragment}
D/com.orgzly.android.ui.fragments.SyncFragment(29047): 1#main: onCreate: null
D/com.orgzly.android.ui.fragments.SyncFragment(29047): 1#main: onCreateView: com.android.internal.policy.PhoneLayoutInflater@fe669fa android.widget.FrameLayout{ac17bab V.E...... ......I. 0,0-0,0 #7f1000ac app:id/drawer_sync_container} null
D/com.orgzly.android.ui.fragments.DrawerFragment(29047): 1#main: onAttach: com.orgzly.android.ui.MainActivity@e88da65
D/com.orgzly.android.ui.MainActivity(29047): 1#main: onAttachFragment: DrawerFragment{1306905 #1 id=0x7f1000ab com.orgzly.android.ui.fragments.DrawerFragment}
D/com.orgzly.android.ui.fragments.DrawerFragment(29047): 1#main: onCreateView: com.android.internal.policy.PhoneLayoutInflater@7a6d5a android.widget.FrameLayout{f0e2b8b V.E...... ......I. 0,0-0,0 #7f1000ab app:id/drawer_list_container} null
D/com.orgzly.android.ui.fragments.DrawerFragment(29047): 1#main: onActivityCreated: null
D/com.orgzly.android.ui.fragments.DrawerFragment(29047): 1#main: onCreateLoader: 7 null
D/com.orgzly.android.ui.fragments.DrawerFragment(29047): 1#main: onCreateLoader: 6 null
D/com.orgzly.android.ui.fragments.BooksFragment(29047): 1#main: onAttach: com.orgzly.android.ui.MainActivity@e88da65
D/com.orgzly.android.ui.MainActivity(29047): 1#main: onAttachFragment: BooksFragment{ed94db2 #2 id=0x7f100079 com.orgzly.android.ui.fragments.BooksFragment}
D/com.orgzly.android.ui.fragments.BooksFragment(29047): 1#main: onCreate: null
D/com.orgzly.android.ui.fragments.BooksFragment(29047): 1#main: onCreateView: com.android.internal.policy.PhoneLayoutInflater@1de8103 android.widget.FrameLayout{25e0880 V.E...... ......I. 0,0-0,0 #7f100079 app:id/single_pane_container} null
D/com.orgzly.android.ui.fragments.BooksFragment(29047): 1#main: onViewCreated: android.widget.RelativeLayout{94491b0 V.E...... ......ID 0,0-0,0 #7f1000b3 app:id/fragment_books_container} null
D/com.orgzly.android.ui.fragments.BooksFragment(29047): 1#main: onActivityCreated: null
D/com.orgzly.android.ui.fragments.BooksFragment(29047): 1#main: onCreateLoader: 2 null
D/com.orgzly.android.ui.fragments.BooksFragment(29047): 1#main: onViewStateRestored: null
D/com.orgzly.android.ui.MainActivity(29047): 1#main: onPostCreate: null
D/com.orgzly.android.ui.MainActivity(29047): 1#main: onResume
D/com.orgzly.android.ui.CommonActivity(29047): 1#main: onResume
D/com.orgzly.android.provider.Provider(29047): 4832#ModernAsyncTask #1: query: content://com.orgzly/books null null null is_dummy,LOWER(COALESCE(books_view.title, books_view.name))
D/com.orgzly.android.provider.Provider(29047): 4833#ModernAsyncTask #2: query: content://com.orgzly/filters null null null position, _id
D/com.orgzly.android.ui.MainActivity(29047): 1#main: onResumeFragments
D/com.orgzly.android.ui.fragments.DrawerFragment(29047): 1#main: onCreateLoader: 7 null
D/com.orgzly.android.ui.fragments.BooksFragment(29047): 1#main: onResume
D/com.orgzly.android.ui.fragments.BooksFragment(29047): 1#main: onCreateLoader: 2 null
D/com.orgzly.android.provider.Provider(29047): 4834#ModernAsyncTask #3: query: content://com.orgzly/books null null null is_dummy,LOWER(COALESCE(books_view.title, books_view.name))
D/com.orgzly.android.provider.Provider(29047): 4835#ModernAsyncTask #4: query: content://com.orgzly/books null null null is_dummy,LOWER(COALESCE(books_view.title, books_view.name))
D/com.orgzly.android.ui.MainActivity(29047): 1#main: announceChanges: com.orgzly.android.ui.fragments.BooksFragment Notebooks null 0
D/com.orgzly.android.provider.Provider(29047): 4836#ModernAsyncTask #5: query: content://com.orgzly/books null null null is_dummy,LOWER(COALESCE(books_view.title, books_view.name))
D/com.orgzly.android.provider.Provider(29047): 4834#ModernAsyncTask #3: query: Cursor count: 1 for books_view null null
D/com.orgzly.android.provider.Provider(29047): 4832#ModernAsyncTask #1: query: Cursor count: 1 for books_view null null
D/com.orgzly.android.provider.Provider(29047): 4833#ModernAsyncTask #2: query: Cursor count: 2 for searches null null
D/com.orgzly.android.provider.Provider(29047): 4836#ModernAsyncTask #5: query: Cursor count: 1 for books_view null null
D/com.orgzly.android.provider.Provider(29047): 4835#ModernAsyncTask #4: query: Cursor count: 1 for books_view null null
D/com.orgzly.android.sync.SyncService(29047): 1#main: onCreate
D/com.orgzly.android.sync.SyncService(29047): 1#main: onBind
D/com.orgzly.android.ui.MainActivity(29047): 1#main: onCreateOptionsMenu: android.support.v7.view.menu.MenuBuilder@ec3fa55
I/ActivityManager( 5140): Displayed com.orgzly/.android.ui.MainActivity: +423ms
D/com.orgzly.android.ui.fragments.BooksFragment(29047): 1#main: onCreateOptionsMenu: android.support.v7.view.menu.MenuBuilder@ec3fa55 android.support.v7.view.SupportMenuInflater@37922c5
D/com.orgzly.android.ui.fragments.DrawerFragment(29047): 1#main: onLoadFinished: CursorLoader{83447e6 id=6} android.content.ContentResolver$CursorWrapperInner@e0ee127
D/com.orgzly.android.ui.fragments.BooksFragment(29047): 1#main: onLoadFinished: CursorLoader{19efd4 id=2} android.content.ContentResolver$CursorWrapperInner@415e57d
D/com.orgzly.android.ui.fragments.DrawerFragment(29047): 1#main: onLoadFinished: CursorLoader{4ecfc72 id=7} android.content.ContentResolver$CursorWrapperInner@ffe68c3
E/AndroidRuntime(29047): Process: com.orgzly, PID: 29047
E/AndroidRuntime(29047): java.lang.NullPointerException: Attempt to invoke virtual method 'long com.orgzly.android.repos.VersionedRook.getMtime()' on a null object reference
E/AndroidRuntime(29047): 	at com.orgzly.android.Book.isModifiedAfterLastSync(Book.java:82)
E/AndroidRuntime(29047): 	at com.orgzly.android.ui.fragments.DrawerFragment.updateFromBooksCursor(DrawerFragment.java:362)
E/AndroidRuntime(29047): 	at com.orgzly.android.ui.fragments.DrawerFragment.onLoadFinished(DrawerFragment.java:307)
E/AndroidRuntime(29047): 	at com.orgzly.android.ui.fragments.DrawerFragment.onLoadFinished(DrawerFragment.java:38)
W/ActivityManager( 5140):   Force finishing activity com.orgzly/.android.ui.MainActivity
W/ActivityManager( 5140): Activity pause timeout for ActivityRecord{b354fc3 u0 com.orgzly/.android.ui.MainActivity t9558 f}
W/InputDispatcher( 5140): channel '9ae9917 com.orgzly/com.orgzly.android.ui.MainActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
E/InputDispatcher( 5140): channel '9ae9917 com.orgzly/com.orgzly.android.ui.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
I/WindowState( 5140): WIN DEATH: Window{9ae9917 u0 com.orgzly/com.orgzly.android.ui.MainActivity}
W/InputDispatcher( 5140): Attempted to unregister already unregistered input channel '9ae9917 com.orgzly/com.orgzly.android.ui.MainActivity (server)'
I/ActivityManager( 5140): Process com.orgzly (pid 29047) has died
W/ActivityManager( 5140): Scheduling restart of crashed service com.orgzly/com.evernote.android.job.JobRescheduleService in 1000ms

@colonelpanic8
Copy link
Contributor Author

colonelpanic8 commented Oct 2, 2017

@jgkamat Ahh oops, i know why thats happening. Try https://drive.google.com/file/d/0B4o0sMkRk8C1OU9Bc0VsTU1PbjA/view?usp=sharing

@nevenz
Copy link
Member

nevenz commented Oct 2, 2017

What about:

public interface TwoWaySyncable {
    VersionedRook syncBook(VersionedRook current, File fromDB, File writeBack) throws IOException;
}

leaving Repo as it was (could be renamed later), make only GitRepo implement TwoWaySyncable and in syncNamesake only have:

        if (repo instanceof TwoWaySyncable) {
            return handleTwoWaySync(repo, namesake);
        } else {
            return handleBookSync(repo, namesake);
        }

@colonelpanic8
Copy link
Contributor Author

leaving Repo as it was (could be renamed later), make only GitRepo implement TwoWaySyncable and in syncNamesake only have:

@nevenz I'm definitely fine with that if it makes you happy.

@jgkamat
Copy link

jgkamat commented Oct 3, 2017

I wasn't able to get past the repository creation screen, the checkbox didn't seem to let me beyond the settings page. In the logs, there were a bunch of errors relating to 'could not delete' the directory where the git repo was to be cloned. after deleting it manually, the error still persisted.

Also, once trying out the "Directory" sync after trying that out, I got a bunch of errors, and the file didn't import properly. Switching to the release version worked fine, so I think that this PR might need some more work 😢

@colonelpanic8
Copy link
Contributor Author

@nevenz Random question -- Did you ever consider letting the actual files be the canonical source of data for orgzly? Given how quickly orgzly was able to sync my 100+ file repository, it seems like parsing etc. is quick enough that everything could be done in memory. I have a hard time believing that peformance is a huge concern in this case -- this is, after all, a TODO application, and we are not dealing with millions of pieces of DATA.

@nevenz
Copy link
Member

nevenz commented Oct 6, 2017

Did you ever consider letting the actual files be the canonical source of data for orgzly? Given how quickly orgzly was able to sync my 100+ file repository, it seems like parsing etc. is quick enough that everything could be done in memory. I have a hard time believing that peformance is a huge concern in this case -- this is, after all, a TODO application, and we are not dealing with millions of pieces of DATA.

Briefly in the beginning. But I didn't see that working very well or fast, without re-inventing a lot of things that you get when you use DB.

Some of the reasons that come to mind...

You'd have to rewrite the whole file after every note modification. Doing a lot of small modifications to just a single large notebook (which sounds like something that it's done often, at least I do) could be a battery killer. It's a similar issue to the one auto-sync now has.

Search across all files would depend too much on number of files and their size and it could be very slow. In addition, it's way too easy to do a search with a complicated query now using a DB.

Also, org files are just one of the possible file formats Orgzly supports for exporting and importing data. Something like BookName.Format is there from day 1 and is used throughout the code. I did get lazy over time, so there are quite a few Org-specific things in the code now. But it's one of the reasons I didn't consider using an org file as a way to store notes.

@colonelpanic8
Copy link
Contributor Author

@nevenz This is pretty much ready to go.

There are several serious bug when the uri of a git repo is edited, but it is not because of any new code.

@colonelpanic8
Copy link
Contributor Author

@jgkamat Sorry about that, I've fixed a bunch of the issues. There might be a few rough spots with this version, but it should at least pull in your repository.

@nevenz
Copy link
Member

nevenz commented Oct 12, 2017

Issues or missing features to be resolved before enabling this in the app

  • Warning when syncing from Android Studio
Warning:WARNING: Dependency org.apache.httpcomponents:httpclient:4.1.3 is ignored for fdroidDebug as it may be conflicting with the internal version provided by Android.
  • Building fails when doing ./gradlew build (proguard-rules.pro needs updating probably)
  • Asking for Storage permission before entering Git repo creation, leaving user in repos list
  • Prepopulate directory (Orgzly/repos/git in storage root or similar)
  • On tapping checkmark (using git@bitbucket.org:nevenz/foo.git)
11-09 08:05:24.383  7914  7914 W System.err: java.io.IOException: Directory /storage/emulated/0/Download/git is not a git repository.
11-09 08:05:24.383  7914  7914 W System.err:    at com.orgzly.android.repos.GitRepo.ensureRepositoryExists(GitRepo.java:109)
11-09 08:05:24.384  7914  7914 W System.err:    at com.orgzly.android.repos.GitRepo.ensureRepositoryExists(GitRepo.java:73)
11-09 08:05:24.384  7914  7914 W System.err:    at com.orgzly.android.ui.fragments.GitRepoFragment$RepoCloneTask.doInBackground(GitRepoFragment.java:343)
11-09 08:05:24.384  7914  7914 W System.err:    at com.orgzly.android.ui.fragments.GitRepoFragment$RepoCloneTask.doInBackground(GitRepoFragment.java:312)
  • Had to delete selected (empty, created from browser) directory (can't use just browser, we have to type?)
  • Edit repo, change to non-existing URL, no check (dialog) this time, repo is accepted
  • Trying to sync gives "No repos configured" (with non-existing URL created above). Later discovered that the file from repository was downloaded at one point after all
  • "Unsupported repository type" trying to edit repo (non-existing URL)
11-09 08:15:50.019  7914  7914 W System.err: java.io.IOException: The file /storage/emulated/0/Documents/nevenz/foo2.git does not exist
11-09 08:15:50.019  7914  7914 W System.err:    at com.orgzly.android.repos.GitRepo.ensureRepositoryExists(GitRepo.java:105)
11-09 08:15:50.019  7914  7914 W System.err:    at com.orgzly.android.repos.GitRepo.ensureRepositoryExists(GitRepo.java:73)
11-09 08:15:50.019  7914  7914 W System.err:    at com.orgzly.android.repos.GitRepo.build(GitRepo.java:57)
11-09 08:15:50.019  7914  7914 W System.err:    at com.orgzly.android.repos.GitRepo.buildFromUri(GitRepo.java:53)
11-09 08:15:50.019  7914  7914 W System.err:    at com.orgzly.android.repos.RepoFactory.getFromUri(RepoFactory.java:49)
11-09 08:15:50.019  7914  7914 W System.err:    at com.orgzly.android.repos.RepoFactory.getFromUri(RepoFactory.java:23)
11-09 08:15:50.019  7914  7914 W System.err:    at com.orgzly.android.ui.ReposActivity.onRepoEditRequest(ReposActivity.java:188)
11-09 08:15:50.019  7914  7914 W System.err:    at com.orgzly.android.ui.fragments.ReposFragment.onListItemClick(ReposFragment.java:130)
  • Using https://nevenz@bitbucket.org/nevenz/foo.git
10-12 23:20:20.008  6287  6416 E AndroidRuntime: Caused by: java.lang.ClassCastException: org.eclipse.jgit.transport.TransportHttp cannot be cast to org.eclipse.jgit.transport.SshTransport
10-12 23:20:20.008  6287  6416 E AndroidRuntime:        at com.orgzly.android.git.GitSSHKeyTransportSetter$2.configure(GitSSHKeyTransportSetter.java:40)
10-12 23:20:20.008  6287  6416 E AndroidRuntime:        at org.eclipse.jgit.api.TransportCommand.configure(TransportCommand.java:138)
10-12 23:20:20.008  6287  6416 E AndroidRuntime:        at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:128)
10-12 23:20:20.008  6287  6416 E AndroidRuntime:        at org.eclipse.jgit.api.CloneCommand.fetch(CloneCommand.java:193)
10-12 23:20:20.008  6287  6416 E AndroidRuntime:        at org.eclipse.jgit.api.CloneCommand.call(CloneCommand.java:133)
10-12 23:20:20.008  6287  6416 E AndroidRuntime:        at com.orgzly.android.repos.GitRepo.ensureRepositoryExists(GitRepo.java:91)
10-12 23:20:20.008  6287  6416 E AndroidRuntime:        at com.orgzly.android.repos.GitRepo.ensureRepositoryExists(GitRepo.java:73)
10-12 23:20:20.008  6287  6416 E AndroidRuntime:        at com.orgzly.android.ui.fragments.GitRepoFragment$RepoCloneTask.doInBackground(GitRepoFragment.java:343)
10-12 23:20:20.008  6287  6416 E AndroidRuntime:        at com.orgzly.android.ui.fragments.GitRepoFragment$RepoCloneTask.doInBackground(GitRepoFragment.java:312)
10-12 23:20:20.008  6287  6416 E AndroidRuntime:        at android.os.AsyncTask$2.call(AsyncTask.java:305)
10-12 23:20:20.008  6287  6416 E AndroidRuntime:        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
  • Clicking checkmark immediately (all fields empty): Snackbar with javaj.io.IOException: Failed to clone repository , null
  • Entering "asd" as URL and pressing checkmark
java.io.IOException: Failed to clone repository asd, org.eclipse.jgit.errors.NoRemoteRepositoryException: asd: not found.
  • Error checking for all other fields
  • Allow login with user/pass

Minor stuff

  • Big button for Git needs to be added in repos list (between Dropbox and Directory)
  • Change order in + drop-down (Dropbox, Git, Directory)
  • Can't scroll down (not using ScrollView?)
  • Git branch's input is half a size (top half is cut off)
  • Snackbar displayed below opened keyboard
  • Action button (imeOptions) - actionNext for all but last, which should be actionDone
  • Remove "Git" from all hints
  • Git author (e.g. My Name) -> Name (e.g. John Doe)
  • Git email (e.g. me@email.com) -> Email (e.g. john@doe.com)
  • Git branch (e.g. master) -> Branch
  • Prepopulate branch with "master"
  • Fields with browse button don't have hint displayed when value is set (TextInputLayout missing?)
  • Git remote address -> Remote URL
  • Extract string resources displayed to user (errors etc.)
  • Move git package to sync/ or repos/ (for now)

@timoc
Copy link

timoc commented Oct 14, 2017

Is this available to play with?
Can you test it with git-crypt?
see:https://www.eclipse.org/forums/index.php/t/1087959/
Does this mean that Orgzly can now use a tree of org files?

@colonelpanic8
Copy link
Contributor Author

like modifying interface for TwoWaySync and adding repository type to stop relying on URLs to determine it)

Yeah I think this is pretty crucial.

@colonelpanic8
Copy link
Contributor Author

@nevenz Did my best to resolve conflicts, but I haven't touched android studio in a while and can't seem to get things working right now.

The original history can be found here:
https://github.com/IvanMalison/orgzly-android/tree/gitSyncOriginal

@nevenz nevenz merged commit 566c20a into orgzly:master May 21, 2018
@nevenz
Copy link
Member

nevenz commented May 21, 2018

@nevenz Did my best to resolve conflicts,

Thanks for taking the time to do this. I was wondering what to do with it as I started moving repository fragments to activities, which would make merging even more difficult.

It's merged to master now, so it doesn't fall behind again.

It's hidden under IS_GIT_ENABLED (set to false in build.gradle) until all issues are fixed. I've just fixed compilation issues and one crash for now.

There's no browser fragment anymore, so currently nothing happens on "Browse". I'll see to fix that and make remaining fragments (directory and now git) into activities.

I'll keep the above comment updated.

but I haven't touched android studio in a while and can't seem to get things working right now.

You might need the latest version if haven't tried it already.

@nevenz
Copy link
Member

nevenz commented May 21, 2018

It's hidden under IS_GIT_ENABLED (set to false in build.gradle)

It's git.enabled in app.properties now.

@bpiel
Copy link

bpiel commented Jul 13, 2018

Can I please send someone money to make this happen? If there were a kickstarter (or similar), I'd donate and help promote it.

@colonelpanic8
Copy link
Contributor Author

@bpiel you can always use the link I posted above to get a really old version that has working git synchronization:

https://keybase.pub/imalison/orgzly-git-sync.apk

I looked at trying to get stuff working again briefly when I did the merge a while back (Guess it was May 20th) and it seemed like a bit too much for me to take on at that moment.

@colonelpanic8 colonelpanic8 deleted the gitSynchronization branch July 13, 2018 16:08
@lfxgroove lfxgroove mentioned this pull request May 13, 2019
33 tasks
@caleb-allen
Copy link

What is the status of this? What needs to get done?

I would be willing to pick this up, if I can find some free time. I'm an android dev and would be comfortable building a diff gui of some sort, or whatever needs doing. Mostly because I would really like this feature and Orgzly doesn't offer me much value until it's in.

@colonelpanic8
Copy link
Contributor Author

@caleb-allen see the first comment on #543 (comment) . Would love it if you could finish this off. I'm not an android dev and it just became too painful for me to do the UI work.

@reyman
Copy link

reyman commented Aug 28, 2019

Thanks @IvanMalison to work on that, i see you use keybase, is there any chance that this plugin work with encrypted keybase:// git capabilities ?

@colonelpanic8
Copy link
Contributor Author

@reyman no, because it uses jgit

@reyman
Copy link

reyman commented Aug 28, 2019

@IvanMalison Seems some people use (with success, i need to test) another strategy with git-remote-gcrypt on termux : keybase/kbfs#1231 and https://md.hecke.rs/s/SyWx8-hBX#

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

git synchroniztion
9 participants