#android #jgit
#Android #jgit
Вопрос:
Я пытаюсь использовать библиотеку JGit для синхронизации документов на моем телефоне Android с сервером.
Это почти работает… но я не могу заставить коммит работать. Всякий раз, когда я пытаюсь выполнить фиксацию, я получаю исключение «ошибка данных». Я отследил проблему до следующих утверждений в org.eclipse.jgit.util.IO:
public static void readFully(final InputStream fd, final byte[] dst,
int off, int len) throws IOException {
while (len > 0) {
final int r = fd.read(dst, off, len);
if (r <= 0)
throw new EOFException(JGitText.get().shortReadOfBlock);
off = r;
len -= r;
}
}
Строка fd.read(dst, off, len) вызовет выполнение. Я думаю, что параметр fd является InflaterInputStream, поэтому этот код пытается считывать данные из сжатого архива.
Я пытаюсь запустить это на HTC Desire Z с Android 2.2.
Я использую org.eclipse.jgit-0.12.1.jar и com.jcraft.jsch_0.1.31.jar чтобы получить доступ к функциональности jgit.
Я сделал несколько тестовых примеров, чтобы попытаться понять проблему
Следующий код выполняется без проблем на моем компьютере с Windows XP:
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
try {
// Create a new directory
File dirF = new File("C:\Test\TestDir");
dirF.mkdir();
log(">>> Created directory.n");
// Initialize git repository
InitCommand init = Git.init();
File initFile = new File("C:\Test\TestDir");
init.setDirectory(initFile);
init.call();
log(">>> Git Init done.n");
// Create a file
File newfile = new File("C:\Test\TestDir\myfile.txt");
newfile.createNewFile();
PrintStream os = new PrintStream(newfile);
os.println("Some text");
os.close();
log(">>> File created.n");
// Add to git
FileRepositoryBuilder builder = new FileRepositoryBuilder();
File f = new File("C:\Test\TestDir\.git");
Repository db = builder.setGitDir(f)
.findGitDir() // scan up the file system tree
.build();
Git git = new Git(db);
AddCommand add = git.add();
add.addFilepattern(".").call();
log(">>> Git Add done.n");
// Commit the change
CommitCommand commit = git.commit();
commit.setAll(true);
commit.setMessage("A JGit message");
commit.call();
log(">>> Git Commit done.n");
// Check the log
for (RevCommit c : git.log().call()) {
log(c.getId() "/" c.getAuthorIdent().getName() "/"
c.getShortMessage());
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void log(String s) {
System.out.print(s);
}
}
Следующий код вызовет исключение на моем телефоне Android:
public class JGitSimpleAndroidActivity extends Activity {
StringBuilder sb;
TextView tv;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sb = new StringBuilder();
tv = new TextView(this);
try {
// Create a new directory
File sdCard;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
sdCard = Environment.getExternalStorageDirectory();
} else {
log(">>> SD card is not available.");
return;
}
File dirF = new File(sdCard,"TestDir");
dirF.mkdir();
log(">>> Created directory.n");
// Initialize git repository
InitCommand init = Git.init();
init.setDirectory(dirF);
init.call();
log(">>> Git Init done.n");
// Create a file
File newfile = new File(dirF,"myfile.txt");
newfile.createNewFile();
PrintStream os = new PrintStream(newfile);
os.println("Some text");
os.close();
log(">>> File created.n");
// Add to git
FileRepositoryBuilder builder = new FileRepositoryBuilder();
File f = new File(dirF,".git");
Repository db = builder.setGitDir(f)
.findGitDir() // scan up the file system tree
.build();
Git git = new Git(db);
AddCommand add = git.add();
add.addFilepattern(".").call();
log(">>> Git Add done.n");
// Commit the change
CommitCommand commit = git.commit();
commit.setAll(true);
commit.setMessage("A JGit message");
commit.call(); // >>>>>>>> EXCEPTION THROWN HERE <<<<<<<
log(">>> Git Commit done.n");
// Check the log
for (RevCommit c : git.log().call()) {
log(c.getId() "/" c.getAuthorIdent().getName() "/"
c.getShortMessage());
}
} catch (Exception e) {
log(e.getMessage());
}
}
private void log(String s) {
sb.append(s);
sb.append('n');
tv.setText(sb);
setContentView(tv);
}
}
Есть идеи о том, что я могу сделать, чтобы это сработало?
С уважением, Андерс
Ответ №1:
Круто!
Попробуйте этот патч: (вероятно, поврежден пробел, поэтому применение его как есть может не сработать)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java index 4b9c572..4e38747 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java
b/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java @@ -214,7 214,7 @@ public static void readFully(final InputStream fd, final byte[] dst,
int off, int len) throws IOException {
while (len > 0) {
final int r = fd.read(dst, off, len);
- if (r <= 0)
if (r < 0)
throw new EOFException(JGitText.get().shortReadOfBlock);
off = r;
len -= r;
@@ -242,7 242,7 @@ public static void skipFully(final InputStream fd, long toSkip)
throws IOException {
while (toSkip > 0) {
final long r = fd.skip(toSkip);
- if (r <= 0)
if (r < 0)
throw new EOFException(JGitText.get().shortSkipOfBlock);
toSkip -= r;
}
Комментарии:
1. Пробовал, но, боюсь, это не помогает. Исключение генерируется вызовом fd.read(dst, off, len), а не последующим тестом if (r <= 0).
2. Любые другие идеи будут оценены. С уважением,
3. Я думаю, вам следует сообщить об этом как об ошибке на bugs.eclipse.org . Включите полную трассировку стека.
4. Я сообщил об ошибке на bugs.eclipse.org пару дней назад. Однако особых действий не последовало. Смотрите bugs.eclipse.org/bugs/show_bug.cgi?id=347485
5. Но на самом деле у меня все равно это работает, используя исправление одного метода в JGit: