Проблема с фиксацией JGit на Android

#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: