03. Working Directory - ivomac/GitBasics GitHub Wiki

🏋️ Working Directory

A typical project folder or working directory (workdir) might look like this:

project/            # 📂 Working Directory
├── .git/           # 🪣 Git Repository
├── src/
├── .gitignore      # 🚫 List of files Git should ignore
│   ...
└── README.md

🏗️ Workdir state as graph

  • ➕ The state of the working directory (workdir) can be decomposed as the HEAD commit plus any changes on top of it.
  • ➕ We can represent the state of the workdir in the git repo graph.
  • 📸 Clean workdir means no staged/unstaged changes with respect to HEAD.
  • Working directory $\leftrightarrow$ HEAD:
         HEAD
          ▼
A ◄─ B ◄─ C
  • If there are staged changes but no unstaged, the workdir is equal to HEAD plus the staged changes:
𝚒: Index/Staged Changes

         HEAD + 𝚒
          ▼
A ◄─ B ◄─ C
  • We represent an unclean workdir with unstaged changes as:
𝚠: Workdir with unstaged changes

         HEAD + 𝚒𝚠
          ▼
A ◄─ B ◄─ C
  • Making manual edits in the workdir files will change 𝚠.
  • At any moment we can move changes between 𝚒 and 𝚠, or commit 𝚒.

✨ Workdir Scenario

  • Start with a clean workdir (HEAD in C):
A ◄─ B ◄─ C ◄ HEAD
  • Add a line in a file:
A ◄─ B ◄─ C ◄ HEAD + 𝚠
  • Stage that line:
A ◄─ B ◄─ C ◄ HEAD + 𝚒
  • ❗ Delete the line we just added:
A ◄─ B ◄─ C ◄ HEAD + 𝚒𝚠  # explicit changes affect 𝚠
  • ❗ Stage the deletion of the line:
A ◄─ B ◄─ C ◄ HEAD       # 𝚒 and 𝚠 changes were exact opposites and cancelled each other!

❔ Untracked files

  • 🎯 Tracked files are those present in the index, meaning they are in the HEAD commit or have been staged.
  • 🥷 Otherwise, the file is untracked.
  • ❕ Untracked files count as unstaged, unless they have been explicitly ignored.

🚫 Ignore an untracked file

  • 🙈 You can instruct git to ignore untracked files that you don't want to accidentally save in the repository.
  • 💫 Some file categories are commonly ignored: binary files, temporary files, secret-holding files...
  • 📋 Ignored files are specified in two main ways:
    • 🛖 in the .git/info/exclude file in the repo folder. This only affects the repository locally.
      • Try it: create this file with the name of an untracked file in it, then try to stage that file.
    • 🌍 in .gitignore files in the workdir, usually saved in the repo so everyone shares the ignore rules in them.
  • ⚠️ Git will not ignore already tracked files even if they are specified in an ignore file.

🪸 Multiple gitignores

  • 🏗️ .gitignore files can be anywhere in the workdir and only affect the folder they are on and subfolders:
project/
├── .git/
├── .gitignore     # 📵 Project gitignore
├── src/
│   ├── main-module/
│   │   ├── .gitignore # 🚳 Subfolder gitignore
│   │   ...
│   └── aux/         # 📵 Applies here # 🚳 does not
│   ...
└── README.md