Skip to content

wsmr/Git

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

44 Commits
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Git Documentation: A Comprehensive Guide

1. Introduction

This document serves as a comprehensive guide to Git, a powerful distributed version control system. It covers fundamental Git commands, configuration, history management, and advanced topics such as handling sensitive data and troubleshooting common issues. This guide is designed for developers of all experience levels, providing clear explanations and practical examples to enhance your understanding and proficiency with Git.

2. Getting Started with Git

To begin working with Git, you can either initialize a new repository for a new project or clone an existing repository from a remote source.

2.1 Initializing a New Repository

When starting a new project that you wish to track with Git, you will typically initialize a new Git repository in your project directory. This command creates a new .git subdirectory, which contains all the necessary Git metadata for the repository.

git init

After initialization, you might want to create a README.md file to describe your project and add it to your repository.

echo "# Your_Project_Name" >> README.md
git add README.md
git commit -m "first commit"

To connect your local repository to a remote repository (e.g., on GitHub), you need to add a remote origin. Replace your-remote-repository-url with the actual URL of your remote repository.

git remote add origin your-remote-repository-url

Finally, push your initial commit to the remote repository. The -u flag sets the upstream branch, so you can simply use git push in the future.

git push -u origin main

2.2 Cloning an Existing Repository

If you are joining an existing project or want to work on a project hosted remotely, you can clone the repository. Cloning downloads a complete copy of the repository, including all files, branches, and commit history, to your local machine.

There are two primary methods for cloning: HTTPS and SSH.

Cloning with HTTPS:

This method is generally simpler for read-only access and does not require SSH key setup. However, you will need to provide your username and password (or a personal access token) for write operations.

git clone https://github.com/your-username/your-repo.git

Cloning with SSH:

SSH provides a more secure way to interact with remote repositories, especially for frequent write operations, as it uses SSH keys for authentication. This requires prior setup of SSH keys on your system and adding them to your Git hosting service (e.g., GitHub).

git clone git@github.com:your-username/your-repo.git

After cloning, you can verify the remote origin to ensure it's correctly set up:

git remote -v

If you need to change the remote URL after cloning, you can use the set-url command:

git remote set-url origin your-new-remote-repository-url

This command is useful if the repository's remote URL changes or if you initially cloned using HTTPS and now wish to switch to SSH, or vice-versa. It's an alternative to removing and re-adding the remote, providing a cleaner way to update the remote configuration.

Cloning a Specific Branch:

Sometimes, you might want to clone a specific branch of a repository directly, rather than the default branch (usually main or master). This is particularly useful for projects that maintain different branches for active development and stable releases.

To clone a specific branch (e.g., stable):

git clone -b stable https://github.com/your-username/your-repo.git

The -b (or --branch) flag tells Git which branch to check out immediately after cloning. This avoids the need to manually switch branches after the initial clone.

3. Basic Git Commands

Understanding and utilizing basic Git commands is crucial for effective version control. These commands allow you to manage your project's history, collaborate with others, and maintain a clean and organized codebase.

3.1 Checking Repository Status

The git status command provides a summary of the current state of your working directory and the staging area. It shows which changes have been staged, which haven't, and which files aren't being tracked by Git.

git status

3.2 Branch Management

Branches are fundamental to Git, allowing you to work on different features or bug fixes in isolation from the main codebase. This section covers essential commands for managing branches.

To list all local branches:

git branch

To switch to the last branch you were on:

git checkout -

To switch to a specific existing branch:

git checkout your-branch-name

To create a new branch and immediately switch to it:

git checkout -b new-branch-name

If a branch exists on the remote but not locally, you can create and switch to it based on the remote branch:

git checkout -b your-branch-name origin/your-branch-name

To find the currently active Git branch:

git branch --show-current
# Alternatively:
git rev-parse --abbrev-ref HEAD

3.3 Staging and Committing Changes

After making changes to your files, you need to stage them and then commit them to your repository's history.

To stage all changes in the current directory (including new files, modifications, and deletions):

git add .

To commit staged changes with a descriptive message:

git commit -m "Your descriptive commit message"

3.4 Working with Remotes

Remote repositories are versions of your project that are hosted on the internet or network. They are essential for collaboration and backing up your work.

