|
|
@@ -1,7 +1,9 @@
|
|
|
package info.knacki.pass.ui;
|
|
|
|
|
|
+import android.content.DialogInterface;
|
|
|
import android.os.Bundle;
|
|
|
import android.support.v7.app.AppCompatActivity;
|
|
|
+import android.view.View;
|
|
|
import android.widget.ProgressBar;
|
|
|
import android.widget.TextView;
|
|
|
|
|
|
@@ -26,11 +28,15 @@ import info.knacki.pass.git.entities.GitCommit;
|
|
|
import info.knacki.pass.git.entities.GitObject;
|
|
|
import info.knacki.pass.io.PathUtils;
|
|
|
import info.knacki.pass.settings.SettingsManager;
|
|
|
+import info.knacki.pass.ui.alertPrompt.AlertPrompt;
|
|
|
+import info.knacki.pass.ui.alertPrompt.views.ConflictView;
|
|
|
|
|
|
public class GitPullActivity extends AppCompatActivity {
|
|
|
private final static Logger log = Logger.getLogger(GitPullActivity.class.getName());
|
|
|
public final static String COMMIT_MSG = "Android pass sync";
|
|
|
|
|
|
+ public final static int ACTIVITY_REQUEST_CODE_BROWSEGPG = 1;
|
|
|
+
|
|
|
private GitInterface fGitInterfage;
|
|
|
private GitCommit fHeadCommit;
|
|
|
|
|
|
@@ -103,17 +109,19 @@ public class GitPullActivity extends AppCompatActivity {
|
|
|
HashMap<String, GitObject.GitBlob> conflictingFiles = new HashMap<>();
|
|
|
|
|
|
for (Map.Entry<String, GitObject.GitBlob>i: fHeadCommit.GetTree().FindAllBlobs().entrySet()) {
|
|
|
- String remoteLocalHash = localVersion.GetHash(i.getKey());
|
|
|
- String currentHash = GitSha1.BytesToString(GitSha1.getRawSha1OfFile(new File(PathUtils.GetPassDir(this) +i.getKey())));
|
|
|
-
|
|
|
- if (remoteLocalHash == null) remoteLocalHash = "";
|
|
|
+ final String remoteKnownHash = localVersion.GetHash(i.getKey(), "");
|
|
|
+ final String remoteHash = GitSha1.BytesToString(i.getValue().GetHash());
|
|
|
+ final String currentHash = GitSha1.BytesToString(GitSha1.getRawSha1OfFile(new File(PathUtils.GetPassDir(this) +i.getKey())));
|
|
|
|
|
|
- final boolean remoteChanged = !remoteLocalHash.equals(GitSha1.BytesToString(i.getValue().GetHash()));
|
|
|
- final boolean localChanged = !remoteLocalHash.equals(currentHash);
|
|
|
+ final boolean remoteChanged = !remoteKnownHash.equals(remoteHash);
|
|
|
+ final boolean localChanged = !remoteKnownHash.equals(currentHash);
|
|
|
|
|
|
if (remoteChanged && localChanged) {
|
|
|
- // Conflict
|
|
|
- conflictingFiles.put(i.getKey(), i.getValue());
|
|
|
+ // Conflict (but file can still has the same content)
|
|
|
+ if (currentHash.equals(remoteHash))
|
|
|
+ filesToPull.put(i.getKey(), i.getValue());
|
|
|
+ else
|
|
|
+ conflictingFiles.put(i.getKey(), i.getValue());
|
|
|
} else if (remoteChanged) {
|
|
|
// remote changed
|
|
|
filesToPull.put(i.getKey(), i.getValue());
|
|
|
@@ -126,7 +134,7 @@ public class GitPullActivity extends AppCompatActivity {
|
|
|
if (fHeadCommit.GetTree().GetObjectFullPath(i) == null) {
|
|
|
log.finer("removed from remote " +i);
|
|
|
final String currentHash = GitSha1.BytesToString(GitSha1.getRawSha1OfFile(new File(PathUtils.GetPassDir(this) +i)));
|
|
|
- final boolean localChanged = !currentHash.equals(localVersion.GetHash(i));
|
|
|
+ final boolean localChanged = !currentHash.equals(localVersion.GetHash(i, ""));
|
|
|
|
|
|
if (localChanged)
|
|
|
conflictingFiles.put(i, null);
|
|
|
@@ -134,15 +142,59 @@ public class GitPullActivity extends AppCompatActivity {
|
|
|
filesToPull.put(i, null);
|
|
|
}
|
|
|
}
|
|
|
- // FIXME new file on local
|
|
|
+ CheckNewFiles(localVersion, new File(PathUtils.GetPassDir(this)), "", filesToPull.keySet(), filesToPush, conflictingFiles.keySet());
|
|
|
+ if (conflictingFiles.isEmpty())
|
|
|
+ SyncFiles(localVersion, filesToPull, filesToPush);
|
|
|
+ else
|
|
|
+ AskForConflicts(localVersion, conflictingFiles, filesToPull, filesToPush);
|
|
|
+ }
|
|
|
|
|
|
- AskForConflicts(localVersion, conflictingFiles, filesToPull, filesToPush);
|
|
|
+ int CheckNewFiles(GitLocal localVersion, File root, String rootPath, Set<String> filesToPull, Set<String> filesToPush, Set<String> conflicts) {
|
|
|
+ int newFiles = 0;
|
|
|
+ for (final File i: root.listFiles()) {
|
|
|
+ if (i.isDirectory()) {
|
|
|
+ newFiles += CheckNewFiles(localVersion, i, rootPath +"/" +i.getName(), filesToPull, filesToPush, conflicts);
|
|
|
+ } else if (i.isFile()){
|
|
|
+ String path = rootPath +"/" +i.getName();
|
|
|
+ if (!localVersion.HasHash(path) && !filesToPull.contains(path) && !conflicts.contains(path)) {
|
|
|
+ // New file
|
|
|
+ filesToPush.add(path);
|
|
|
+ newFiles++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return newFiles;
|
|
|
}
|
|
|
|
|
|
- void AskForConflicts(GitLocal localVersion, HashMap<String, GitObject.GitBlob> conflicts, HashMap<String, GitObject.GitBlob> filesToPull, Set<String> filesToPush) {
|
|
|
- // FIXME
|
|
|
- filesToPush.addAll(conflicts.keySet());
|
|
|
- SyncFiles(localVersion, filesToPull, filesToPush);
|
|
|
+ void AskForConflicts(final GitLocal localVersion, final HashMap<String, GitObject.GitBlob> conflicts, final HashMap<String, GitObject.GitBlob> filesToPull, final Set<String> filesToPush) {
|
|
|
+ runOnUiThread(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ AlertPrompt pt = new AlertPrompt(GitPullActivity.this)
|
|
|
+ .setCancelable(true)
|
|
|
+ .setNegativeButton(R.string.cancel, new AlertPrompt.OnClickListener() {
|
|
|
+ @Override
|
|
|
+ public void onClick(DialogInterface dialogInterface, View view) {
|
|
|
+ GitPullActivity.this.finish();
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .setPositiveButton(R.string.ok, new AlertPrompt.OnClickListener() {
|
|
|
+ @Override
|
|
|
+ public void onClick(DialogInterface dialogInterface, View v) {
|
|
|
+ ConflictView.ConflictViewResult viewResult = ((ConflictView) v).GetResult();
|
|
|
+ for (String s: viewResult.fUseTheir) {
|
|
|
+ filesToPull.put(s, conflicts.get(s));
|
|
|
+ }
|
|
|
+ filesToPush.addAll(viewResult.fUseMine);
|
|
|
+ SyncFiles(localVersion, filesToPull, filesToPush);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .setTitle(R.string.conflictingFiles);
|
|
|
+ ConflictView view = new ConflictView(GitPullActivity.this, pt, conflicts.keySet());
|
|
|
+ pt.setView(view).show();
|
|
|
+ view.UpdateButtonState();
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
void RmEmptyDirs(File dir, boolean isRoot) {
|
|
|
@@ -159,6 +211,13 @@ public class GitPullActivity extends AppCompatActivity {
|
|
|
}
|
|
|
|
|
|
void SyncFiles(final GitLocal localVersion, final HashMap<String, GitObject.GitBlob> filesToPull, final Set<String> filesToPush) {
|
|
|
+ log.severe("Sync : ");
|
|
|
+ for (String i: filesToPush)
|
|
|
+ log.severe("PUSH > " +i);
|
|
|
+ for (String i: filesToPull.keySet())
|
|
|
+ log.severe("PULL > " +i);
|
|
|
+ log.severe("End listing files");
|
|
|
+ //*
|
|
|
final GitInterface.OnStreamResponseListener<Void> allDone = new GitInterface.OnStreamResponseListener<Void>() {
|
|
|
@Override
|
|
|
public void onResponse(Void result) {
|
|
|
@@ -194,20 +253,32 @@ public class GitPullActivity extends AppCompatActivity {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- DownloadBlobs(filesToPull, localVersion, new GitInterface.OnResponseListener<Void>(){
|
|
|
+ final Runnable afterFetching = new Runnable() {
|
|
|
@Override
|
|
|
- public void onResponse(Void result) {
|
|
|
+ public void run() {
|
|
|
if (filesToPush.size() > 0)
|
|
|
PushBlobs(filesToPush, localVersion, allDone);
|
|
|
else
|
|
|
- allDone.onResponse(result);
|
|
|
+ allDone.onResponse(null);
|
|
|
}
|
|
|
+ };
|
|
|
|
|
|
- @Override
|
|
|
- public void onError(String msg, Throwable e) {
|
|
|
- allDone.onError(msg, e);
|
|
|
- }
|
|
|
- });
|
|
|
+ if (filesToPull.isEmpty()) {
|
|
|
+ afterFetching.run();
|
|
|
+ } else {
|
|
|
+ DownloadBlobs(filesToPull, localVersion, new GitInterface.OnResponseListener<Void>() {
|
|
|
+ @Override
|
|
|
+ public void onResponse(Void result) {
|
|
|
+ afterFetching.run();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onError(String msg, Throwable e) {
|
|
|
+ allDone.onError(msg, e);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ //*/
|
|
|
}
|
|
|
|
|
|
void DownloadBlobs(Map<String, GitObject.GitBlob> blobs, final GitLocal localVersion, final GitInterface.OnResponseListener<Void> resp) {
|
|
|
@@ -317,7 +388,10 @@ public class GitPullActivity extends AppCompatActivity {
|
|
|
public void onResponse(Void result) {
|
|
|
final GitObject.GitTree tree = commit.Build().GetTree();
|
|
|
for (String i: files) {
|
|
|
- localVersion.SetHash(i, GitSha1.BytesToString(tree.GetObjectFullPath(i).GetHash()));
|
|
|
+ if (tree.GetObjectFullPath(i) == null)
|
|
|
+ localVersion.remove(i);
|
|
|
+ else
|
|
|
+ localVersion.SetHash(i, GitSha1.BytesToString(tree.GetObjectFullPath(i).GetHash()));
|
|
|
}
|
|
|
onMsg("Done");
|
|
|
resp.onResponse(result);
|