LearnGitBranching

repository·main·Indexed 11 days ago

https://github.com/pcottle/learngitbranching

An interactive Git repository simulator and educational tool version 0.8.0 that teaches Git commands through real-time tree visualization. It features structured tutorial levels, a sandbox mode for experimentation, and a Level Builder for creating custom challenges. The tool includes a GitEngine to simulate operations like commit, push, fetch, pull, revert, and cherry-pick, and supports both Git and Mercurial (hg) command processing.

Tokens
13.4K
Snippets
48
Records
73
Agent score
97%

What's inside LearnGitBranching

  1. Use Sandbox Mode to practice Git commands

    main

    Sandbox mode allows you to experiment with Git commands in a free-form environment with a basic repository already created. You can use the following special commands to manage your session:

    • undo: Undoes the effects of the last command.
    • reset: Starts over with a clean slate (this also works within specific levels).
    • git clone: Simulates remote repositories.

    This mode is ideal for demonstrating Git concepts or testing command sequences without the constraints of a specific tutorial level.

  2. How the i18n system works in learnGitBranching

    main

    The internationalization (i18n) system uses a key-based object structure to store translatable text in two primary locations:

    1. UI strings: Located in src/js/intl/strings.js. These include button labels, dialog text, and error messages.
    2. Level content: Located in src/levels/**/*.js. These include level names, hints, and tutorial dialogs.

    Each translatable entry is an object where keys represent the locale code (following the language_REGION pattern, e.g., en_US, de_DE, or just language like ko). An optional __desc__ key can be used to describe the string's purpose.

    "some-key": {
      "__desc__": "What this string is used for",
      "en_US": "English text",
      "de_DE": "Deutschsprachiger Text",
      "hu_HU": "Magyar szöveg"
    }
  3. Run LearnGitBranching via Docker

    main

    You can run the application using Docker containers.

    Run a stable image:

    docker run -p 8080:80 ghcr.io/pcottle/learngitbranching:main

    Access the app at http://localhost:8080/.

    Build a new image:

    docker build -t ghcr.io/pcottle/learngitbranching:latest .
    # Run stable image
    docker run -p 8080:80 ghcr.io/pcottle/learngitbranching:main
    
    # Build latest image
    docker build -t ghcr.io/pcottle/learngitbranching:latest .
  4. Add a new language to learnGitBranching

    main

    To add a new language, follow these four steps:

    1. Register the locale

    Edit src/js/stores/LocaleStore.js. Add your language code to langLocaleMap. Optionally, add mappings to headerLocaleMap to support browser Accept-Language headers.

    // In langLocaleMap:
    xx: 'xx_XX',
    
    // In headerLocaleMap (optional):
    'xx-XX': 'xx_XX',
    'xx': 'xx_XX',

    2. Add the UI button

    Edit src/js/react_views/IntlHelperBarView.jsx and add a new object to the getItems() array to allow users to select the language via the UI.

    }, {
      text: 'Your Language Name',
      testID: 'yourlanguage',
      onClick: function() {
        this.fireCommand('locale xx_XX; levels');
      }.bind(this)
    }, {

    3. Translate UI strings

    Edit src/js/intl/strings.js. For every existing key, add your new locale key and the translated string.

    "finish-dialog-finished": {
      "en_US": "Wow! You finished the last level, great!",
      "xx_XX": "Your translation here"
    },

    4. Translate level content

    In every file within src/levels/, add your locale to the name, hint, and startDialog fields.

    "name": {
      "en_US": "Introduction to Git Commits",
      "xx_XX": "Your translated level name"
    },
    
    "hint": {
      "en_US": "Try using git commit",
      "xx_XX": "Your translated hint"
    },
    
    "startDialog": {
      "en_US": { "childViews": [...] },
      "xx_XX": {
        "childViews": [
          {
            "type": "ModalAlert",
            "options": {
              "markdowns": [
                "## Your Translated Title",
                "Your translated paragraph text."
              ]
            }
          }
        ]
      }
    }
  5. Access and navigate Levels

    main

    Levels are structured tutorials and challenges designed to teach specific Git concepts. To interact with them:

    • Type levels in the command input to see all available lessons/challenges and track which ones you have solved.
    • Levels are organized into tabs that separate major Git concepts (e.g., local vs. remote repositories).
    • The application tracks your 'git golf' score, which is the number of commands used to solve each level.
  6. Create and share custom levels with Level Builder

    main

    You can design your own Git challenges using the built-in Level Builder:

    1. Run the build level command. A dialog will guide you through the creation process.
    2. At the end, the tool generates a JSON blob representing the level.
    3. To share/submit: Paste the JSON into a Gist or an issue.
    4. To import: Other users can run import level and paste the JSON, or use a custom URL containing a Gist ID: https://pcottle.github.io/learnGitBranching/?gist_level_id=YOUR_GIST_ID
  7. Test translations locally

    main

    Because the app loads a pre-bundled JS file from the build/ directory, you must rebuild the application every time you modify a translation file in src/ to see your changes.

    1. Build the app:
      yarn install
      yarn gulp fastBuild
    2. Start the dev server:
      yarn dev
    3. Switch to your locale in the browser by clicking the language selector or using the command line: locale xx_XX; levels.
    4. Verify by navigating levels and running the validation scripts:
      • node scripts/validate-locale.js xx_XX
      • yarn gulp lintStrings
    yarn install
    yarn gulp fastBuild
    yarn dev
  8. Share LearnGitBranching sessions via permalinks

    main

    You can share a specific state of the application by appending URL parameters. This allows a link to execute a specific set of commands automatically upon loading.

    • command: An arbitrary set of commands to execute (URL-encoded).
    • NODEMO: Disables the introductory dialog, which is useful when sharing command sequences.

    Example URL structure: https://learngitbranching.js.org/?NODEMO&command=echo%20%22hello%22;%20git%20commit

    https://learngitbranching.js.org/?NODEMO&command=echo%20%22hello%22;%20git%20commit
  9. Build and contribute to LearnGitBranching

    main

    To contribute to the core application, you must build it locally using gulp.js and yarn.

    Prerequisites:

    • gulp.js
    • yarn

    Development Workflow:

    # 1. Setup
    git clone <your fork of the repo>
    cd learnGitBranching
    yarn install
    
    # 2. Feature Development
    git checkout -b newAwesomeFeature
    # ... make changes to files like ./src/js/git/index.js ...
    
    # 3. Fast Build (skips tests and linting)
    yarn gulp fastBuild
    
    # 4. View changes
    # Open the generated index.html in your browser
    open ./index.html
    
    # 5. Final Build (runs tests and linting)
    yarn gulp build
    
    # 6. Submit
    git commit -am "My new sweet feature!"
    git push
    # Go online and request a pull
    git clone <your fork of the repo>
    cd learnGitBranching
    yarn install
    
    git checkout -b newAwesomeFeature
    # ... make changes ...
    yarn gulp fastBuild
    
    # after building you can open up your browser to the index.html
    open ./index.html
    
    # ... more changes ...
    yarn gulp build
    
    git commit -am "My new sweet feature!"
    git push
  10. Process command sequences with CommandBuffer

    main

    The CommandBuffer class is used to manage and sequence the execution of Git commands. It listens to a CommandCollection for new commands and buffers them to ensure they are processed with a delay (defined by TIME.betweenCommandsDelay).

    Key behaviors:

    • Buffering: When a command is added to the associated collection, it is pushed to the buffer and touchBuffer() is called.
    • Delayed Processing: Commands are not executed immediately. Instead, a timeout is set to process the buffer after a short delay.
    • Error Handling: During processing (popAndProcess), the buffer skips commands that have an error property set, continuing until it finds a valid command or the buffer is empty.
    • Event Integration: The buffer uses the Main.getEventBaton() to trigger the specific event associated with a command (command.get('eventName')). If no listener exists for that event, the command is marked with a GitError stating the command is not supported.
    const { CommandBuffer } = require('../js/models/collections');
    
    // Assuming commandCollection is an existing CommandCollection instance
    const buffer = new CommandBuffer({ collection: commandCollection });
    
    // The buffer will now automatically react to 'add' events on commandCollection
    // and attempt to process commands after the configured delay.
  11. Understand the Command model

    main

    The Command class is a core model in LearnGitBranching that represents an individual Git operation entered by a user. It manages the lifecycle of a command from its raw string input through parsing, validation, and execution.

    Key responsibilities include:

    • Parsing: Using a ParseWaterfall to transform raw input strings into structured data (arguments, options, etc.).
    • State Management: Tracking the command's status (e.g., inqueue, finished, error, warning), result, and any error or warnings encountered.
    • Argument Validation: Ensuring that the provided arguments match the expected bounds for specific Git methods (e.g., checking if a command has the correct number of arguments).
    • Event Emission: Emitting change events (e.g., change:error, change:status) when command attributes are updated, allowing the UI to react to command processing.
  12. Configure Level command parsing with a custom waterfall

    main

    The Level class uses a parseWaterfall to process commands. It injects specific logic at the beginning of the waterfall:

    1. parseWaterfall: Uses a regex map to process standard level commands.
    2. instantWaterfall: Provides instant commands like hint or help.
    3. disabledMap: If options.level.disabledMap is provided, it uses a DisabledMap to restrict certain commands.

    Level-specific commands handled via processLevelCommand include:

    • show goal / hide goal
    • show solution
    • start dialog / help level
    • objective