To verify the remote repositories configured for your project:

git remote -v

To fetch the latest changes from the remote repository and then switch to a specific branch (useful for updating your local branch with remote changes):

git fetch && git checkout your-branch-name

To push your local commits to the remote repository. The -u flag sets the upstream branch, which is useful for subsequent pushes.

git push -u origin main
# Or for a new remote and branch:
git push new_remote_name branch_name

For pushing to a specific GitHub repository using a Personal Access Token (PAT) for authentication (replace placeholders):

git push https://YOUR_GITHUB_USERNAME:YOUR_PERSONAL_ACCESS_TOKEN@github.com/your-username/your-repo.git

To pull changes from a specific remote and branch:

git pull origin main

To fetch all branches and their respective commits from the remote repository:

git fetch origin

4. Git Configuration

Git allows extensive configuration to tailor its behavior to your preferences and project needs. These configurations can be set at different levels: system, global (user), and local (repository).

4.1 Viewing Git Configuration

To view your Git configuration settings, you can use the git config command with various flags.

To display all Git configuration settings for your user account on the current system:

git config --list

This command will show a comprehensive list of all settings, including user name, email, core settings, and remote configurations. For example, you might see output similar to this (placeholders used):

credential.helper=osxkeychain
init.defaultbranch=main
user.name=your-username
user.email=your-email@example.com
core.autocrlf=input
core.repositoryformatversion=0
core.filemode=true
core.logallrefupdates=true
core.ignorecase=true
core.precomposeunicode=true
remote.origin.url=git@github.com:your-username/your-repo.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master

To show only global settings (those applied to all your repositories):

git config --global --list

To show only local repository settings (those specific to the current repository):

git config --local --list

4.2 Changing User Information

It is essential to configure your Git username and email address, as this information is embedded in every commit you make. This helps identify who made which changes.

To change your global Git username:

git config --global user.name "Your Name"

To change your global Git email address:

git config --global user.email "your-email@example.com"

4.3 Handling Line Endings

Line ending inconsistencies between different operating systems (Windows uses CRLF, macOS/Linux use LF) can cause issues in collaborative projects. Git provides the core.autocrlf setting to manage this automatically.

To configure Git to convert CRLF to LF on commit (for macOS or Linux users), ensuring Unix-style line endings in the repository, but leaving line endings unchanged on checkout:

git config --global core.autocrlf input

To configure Git to convert LF to CRLF on checkout and CRLF to LF on commit (for Windows users):

git config --global core.autocrlf true

To disable automatic conversion and leave line endings unchanged:

git config --global core.autocrlf false

For most macOS and Linux users, setting core.autocrlf to input is recommended. This helps maintain consistent line endings across different development environments.

5. Understanding Git History

Git maintains a detailed history of all changes made to your repository, allowing you to track, review, and revert modifications. Understanding how to navigate and interpret this history is crucial for effective version control.

5.1 Viewing Commit History

The git log command is your primary tool for exploring the commit history. It displays a list of commits in reverse chronological order, showing the commit hash, author, date, and commit message.

To view the full commit history with detailed information:

git log

For a more compact view, displaying each commit on a single line with an abbreviated commit hash and message:

git log --oneline

To visualize branches and their commit history graphically:

git log --graph --oneline --all

To see commits along with the patches or changes introduced by each commit:

git log -p

To limit the number of commits shown (e.g., to show only the 5 most recent commits):

git log -n 5

To see commits by a specific author:

git log --author="Your Author Name"

To see commits within a specific date range:

git log --since="YYYY-MM-DD" --until="YYYY-MM-DD"

To list all the files modified or added in a specific commit (replace commit-hash with the actual commit hash):

git diff-tree --no-commit-id --name-only -r commit-hash

5.2 Amending Commit Messages

Sometimes you might need to modify the message of your most recent commit. The git commit --amend command allows you to do this.

To change the most recent commit message:

git commit --amend -m "Your new commit message"

This command replaces the last commit with a new one that includes the previous commit’s contents and any newly staged changes. If you have already staged new changes with git add ., they will be included in the amended commit.

Important Consideration: Changing local commit history (with --amend or rebase) is only risky after you have shared it with others (e.g., by pushing to a remote repository). If the commit has already been pushed, amending it will create a new commit that diverges from the remote history, potentially causing issues for collaborators.

Undoing an Amend and Splitting into Multiple Commits:

If you amend a commit and then decide you want to split it into two separate commits, you can do so by resetting the last commit and then re-committing your changes.

  1. Reset the last commit but keep changes staged:

git reset --soft HEAD~1 ```

This command moves the `HEAD` pointer back one commit, but keeps the changes from that commit in your staging area.
  1. Make two new commits:

    Now your changes will be staged again. You can selectively commit them.

git commit -m "First part of the commit message" ```

If some changes still remain staged after the first commit, unstage them:

```bash

git reset ```

Then, selectively add the remaining changes and commit them:

```bash

git add . # or specific files git commit -m "Second part of the commit message" ```

This process allows you to refine your commit history by breaking down a single amended commit into more granular, logically separated commits.

6. Managing Files with .gitignore

Effective use of .gitignore is crucial for maintaining a clean and manageable Git repository. This file tells Git which files or folders to intentionally ignore, preventing them from being tracked or included in commits.

6.1 What is .gitignore?

A .gitignore file is a plain text file where each line contains a pattern for files or directories that Git should ignore. This is particularly useful for excluding temporary files, build artifacts, dependency directories (like node_modules), environment-specific configuration files, and operating system-generated files (like .DS_Store). By ignoring these files, you ensure that your repository only contains relevant source code and project assets, reducing repository size and avoiding unnecessary conflicts.

6.2 Setting Up .gitignore

To set up a .gitignore file, you typically create it in the root directory of your Git repository. Each line in the file specifies a pattern for files or directories to ignore.

  1. Create the .gitignore file:
touch .gitignore
  1. Add patterns to the file. Below is a suggested .gitignore template for projects that might involve both Node.js and Python components, along with common system and log files. You should adapt this to your specific project needs.
# Node.js specific ignores
node_modules/
npm-debug.log
# Optional: npm lock file if you prefer to not track it
package-lock.json

# Python specific ignores
__pycache__/
*.py[cod]
*.pyo
*.pyc

# Environment files
.env
.venv/
env/
venv/

# System Files (macOS, Windows)
*.DS_Store
Thumbs.db

# Log files
*.log
  1. Save and commit the .gitignore file:

    After adding your desired patterns, save the file and commit it to your repository. This ensures that all collaborators will use the same ignore rules.

git add .gitignore
git commit -m "Add .gitignore"
GitHub maintains extensive `.gitignore` templates for various programming languages and frameworks, which can be a great starting point for your projects [1]. You can find these templates at `https://github.com/github/gitignore`.

6.3 Untracking Already Added Files

A common scenario is that you might have mistakenly added and committed files (e.g., node_modules/, .DS_Store, .env) before setting up your .gitignore file. In such cases, Git will continue to track these files even after you add them to .gitignore.

To remove these files from Git's tracking (but keep them locally in your working directory), you need to use the git rm --cached command. This command removes the specified files from the Git index without deleting them from your filesystem.

Example Scenario:

Suppose you accidentally ran git add . and it included node_modules/, .DS_Store, and .env.

To untrack these specific items:

git rm -r --cached node_modules
git rm --cached .DS_Store
git rm --cached .env
git commit -m "Remove unwanted tracked files and apply .gitignore"
git push

Alternatively, to untrack all files that are now ignored by your .gitignore and then re-add only the files that should be tracked:

git rm -r --cached .
git add .
git commit -m "Clean up unwanted tracked files using .gitignore"

This sequence first untracks everything in your repository, then re-adds only the files that are not matched by any pattern in your .gitignore file.

6.4 Common .gitignore Mistakes and Fixes

One common mistake is accidentally removing the .gitignore file from Git tracking. If you run git rm -r --cached .gitignore, the file will remain on your disk but Git will no longer track it.

To fix this, simply re-add the .gitignore file to Git:

git add .gitignore
git commit -m "Re-add .gitignore"

6.5 Best Practices for .gitignore

