|
|
@@ -27,7 +27,7 @@ import info.knacki.pass.settings.SettingsManager;
|
|
|
public class SSHGitProtocol extends BaseGitProtocol {
|
|
|
private final static Logger log = Logger.getLogger(SSHGitProtocol.class.getName());
|
|
|
private final SSHUrl fRepoUrl;
|
|
|
-
|
|
|
+ private GitRef[] fRefsCache = null;
|
|
|
private final class ActiveSSHWrapper {
|
|
|
final SSHConnection fConnection;
|
|
|
final OutputStream fStdin;
|
|
|
@@ -42,8 +42,6 @@ public class SSHGitProtocol extends BaseGitProtocol {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private ActiveSSHWrapper fActiveConnection = null;
|
|
|
-
|
|
|
private final class SSHUrl implements SSHConnection.ConnectionParams {
|
|
|
private final String repoHost;
|
|
|
final String repoName;
|
|
|
@@ -148,8 +146,12 @@ public class SSHGitProtocol extends BaseGitProtocol {
|
|
|
return references.toArray(refs);
|
|
|
}
|
|
|
|
|
|
- private void ListenForErrors(InputStream stderr, OnErrorListener OnError) {
|
|
|
- (new Thread() {
|
|
|
+ private void ListenForErrors(InputStream stderr, OnErrorListener onError) {
|
|
|
+ ListenForErrors(stderr, onError, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ListenForErrors(InputStream stderr, OnErrorListener onError, boolean separateThread) {
|
|
|
+ Thread thread = (new Thread() {
|
|
|
@Override
|
|
|
public void run() {
|
|
|
BufferedReader reader = new BufferedReader(new InputStreamReader(stderr));
|
|
|
@@ -157,36 +159,39 @@ public class SSHGitProtocol extends BaseGitProtocol {
|
|
|
|
|
|
try {
|
|
|
while ((line = reader.readLine()) != null) {
|
|
|
- OnError.OnError(line, null);
|
|
|
+ onError.OnError(line, null);
|
|
|
}
|
|
|
}
|
|
|
catch (IOException e) {
|
|
|
log.log(Level.SEVERE, "Cannot read from stderr", e);
|
|
|
}
|
|
|
}
|
|
|
- }).start();
|
|
|
+ });
|
|
|
+
|
|
|
+ if (separateThread)
|
|
|
+ thread.start();
|
|
|
+ else
|
|
|
+ thread.run();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void GetRefs(OnResponseListener<GitRef[]> callback) {
|
|
|
- if (fActiveConnection != null) {
|
|
|
- GitRef[] refs = GetRefs(fActiveConnection, callback);
|
|
|
- if (refs != null)
|
|
|
- callback.OnResponse(refs);
|
|
|
- } else {
|
|
|
- AppendableInputStream stdin = new AppendableInputStream();
|
|
|
-
|
|
|
- SSHFactory
|
|
|
- .createInstance(fRepoUrl, "git-upload-pack " + fRepoUrl.repoName)
|
|
|
- .SetOnConnectionReadyListener((connection, stdout, stderr) -> {
|
|
|
- ListenForErrors(stderr, (msg, exc) -> log.severe(msg));
|
|
|
- GitRef[] refs = GetRefs(new ActiveSSHWrapper(connection, stdin.GetWriter(), stdout, stderr), callback);
|
|
|
- connection.disconnect();
|
|
|
- if (refs != null)
|
|
|
- callback.OnResponse(refs);
|
|
|
- })
|
|
|
- .connect();
|
|
|
+ if (fRefsCache != null) {
|
|
|
+ callback.OnResponse(fRefsCache);
|
|
|
+ return;
|
|
|
}
|
|
|
+ AppendableInputStream stdin = new AppendableInputStream();
|
|
|
+
|
|
|
+ SSHFactory
|
|
|
+ .createInstance(fRepoUrl, "git-upload-pack " + fRepoUrl.repoName)
|
|
|
+ .SetOnConnectionReadyListener((connection, stdout, stderr) -> {
|
|
|
+ ListenForErrors(stderr, (msg, exc) -> log.severe(msg));
|
|
|
+ fRefsCache = GetRefs(new ActiveSSHWrapper(connection, stdin.GetWriter(), stdout, stderr), callback);
|
|
|
+ connection.disconnect();
|
|
|
+ if (fRefsCache != null)
|
|
|
+ callback.OnResponse(fRefsCache);
|
|
|
+ })
|
|
|
+ .connect();
|
|
|
}
|
|
|
|
|
|
private byte[] PullPackData(ActiveSSHWrapper sshWrapper, String hash, OnStreamResponseListener<byte[]> listener) {
|
|
|
@@ -212,22 +217,17 @@ public class SSHGitProtocol extends BaseGitProtocol {
|
|
|
}
|
|
|
|
|
|
private void PullPackData(String hash, OnStreamResponseListener<byte[]> response) {
|
|
|
- if (fActiveConnection != null) {
|
|
|
- byte[] result = PullPackData(fActiveConnection, hash, response);
|
|
|
- response.OnResponse(result);
|
|
|
- } else {
|
|
|
- AppendableInputStream stdin = new AppendableInputStream();
|
|
|
-
|
|
|
- SSHFactory
|
|
|
- .createInstance(fRepoUrl, "git-upload-pack " + fRepoUrl.repoName)
|
|
|
- .SetOnConnectionReadyListener((connection, stdout, stderr) -> {
|
|
|
- ListenForErrors(stderr, (msg, exc) -> log.severe(msg));
|
|
|
- byte[] data = PullPackData(new ActiveSSHWrapper(connection, stdin.GetWriter(), stdout, stderr), hash, response);
|
|
|
- connection.disconnect();
|
|
|
- response.OnResponse(data);
|
|
|
- })
|
|
|
- .connect();
|
|
|
- }
|
|
|
+ AppendableInputStream stdin = new AppendableInputStream();
|
|
|
+
|
|
|
+ SSHFactory
|
|
|
+ .createInstance(fRepoUrl, "git-upload-pack " + fRepoUrl.repoName)
|
|
|
+ .SetOnConnectionReadyListener((connection, stdout, stderr) -> {
|
|
|
+ ListenForErrors(stderr, (msg, exc) -> log.severe(msg));
|
|
|
+ byte[] data = PullPackData(new ActiveSSHWrapper(connection, stdin.GetWriter(), stdout, stderr), hash, response);
|
|
|
+ connection.disconnect();
|
|
|
+ response.OnResponse(data);
|
|
|
+ })
|
|
|
+ .connect();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -258,24 +258,19 @@ public class SSHGitProtocol extends BaseGitProtocol {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- protected void PushPack(GitCommit commit, Pacman pack, OnStreamResponseListener<Void> resp) {
|
|
|
- if (fActiveConnection != null)
|
|
|
- fActiveConnection.fConnection.disconnect();
|
|
|
+ protected void PushPack(GitCommit commit, Pacman pack, String branch, OnStreamResponseListener<Void> resp) {
|
|
|
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));
|
|
|
+ ActiveSSHWrapper activeSSHWrapper = new ActiveSSHWrapper(connection, in.GetWriter(), stdout, stderr);
|
|
|
+ fRefsCache = null;
|
|
|
+ GitRef ref = GetRefFromBranchName(GetRefs(activeSSHWrapper, resp), branch);
|
|
|
ListenForErrors(stderr, (msg, e) -> resp.OnMsg(msg));
|
|
|
try {
|
|
|
OutputStream w = in.GetWriter();
|
|
|
- w.write(GitLine(ref.GetHash() + " " + GitSha1.BytesToString(GitSha1.getRawSha1OfPackable(commit)) + " " + ref.GetBranch()));
|
|
|
+ String prev = ref == null ? "0000000000000000000000000000000000000000" : ref.GetHash();
|
|
|
+ w.write(GitLine(prev + " " + GitSha1.BytesToString(GitSha1.getRawSha1OfPackable(commit)) + " " + branch));
|
|
|
w.write(GitLine(null));
|
|
|
if (!pack.Write(w)) {
|
|
|
resp.OnError("Pack error", null);
|
|
|
@@ -285,6 +280,7 @@ public class SSHGitProtocol extends BaseGitProtocol {
|
|
|
catch (IOException e) {
|
|
|
resp.OnError("Cannot write pack: " +e.getMessage(), e);
|
|
|
}
|
|
|
+ ListenForErrors(stdout, (msg, e) -> resp.OnMsg(msg), false);
|
|
|
resp.OnResponse(null);
|
|
|
})
|
|
|
.connect(in);
|
|
|
@@ -305,8 +301,8 @@ public class SSHGitProtocol extends BaseGitProtocol {
|
|
|
SSHFactory
|
|
|
.createInstance(fRepoUrl, "git-upload-pack " +fRepoUrl.repoName)
|
|
|
.SetOnConnectionReadyListener((connection, stdout, stderr) -> {
|
|
|
- fActiveConnection = new ActiveSSHWrapper(connection, stdin.GetWriter(), stdout, stderr);
|
|
|
- GitRef ref = GetHeadRef(GetRefs(fActiveConnection, response));
|
|
|
+ ActiveSSHWrapper SSHWrapper = new ActiveSSHWrapper(connection, stdin.GetWriter(), stdout, stderr);
|
|
|
+ GitRef ref = GetHeadRef(GetRefs(SSHWrapper, response));
|
|
|
if (ref == null)
|
|
|
return;
|
|
|
GetHeadCommitFromRef(ref, new OnStreamResponseListener<GitCommit>() {
|
|
|
@@ -317,19 +313,20 @@ public class SSHGitProtocol extends BaseGitProtocol {
|
|
|
|
|
|
@Override
|
|
|
public void OnResponse(GitCommit result) {
|
|
|
- fActiveConnection.fConnection.disconnect();
|
|
|
- fActiveConnection = null;
|
|
|
response.OnResponse(result);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void OnError(String msg, Throwable e) {
|
|
|
- fActiveConnection.fConnection.disconnect();
|
|
|
- fActiveConnection = null;
|
|
|
response.OnError(msg, e);
|
|
|
}
|
|
|
});
|
|
|
})
|
|
|
.connect(stdin);
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void OnBranchCreated() {
|
|
|
+ fRefsCache = null;
|
|
|
+ }
|
|
|
}
|