diff --git a/CHANGELOG.md b/CHANGELOG.md
index a83211896256b0101746b3cd611673213b02a8b5..faa668e6461481db7ee0c4dfe9aee378ecba85bb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,8 +17,20 @@
 - No modifications / Keep major and minors versions in sync with all parts of the project
 -->
 
+## 3.2.0 (???)
 
-## 3.1.0 (???)
+### ✨ Feature
+- **AssignmentCheck**: Add linter for help improve the quality of the assignment (the linter will not throw errors but warnings)
+- **CLI**: Add possibility to clone a repository at creation
+
+### 🤏 Minor change
+- **Exercices**: Set names of students in exercise name in alphabetical order
+
+### 🐛 Bugfix
+- **CLI**: Show a correct error message when the user is not logged into the Dojo server
+
+
+## 3.1.0 (2023-12-06)
 
 ### 🔨 Internal / Developers
 - **Typescript**: Add linter (ESLint)
diff --git a/NodeApp/package-lock.json b/NodeApp/package-lock.json
index 348f49dc0943f7978b4999de37c5f06c5b0199e7..22d254cfdbd40a28109101927822f7b1d437a9c1 100644
--- a/NodeApp/package-lock.json
+++ b/NodeApp/package-lock.json
@@ -1,12 +1,12 @@
 {
     "name": "dojo_cli",
-    "version": "3.1.2",
+    "version": "3.2.0",
     "lockfileVersion": 3,
     "requires": true,
     "packages": {
         "": {
             "name": "dojo_cli",
-            "version": "3.1.2",
+            "version": "3.2.0",
             "license": "AGPLv3",
             "dependencies": {
                 "ajv": "^8.12.0",
diff --git a/NodeApp/package.json b/NodeApp/package.json
index 1b72e69833e4ed195b6c76fc52eb8c798cb2f0f7..9090367219b7b21fd7593169c4ba608a473d9258 100644
--- a/NodeApp/package.json
+++ b/NodeApp/package.json
@@ -1,7 +1,7 @@
 {
     "name"           : "dojo_cli",
     "description"    : "CLI of the Dojo project",
-    "version"        : "3.1.2",
+    "version"        : "3.2.0",
     "license"        : "AGPLv3",
     "author"         : "Michaël Minelli <dojo@minelli.me>",
     "main"           : "dist/app.js",
diff --git a/NodeApp/src/commander/assignment/subcommands/AssignmentCreateCommand.ts b/NodeApp/src/commander/assignment/subcommands/AssignmentCreateCommand.ts
index 623f9b64116a5229814aa481de7087914ed7b82d..3429b7518bb8694b892f2037f1ed138b163b28e9 100644
--- a/NodeApp/src/commander/assignment/subcommands/AssignmentCreateCommand.ts
+++ b/NodeApp/src/commander/assignment/subcommands/AssignmentCreateCommand.ts
@@ -1,12 +1,12 @@
 import CommanderCommand   from '../../CommanderCommand';
 import chalk              from 'chalk';
 import ora                from 'ora';
-import GitlabManager      from '../../../managers/GitlabManager';
+import AccessesHelper     from '../../../helpers/AccessesHelper';
+import Assignment         from '../../../sharedByClients/models/Assignment';
 import GitlabUser         from '../../../shared/types/Gitlab/GitlabUser';
+import GitlabManager      from '../../../managers/GitlabManager';
 import DojoBackendManager from '../../../managers/DojoBackendManager';
 import Toolbox            from '../../../shared/helpers/Toolbox';
-import AccessesHelper     from '../../../helpers/AccessesHelper';
-import Assignment         from '../../../sharedByClients/models/Assignment';
 
 
 class AssignmentCreateCommand extends CommanderCommand {
@@ -19,12 +19,14 @@ class AssignmentCreateCommand extends CommanderCommand {
         .option('-i, --members_id <ids...>', 'list of gitlab members ids (teaching staff) to add to the repository')
         .option('-u, --members_username <usernames...>', 'list of gitlab members username (teaching staff) to add to the repository')
         .option('-t, --template <string>', 'id or url of the template (http/s and ssh urls are possible)')
+        .option('-c, --clone [string]', 'automatically clone the repository (SSH required) in the specified directory (this will create a subdirectory with the assignment name)')
         .action(this.commandAction.bind(this));
     }
 
-    protected async commandAction(options: { name: string, template?: string, members_id?: Array<number>, members_username?: Array<string> }): Promise<void> {
+    protected async commandAction(options: { name: string, template?: string, members_id?: Array<number>, members_username?: Array<string>, clone?: string | boolean }): Promise<void> {
         let members!: Array<GitlabUser> | false;
         let templateIdOrNamespace: string | null = null;
+        let assignment!: Assignment;
 
         // Check access and retrieve data
         {
@@ -64,7 +66,7 @@ class AssignmentCreateCommand extends CommanderCommand {
             console.log(chalk.cyan('Please wait while we are creating the assignment (approximately 10 seconds)...'));
 
             try {
-                const assignment: Assignment = await DojoBackendManager.createAssignment(options.name, members, templateIdOrNamespace);
+                assignment = await DojoBackendManager.createAssignment(options.name, members, templateIdOrNamespace);
 
                 const oraInfo = (message: string) => {
                     ora({
@@ -81,6 +83,15 @@ class AssignmentCreateCommand extends CommanderCommand {
                 return;
             }
         }
+
+        // Clone the repository
+        {
+            if ( options.clone ) {
+                console.log(chalk.cyan('Please wait while we are cloning the repository...'));
+
+                await GitlabManager.cloneRepository(options.clone, assignment.gitlabCreationInfo.ssh_url_to_repo, undefined, true, 0);
+            }
+        }
     }
 }
 
diff --git a/NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts b/NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts
index 9660a3e753c67c3e2c590c39cef4adae763a3e9f..c728d5ab785878da794fe70c665874cfc6da81a9 100644
--- a/NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts
+++ b/NodeApp/src/commander/exercise/subcommands/ExerciseCreateCommand.ts
@@ -18,12 +18,14 @@ class ExerciseCreateCommand extends CommanderCommand {
         .requiredOption('-a, --assignment <value>', 'assignment source (Dojo assignment ID, Dojo assignment name or Gitlab assignment URL)')
         .option('-i, --members_id <ids...>', 'list of gitlab members ids (group\'s student) to add to the repository')
         .option('-u, --members_username <usernames...>', 'list of gitlab members username (group\'s student) to add to the repository')
+        .option('-c, --clone [string]', 'automatically clone the repository (SSH required) in the specified directory (this will create a subdirectory with the assignment name)')
         .action(this.commandAction.bind(this));
     }
 
-    protected async commandAction(options: { assignment: string, members_id?: Array<number>, members_username?: Array<string> }): Promise<void> {
+    protected async commandAction(options: { assignment: string, members_id?: Array<number>, members_username?: Array<string>, clone?: string | boolean }): Promise<void> {
         let members!: Array<GitlabUser> | false;
         let assignment!: Assignment | undefined;
+        let exercise!: Exercise;
 
         // Check access and retrieve data
         {
@@ -66,7 +68,7 @@ class ExerciseCreateCommand extends CommanderCommand {
             console.log(chalk.cyan('Please wait while we are creating the exercise (approximately 10 seconds)...'));
 
             try {
-                const exercise: Exercise = await DojoBackendManager.createExercise((assignment as Assignment).name, members);
+                exercise = await DojoBackendManager.createExercise((assignment as Assignment).name, members);
 
                 const oraInfo = (message: string) => {
                     ora({
@@ -84,6 +86,15 @@ class ExerciseCreateCommand extends CommanderCommand {
                 return;
             }
         }
+
+        // Clone the repository
+        {
+            if ( options.clone ) {
+                console.log(chalk.cyan('Please wait while we are cloning the repository...'));
+
+                await GitlabManager.cloneRepository(options.clone, assignment.gitlabCreationInfo.ssh_url_to_repo, `DojoExercise - ${ exercise.assignmentName }`, true, 0);
+            }
+        }
     }
 }
 
diff --git a/NodeApp/src/managers/GitlabManager.ts b/NodeApp/src/managers/GitlabManager.ts
index 67de5c9dad4cfe101e7c270410bd80448b9e727e..356d9e26d61f1e55a591be9e6c811271c9ef8323 100644
--- a/NodeApp/src/managers/GitlabManager.ts
+++ b/NodeApp/src/managers/GitlabManager.ts
@@ -4,6 +4,8 @@ import GitlabUser       from '../shared/types/Gitlab/GitlabUser';
 import GitlabRoute      from '../shared/types/Gitlab/GitlabRoute';
 import SharedConfig     from '../shared/config/SharedConfig';
 import GitlabRepository from '../shared/types/Gitlab/GitlabRepository';
+import fs               from 'fs-extra';
+import { spawn }        from 'child_process';
 
 
 class GitlabManager {
@@ -179,6 +181,44 @@ class GitlabManager {
 
         return members;
     }
+
+    public async cloneRepository(clonePath: string | boolean, repositorySshUrl: string, folderName?: string, verbose: boolean = false, verboseIndent: number = 0) {
+        let path = './';
+        if ( typeof clonePath === 'string' ) {
+            path = clonePath;
+
+            fs.mkdirSync(path, { recursive: true });
+        }
+
+        let cloningSpinner!: ora.Ora;
+        if ( verbose ) {
+            cloningSpinner = ora({
+                                     text  : 'Cloning the repository...',
+                                     indent: verboseIndent
+                                 }).start();
+        }
+
+        try {
+            await new Promise<void>((resolve, reject) => {
+                const gitClone = spawn(`git clone ${ repositorySshUrl } "${ folderName ?? '' }"`, {
+                    cwd  : path,
+                    shell: true
+                });
+
+                gitClone.on('exit', (code) => {
+                    code !== null && code == 0 ? resolve() : reject();
+                });
+            });
+
+            if ( verbose ) {
+                cloningSpinner.succeed('Repository cloned');
+            }
+        } catch ( error ) {
+            if ( verbose ) {
+                cloningSpinner.fail('Error while cloning the repository');
+            }
+        }
+    }
 }