Adhering to these best practices will help you maintain a clean and efficient Git repository:

  • Create .gitignore early: Always create and configure your .gitignore file at the very beginning of your project. This prevents unwanted files from ever being tracked.
  • Never commit sensitive or unnecessary files: Ensure that directories like node_modules, .env files (containing sensitive environment variables), and OS-specific junk files are always ignored.
  • Use git rm --cached: If files are accidentally committed, use git rm --cached to stop tracking them without deleting them locally.
  • Leverage GitHub’s .gitignore templates: Utilize the official .gitignore templates provided by GitHub for project-specific setups. These templates are well-maintained and cover most common ignore patterns for various technologies.

[1] GitHub. (n.d.). gitignore templates. Retrieved from https://github.com/github/gitignore

7. Troubleshooting Common Git Issues

Even with a good understanding of Git, you might encounter common issues. This section provides solutions and explanations for some frequently faced problems.

7.1 Updates Rejected Due to Remote Changes

One common error message you might encounter is: Updates were rejected because the remote contains work that you do not have locally. This means that the remote repository has commits that are not present in your local branch, and Git prevents you from pushing your changes directly to avoid overwriting remote work.

Solution 1: Merge Remote Changes Locally and Push (Recommended)

The safest and most common way to resolve this is to first pull the latest changes from the remote, integrate them with your local commits, and then push.

  1. Set upstream branch:
git branch --set-upstream-to=origin/main main
This command sets up your local `main` branch to track the `main` branch on the `origin` remote.
  1. Pull remote changes and merge them locally:
git pull origin main --allow-unrelated-histories
The `--allow-unrelated-histories` flag is crucial when merging two branches that do not share a common commit history (e.g., when you initialize a new local repository and then try to push to an existing remote that already has some commits like a license file). Git may open an editor (like Vim) to finalize a merge commit message. To save and exit in Vim:

*   Press `i` to go into insert mode.
*   Type your commit message (or leave the default).
*   Press `Esc`.
*   Type `:wq` and hit `Enter`.
  1. Push your changes:
git push origin main

Solution 2: Alternative (If You Want to Overwrite the Remote Repo)

⚠️ Use this with extreme caution. This will delete everything currently in the remote repository and replace it with your local files. Only use this if you are absolutely sure you want to discard all remote changes and replace them with your local version.

git push origin main --force

7.2 Handling Diverged Branches During Pull

