Git Integration =============== Raisin provides powerful Git integration commands to manage multiple repositories in your project workspace. These commands help you keep all your source repositories synchronized and properly configured. Overview -------- The Git integration features allow you to: * Check the status of all repositories in your workspace * Pull updates from remote repositories * Configure remotes for all repositories at once * Track synchronization state across multiple remotes All git commands automatically discover repositories in: 1. The project root directory (if it's a git repository) 2. All subdirectories under ``src/`` that contain a ``.git`` folder Git Commands ------------ git status ^^^^^^^^^^ **Command:** .. code-block:: shell python raisin.py git status **Description:** Fetches and displays a detailed synchronization status for all local repositories. This command provides a comprehensive view of how each repository compares to its remote counterparts. **What it does:** 1. Discovers all git repositories in the current directory and ``src/`` 2. For each repository, fetches the latest data from all remotes 3. Compares the local branch with each remote's corresponding branch 4. Displays a formatted table showing: * Repository name * Current branch * Status for each remote (synced, ahead, behind, or diverged) * Commit count differences **Output format:** The status display shows repositories grouped and sorted by owner, with color-coded status indicators: * **Synced (✅)** - Local branch matches the remote * **Ahead (⬆️ N)** - Local has N commits not yet pushed * **Behind (⬇️ N)** - Remote has N commits not yet pulled * **Diverged** - Local and remote have different commits * **No remote** - The branch doesn't exist on that remote **Example output:** .. code-block:: text 🔍 Scanning for git repositories... Found 5 repositories. 📦 owner1/project_a Branch: main origin: ✅ Synced 📦 owner1/project_b Branch: develop origin: ⬆️ 3 ahead upstream: ✅ Synced 📦 owner2/project_c Branch: main origin: ⬇️ 2 behind fork: ⬆️ 1 ahead git pull ^^^^^^^^ **Command:** .. code-block:: shell python raisin.py git pull [remote] **Description:** Pulls changes for all local repositories from the specified remote. This command helps you quickly update all repositories in your workspace. **Parameters:** * ``remote`` (optional) - The name of the remote to pull from. Defaults to ``'origin'`` if not specified. **What it does:** 1. Discovers all git repositories in the current directory and ``src/`` 2. For each repository: a. Fetches updates from the specified remote b. Attempts to pull changes for the current branch c. Reports success or failure 3. Provides a summary of all pull operations **Output format:** .. code-block:: text --- Pull Summary --- ✅ project_a: Successfully pulled from origin ✅ project_b: Successfully pulled from origin ⚠️ project_c: Failed to pull (merge conflict) **Usage examples:** .. code-block:: shell # Pull from the default 'origin' remote python raisin.py git pull # Pull from an 'upstream' remote python raisin.py git pull upstream # Pull from a custom remote python raisin.py git pull raion **Important notes:** * This command will fail gracefully if there are merge conflicts * It does not automatically resolve conflicts - you must resolve them manually * The command uses authentication from ``configuration_setting.yaml`` for private repositories * Only works with HTTPS remotes when using token authentication git setup ^^^^^^^^^ **Command:** .. code-block:: shell python raisin.py git setup [remote:user ...] **Description:** Clears all existing remotes and sets up new ones for all repositories in ``src/``. This command is particularly useful when you need to reconfigure remotes across multiple repositories, such as when forking projects or changing organizational structure. **Parameters:** * ```` - One or more remote specifications in the format ``remotename:username`` * ``remotename`` - The name of the remote (e.g., ``origin``, ``upstream``, ``fork``) * ``username`` - The GitHub username or organization name **What it does:** 1. Scans all subdirectories in ``src/`` for git repositories 2. For each repository: a. Discovers the actual GitHub repository name from the existing ``origin`` remote URL b. **Removes all existing remotes** (this is a destructive operation) c. Adds new remotes based on the provided specifications d. Constructs remote URLs using SSH format: ``git@github.com:username/reponame.git`` 3. Reports success or failure for each repository **URL format:** All remotes are configured using SSH URLs in the format: .. code-block:: text git@github.com:/.git **Usage examples:** **Example 1: Single remote** Set up only an ``origin`` remote pointing to ``myusername``: .. code-block:: shell python raisin.py git setup origin:myusername Result for a repository named ``project_a``: .. code-block:: text origin -> git@github.com:myusername/project_a.git **Example 2: Multiple remotes** Set up ``origin`` pointing to your fork and ``upstream`` pointing to the original: .. code-block:: shell python raisin.py git setup origin:myusername upstream:originalorg Results: .. code-block:: text origin -> git@github.com:myusername/project_a.git upstream -> git@github.com:originalorg/project_a.git **Example 3: Organization remotes** Set up remotes for organization collaboration: .. code-block:: shell python raisin.py git setup origin:raisim raion:raionrobotics Results: .. code-block:: text origin -> git@github.com:raisim/project_a.git raion -> git@github.com:raionrobotics/project_a.git **Output format:** .. code-block:: text Scanning for git repositories in '/path/to/project/src'... --- Configuring repository: project_a --- Discovered GitHub repository name: 'project_a' Removing all existing remotes... Removed remote: origin Adding remote 'origin' -> git@github.com:myusername/project_a.git Adding remote 'upstream' -> git@github.com:originalorg/project_a.git --- Configuring repository: project_b --- Discovered GitHub repository name: 'project_b' ... **Important warnings:** .. warning:: This command is **destructive**! It removes ALL existing remotes before adding new ones. Make sure you have the correct remote specifications before running this command. .. warning:: This command uses SSH URLs. Ensure your SSH keys are properly configured with GitHub before using this command. See `GitHub's SSH key documentation `_ for setup instructions. **Common use cases:** 1. **After forking repositories**: Reconfigure remotes to point to your fork as ``origin`` and the original as ``upstream`` 2. **Changing organizations**: Update all remotes when transferring projects between organizations 3. **Standardizing remote names**: Ensure all repositories use consistent remote naming conventions 4. **Team onboarding**: Quickly configure a new developer's workspace with the correct remotes **Troubleshooting:** **Problem**: "Could not discover GitHub repository name" **Solution**: The command couldn't parse the existing ``origin`` remote URL. This can happen if: * The repository has no ``origin`` remote * The ``origin`` URL is not a GitHub URL * The URL format is non-standard **Problem**: "Failed to add remote" **Solution**: Check that: * Your SSH keys are properly configured with GitHub * The repository exists at the specified username/organization * You have network connectivity to GitHub **Problem**: "Permission denied (publickey)" **Solution**: Your SSH keys are not properly configured. Follow GitHub's guide to add your SSH key to your GitHub account. Authentication -------------- Git commands that access remote repositories (``git status``, ``git pull``) use token authentication for HTTPS URLs. **Configuration:** Tokens are configured in ``configuration_setting.yaml``: .. code-block:: yaml gh_tokens: github.com: "ghp_xxxxxxxxxxxxxxxxxxxx" your-org: "ghp_yyyyyyyyyyyyyyyyyyyy" **Token requirements:** * Tokens must have appropriate scopes: * ``repo`` - For accessing private repositories * ``read:org`` - For accessing organization repositories (if applicable) **SSH vs HTTPS:** * ``git setup`` command uses **SSH URLs** (``git@github.com:...``) * ``git status`` and ``git pull`` can work with both SSH and HTTPS * Token authentication only applies to HTTPS URLs * SSH authentication uses your SSH keys Best Practices -------------- 1. **Regular status checks**: Run ``git status`` frequently to stay aware of synchronization state 2. **Pull before pushing**: Always run ``git pull`` before pushing to avoid merge conflicts 3. **Consistent naming**: Use standard remote names (``origin``, ``upstream``, ``fork``) across all repositories 4. **Backup before setup**: The ``git setup`` command is destructive - ensure you have backups or know your remote URLs 5. **Use SSH for write operations**: SSH is more secure and convenient for push operations 6. **Keep tokens secure**: Never commit ``configuration_setting.yaml`` to version control Workflow Examples ----------------- **Daily development workflow:** .. code-block:: shell # Check status of all repositories python raisin.py git status # Pull latest changes python raisin.py git pull # ... make your changes ... # Check status again before committing python raisin.py git status **Setting up a new workspace:** .. code-block:: shell # Clone the main project git clone git@github.com:myorg/main-project.git cd main-project # Set up remotes for all repositories in src/ python raisin.py git setup origin:myusername upstream:myorg # Pull all latest changes python raisin.py git pull **Contributing to open source:** .. code-block:: shell # Fork all repositories, then configure remotes python raisin.py git setup origin:myusername upstream:original-org # Create feature branch in each repo (manual) # Make changes # Push to your fork # Create pull requests to upstream **Working with multiple organizations:** .. code-block:: shell # Set up multiple remotes python raisin.py git setup origin:myusername company:mycompany upstream:original-org # Check status across all remotes python raisin.py git status # Pull from company remote python raisin.py git pull company