.. index:: git local repository version control .. _`sec:local_repository`: Local repository ---------------- The ubiquitous `version control `_ tool is ``git``. Install ``git`` on your machine and run the configuration: .. code-block:: console $ git config Create a Local Repository ^^^^^^^^^^^^^^^^^^^^^^^^^ ``uv`` automatically initializes a local git repository when a project is initialized with ``uv init``. Notice the ``.git`` and ``.gitignore`` in the project folder. The first is automatically handled with git commands, the second can be directly edited manually, more on that later. To initialize a local repo in an existing project: .. code-block:: console $ cd my-project $ git init Staging Area (Index) ^^^^^^^^^^^^^^^^^^^^ To display the status of the files: .. code-block:: console $ git status Concept of staging using ``git add`` before committing: Git uses a two-step commit process. First, you **stage** changes using: .. code-block:: console $ git add file_to_stage This command places the changes into the *staging area* (also known as the *index*), preparing them to be included in the next commit. The staging area allows you to group changes meaningfully before committing, giving you full control over what becomes part of your project history. To stage every file which has changed: .. code-block:: console $ git add . To avoid keeping track of some undesired files (private, temporary, etc), a ``.gitignore`` file can be added. The package management tool populates this file automatically, however one can add his own exclusions. Commits ^^^^^^^ Recording changes with ``git commit``. A commit saves a snapshot of all files currently staged. It includes a message, the author's identity, a timestamp, and a unique hash identifier. To create a commit: .. code-block:: console $ git commit This will open your configured text editor where you should write a clear and descriptive message. Commit message guidelines: + Use the imperative mood (*"Fix bug"*, not *"Fixed bug"*) + First line should be concise (≤50 characters) + Optionally add a detailed explanation after a blank line To give a special name to a commit (by default the last): .. code-block:: console $ git commit TAG_NAME To stage and commit in a single action all tracked files: .. code-block:: console $ git commit -a Branches ^^^^^^^^ Creating and switching **branches**. Branches let you isolate changes from the main branch. Create a new branch: .. code-block:: console $ git branch new_feature Switch to the branch: .. code-block:: console $ git switch new_feature .. note:: You must commit or stash your changes before switching branches, or Git will block the switch to prevent potential loss. Use branches for developing features, experimenting, or fixing bugs independently from the main branch. Merging and Conflict Resolution ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Merging branches. Once a feature branch is complete (and committed), it can be **merged** back into the main branch. .. code-block:: console $ git switch main $ git merge new_feature If both branches changed the same part of the same file, a **merge conflict** will occur. Git will mark the conflict using these markers in the affected files: .. code-block:: console <<<<<<< HEAD Current branch content ======= Incoming branch content >>>>>>> new_feature After manually editing the file to resolve the conflict, you must stage and commit the resolved version. After a merge, a branch can (and should) be deleted to keep the branch tree clean: .. code-block:: console $ git branch -d new_feature Log, Diff, and Commit Hashes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Viewing commit history. The Git log displays previous commits: .. code-block:: console $ git log This includes by default: - Commit hash (a unique SHA-1 identifier, e.g., ``e3f1e4d``) - Author - Date - Commit message The hash is critical for referencing commits in operations like ``revert``, ``checkout``, and ``reset``. Short and visual log: .. code-block:: console $ git log --branches --graph --oneline --decorate=short Viewing file changes .. code-block:: console $ git diff # Show unstaged changes $ git diff --staged # Show staged changes $ git diff commit1 commit2 # Compare two commits Undoing Changes ^^^^^^^^^^^^^^^ Git provides several tools to reverse or discard changes. The key concepts are: + **unstaging**: Remove files from the staging area but keep the working directory changes + **restore**: Restore a file from the last commit (discard working changes) + **revert**: Create a new commit that undoes an older commit Unstage a file: .. code-block:: console $ git reset This removes the files from the index but does **not** change its content in your working directory. Discard changes in the working directory: .. code-block:: console $ git restore file_to_restore This command overwrites ``file_to_restore`` with the version from the last commit, losing all local changes. Undo a commit with a new commit (safe for shared history): .. code-block:: console $ git revert ID This creates a new commit that reverses the effects of the one specified by its hash ID. .. figure:: unstage_restore_revert.png :width: 700 :alt: Undoing with git Undoing with git .. note:: To summarize, ``git`` tracks changes in project files: +--------------------------------------------------------------+------------------------------------------------+ | ``git add .`` | stage every new files | +--------------------------------------------------------------+------------------------------------------------+ | ``git commit -a`` | stage tracked files and commit | +--------------------------------------------------------------+------------------------------------------------+ | ``git status`` | show status of all new and modified files | +--------------------------------------------------------------+------------------------------------------------+ | ``git log --branches --graph --oneline --decorate=short`` | show commit history | +--------------------------------------------------------------+------------------------------------------------+ | ``git reset`` | unstage all | +--------------------------------------------------------------+------------------------------------------------+ | ``git revert ID`` | undo commit ID and make new commit | +--------------------------------------------------------------+------------------------------------------------+ | ``git restore FILE`` | restore a file from last commit | +--------------------------------------------------------------+------------------------------------------------+ | ``git branch NAME`` | create a new branch | +--------------------------------------------------------------+------------------------------------------------+ | ``git branch -d NAME`` | delete a branch | +--------------------------------------------------------------+------------------------------------------------+ | ``git switch NAME`` | switch to an other branch | +--------------------------------------------------------------+------------------------------------------------+ | ``git merge NAME`` | merge changes from an other branch | +--------------------------------------------------------------+------------------------------------------------+ Basic usage ^^^^^^^^^^^ .. literalinclude:: git_local_demo.sh :name: demo_git :linenos: :caption: demo .. raw:: html :file: output_git.html