If your local and remote branches have diverged (both have new commits that the other doesn't have), Git needs to know how to combine them during a pull. You might see a message indicating this divergence.

What This Means:

Your local branch and the remote branch both have new commits that the other doesn't have. Git needs to know whether to:

  • Merge the changes (default in older Git versions).
  • Rebase your changes on top of the remote.
  • Fast-forward only (only allow pull if the remote is ahead and no conflict exists).

Fix Option 1: Merge (Safe and Common)

This option merges the remote changes into your local branch with a merge commit.

git config pull.rebase false
git pull

Fix Option 2: Rebase (Cleaner History, Advanced)

This option re-applies your local commits on top of the latest remote commits. This results in a cleaner, linear history but can cause conflicts that you'll need to resolve.

git config pull.rebase true
git pull --rebase

Fix Option 3: One-time Override

If you don't want to change your global Git configuration, you can use these options for a one-time pull:

  • Merge:
git pull --no-rebase
  • Rebase:
git pull --rebase
  • Fast-forward only:
git pull --ff-only

To Set as Global Default (Recommended for Future Clarity):

Choose one of these to set your preferred default behavior for git pull:

  • Merge (recommended for simplicity):
git config --global pull.rebase false
  • Rebase (recommended for cleaner history, if comfortable with conflict resolution):
git config --global pull.rebase true
  • Fast-forward only:
git config --global pull.ff only

7.3 GitHub File Not Showing (Incorrect File Creation/Ignored)

This issue typically arises when you attempt to add a file, but it doesn't appear in your Git repository or on GitHub after pushing. Common causes include incorrect file creation commands or the file being ignored by a .gitignore rule.

Problem Summary:

You might have tried to add a file (e.g., a GitHub Actions workflow file like .github/workflows/deploy.yml), but after git add . it wasn't added, and after git commit and git push, it was missing on GitHub. Git might also report the file as ignored, even if you believe it's not in your .gitignore.

Root Causes Identified:

  1. Incorrect File Creation Command: Using mkdir -p .github/workflows/deploy.yml creates a directory named deploy.yml, not a file. Git does not track empty directories, so nothing is added or committed.
  2. File Ignored by .gitignore: A rule in one of your .gitignore files (e.g., in .github/, .github/workflows/, or a general *.yml pattern) is preventing Git from tracking the file.

βœ… Step-by-Step Fix:

πŸ”§ Step 1: Create the Correct File

Ensure you are creating an actual file, not a directory. First, create the necessary directory structure, then create the file.

mkdir -p .github/workflows
touch .github/workflows/deploy.yml

Optionally, add initial content to the file:

echo "# GitHub Actions workflow" > .github/workflows/deploy.yml

πŸ” Step 2: Diagnose Which .gitignore Rule Is Blocking It

Use git check-ignore -v to determine which specific .gitignore rule is causing the file to be ignored. This command provides detailed output, including the rule, line number, and the .gitignore file that contains the rule.

git check-ignore -v .github/workflows/deploy.yml

Example output indicating the ignoring rule:

.gitignore:12: .github/  .github/workflows/deploy.yml

🧹 Step 3: Fix the .gitignore Rules

Based on the output from Step 2, you have two main options:

  • Option A – Refine or Remove the Rule: If the existing rule is too broad, make it more specific. For example, if .github/ is ignoring everything in the .github directory, you can refine it to ignore most content but explicitly allow your workflow files.

    Before (too broad):

.github/
**After (more specific, allowing workflows):**
# Ignore all .github content EXCEPT workflows and deploy.yml
.github/*
!.github/workflows/
!.github/workflows/deploy.yml
  • Option B – Force Add the File: If you prefer not to modify your .gitignore file, you can force Git to add the ignored file for a single instance. This is generally not recommended for files that should always be tracked, but can be useful in specific edge cases.
git add -f .github/workflows/deploy.yml
git commit -m "Add GitHub Actions deploy workflow"
git push

βœ… Step 4: Confirm the File Was Added

After applying the fix, verify that the file is now tracked and present in your repository.

git status
git log --name-status

Finally, confirm the file appears on your GitHub repository at the expected path: https://github.com/your-username/your-repo/tree/main/.github/workflows.

πŸ’‘ Best Practices for Workflow Files:

  • Always create .yml files inside the .github/workflows/ directory for GitHub Actions.
  • Avoid placing .github/ in your .gitignore unless you have a very strong and specific reason.
  • Use git check-ignore -v anytime a file unexpectedly won't add to diagnose the issue quickly.

Summary of Commands Used for Fixing the Issue:

# Fixing the issue
mkdir -p .github/workflows
touch .github/workflows/deploy.yml
echo "# GitHub Actions workflow" > .github/workflows/deploy.yml

# Check ignore source
git check-ignore -v .github/workflows/deploy.yml

# Add file normally (after fixing .gitignore)
git add .github/workflows/deploy.yml

# OR force add if needed
git add -f .github/workflows/deploy.yml

# Commit and push
git commit -m "Add deploy workflow"
git push

7.4 Resolving

SSH Key Errors (Permission Denied)

If you encounter an error message like no such identity: /Users/sahan/.ssh/id_ed25519: No such file or directory or git@github.com: Permission denied (publickey), it indicates that Git is configured to use SSH for connecting to GitHub, but it cannot find or use your SSH private key.

Root Cause:

Your Git configuration (e.g., remote.origin.url=git@github.com:your-username/your-repo.git) specifies SSH for remote operations, but the SSH private key file it expects (~/.ssh/id_ed25519 in the example) either does not exist or is not accessible. Consequently, GitHub denies access because it cannot authenticate your connection.

πŸ› οΈ Solution Options:

Option 1: Use HTTPS Instead of SSH (Simpler)

If you prefer not to manage SSH keys, you can switch your remote URL to use HTTPS. This will prompt you for your GitHub credentials (username and password, or a Personal Access Token) when performing operations that require authentication.

git remote set-url origin https://github.com/your-username/your-repo.git

After changing the URL, git pull and git push operations will use HTTPS for authentication.

Option 2: Fix SSH Key (Advanced / Recommended for Power Users)

If you prefer to use SSH for its security and convenience (especially for automation), you need to ensure your SSH key is correctly set up and accessible.

  1. Check for Existing SSH Keys:

    First, verify if you have any existing SSH keys in your ~/.ssh/ directory:

ls -la ~/.ssh/
Look for files like `id_rsa`, `id_ecdsa`, or `id_ed25519` (private keys) and their corresponding `.pub` files (public keys). If you don't find any, you'll need to generate a new one.
  1. Generate a New SSH Key (if needed):

    If you don't have an existing key or want to create a new one, use ssh-keygen. Replace your-email@example.com with your GitHub email address.

ssh-keygen -t ed25519 -C "your-email@example.com"
Press `Enter` to accept the default file path (e.g., `/Users/your-username/.ssh/id_ed25519`). You can optionally set a strong passphrase for added security.
  1. Add the Key to SSH Agent:

    The ssh-agent manages your SSH keys and passphrases, so you don't have to enter your passphrase every time you use your key.

    • Start the ssh-agent:
eval "$(ssh-agent -s)"
*   Add your private key to the agent:
ssh-add ~/.ssh/id_ed25519
    (Replace `id_ed25519` with your actual private key filename if different.) You will be prompted for your passphrase if you set one.
  1. Add the SSH Key to GitHub:

    You need to add your public SSH key to your GitHub account so GitHub can authenticate you.

    • Copy your public key to your clipboard:
cat ~/.ssh/id_ed25519.pub
    Copy the entire output.

*   **Go to GitHub:** Navigate to `Settings` -> `SSH and GPG keys` -> `New SSH key`. Paste the copied public key into the 

field and give it a descriptive title (e.g., "My Laptop SSH Key").

  1. Test Your SSH Connection:

    After adding the key to GitHub, test your connection to ensure everything is set up correctly:

ssh -T git@github.com
A successful connection will display a message like: `Hi your-username! You've successfully authenticated, but GitHub does not provide shell access.`

Bonus: Typo in Your Remote URL?

Sometimes, the issue might be a simple typo in your remote URL. Double-check the actual repository name on GitHub and correct it if needed:

git remote set-url origin git@github.com:your-username/your-correct-repo-name.git

7.5 Resolving .DS_Store and .idea/ Issues

Files like .DS_Store (macOS system files) and .idea/ directories (IDE-specific configuration for IntelliJ/Android Studio) are often accidentally staged or committed. These files should typically be ignored by Git to prevent unnecessary commits and conflicts.

Problem: .DS_Store is staged and Git refuses to remove it.

If you see an error indicating that .DS_Store is staged and Git doesn't want to remove it, it means the file's content in the staging area differs from both your working directory and the last committed version. Git is being cautious.

Solution:

To forcefully remove .DS_Store from Git's tracking (but keep it locally):

git rm -f --cached .DS_Store

Next Steps (Recommended for .DS_Store files):

Add .DS_Store to your .gitignore file so it doesn't get tracked again. You can do this by appending the line to your .gitignore:

echo .DS_Store >> .gitignore

Then, commit the changes to your .gitignore:

git commit -m "Remove .DS_Store and update .gitignore"

Problem: Git refuses to remove .idea/ directory.

If Git refuses to remove a directory like android/.idea/ because its files are staged, it means the files within that directory are in Git's index but not yet committed, and Git requires explicit confirmation for their removal.

Solution Options:

  1. Remove .idea/ from Git but keep it locally (Most Common):

    This is the typical approach for IDE-specific folders. It removes the directory from Git's tracking but leaves it in your local working directory.

git rm -r --cached android/.idea/
Then, add it to your `.gitignore` file to prevent it from being tracked again:
echo android/.idea/ >> .gitignore
Finally, commit these changes:
git commit -m "Remove android/.idea/ from git tracking and update .gitignore"
  1. Remove the .idea/ directory from Git AND your local machine:

    If you want to completely remove the directory from both Git and your local filesystem:

git rm -rf android/.idea/
Then commit the removal:
git commit -m "Remove android/.idea/ completely"

πŸ’‘ Important Tip: .idea/ folders are specific to IDEs (like Android Studio or IntelliJ) and generally should not be version controlled. Excluding them from your repository helps avoid conflicts and keeps your repository clean and focused on source code.

7.6 Resolving Staged File Removal Issues

Sometimes, Git might refuse to remove a file or directory because its contents are staged (added to Git's index but not yet committed), and Git requires explicit confirmation for the removal.

Problem: Git refuses to remove a staged file (e.g., .DS_Store).

If you encounter an error message indicating that a file like .DS_Store is staged and Git doesn't want to remove it, it means the file's content in the staging area differs from both your working directory and the last committed version. Git is being cautious and wants you to explicitly confirm the removal.

Solution:

To forcefully remove the file from Git's tracking (but keep it locally), use the -f (force) and --cached flags:

git rm -f --cached .DS_Store

Next Steps (Recommended for .DS_Store files):

After untracking, it's crucial to add .DS_Store to your .gitignore file to prevent it from being tracked again in the future. You can append the line to your .gitignore file:

echo .DS_Store >> .gitignore

Then, commit these changes to your .gitignore:

git commit -m "Remove .DS_Store from tracking and update .gitignore"

Problem: Git refuses to remove a staged directory (e.g., android/.idea/).

If Git refuses to remove a directory like android/.idea/ because its files are staged, it means the files within that directory are in Git's index but not yet committed, and Git requires explicit confirmation for their removal.

Solution Options:

  1. Remove the directory from Git but keep it locally (Most Common):

    This is the typical approach for IDE-specific folders. It removes the directory from Git's tracking but leaves it in your local working directory.

git rm -r --cached android/.idea/
Then, add it to your `.gitignore` file to prevent it from being tracked again:
echo android/.idea/ >> .gitignore
Finally, commit these changes:
git commit -m "Remove android/.idea/ from git tracking and update .gitignore"
  1. Remove the directory from Git AND your local machine:

    If you want to completely remove the directory from both Git and your local filesystem:

git rm -rf android/.idea/
Then commit the removal:
git commit -m "Remove android/.idea/ completely"

πŸ’‘ Important Tip: .idea/ folders are specific to IDEs (like Android Studio or IntelliJ) and generally should not be version controlled. Excluding them from your repository helps avoid conflicts and keeps your repository clean and focused on source code.

8. Advanced Topics

This section delves into more advanced Git topics, including how to clean your Git history of sensitive data and how to set up SSH keys for secure authentication with GitHub.

8.1 Clean Git History (Removing Sensitive Data)

If sensitive credentials, API keys, or other confidential information are accidentally committed to your Git repository, simply deleting the file and committing again is not enough. The sensitive data will still exist in the repository's history. To truly remove such data from all commits, you need to rewrite the Git history.

Warning: Rewriting Git history is a powerful operation that changes the commit hashes. If the repository has already been shared with others, this can cause significant issues for collaborators. Always communicate with your team before performing such operations.

Two common tools for cleaning Git history are git-filter-repo and BFG Repo-Cleaner.

Using git-filter-repo:

git-filter-repo is a highly efficient tool for rewriting repository history. It needs to be installed separately.

  1. Install git-filter-repo (if not already installed):
pip install git-filter-repo
  1. Remove the sensitive content from all commits:

    This example demonstrates removing a file named README.md from the history. Replace README.md with the actual path to the file containing sensitive data. The --invert-paths flag ensures that everything except the specified path is kept, effectively removing the path.

git filter-repo --path path/to/sensitive-file.txt --invert-paths --force
If the sensitive data is within a specific file that you want to keep but remove the sensitive content from, you might need more advanced filtering or use BFG Repo-Cleaner.

Using BFG Repo-Cleaner:

BFG Repo-Cleaner is another powerful tool, often simpler to use for common cleanup tasks like removing large files or sensitive data. It is a JAR file and requires Java to run.

For more complex cleanup scenarios, such as removing specific text from all files in the history, BFG Repo-Cleaner might be more suitable. Refer to its official documentation for detailed usage instructions.

8.2 SSH Key Setup for GitHub

SSH (Secure Shell) keys provide a secure way to authenticate with GitHub without exposing your username and password. This is generally recommended for frequent interactions with remote repositories.

  1. Check for existing SSH keys:

    Open your terminal and list the contents of your .ssh directory:

ls -al ~/.ssh
Look for files like `id_rsa.pub`, `id_ecdsa.pub`, or `id_ed25519.pub`. These are your public SSH keys. If you find existing keys, you might be able to use one of them. If no keys exist, proceed to generate a new SSH key.
  1. Generate a new SSH key:

    Run the following command, replacing your-email@example.com with your actual email address associated with your GitHub account:

ssh-keygen -t ed25519 -C "your-email@example.com"
The `ed25519` algorithm is generally recommended for its security and performance. If your system does not support `ed25519`, you can use the RSA algorithm:
ssh-keygen -t rsa -b 4096 -C "your-email@example.com"
Follow the prompts to save the key to the default location (`~/.ssh/id_ed25519` or `~/.ssh/id_rsa`) and optionally add a strong passphrase for extra security. A passphrase encrypts your private key on disk, requiring you to enter it whenever you use the key.
  1. Add the SSH key to the ssh-agent:

    The ssh-agent is a program that holds your private keys in memory, so you don't have to enter your passphrase every time you use your SSH key.

    • Start the ssh-agent in the background:
eval "$(ssh-agent -s)"
*   **Add your SSH private key to the agent:**
ssh-add ~/.ssh/id_ed25519
    (Replace `id_ed25519` with the name of your private key file if it's different (e.g., `id_rsa`). If you set a passphrase, you will be prompted to enter it here.
  1. Add the SSH key to your GitHub account:

    You need to add your public SSH key to your GitHub account so GitHub can authenticate you.

    • Copy your public key to your clipboard:
cat ~/.ssh/id_ed25519.pub
    Copy the entire output.

*   **Go to GitHub:** Navigate to `Settings` -> `SSH and GPG keys` -> `New SSH key`. Paste the copied public key into the field and give it a descriptive title (e.g., "My Laptop SSH Key").
  1. Test Your SSH Connection:

    After adding the key to GitHub, test your connection to ensure everything is set up correctly:

ssh -T git@github.com
A successful connection will display a message like: `Hi your-username! You've successfully authenticated, but GitHub does not provide shell access.`

Bonus: Typo in Your Remote URL?

Sometimes, the issue might be a simple typo in your remote URL. Double-check the actual repository name on GitHub and correct it if needed:

git remote set-url origin git@github.com:your-username/your-correct-repo-name.git

9. Summary of Key Git Commands

This section provides a quick reference for some of the most frequently used Git commands discussed in this document.

Command Description Example Usage
git init Initializes a new Git repository in the current directory. git init
git status Shows the status of changes as untracked, modified, or staged. git status
git add . Stages all changes in the current directory for the next commit. git add .
git commit -m "Message" Records staged changes to the repository with a message. git commit -m "Initial commit"
git remote add origin URL Adds a new remote repository. git remote add origin https://github.com/user/repo.git
git remote -v Lists all configured remote repositories. git remote -v
git remote set-url origin URL Changes the URL of an existing remote. git remote set-url origin https://github.com/user/new-repo.git
git push -u origin branch Pushes local commits to a remote repository and sets upstream. git push -u origin main
git pull origin branch Fetches from and integrates with another repository or a local branch. git pull origin main
git fetch origin Downloads objects and refs from another repository. git fetch origin
git branch Lists, creates, or deletes branches. git branch
git checkout branch Switches to a specified branch. git checkout develop
git checkout -b new-branch Creates a new branch and switches to it. git checkout -b feature/new-feature
git config --list Lists all Git configurations. git config --list
git config --global user.name "Name" Sets the global user name for commits. git config --global user.name "John Doe"
git config --global user.email "Email" Sets the global user email for commits. git config --global user.email "john.doe@example.com"
git log Shows the commit history. git log
git log --oneline Shows a compact commit history. git log --oneline
git commit --amend -m "Msg" Amends the last commit message. git commit --amend -m "Updated message"
git rm --cached file Untracks a file from Git without deleting it locally. git rm --cached unwanted-file.log
git check-ignore -v file Shows which .gitignore rule is ignoring a file. git check-ignore -v .github/workflows/deploy.yml

About

Git Commends

Resources

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published