Browse Source

Refs #47 git push

isundil 7 years ago
parent
commit
e07f2e7b7b

+ 21 - 4
app/src/main/java/info/knacki/pass/git/BaseGitProtocol.java

@@ -4,6 +4,7 @@ import java.util.logging.Logger;
 
 import info.knacki.pass.git.entities.GitCommit;
 import info.knacki.pass.git.entities.GitRef;
+import info.knacki.pass.io.CharsetHelper;
 import info.knacki.pass.io.OnResponseListener;
 import info.knacki.pass.io.OnStreamResponseListener;
 import info.knacki.pass.settings.SettingsManager;
@@ -16,9 +17,10 @@ public abstract class BaseGitProtocol implements GitInterface {
         fConfig = config;
     }
 
-    abstract void FetchCommit(GitRef ref, OnStreamResponseListener<GitCommit> response);
+    abstract protected void PushPack(GitCommit commit, Pacman pack, OnStreamResponseListener<Void> resp);
+    abstract protected void FetchCommit(GitRef ref, OnStreamResponseListener<GitCommit> response);
 
-    protected void GetHeadCommitFromRef(GitRef myRef, final OnStreamResponseListener<GitCommit> response) {
+    void GetHeadCommitFromRef(GitRef myRef, final OnStreamResponseListener<GitCommit> response) {
         if (myRef != null) {
             response.OnMsg("Checking out branch " +myRef.GetBranchName() +" revision " +myRef.GetHash());
             FetchCommit(myRef, new OnStreamResponseListener<GitCommit>() {
@@ -42,7 +44,7 @@ public abstract class BaseGitProtocol implements GitInterface {
         }
     }
 
-    public GitRef GetRefFromBranchName(GitRef[] refs, String branchName) {
+    private GitRef GetRefFromBranchName(GitRef[] refs, String branchName) {
         if (refs != null)
             for (GitRef ref: refs)
                 if (ref.GetBranch().equals(branchName))
@@ -50,7 +52,7 @@ public abstract class BaseGitProtocol implements GitInterface {
         return null;
     }
 
-    public GitRef GetHeadRef(GitRef[] refs) {
+    GitRef GetHeadRef(GitRef[] refs) {
         return GetRefFromBranchName(refs, fConfig.GetBranch());
     }
 
@@ -68,4 +70,19 @@ public abstract class BaseGitProtocol implements GitInterface {
             }
         });
     }
+
+    byte[] GitLine(String line) {
+        String lineResult;
+        if (line == null) {
+            lineResult = "0000";
+        } else {
+            lineResult = String.format("%04x%s\n", line.length() +5, line);
+        }
+        return CharsetHelper.StringToByteArray(lineResult);
+    }
+
+    @Override
+    public void PushCommitBuilder(GitCommit.Builder commit, OnStreamResponseListener<Void> resp) {
+        PushPack(commit.Build(), new Pacman(commit.PreparePack()), resp);
+    }
 }

+ 1 - 1
app/src/main/java/info/knacki/pass/git/GitInterface.java

@@ -10,5 +10,5 @@ public interface GitInterface {
     void GetRefs(OnResponseListener<GitRef[]> callback);
     void FetchHead(final OnStreamResponseListener<GitCommit> response);
     void FetchBlob(GitObject.GitBlob blob, OnStreamResponseListener<byte[]> response);
-    void PushBlobs(GitCommit.Builder commitBuilder, OnStreamResponseListener<Void> resp);
+    void PushCommitBuilder(GitCommit.Builder commit, OnStreamResponseListener<Void> resp);
 }

+ 43 - 52
app/src/main/java/info/knacki/pass/git/HttpGitProtocol.java

@@ -6,7 +6,6 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.nio.charset.Charset;
 import java.util.HashMap;
-import java.util.Locale;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -171,65 +170,57 @@ class HttpGitProtocol extends BaseGitProtocol {
         });
     }
 
-
-    public void PushBlobs(final GitCommit.Builder commit, final OnStreamResponseListener<Void> response) {
+    @Override
+    public void PushPack(final GitCommit commit, Pacman pack, final OnStreamResponseListener<Void> response) {
         GetRefs(new OnResponseListener<GitRef[]>() {
             @Override
             public void OnResponse(final GitRef[] result) {
-                GitRef myRef = null;
-                for (GitRef ref: result) {
-                    if (ref.GetBranch().equals(fConfig.GetBranch()))
-                        myRef = ref;
+                final GitRef myRef = GetHeadRef(result);
+                if (myRef == null) {
+                    response.OnError("Branch " +fConfig.GetBranch() + " not found on remote for pushing", null);
+                    return;
                 }
-                if (myRef != null) {
-                    final GitRef finalRef = myRef;
-                    response.OnMsg("Pushing over " +myRef.GetBranch() +" revision " +myRef.GetHash());
-                    try {
-                        HashMap<String, String> headers = new HashMap<>();
-                        headers.put("Content-Type", "application/x-git-receive-pack-request");
-                        ProtoPost(new URL(fConfig.GetUrl() +"/git-receive-pack"), headers, fConfig, new OnResponseListener<byte[]>() {
-                            @Override
-                            public void OnResponse(byte[] result) {
-                                response.OnResponse(null);
-                            }
+                response.OnMsg("Pushing over " +myRef.GetBranch() +" revision " +myRef.GetHash());
+                try {
+                    HashMap<String, String> headers = new HashMap<>();
+                    headers.put("Content-Type", "application/x-git-receive-pack-request");
+                    ProtoPost(new URL(fConfig.GetUrl() +"/git-receive-pack"), headers, fConfig, new OnResponseListener<byte[]>() {
+                        @Override
+                        public void OnResponse(byte[] result) {
+                            response.OnResponse(null);
+                        }
 
-                            @Override
-                            public void OnError(String msg, Throwable e) {
-                                log.log(Level.SEVERE, "git-receive-pack error", e);
-                                response.OnError(msg, e);
-                            }
-                        }, new OnResponseListener<OutputStream>() {
-                            @Override
-                            public void OnResponse(OutputStream result) {
-                                byte[] msgLine = (finalRef.GetHash() + " " + GitSha1.BytesToString(GitSha1.getRawSha1OfPackable(commit.Build())) +" " +finalRef.GetBranch()).getBytes();
-                                try {
-                                    result.write(String.format(Locale.US, "%04X", msgLine.length +4).getBytes());
-                                    result.write(msgLine);
-                                    result.write("0000".getBytes());
-                                    Pacman pac = new Pacman(commit.PreparePack());
-                                    if (!pac.Write(result)) {
-                                        OnError("Pack error", null);
-                                        return;
-                                    }
-                                    result.close();
-                                }
-                                catch (IOException e) {
-                                    log.log(Level.SEVERE, "Cannot git-upload-pack: " +e.getMessage(), e);
-                                    OnError(e.getMessage(), e);
+                        @Override
+                        public void OnError(String msg, Throwable e) {
+                            log.log(Level.SEVERE, "git-receive-pack error", e);
+                            response.OnError(msg, e);
+                        }
+                    }, new OnResponseListener<OutputStream>() {
+                        @Override
+                        public void OnResponse(OutputStream result) {
+                            try {
+                                result.write(GitLine(myRef.GetHash() + " " + GitSha1.BytesToString(GitSha1.getRawSha1OfPackable(commit)) +" " +myRef.GetBranch()));
+                                result.write(GitLine(null));
+                                if (!pack.Write(result)) {
+                                    OnError("Pack error", null);
+                                    return;
                                 }
+                                result.close();
                             }
-
-                            @Override
-                            public void OnError(String msg, Throwable e) {
-                                response.OnError(msg, e);
+                            catch (IOException e) {
+                                log.log(Level.SEVERE, "Cannot git-upload-pack: " +e.getMessage(), e);
+                                OnError(e.getMessage(), e);
                             }
-                        });
-                    }
-                    catch (IOException e) {
-                        response.OnError(e.getMessage(), e);
-                    }
-                } else {
-                    response.OnError("Branch " +fConfig.GetBranch() + " not found on remote for pushing", null);
+                        }
+
+                        @Override
+                        public void OnError(String msg, Throwable e) {
+                            response.OnError(msg, e);
+                        }
+                    });
+                }
+                catch (IOException e) {
+                    response.OnError(e.getMessage(), e);
                 }
             }
 

+ 2 - 1
app/src/main/java/info/knacki/pass/git/Pacman.java

@@ -58,7 +58,8 @@ class Pacman {
                 GitObject.GitTree realTree = FindTree(nextUninitialized.GetHash());
                 if (realTree == null)
                     throw new PacmanBuilder.InvalidPackException("Cannot find object in pack");
-                nextUninitialized.GetParent().SetRealObject(nextUninitialized.GetFilename(), new GitObject.GitTree(nextUninitialized.GetParent(), realTree, nextUninitialized.GetFilename()));
+                realTree = new GitObject.GitTree(nextUninitialized.GetParent(), realTree, nextUninitialized.GetFilename());
+                nextUninitialized.GetParent().SetRealObject(nextUninitialized.GetFilename(), realTree);
                 nextUninitialized = realTree;
             }
             for (GitObject.GitBlob i: nextUninitialized.GetBlobs()) {

+ 30 - 12
app/src/main/java/info/knacki/pass/git/SSHGitProtocol.java

@@ -189,16 +189,6 @@ public class SSHGitProtocol extends BaseGitProtocol {
         }
     }
 
-    private byte[] GitLine(String line) {
-        String lineResult;
-        if (line == null) {
-            lineResult = "0000";
-        } else {
-            lineResult = String.format("%04x%s\n", line.length() +5, line);
-        }
-        return CharsetHelper.StringToByteArray(lineResult);
-    }
-
     private byte[] PullPackData(ActiveSSHWrapper sshWrapper, String hash, OnStreamResponseListener<byte[]> listener) {
         try {
             ListenForErrors(sshWrapper.fStderr, (msg, e) -> listener.OnMsg(msg));
@@ -270,8 +260,36 @@ public class SSHGitProtocol extends BaseGitProtocol {
     }
 
     @Override
-    public void PushBlobs(GitCommit.Builder commitBuilder, OnStreamResponseListener<Void> resp) {
-
+    protected void PushPack(GitCommit commit, Pacman pack, OnStreamResponseListener<Void> resp) {
+        if (fActiveConnection != null)
+            fActiveConnection.fConnection.disconnect();
+        AppendableInputStream in = new AppendableInputStream();
+        SSHFactory
+            .createInstance(fRepoUrl, "git-receive-pack " +fRepoUrl.repoName)
+            .SetOnConnectionReadyListener((connection, stdout, stderr) -> {
+                fActiveConnection = new ActiveSSHWrapper(connection, in.GetWriter(), stdout, stderr);
+                GitRef ref = GetHeadRef(GetRefs(fActiveConnection, resp));
+                if (ref == null) {
+                    resp.OnError("Cannot push to " +fRepoUrl.repoName +": branch ref not found", null);
+                    return;
+                }
+                ListenForErrors(stdout, (msg, e) -> resp.OnMsg(msg));
+                ListenForErrors(stderr, (msg, e) -> resp.OnMsg(msg));
+                try {
+                    OutputStream w = in.GetWriter();
+                    w.write(GitLine(ref.GetHash() + " " + GitSha1.BytesToString(GitSha1.getRawSha1OfPackable(commit)) + " " + ref.GetBranch()));
+                    w.write(GitLine(null));
+                    if (!pack.Write(w)) {
+                        resp.OnError("Pack error", null);
+                        return;
+                    }
+                }
+                catch (IOException e) {
+                    resp.OnError("Cannot write pack: " +e.getMessage(), e);
+                }
+                resp.OnResponse(null);
+            })
+            .connect(in);
     }
 
     @Override

+ 6 - 1
app/src/main/java/info/knacki/pass/git/entities/GitObject.java

@@ -19,7 +19,7 @@ import info.knacki.pass.io.CharsetHelper;
 import info.knacki.pass.io.FileUtils;
 
 public abstract class GitObject implements Comparable<GitObject>, GitPackable {
-    final GitTree fParent;
+    GitTree fParent;
     final byte[] fMode;
     final String fName;
     byte[] fSha1;
@@ -134,6 +134,9 @@ public abstract class GitObject implements Comparable<GitObject>, GitPackable {
             this(parent, filename);
             fItems = content.fItems;
             fItemOrder = content.fItemOrder;
+            for (GitObject i: fItems.values()) {
+                i.SetParent(this);
+            }
         }
 
         public GitTree Initialize() {
@@ -369,6 +372,8 @@ public abstract class GitObject implements Comparable<GitObject>, GitPackable {
         return fParent;
     }
 
+    private void SetParent(GitTree t) { fParent = t; }
+
     public String GetMode() {
         return new String(fMode);
     }

+ 5 - 1
app/src/main/java/info/knacki/pass/git/entities/GitRef.java

@@ -8,7 +8,11 @@ public class GitRef {
 
     public GitRef(String hash, String branch) {
         fHash = hash;
-        fBranch = branch;
+        int pos = branch.indexOf('\0');
+        if (pos >= 0)
+            fBranch = branch.substring(0, pos);
+        else
+            fBranch = branch;
     }
 
     public String GetBranch() {

+ 1 - 1
app/src/main/java/info/knacki/pass/ui/GitPullActivity.java

@@ -352,7 +352,7 @@ public class GitPullActivity extends AppCompatActivity {
             final GitCommit.Builder commit = new GitCommit.Builder(fHeadCommit, config.GetUsername(), config.GetUserEmail(), COMMIT_MSG);
             for (String i : files)
                 commit.AddFile(i, new File(PathUtils.GetPassDir(this) + i));
-            fGitInterface.PushBlobs(commit, new OnStreamResponseListener<Void>() {
+            fGitInterface.PushCommitBuilder(commit, new OnStreamResponseListener<Void>() {
                 @Override
                 public void OnMsg(String message) {
                     resp.OnMsg(message);