|
1 | 1 | package svnserver.repository.git;
|
2 | 2 |
|
3 |
| -import org.eclipse.jgit.api.Git; |
4 |
| -import org.eclipse.jgit.api.errors.GitAPIException; |
5 | 3 | import org.eclipse.jgit.internal.storage.file.FileRepository;
|
6 | 4 | import org.eclipse.jgit.lib.*;
|
7 | 5 | import org.eclipse.jgit.revwalk.RevCommit;
|
8 | 6 | import org.eclipse.jgit.revwalk.RevWalk;
|
9 |
| -import org.eclipse.jgit.transport.PushResult; |
10 |
| -import org.eclipse.jgit.transport.RefSpec; |
11 |
| -import org.eclipse.jgit.transport.RemoteRefUpdate; |
12 | 7 | import org.eclipse.jgit.treewalk.CanonicalTreeParser;
|
13 | 8 | import org.jetbrains.annotations.NotNull;
|
14 | 9 | import org.jetbrains.annotations.Nullable;
|
|
19 | 14 | import org.tmatesoft.svn.core.SVNException;
|
20 | 15 | import svnserver.StringHelper;
|
21 | 16 | import svnserver.auth.User;
|
22 |
| -import svnserver.repository.*; |
| 17 | +import svnserver.repository.VcsCommitBuilder; |
| 18 | +import svnserver.repository.VcsDeltaConsumer; |
| 19 | +import svnserver.repository.VcsFile; |
| 20 | +import svnserver.repository.VcsRepository; |
23 | 21 |
|
24 | 22 | import java.io.File;
|
25 | 23 | import java.io.IOException;
|
@@ -49,6 +47,9 @@ public class GitRepository implements VcsRepository {
|
49 | 47 | private final Map<String, int[]> lastUpdates = new ConcurrentHashMap<>();
|
50 | 48 | @NotNull
|
51 | 49 | private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
| 50 | + // Lock for prevent concurrent pushes. |
| 51 | + @NotNull |
| 52 | + private final Object pushLock = new Object(); |
52 | 53 | @NotNull
|
53 | 54 | private final String uuid;
|
54 | 55 | @NotNull
|
@@ -385,48 +386,31 @@ public void delete(@NotNull String name, @NotNull VcsFile file) throws SVNExcept
|
385 | 386 |
|
386 | 387 | @Override
|
387 | 388 | public GitRevision commit(@NotNull User userInfo, @NotNull String message) throws SVNException, IOException {
|
388 |
| - final GitTreeUpdate root = treeStack.element(); |
389 |
| - final ObjectId treeId = root.buildTree(inserter); |
390 |
| - log.info("Create tree {} for commit.", treeId.name()); |
391 |
| - |
392 |
| - final CommitBuilder commitBuilder = new CommitBuilder(); |
393 |
| - final PersonIdent ident = createIdent(userInfo); |
394 |
| - commitBuilder.setAuthor(ident); |
395 |
| - commitBuilder.setCommitter(ident); |
396 |
| - commitBuilder.setMessage(message); |
397 |
| - commitBuilder.setParentId(commit.getId()); |
398 |
| - commitBuilder.setTreeId(treeId); |
399 |
| - final ObjectId commitId = inserter.insert(commitBuilder); |
400 |
| - |
401 |
| - log.info("Create commit {}: {}", commitId.name(), message); |
402 |
| - |
403 |
| - try { |
404 |
| - log.info("Try to push commit in branch: {}", branchRef); |
405 |
| - Iterable<PushResult> results = new Git(repository) |
406 |
| - .push() |
407 |
| - .setRemote(".") |
408 |
| - .setRefSpecs(new RefSpec(commitId.name() + ":" + branchRef.getName())) |
409 |
| - .call(); |
410 |
| - for (PushResult result : results) { |
411 |
| - for (RemoteRefUpdate remoteUpdate : result.getRemoteUpdates()) { |
412 |
| - switch (remoteUpdate.getStatus()) { |
413 |
| - case REJECTED_NONFASTFORWARD: |
414 |
| - log.info("Non fast forward push rejected"); |
415 |
| - return null; |
416 |
| - case OK: |
417 |
| - break; |
418 |
| - default: |
419 |
| - log.error("Unexpected push error: {}", remoteUpdate); |
420 |
| - throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_WRITE_ERROR, remoteUpdate.toString())); |
421 |
| - } |
422 |
| - } |
| 389 | + synchronized (pushLock) { |
| 390 | + final GitTreeUpdate root = treeStack.element(); |
| 391 | + final ObjectId treeId = root.buildTree(inserter); |
| 392 | + log.info("Create tree {} for commit.", treeId.name()); |
| 393 | + |
| 394 | + final CommitBuilder commitBuilder = new CommitBuilder(); |
| 395 | + final PersonIdent ident = createIdent(userInfo); |
| 396 | + commitBuilder.setAuthor(ident); |
| 397 | + commitBuilder.setCommitter(ident); |
| 398 | + commitBuilder.setMessage(message); |
| 399 | + commitBuilder.setParentId(commit.getId()); |
| 400 | + commitBuilder.setTreeId(treeId); |
| 401 | + final ObjectId commitId = inserter.insert(commitBuilder); |
| 402 | + |
| 403 | + log.info("Create commit {}: {}", commitId.name(), message); |
| 404 | + log.info("Try to push commit in branch: {}", branchRef.getName()); |
| 405 | + if (!GitHelper.pushNative(repository, commitId, branchRef)) { |
| 406 | + log.info("Non fast forward push rejected"); |
| 407 | + return null; |
423 | 408 | }
|
424 | 409 | log.info("Commit is pushed");
|
425 |
| - } catch (GitAPIException e) { |
426 |
| - throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_WRITE_ERROR, e)); |
| 410 | + |
| 411 | + updateRevisions(); |
| 412 | + return getRevision(commitId); |
427 | 413 | }
|
428 |
| - updateRevisions(); |
429 |
| - return getRevision(commitId); |
430 | 414 | }
|
431 | 415 |
|
432 | 416 | private PersonIdent createIdent(User userInfo) {
|
|
0 commit comments