git tasks refactoring (clone working)

This commit is contained in:
zeapo 2014-12-17 22:55:45 +01:00
parent 33689cefc7
commit f48bd5faa0
11 changed files with 351 additions and 99 deletions

View file

@ -11,7 +11,7 @@
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".git.GitHandler" <activity android:name=".git.GitActivity"
android:parentActivityName=".PasswordStore"> android:parentActivityName=".PasswordStore">
<meta-data android:name="android.PARENT_ACTIVITY1" <meta-data android:name="android.PARENT_ACTIVITY1"
android:value="com.zeapo.pwdstore.PasswordStore" /> android:value="com.zeapo.pwdstore.PasswordStore" />

View file

@ -18,8 +18,8 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import com.zeapo.pwdstore.crypto.PgpHandler; import com.zeapo.pwdstore.crypto.PgpHandler;
import com.zeapo.pwdstore.git.GitActivity;
import com.zeapo.pwdstore.git.GitAsyncTask; import com.zeapo.pwdstore.git.GitAsyncTask;
import com.zeapo.pwdstore.git.GitHandler;
import com.zeapo.pwdstore.utils.PasswordItem; import com.zeapo.pwdstore.utils.PasswordItem;
import com.zeapo.pwdstore.utils.PasswordRecyclerAdapter; import com.zeapo.pwdstore.utils.PasswordRecyclerAdapter;
import com.zeapo.pwdstore.utils.PasswordRepository; import com.zeapo.pwdstore.utils.PasswordRepository;
@ -151,9 +151,9 @@ public class PasswordStore extends ActionBarActivity {
break; break;
} }
intent = new Intent(this, GitHandler.class); intent = new Intent(this, GitActivity.class);
intent.putExtra("Operation", GitHandler.REQUEST_PUSH); intent.putExtra("Operation", GitActivity.REQUEST_PUSH);
startActivityForResult(intent, GitHandler.REQUEST_PUSH); startActivityForResult(intent, GitActivity.REQUEST_PUSH);
this.leftActivity = true; this.leftActivity = true;
return true; return true;
@ -163,9 +163,9 @@ public class PasswordStore extends ActionBarActivity {
break; break;
} }
intent = new Intent(this, GitHandler.class); intent = new Intent(this, GitActivity.class);
intent.putExtra("Operation", GitHandler.REQUEST_PULL); intent.putExtra("Operation", GitActivity.REQUEST_PULL);
startActivityForResult(intent, GitHandler.REQUEST_PULL); startActivityForResult(intent, GitActivity.REQUEST_PULL);
this.leftActivity = true; this.leftActivity = true;
return true; return true;
@ -186,9 +186,9 @@ public class PasswordStore extends ActionBarActivity {
} }
public void getClone(View view){ public void getClone(View view){
Intent intent = new Intent(this, GitHandler.class); Intent intent = new Intent(this, GitActivity.class);
intent.putExtra("Operation", GitHandler.REQUEST_CLONE); intent.putExtra("Operation", GitActivity.REQUEST_CLONE);
startActivityForResult(intent, GitHandler.REQUEST_CLONE); startActivityForResult(intent, GitActivity.REQUEST_CLONE);
} }
private void createRepository() { private void createRepository() {
@ -228,7 +228,7 @@ public class PasswordStore extends ActionBarActivity {
@Override @Override
public void onClick(DialogInterface dialogInterface, int i) { public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(activity, UserPreference.class); Intent intent = new Intent(activity, UserPreference.class);
startActivityForResult(intent, GitHandler.REQUEST_INIT); startActivityForResult(intent, GitActivity.REQUEST_INIT);
} }
}) })
.setNegativeButton(this.getResources().getString(R.string.dialog_negative), new DialogInterface.OnClickListener() { .setNegativeButton(this.getResources().getString(R.string.dialog_negative), new DialogInterface.OnClickListener() {
@ -433,7 +433,7 @@ public class PasswordStore extends ActionBarActivity {
protected void onActivityResult(int requestCode, int resultCode, protected void onActivityResult(int requestCode, int resultCode,
Intent data) { Intent data) {
if (resultCode == RESULT_OK) { if (resultCode == RESULT_OK) {
if (requestCode == GitHandler.REQUEST_CLONE) if (requestCode == GitActivity.REQUEST_CLONE)
checkLocalRepository(); checkLocalRepository();
switch (requestCode) { switch (requestCode) {
@ -446,10 +446,10 @@ public class PasswordStore extends ActionBarActivity {
); );
refreshListAdapter(); refreshListAdapter();
break; break;
case GitHandler.REQUEST_INIT: case GitActivity.REQUEST_INIT:
initRepository(getCurrentFocus()); initRepository(getCurrentFocus());
break; break;
case GitHandler.REQUEST_PULL: case GitActivity.REQUEST_PULL:
updateListAdapter(); updateListAdapter();
break; break;
} }

View file

@ -12,7 +12,7 @@ import android.util.Log;
import android.view.MenuItem; import android.view.MenuItem;
import com.zeapo.pwdstore.crypto.PgpHandler; import com.zeapo.pwdstore.crypto.PgpHandler;
import com.zeapo.pwdstore.git.GitHandler; import com.zeapo.pwdstore.git.GitActivity;
import com.zeapo.pwdstore.utils.PasswordRepository; import com.zeapo.pwdstore.utils.PasswordRepository;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
@ -105,8 +105,8 @@ public class UserPreference extends ActionBarActivity implements Preference.OnPr
break; break;
case "git_server_info": case "git_server_info":
{ {
Intent intent = new Intent(this, GitHandler.class); Intent intent = new Intent(this, GitActivity.class);
intent.putExtra("Operation", GitHandler.EDIT_SERVER); intent.putExtra("Operation", GitActivity.EDIT_SERVER);
startActivityForResult(intent, EDIT_GIT_INFO); startActivityForResult(intent, EDIT_GIT_INFO);
} }
break; break;

View file

@ -0,0 +1,54 @@
package com.zeapo.pwdstore.git;
import android.app.Activity;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import java.io.File;
public class CloneOperation extends GitOperation {
private static final String TAG = "CLONEOPT";
/**
* Creates a new clone operation
* @param fileDir the git working tree directory
* @param callingActivity the calling activity
*/
public CloneOperation(File fileDir, Activity callingActivity) {
super(fileDir, callingActivity);
}
/**
* Sets the command using the repository uri
* @param uri the uri of the repository
* @return the current object
*/
public CloneOperation setCommand(String uri) {
this.command = Git.cloneRepository().
setCredentialsProvider(provider).
setCloneAllBranches(true).
setDirectory(repository.getWorkTree()).
setURI(uri);
return this;
}
/**
* sets the authentication for user/pwd scheme
* @param username the username
* @param password the password
* @return the current object
*/
@Override
public CloneOperation setAuthentication(String username, String password) {
super.setAuthentication(username, password);
return this;
}
@Override
public CloneOperation setAuthentication(File sshKey, String username, String passphrase) {
super.setAuthentication(sshKey, username, passphrase);
return this;
}
}

View file

@ -28,6 +28,8 @@ import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo; import com.jcraft.jsch.UserInfo;
import com.zeapo.pwdstore.R; import com.zeapo.pwdstore.R;
import com.zeapo.pwdstore.UserPreference; import com.zeapo.pwdstore.UserPreference;
import com.zeapo.pwdstore.git.config.GitConfigSessionFactory;
import com.zeapo.pwdstore.git.config.SshConfigSessionFactory;
import com.zeapo.pwdstore.utils.PasswordRepository; import com.zeapo.pwdstore.utils.PasswordRepository;
import org.eclipse.jgit.api.CloneCommand; import org.eclipse.jgit.api.CloneCommand;
@ -56,7 +58,7 @@ import java.util.regex.Pattern;
// TODO move the messages to strings.xml // TODO move the messages to strings.xml
public class GitHandler extends ActionBarActivity { public class GitActivity extends ActionBarActivity {
private Activity activity; private Activity activity;
private Context context; private Context context;
@ -77,8 +79,6 @@ public class GitHandler extends ActionBarActivity {
public static final int REQUEST_INIT = 104; public static final int REQUEST_INIT = 104;
public static final int EDIT_SERVER = 105; public static final int EDIT_SERVER = 105;
private static final int GET_SSH_KEY_FROM_CLONE = 201;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -397,74 +397,6 @@ public class GitHandler extends ActionBarActivity {
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
protected class GitConfigSessionFactory extends JschConfigSessionFactory {
protected void configure(OpenSshConfig.Host hc, Session session) {
session.setConfig("StrictHostKeyChecking", "no");
}
@Override
protected JSch
getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
JSch jsch = super.getJSch(hc, fs);
jsch.removeAllIdentity();
return jsch;
}
}
protected class SshConfigSessionFactory extends GitConfigSessionFactory {
private String sshKey;
private String passphrase;
public SshConfigSessionFactory(String sshKey, String passphrase) {
this.sshKey = sshKey;
this.passphrase = passphrase;
}
@Override
protected JSch
getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
JSch jsch = super.getJSch(hc, fs);
jsch.removeAllIdentity();
jsch.addIdentity(sshKey);
return jsch;
}
@Override
protected void configure(OpenSshConfig.Host hc, Session session) {
session.setConfig("StrictHostKeyChecking", "no");
CredentialsProvider provider = new CredentialsProvider() {
@Override
public boolean isInteractive() {
return false;
}
@Override
public boolean supports(CredentialItem... items) {
return true;
}
@Override
public boolean get(URIish uri, CredentialItem... items) throws UnsupportedCredentialItem {
for (CredentialItem item : items) {
if (item instanceof CredentialItem.Username) {
((CredentialItem.Username) item).setValue(settings.getString("git_remote_username", "git"));
continue;
}
if (item instanceof CredentialItem.StringType) {
((CredentialItem.StringType) item).setValue(passphrase);
}
}
return true;
}
};
UserInfo userInfo = new CredentialsProviderUserInfo(session, provider);
session.setUserInfo(userInfo);
}
}
/** /**
* Clones the repository, the directory exists, deletes it * Clones the repository, the directory exists, deletes it
* @param view * @param view
@ -539,7 +471,10 @@ public class GitHandler extends ActionBarActivity {
show(); show();
} else { } else {
try { try {
authenticateAndRun("cloneOperation"); // authenticateAndRun("cloneOperation");
new CloneOperation(localDir, activity)
.setCommand(hostname)
.executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key"));
} catch (Exception e) { } catch (Exception e) {
//This is what happens when jgit fails :( //This is what happens when jgit fails :(
//TODO Handle the diffent cases of exceptions //TODO Handle the diffent cases of exceptions
@ -692,7 +627,7 @@ public class GitHandler extends ActionBarActivity {
/** Finds the method and provides it with authentication paramters via invokeWithAuthentication */ /** Finds the method and provides it with authentication paramters via invokeWithAuthentication */
private void authenticateAndRun(String operation) { private void authenticateAndRun(String operation) {
try { try {
invokeWithAuthentication(this, GitHandler.class.getMethod(operation, UsernamePasswordCredentialsProvider.class)); invokeWithAuthentication(this, GitActivity.class.getMethod(operation, UsernamePasswordCredentialsProvider.class));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -703,7 +638,7 @@ public class GitHandler extends ActionBarActivity {
* @param activity * @param activity
* @param method * @param method
*/ */
private void invokeWithAuthentication(final GitHandler activity, final Method method) { private void invokeWithAuthentication(final GitActivity activity, final Method method) {
if (connectionMode.equalsIgnoreCase("ssh-key")) { if (connectionMode.equalsIgnoreCase("ssh-key")) {
final File sshKey = new File(getFilesDir() + "/.ssh_key"); final File sshKey = new File(getFilesDir() + "/.ssh_key");
@ -717,7 +652,7 @@ public class GitHandler extends ActionBarActivity {
try { try {
Intent intent = new Intent(getApplicationContext(), UserPreference.class); Intent intent = new Intent(getApplicationContext(), UserPreference.class);
intent.putExtra("operation", "get_ssh_key"); intent.putExtra("operation", "get_ssh_key");
startActivityForResult(intent, GET_SSH_KEY_FROM_CLONE); startActivityForResult(intent, GitOperation.GET_SSH_KEY_FROM_CLONE);
} catch (Exception e) { } catch (Exception e) {
System.out.println("Exception caught :("); System.out.println("Exception caught :(");
e.printStackTrace(); e.printStackTrace();
@ -745,7 +680,9 @@ public class GitHandler extends ActionBarActivity {
SshSessionFactory.setInstance(new GitConfigSessionFactory()); SshSessionFactory.setInstance(new GitConfigSessionFactory());
try { try {
JschConfigSessionFactory sessionFactory = new SshConfigSessionFactory(sshKey.getAbsolutePath(), passphrase.getText().toString()); JschConfigSessionFactory sessionFactory = new SshConfigSessionFactory(sshKey.getAbsolutePath(),
settings.getString("git_remote_username", "git"),
passphrase.getText().toString());
SshSessionFactory.setInstance(sessionFactory); SshSessionFactory.setInstance(sessionFactory);
try { try {
@ -815,8 +752,14 @@ public class GitHandler extends ActionBarActivity {
case REQUEST_PUSH: case REQUEST_PUSH:
authenticateAndRun("pushOperation"); authenticateAndRun("pushOperation");
break; break;
case GET_SSH_KEY_FROM_CLONE: case GitOperation.GET_SSH_KEY_FROM_CLONE:
authenticateAndRun("cloneOperation"); try {
new CloneOperation(localDir, activity)
.setCommand(hostname)
.executeAfterAuthentication(connectionMode, settings.getString("git_remote_username", "git"), new File(getFilesDir() + "/.ssh_key"));
} catch (Exception e) {
e.printStackTrace();
}
} }
} }

View file

@ -0,0 +1,161 @@
package com.zeapo.pwdstore.git;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.annotation.Nullable;
import android.text.InputType;
import android.util.Log;
import android.widget.EditText;
import android.widget.LinearLayout;
import com.zeapo.pwdstore.R;
import com.zeapo.pwdstore.UserPreference;
import com.zeapo.pwdstore.git.config.GitConfigSessionFactory;
import com.zeapo.pwdstore.git.config.SshConfigSessionFactory;
import com.zeapo.pwdstore.utils.PasswordRepository;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.GitCommand;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import java.io.File;
public abstract class GitOperation {
private static final String TAG = "GitOpt";
public static final int GET_SSH_KEY_FROM_CLONE = 201;
protected final Repository repository;
protected final Activity callingActivity;
protected UsernamePasswordCredentialsProvider provider;
protected GitCommand command;
/**
* Creates a new git operation
* @param fileDir the git working tree directory
* @param callingActivity the calling activity
*/
public GitOperation(File fileDir, Activity callingActivity) {
this.repository = PasswordRepository.getRepository(fileDir);
this.callingActivity = callingActivity;
}
/**
* Sets the authentication using user/pwd scheme
* @param username the username
* @param password the password
* @return the current object
*/
public GitOperation setAuthentication(String username, String password) {
SshSessionFactory.setInstance(new GitConfigSessionFactory());
this.provider = new UsernamePasswordCredentialsProvider(username,password);
return this;
}
/**
* Sets the authentication using ssh-key scheme
* @param sshKey the ssh-key file
* @param username the username
* @param passphrase the passphrase
* @return the current object
*/
public GitOperation setAuthentication(File sshKey, String username, String passphrase) {
JschConfigSessionFactory sessionFactory = new SshConfigSessionFactory(sshKey.getAbsolutePath(), username, passphrase);
SshSessionFactory.setInstance(sessionFactory);
this.provider = null;
return this;
}
/**
* Executes the GitCommand in an async task
* @throws Exception
*/
public void execute() throws Exception {
Log.d(TAG, command + " << ");
new GitAsyncTask(callingActivity, true, false, CloneCommand.class).execute(command);
}
public void executeAfterAuthentication(String connectionMode, final String username, @Nullable final File sshKey) throws Exception {
if (connectionMode.equalsIgnoreCase("ssh-key")) {
if (sshKey == null || !sshKey.exists()) {
new AlertDialog.Builder(callingActivity)
.setMessage(callingActivity.getResources().getString(R.string.ssh_preferences_dialog_text))
.setTitle(callingActivity.getResources().getString(R.string.ssh_preferences_dialog_title))
.setPositiveButton(callingActivity.getResources().getString(R.string.dialog_ok), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
try {
Intent intent = new Intent(callingActivity.getApplicationContext(), UserPreference.class);
intent.putExtra("operation", "get_ssh_key");
callingActivity.startActivityForResult(intent, GET_SSH_KEY_FROM_CLONE);
} catch (Exception e) {
System.out.println("Exception caught :(");
e.printStackTrace();
}
}
}).setNegativeButton(callingActivity.getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
// Do nothing...
}
}).show();
} else {
final EditText passphrase = new EditText(callingActivity);
passphrase.setHint("Passphrase");
passphrase.setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
passphrase.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
new AlertDialog.Builder(callingActivity)
.setTitle(callingActivity.getResources().getString(R.string.passphrase_dialog_title))
.setMessage(callingActivity.getResources().getString(R.string.passphrase_dialog_text))
.setView(passphrase)
.setPositiveButton(callingActivity.getResources().getString(R.string.dialog_ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
SshSessionFactory.setInstance(new GitConfigSessionFactory());
try {
setAuthentication(sshKey, username, passphrase.getText().toString()).execute();
} catch (Exception e){
e.printStackTrace();
}
}
}).setNegativeButton(callingActivity.getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Do nothing.
}
}).show();
}
} else {
final EditText password = new EditText(callingActivity);
password.setHint("Password");
password.setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
password.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
new AlertDialog.Builder(callingActivity)
.setTitle(callingActivity.getResources().getString(R.string.passphrase_dialog_title))
.setMessage(callingActivity.getResources().getString(R.string.password_dialog_text))
.setView(password)
.setPositiveButton(callingActivity.getResources().getString(R.string.dialog_ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
setAuthentication(username, password.getText().toString());
try {
execute();
} catch (Exception e){
e.printStackTrace();
}
}
}).setNegativeButton(callingActivity.getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Do nothing.
}
}).show();
}
}
}

View file

@ -0,0 +1,24 @@
package com.zeapo.pwdstore.git.config;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig;
import org.eclipse.jgit.util.FS;
public class GitConfigSessionFactory extends JschConfigSessionFactory {
protected void configure(OpenSshConfig.Host hc, Session session) {
session.setConfig("StrictHostKeyChecking", "no");
}
@Override
protected JSch
getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
JSch jsch = super.getJSch(hc, fs);
jsch.removeAllIdentity();
return jsch;
}
}

View file

@ -0,0 +1,70 @@
package com.zeapo.pwdstore.git.config;
import android.content.SharedPreferences;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
import org.eclipse.jgit.transport.CredentialItem;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.CredentialsProviderUserInfo;
import org.eclipse.jgit.transport.OpenSshConfig;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.util.FS;
public class SshConfigSessionFactory extends GitConfigSessionFactory {
private String sshKey;
private String passphrase;
private String username;
public SshConfigSessionFactory(String sshKey, String username, String passphrase) {
this.sshKey = sshKey;
this.passphrase = passphrase;
this.username = username;
}
@Override
protected JSch
getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
JSch jsch = super.getJSch(hc, fs);
jsch.removeAllIdentity();
jsch.addIdentity(sshKey);
return jsch;
}
@Override
protected void configure(OpenSshConfig.Host hc, Session session) {
session.setConfig("StrictHostKeyChecking", "no");
CredentialsProvider provider = new CredentialsProvider() {
@Override
public boolean isInteractive() {
return false;
}
@Override
public boolean supports(CredentialItem... items) {
return true;
}
@Override
public boolean get(URIish uri, CredentialItem... items) throws UnsupportedCredentialItem {
for (CredentialItem item : items) {
if (item instanceof CredentialItem.Username) {
((CredentialItem.Username) item).setValue(username);
continue;
}
if (item instanceof CredentialItem.StringType) {
((CredentialItem.StringType) item).setValue(passphrase);
}
}
return true;
}
};
UserInfo userInfo = new CredentialsProviderUserInfo(session, provider);
session.setUserInfo(userInfo);
}
}

View file

@ -6,7 +6,7 @@
android:paddingRight="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin" android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.zeapo.pwdstore.git.GitHandler" tools:context="com.zeapo.pwdstore.git.GitActivity"
android:background="@android:color/white"> android:background="@android:color/white">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -1,7 +1,7 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
xmlns:pwstore="http://schemas.android.com/apk/res-auto" xmlns:pwstore="http://schemas.android.com/apk/res-auto"
tools:context="com.zeapo.pwdstore.git.GitHandler" > tools:context="com.zeapo.pwdstore.git.GitActivity" >
<item android:id="@+id/user_pref" <item android:id="@+id/user_pref"
android:title="@string/action_settings" android:title="@string/action_settings"
android:orderInCategory="100" android:orderInCategory="100"

View file

@ -41,7 +41,7 @@
<!-- Git Async Task --> <!-- Git Async Task -->
<string name="running_dialog_text">Running command...</string> <string name="running_dialog_text">Running command...</string>
<string name="jgit_error_dialog_title">Internal exception occurred</string> <string name="jgit_error_dialog_title">Internal exception occurred</string>
<string name="jgit_error_dialog_text">Message from jgit: /n</string> <string name="jgit_error_dialog_text">Message from jgit: \n</string>
<!-- Git Handler --> <!-- Git Handler -->
<string name="read_only_dialog_text">You are about to use a read-only repository, you will not be able to push to it</string> <string name="read_only_dialog_text">You are about to use a read-only repository, you will not be able to push to it</string>