diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml
deleted file mode 100644
index 27bcee3f..00000000
--- a/.github/release-drafter.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-template: |
- ## What’s Changed
-
- $CHANGES
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 9672bd85..b521865d 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -21,10 +21,16 @@ jobs:
java-version: '11.x'
- name: 🪦 Install node.js packages
run: npm install
+ - name: 🚮 Remove current git
+ run: sudo apt-get remove git git-man
+ - name: Add repo
+ run: sudo add-apt-repository --remove --yes ppa:git-core/ppa
- name: Update platform
run: sudo apt-get update
+ - name: Upgrade platform
+ run: sudo apt-get upgrade
- name: Install git-svn
- run: sudo apt-get install git-svn
+ run: sudo apt-get install --yes git git-svn
- name: 🔍 Analyze code with SonarQube
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -44,3 +50,5 @@ jobs:
GIT_TAG=:${GITHUB_REF#refs/tags/}
DOCKER_TAG=${GIT_TAG#:refs/heads/main}
./mvnw -ntp jib:build -Djib.to.image=yodamad/svn2git:latest -Djib.to.auth.username="${{ secrets.DOCKERHUB_LOGIN }}" -Djib.to.auth.password="${{ secrets.DOCKERHUB_PWD }}"
+ VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
+ ./mvnw -ntp jib:build -Djib.to.image=yodamad/svn2git:$VERSION -Djib.to.auth.username="${{ secrets.DOCKERHUB_LOGIN }}" -Djib.to.auth.password="${{ secrets.DOCKERHUB_PWD }}"
diff --git a/pom.xml b/pom.xml
index bef20e4a..fc6095de 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
fr.yodamad.svn2git
svn-2-git
- 2.1.0
+ 2.1.1
jar
Svn 2 GitLab
diff --git a/src/main/java/fr/yodamad/svn2git/config/ApplicationProperties.java b/src/main/java/fr/yodamad/svn2git/config/ApplicationProperties.java
index 8d56ba39..7db209b9 100644
--- a/src/main/java/fr/yodamad/svn2git/config/ApplicationProperties.java
+++ b/src/main/java/fr/yodamad/svn2git/config/ApplicationProperties.java
@@ -128,6 +128,11 @@ public static class Svn {
*/
public String svnUrlModifiable;
+ /**
+ * Max attempts of git-svn fetch before failing migration
+ */
+ public Integer maxFetchAttempts;
+
public String getUser() {
return user;
}
@@ -167,6 +172,10 @@ public String getSvnUrlModifiable() {
public void setSvnUrlModifiable(String svnUrlModifiable) {
this.svnUrlModifiable = svnUrlModifiable;
}
+
+ public Integer getMaxFetchAttempts() { return maxFetchAttempts; }
+
+ public void setMaxFetchAttempts(Integer maxFetchAttempts) { this.maxFetchAttempts = maxFetchAttempts; }
}
public static class Gitlab {
diff --git a/src/main/java/fr/yodamad/svn2git/domain/Migration.java b/src/main/java/fr/yodamad/svn2git/domain/Migration.java
index 5577e82f..bb24b6ad 100644
--- a/src/main/java/fr/yodamad/svn2git/domain/Migration.java
+++ b/src/main/java/fr/yodamad/svn2git/domain/Migration.java
@@ -146,6 +146,10 @@ public class Migration implements Serializable {
@JsonView(View.Public.class)
private String uploadType;
+ @Column(name = "emptydirs")
+ @JsonView(View.Public.class)
+ private Boolean emptyDirs = false;
+
@OneToMany(mappedBy = "migration")
@OrderBy("id ASC")
private Set histories = new HashSet<>();
@@ -530,6 +534,10 @@ public void setFlat(Boolean flat) {
public void setUploadType(String uploadType) { this.uploadType = uploadType; }
+ public Boolean getEmptyDirs() { return emptyDirs; }
+
+ public void setEmptyDirs(Boolean emptyDirs) { this.emptyDirs = emptyDirs; }
+
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
@Override
diff --git a/src/main/java/fr/yodamad/svn2git/domain/enumeration/StepEnum.java b/src/main/java/fr/yodamad/svn2git/domain/enumeration/StepEnum.java
index c669259d..88ca58b7 100644
--- a/src/main/java/fr/yodamad/svn2git/domain/enumeration/StepEnum.java
+++ b/src/main/java/fr/yodamad/svn2git/domain/enumeration/StepEnum.java
@@ -7,5 +7,5 @@ public enum StepEnum {
GIT_CLONE, GITLAB_PROJECT_CREATION, SVN_CHECKOUT, GIT_CLEANING, GIT_PUSH, CLEANING, GIT_MV, INIT, BRANCH_CLEAN,
TAG_CLEAN, README_MD, GIT_CONFIG_GC_AUTO_OFF, GIT_CONFIG_GLOBAL_GC_AUTO_OFF, GIT_GC_EXPLICIT,
GIT_DYNAMIC_LOCAL_CONFIG, GIT_SHOW_CONFIG, LIST_REMOVED_FILES, UPLOAD_TO_ARTIFACTORY, ARTIFACTORY_FOLDER_CLEANING,
- SVN_COPY_ROOT_FOLDER, ULIMIT, GIT_SET_CONFIG, UPLOAD_TO_GITLAB, UPLOAD_TO_NEXUS
+ SVN_COPY_ROOT_FOLDER, ULIMIT, GIT_SET_CONFIG, UPLOAD_TO_GITLAB, UPLOAD_TO_NEXUS, SVN_FETCH, GIT_GC
}
diff --git a/src/main/kotlin/fr/yodamad/svn2git/service/GitManager.kt b/src/main/kotlin/fr/yodamad/svn2git/service/GitManager.kt
index f9549063..c51cedf7 100644
--- a/src/main/kotlin/fr/yodamad/svn2git/service/GitManager.kt
+++ b/src/main/kotlin/fr/yodamad/svn2git/service/GitManager.kt
@@ -96,10 +96,76 @@ open class GitManager(val historyMgr: HistoryManager,
val history = historyMgr.startStep(workUnit.migration, StepEnum.SVN_CHECKOUT,
(if (workUnit.commandManager.isFirstAttemptMigration) "" else Constants.REEXECUTION_SKIPPING) + safeCommand)
// Only Clone if first attempt at migration
+ var cloneOK = true
if (workUnit.commandManager.isFirstAttemptMigration) {
- execCommand(workUnit.commandManager, workUnit.root, cloneCommand, safeCommand)
+ try {
+ execCommand(workUnit.commandManager, workUnit.root, cloneCommand, safeCommand)
+ } catch (thr: Throwable) {
+ LOG.warn("Cannot git svn clone", thr.message)
+ cloneOK = false
+ var round = 0
+ var notOk = true
+ while (round++ < applicationProperties.svn.maxFetchAttempts && notOk) {
+ notOk = gitSvnFetch(workUnit, round)
+ gitGC(workUnit, round)
+ }
+ }
+ }
+ if (cloneOK) {
+ historyMgr.endStep(history, StatusEnum.DONE, null)
+ } else {
+ historyMgr.endStep(history, StatusEnum.DONE_WITH_WARNINGS, null)
+ }
+ }
+
+ /**
+ * Git svn fetch command to copy svn as git repository
+ *
+ * @param workUnit Current work unit
+ * @param round Round number
+ * @return if fetch is in failure or not
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ @Throws(IOException::class, InterruptedException::class)
+ open fun gitSvnFetch(workUnit: WorkUnit, round: Int) : Boolean {
+ val fetchCommand = "git svn fetch";
+
+ val history = historyMgr.startStep(workUnit.migration, StepEnum.SVN_FETCH, "Round $round : $fetchCommand")
+ return try {
+ execCommand(workUnit.commandManager, workUnit.directory, fetchCommand)
+ historyMgr.endStep(history, StatusEnum.DONE, null)
+ false
+ } catch (thr: Throwable) {
+ LOG.error("Cannot git svn fetch", thr.printStackTrace())
+ historyMgr.endStep(history, StatusEnum.FAILED, null)
+ true
+ }
+ }
+
+ /**
+ * Git gc command to cleanup unnecessary files and optimize the local repository
+ *
+ * @param workUnit Current work unit
+ * @param round Round number
+ * @return if fetch is in failure or not
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ @Throws(IOException::class, InterruptedException::class)
+ open fun gitGC(workUnit: WorkUnit, round: Int) : Boolean {
+ val gcCommand = "git gc";
+
+ val history = historyMgr.startStep(workUnit.migration, StepEnum.GIT_GC, "Round $round : $gcCommand")
+ return try {
+ execCommand(workUnit.commandManager, workUnit.directory, gcCommand)
+ historyMgr.endStep(history, StatusEnum.DONE, null)
+ false
+ } catch (thr: Throwable) {
+ LOG.error("Cannot git gc", thr.printStackTrace())
+ historyMgr.endStep(history, StatusEnum.FAILED, null)
+ true
}
- historyMgr.endStep(history, StatusEnum.DONE, null)
}
/**
diff --git a/src/main/kotlin/fr/yodamad/svn2git/service/util/GitCommandManager.kt b/src/main/kotlin/fr/yodamad/svn2git/service/util/GitCommandManager.kt
index 84233141..b6f4e325 100644
--- a/src/main/kotlin/fr/yodamad/svn2git/service/util/GitCommandManager.kt
+++ b/src/main/kotlin/fr/yodamad/svn2git/service/util/GitCommandManager.kt
@@ -47,7 +47,8 @@ open class GitCommandManager(val historyMgr: HistoryManager,
setSvnElement("branches", workUnit.migration.branches, workUnit),
setSvnElement("tags", workUnit.migration.tags, workUnit),
ignorePaths, ignoreRefs,
- if (applicationProperties.getFlags().isGitSvnClonePreserveEmptyDirsOption) "--preserve-empty-dirs" else EMPTY,
+ if (workUnit.migration.emptyDirs) "--preserve-empty-dirs"
+ else if (workUnit.migration.emptyDirs == null && applicationProperties.getFlags().isGitSvnClonePreserveEmptyDirsOption) "--preserve-empty-dirs" else EMPTY,
if (workUnit.migration.svnUrl.endsWith("/")) workUnit.migration.svnUrl else "${workUnit.migration.svnUrl}/",
workUnit.migration.svnGroup)
diff --git a/src/main/kotlin/fr/yodamad/svn2git/web/rest/GitlabResource.kt b/src/main/kotlin/fr/yodamad/svn2git/web/rest/GitlabResource.kt
index 94d1997a..3bbb00ab 100644
--- a/src/main/kotlin/fr/yodamad/svn2git/web/rest/GitlabResource.kt
+++ b/src/main/kotlin/fr/yodamad/svn2git/web/rest/GitlabResource.kt
@@ -103,7 +103,7 @@ open class GitlabResource(val gitlabAdmin: GitlabAdmin,
.findAny()
if (subgroup.isPresent) {
if (cycle == depth - 1) {
- return checkUserForProject(user!!, group, gitlab)
+ return checkUserForProject(user!!, subgroup, gitlab)
}
cycle++
groupId = subgroup.get().id
diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml
index 605bde22..31a2d687 100644
--- a/src/main/resources/config/application.yml
+++ b/src/main/resources/config/application.yml
@@ -155,6 +155,7 @@ application:
password:
credentials: required
svnUrlModifiable: true
+ maxFetchAttempts: 20
override:
extensions: false
mappings: false
diff --git a/src/main/resources/config/liquibase/changelog/2021031721150000_added_Migration_emptydirs_column.xml b/src/main/resources/config/liquibase/changelog/2021031721150000_added_Migration_emptydirs_column.xml
new file mode 100644
index 00000000..c20b44e9
--- /dev/null
+++ b/src/main/resources/config/liquibase/changelog/2021031721150000_added_Migration_emptydirs_column.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/config/liquibase/master.xml b/src/main/resources/config/liquibase/master.xml
index f8af392b..0dd0e85a 100644
--- a/src/main/resources/config/liquibase/master.xml
+++ b/src/main/resources/config/liquibase/master.xml
@@ -27,5 +27,6 @@
+
diff --git a/src/main/webapp/app/entities/migration/migration-update.component.html b/src/main/webapp/app/entities/migration/migration-update.component.html
index f386509c..ff69771c 100644
--- a/src/main/webapp/app/entities/migration/migration-update.component.html
+++ b/src/main/webapp/app/entities/migration/migration-update.component.html
@@ -165,7 +165,7 @@
+ [(ngModel)]="migration.emptyDirs" />
diff --git a/src/main/webapp/app/migration/migration-stepper.component.ts b/src/main/webapp/app/migration/migration-stepper.component.ts
index a2d89c4a..846fdc1c 100644
--- a/src/main/webapp/app/migration/migration-stepper.component.ts
+++ b/src/main/webapp/app/migration/migration-stepper.component.ts
@@ -573,9 +573,9 @@ export class MigrationStepperComponent implements OnInit {
console.log(this.mig.maxFileSize);
}
if (this.preserveEmptyDirs !== undefined) {
- this.mig.preserveEmptyDirs = this.preserveEmptyDirs;
+ this.mig.emptyDirs = this.preserveEmptyDirs;
} else {
- this.mig.preserveEmptyDirs = false;
+ this.mig.emptyDirs = false;
}
if (this.staticExtensions !== undefined && this.staticExtensions.length > 0) {
const values: string[] = [];
diff --git a/src/main/webapp/app/shared/model/migration.model.ts b/src/main/webapp/app/shared/model/migration.model.ts
index 660879ef..93bc1ece 100644
--- a/src/main/webapp/app/shared/model/migration.model.ts
+++ b/src/main/webapp/app/shared/model/migration.model.ts
@@ -40,7 +40,7 @@ export interface IMigration {
branchesToMigrate?: string;
createdTimestamp?: Moment;
workingDirectory?: string;
- preserveEmptyDirs?: boolean;
+ emptyDirs?: boolean;
histories?: IMigrationHistory[];
mappings?: IMapping[];
flat?: boolean;
@@ -72,12 +72,12 @@ export class Migration implements IMigration {
public branchesToMigrate?: string,
public createdTimestamp?: Moment,
public workingDirectory?: string,
- public preserveEmptyDirs?: boolean,
+ public emptyDirs?: boolean,
public histories?: IMigrationHistory[],
public mappings?: IMapping[],
public flat?: boolean,
public uploadType?: string
) {
- this.preserveEmptyDirs = this.preserveEmptyDirs || false;
+ this.emptyDirs = this.emptyDirs || false;
}
}