Exercise notebook: Git committing

Offered by: Digital Work at Otto-Friedrich-Universität Bamberg License: CC BY 4.0

Edit The notebook builds on our peer-reviewed pedagogical foundations.

We Edit your feedback and suggestions on this notebook!


Concepts: Git areas

The slides explaining the Git areas are here.


With this notebook, you can practice committing changes in Git.

Edit We are here to help if errors or questions come up!



Important: Make sure to copy the commands and enter them in the shell as shown in the screenshot. It is not possible to run the cells in this notebook.

Part 1: Clone the repository

In this part, we work with an existing project. To download the example, run the following commands:

cd /workspaces
git clone https://github.com/CoLRev-Environment/colrev
<summary {style='color:green;font-weight:bold'}>Check</summary>

The clone command should print something like the following (the number of objects may differ):

```python Cloning into 'colrev'... remote: Counting objects: 100% (125/125), done. remote: Total 22225 (delta 41), reused 54 (delta 27), pack-reused 22100 Receiving objects: 100% (22225/22225), 10.11 MiB | 2.37 MiB/s, done. Resolving deltas: 100% (18519/18519), done. ```

The repository has been downloaded to our machine (i.e., the Codespace environment). Let's enter the directory and to check the status.

Note: To create an empty git project, you would run git init.

Info The code -a ... command will reopen the codespace window and add the new project to the explorer sidebar. You will have to navigate to this notebook again.
code -a /workspaces/colrev

The status command provides an overview of the current state of the project and the files in the three sections. Therefore, you will need to run git status regularly.

Note: The comments after the hashtag (#) are ignored.


# Enter the directory of the colrev project
cd /workspaces/colrev
# Check the status of the project
git status
<summary {style='color:green;font-weight:bold'}>Check</summary>

The `git status` command should print something like the following:

```python On branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean ```

The last line indicates that there are no changes in the staging area (nothing to commit). The working directory has the same content as the last version in the git repository (working tree clean).

Part 2: Create, stage, and commit changes

Next, we modify files (state: untracked/modified), mark them to be in the next commit (state: staged) and create the first version (state: committed). This corresponds to the three sections of a Git project.

Task: Open the README.md file in the colrev repository (shift + double click to open in a separate tab) and add your name to the project citation (# Citing CoLRev section).

# Check the `git status` between each command
git status

Task: Open the CONTRIBUTING.md file and change it.

The git status should now show two files with changes in the working directory (state: modified)

We decide that the changes in the README.md file should be staged for the next commit. The changes in the CONTRIBUTING.md file are no longer needed.

Task: Use the commands suggested by git status to accomplish this.

This means that changes in the README.md are staged (to be committed).

<summary {style='color:green;font-weight:bold'}>Check</summary> The `git status` should now display ```python On branch main Your branch is up to date with 'origin/main'. Changes to be committed: (use "git restore --staged ..." to unstage) modified: README.md ``` </details>

To commit the changes, we run

```python git commit -m 'add contributor' ```

The -m 'add contributor' adds a short summary message, which is expected for every commit.

<summary {style='color:green;font-weight:bold'}>Check</summary> `git status` should reflect your expected state of files in the three Git sections.
## Part 3: Undo committed changes

To undo the last commit, we can simply run:

```python git reset --soft HEAD~1 ```

You should now have the README.md file in the staging area again.

Note: the HEAD~1 refers to the last commit.

Task: Run git status to see the changes.

We decide to discard our changes.

Task: Use the commands suggested by git status to do that.

<summary {style='color:green;font-weight:bold'}>Check</summary> The `git status` should show the following: ``` On branch main nothing to commit, working tree clean ```
To analyze the specific changes, open the Git GUI: ## Part 4: Create atomic commits

It is good practice to create atomic commits, i.e., small changes that belong together. One should avoid large commits that modify many unrelated parts of the code base and pursue different objectives.

Analyze the following commits and discuss which ones are atomic and which ones combine changes that do not belong together (i.e., should be in separate commits).

Also check the commit message (short summary at the beginning). Does the message clearly summarize the changes?

Commit 1
<summary {style='color:green;font-weight:bold'}>Check</summary> **Solution**: Atomic commit, ok.
Commit 2
<summary {style='color:green;font-weight:bold'}>Check</summary> **Solution**: Relatively atomic. There are a few changes beyond `compute_language()`. May be improved.
Commit 3
<summary {style='color:green;font-weight:bold'}>Check</summary> **Solution**: Many files changed. Changes not related to each other. Message refers to refactoring and testing, but the commit also adds functionality.
Commit 4
<summary {style='color:green;font-weight:bold'}>Check</summary> **Solution**: Many files changed, but the changes belong together. ok.
Commit 5
<summary {style='color:green;font-weight:bold'}>Check</summary> **Solution**: Atomic commit, ok.

It is ok to combine functionality, tests, and docs that belong together in one commit!

**Optional**: If you have the time, you may check the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/){: target="_blank"} specification.

To create atomic commits, you may need to add specific lines of code that should go into a commit, leaving other changes in the working directory.

The changes are provided in the rec_dict.patch file, which must be placed in the project's working directory. To apply it, run:

```python # Suggests to rename the method but also introduces unrelated changes. git apply /workspaces/practice-git/notebooks/rec_dict.patch # Different files were modified by the patch git status ```

Task: Use the Git GUI to check the changes that were introduced by the patch.

In the following, we would like to add only the changes in lines related to the load_records_dict method and the skip_notification parameter (using -p for a partial git add):

```python # Add specific lines of code from the colrev/dataset.py # using y/n to add or skip (confirming with ENTER) git add -p colrev/dataset.py ```

Task: Check whether the correct lines were added! Create a commit containing the relevant changes. Afterwards, discard the remaining changes.

## Part 5: Undo changes (advanced)

To undo committed changes, there several options:

- Revert the commit, i.e., create a new commit to undo changes: `git revert COMMIT_SHA --no-edit` - Undo the commit and leave the changes in the staging area: `git reset --soft COMMIT_SHA` (*) - Stage changes, and run `git commit --amend` to modify the last commit (*)

If you have the time, try the different undo operations in the session.

(*) Important: only amend commits that are not yet shared with the team. Otherwise, revert is preferred.

Info Once you have committed changes, Git takes takes care of the data and it is very hard to lose the data. Uncommitted data can be lost more easily. Therefore, commit often!

Even if you run git reset --hard ..., you can still recover commits using git reflog. Committed data will only be lost permanently if you run git reflog expire --expire=now --all and git gc --prune=now --aggressive. If the commits are already on GitHub, you would need git push --force and the changes may also be synchronized in other local repositories.

Avoid options like --force, --hard, or --aggressive. Use them only if you know what you are doing.

--- ## Wrap-up 🎉🎈 You have completed the Git commit notebook - good work! 🎈🎉 In this notebook, we have learned to - Clone a repository and check the `git status` - Create, stage, and commit changes using `git add`, `git commit` and `git restore` - Create atomic commits - Undo changes - Navigate VisualStudio Code on GitHub Codespaces Remember to delete your codespace [here](https://github.com/codespaces){: target="_blank"} (see [instructions](codespaces.ipynb)).