Support local-to-remote mirroring#717
Conversation
Motivation We currently support only remote-to-local mirroring. We should support the opposite direction as well. Modifications: - Implement `GitMirror#mirrorToLocalRemote()` which threw `UnsupportedOperationException` before. Result: - Close line#53 - You can now enable mirroring from Central Dogma to a remote Git server.
Codecov ReportBase: 64.95% // Head: 65.11% // Increases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## master #717 +/- ##
============================================
+ Coverage 64.95% 65.11% +0.15%
- Complexity 3227 3259 +32
============================================
Files 349 349
Lines 13474 13670 +196
Branches 1454 1485 +31
============================================
+ Hits 8752 8901 +149
- Misses 3896 3928 +32
- Partials 826 841 +15
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
ikhoon
left a comment
There was a problem hiding this comment.
Review in progress. Don't need to address the comments at the moment. I am going to review the remaining things tomorrow. Mostly looking good though. 😉
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Outdated
Show resolved
Hide resolved
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Show resolved
Hide resolved
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Outdated
Show resolved
Hide resolved
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Outdated
Show resolved
Hide resolved
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Outdated
Show resolved
Hide resolved
|
@ikhoon Addressed all the comments. 😉 |
|
The master branch is merged into the working branch to run in Apple Silicon. |
ikhoon
left a comment
There was a problem hiding this comment.
Left minor comments and questions.
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Outdated
Show resolved
Hide resolved
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Outdated
Show resolved
Hide resolved
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Outdated
Show resolved
Hide resolved
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Outdated
Show resolved
Hide resolved
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Outdated
Show resolved
Hide resolved
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Outdated
Show resolved
Hide resolved
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
If we eventually convert text into bytes, should we directly write JsonNode into bytes and use it as is? It would allocate fewer objects.
There was a problem hiding this comment.
I thought we need to convert to String first because we need to use the pretty printer. If we use bytes, the mirror repository would see something like
{"a": {"foo":"bar"}} instead of
{
"a" : {
"foo": "bar"
}
}
There was a problem hiding this comment.
I see, I think this is reasonable:
- For remote git repositories, we pretty print
- For local storage, we save the compact json
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Outdated
Show resolved
Hide resolved
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Outdated
Show resolved
Hide resolved
server/src/main/java/com/linecorp/centraldogma/server/internal/mirror/GitMirror.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
I thought we need to convert to String first because we need to use the pretty printer. If we use bytes, the mirror repository would see something like
{"a": {"foo":"bar"}} instead of
{
"a" : {
"foo": "bar"
}
}
jrhee17
left a comment
There was a problem hiding this comment.
Sorry about the late review 😅 I think this PR looks pretty much done 👍 Left some minor comments
|
|
||
| git.push() | ||
| .setRefSpecs(new RefSpec(headBranchRefName)) | ||
| .setForce(true) |
There was a problem hiding this comment.
I think this can potentially overwrite commits. (e.g. multiple local repositories are pushed to a single remote repository, mis-operation can overwrite a repository, etc..)
If there is a conflict, what do you think of just failing the current iteration and allowing to update on the next iteration of mirror?
There was a problem hiding this comment.
If there is a conflict, what do you think of just failing the current iteration and allowing to update on the next iteration of mirror?
That's a good suggestion. 👍
There was a problem hiding this comment.
minor nit; to avoid allocating an extra Stream object
| final Stream<Map.Entry<String, Entry<?>>> entryStream = | |
| localRawHeadEntries.entrySet() | |
| .stream(); | |
| if (ignoreNode == null) { | |
| // Use HashMap to manipulate it. | |
| return entryStream.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); | |
| } | |
| if (ignoreNode == null) { | |
| // Use HashMap to manipulate it. | |
| return localRawHeadEntries; | |
| } | |
| final Stream<Map.Entry<String, Entry<?>>> entryStream = localRawHeadEntries.entrySet().stream(); |
There was a problem hiding this comment.
We cannot just return localRawHeadEntries because it can be a singleton map that is not modifiable.
We do remove operation on the returned map.
There was a problem hiding this comment.
Question) Just curious, what happens if the branch doesn't exist in the remote repository? Will an exception be thrown? (as opposed to creating a branch if it doesn't exist)
I think it's fine to throw an exception, just want to make sure the behavior is known/defined.
There was a problem hiding this comment.
I actually checked and verified an exception is thrown 👍
There was a problem hiding this comment.
Thanks for checking it. 😉
There was a problem hiding this comment.
nit; technically String.length() isn't really the number of bytes (although I guess this is a more lenient upper-bound so this discrepancy isn't very critical)
There was a problem hiding this comment.
Yeah, because it's not critical let's leave it as is.
Will get back and use
reader.getObjectSize(inserted, ObjectReader.OBJ_ANY) if it becomes a problem. 😉
There was a problem hiding this comment.
Q) Is it possible to use a common method for this logic? (with storage side)
There was a problem hiding this comment.
It seems like this comment wasn't addressed. Is it possible to dedup this method?
There was a problem hiding this comment.
Ah forgot to leave a comment about this. 😄
I didn't intentionally dedup logic because of this PR #681
Let me cleanup the logic in the PR! 😉
There was a problem hiding this comment.
I see, I think this is reasonable:
- For remote git repositories, we pretty print
- For local storage, we save the compact json
There was a problem hiding this comment.
What do you think of also adding this to GitMirrorTest as well?
| " \"remoteUri\": \"" + gitUri + firstNonNull(remotePath, "") + '"' + | |
| " \"remoteUri\": \"" + gitUri + firstNonNull(remotePath, "") + '"' + | |
| " \"schedule\": \"0 0 0 1 1 ? 2099\"," + |
There was a problem hiding this comment.
It seems like this comment wasn't addressed. Is it possible to dedup this method?
Motivation
We currently support only remote-to-local mirroring. We should support the opposite direction as well.
Modifications:
GitMirror#mirrorToLocalRemote()which used to throwUnsupportedOperationExceptionbefore.Result: