Git Essentials: Core Concepts to Advanced Techniques

  1. Introduction to Git
  • Definition and Importance of Git
  • Basic Concepts in Git
  1. Git Setup and Configuration
  • Installation of Git
  • Initial Configuration (username, email)
  1. Creating and Cloning Repositories
  • Initializing a New Repository
  • Cloning an Existing Repository
  1. Basic Git Commands
  • git add
  • git commit
  • git status
  • git log
  1. Branching and Merging
  • Creating Branches
  • Switching Branches
  • Merging Branches
  • Merge Conflicts
  1. Remote Repositories
  • Connecting to a Remote Repository
  • Pushing Changes to Remote
  • Pulling Changes from Remote
  1. Undoing Changes
  • git revert
  • git reset
  1. Dealing with Merge Conflicts
  • Understanding Merge Conflicts
  • Resolving Merge Conflicts

  1. Git Stash and Advanced Stashing
  • Using Git Stash
  • Applying and Managing Stashes
  1. Rebasing in Detail
    • Understanding Rebasing
    • Performing a Rebase
  2. Tags and Releases
    • Creating Tags
    • Managing Release Versions
  3. Git Best Practices
    • Committing Best Practices
    • Branch Management
  4. Git Workflows
    • Centralized Workflow
    • Feature Branch Workflow
    • Gitflow Workflow
    • Forking Workflow
  5. Git Hooks
    • Implementing Git Hooks
  6. Gitignore File
    • Ignoring Files in GitSecurity in Git
    • Signing Commits and TagsGit GUI Clients
    • Overview of GUI Options
  7. Collaborating with Pull Requests
    • Process and Benefits of Pull RequestsGit in the Cloud
    • Cloud Services for Git Hosting and Collaboration

1. Introduction to Git

What is Git?

Git is a distributed version control system created by Linus Torvalds in 2005. It’s designed to handle everything from small to very large projects with speed and efficiency. Git is distributed, meaning that every developer’s computer holds the full history of the project, enabling easy branching and merging.

Importance of Version Control

Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later. It allows you to:

  • Revert files back to a previous state.
  • Revert the entire project back to a previous state.
  • Compare changes over time.
  • See who last modified something that might be causing a problem.
  • Who introduced an issue and when.

Key Terms

  • Repository (Repo): A directory which contains your project work, as well as a few files (hidden by default in Unix) which are used to communicate with Git. Repositories can exist either locally on your computer or as a remote copy on another computer.
  • Commit: A commit, or “revision”, is an individual change to a file (or set of files). It’s like when you save a file, but with Git, every time you save it creates a unique ID (a.k.a. the “commit hash”) that allows you to keep a record of what changes were made when and by who.
  • Branch: A branch in Git is simply a lightweight movable pointer to one of these commits. The default branch name in Git is master. As you start making commits, you’re given a master branch that points to the last commit you made. Every time you commit, the master branch pointer moves forward automatically.
  • Merge: Merging is Git’s way of putting a forked history back together again. The git merge command lets you take the independent lines of development created by git branch and integrate them into a single branch.

2. Setting Up and Configuring Git

Before you can use Git, you need to install it and configure it on your machine.

Installing Git

  • On Windows: Download the official Git installer from git-scm.com, and follow the instructions.
  • On macOS: Use Homebrew by typing brew install git in the terminal, or download the installer as with Windows.
  • On Linux: Use your distro’s package manager, e.g., sudo apt-get install git for Ubuntu or sudo yum install git for Fedora.

Basic Git Configuration

After installing Git, you should configure your personal information.

  • Set your name (which will appear in commits):
  git config --global user.name "Your Name"
  • Set your email address (which should match your version control service account, like GitHub):
  git config --global user.email "your_email@example.com"

Checking Your Settings

You can check your configuration at any time:

git config --list

Configuring Text Editor

Set your favorite text editor to be used by default with Git:

  • For Vim: git config --global core.editor "vim"
  • For Nano: git config --global core.editor "nano"
  • For VS Code: git config --global core.editor "code --wait"

Caching Your Login Credentials

So you don’t have to keep re-entering your username and password, you can tell Git to remember them for a while:

git config --global credential.helper cache

3. Getting Started with Git

Creating a New Repository

  • To create a new repo, you’ll use the git init command. Here’s how you do it:
  mkdir MyNewProject
  cd MyNewProject
  git init

This initializes a new Git repository. Inside your project folder, Git has created a hidden directory named .git that houses all of the necessary repository files.

Cloning an Existing Repository

  • If you want to work on an existing project that is hosted on a remote server, you will clone it using:
  git clone [url]

For example:

  git clone https://github.com/user/repo.git

This command makes a complete copy of the entire history of the project.

4. Basic Git Operations

Checking the Status

  • The git status command gives you all the necessary information about the current branch.
  git status

Tracking New Files

  • To start tracking a file, use the git add command.
  git add <filename>
  • To add everything at once:
  git add .

Ignoring Files

  • Sometimes there are files you don’t want to track. Create a file named .gitignore in your project root and list the files/folders to ignore.
  # Example .gitignore content
  log/*.log
  tmp/

Committing Changes

  • To commit changes to your repository, use:
  git commit -m "Commit message here"
  • To commit all staged changes:
  git commit -a -m "Commit message here"

Viewing the Commit History

  • To see the commit history:
  git log
  • For a more condensed view:
  git log --oneline

5. Branching and Merging in Git

Branching in Git

Branches are a powerful feature in Git that enable you to diverge from the main line of development and work independently, without affecting the main line.

Creating a New Branch

  • To create a new branch:
  git branch <branch-name>
  • To switch to the new branch:
  git checkout <branch-name>
  • You can also create and switch to a new branch in one command using:
  git checkout -b <branch-name>

Listing Branches

  • To list all the branches in your repo, including remote branches:
  git branch -a

Merging Branches

  • To merge changes from one branch into another:
  git checkout <branch-you-want-to-merge-into>
  git merge <branch-you-want-to-merge-from>
  • If Git can’t automatically merge changes, you may have to solve conflicts manually. After resolving the conflicts, you need to stage the changes and make a commit.

Deleting Branches

  • To delete a branch:
  git branch -d <branch-name>

The -d option deletes the branch only if you have already merged it into another branch. If you want to force deletion, use -D instead.

6. Working with Remote Repositories

Remote repositories are versions of your project that are hosted on the internet or network somewhere.

Adding a Remote Repository

  • When you clone a repository, it automatically adds that remote repository under the name “origin”.
  • To add a new remote URL:
  git remote add <name> <url>

Viewing Remote Repositories

  • To view the remote repositories configured for your project:
  git remote -v

Pulling Changes from a Remote Repository

  • To fetch changes from a remote repository and merge them into your current branch:
  git pull <remote>

Pushing Changes to a Remote Repository

  • To send your commits to a remote repository:
  git push <remote> <branch>

Checking out Remote Branches

  • To check out a remote branch:
  git fetch
  git checkout -b <branch-name> <remote>/<branch-name>

7. Advanced Git Features

Stashing Changes

  • You can use git stash to record the current state of the working directory and the index, but want a clean working directory:
  git stash
  git stash apply   # re-apply the stashed changes

Rebasing

  • Rebasing is another way to integrate changes from one branch into another. Rebasing re-writes the commit history by creating new commits for each commit in the original branch.
  git rebase <base>

Tagging

  • Tags are used to mark specific points in history as being important:
  git tag <tagname>

This concludes the essentials of branching, merging, and working with remote repositories, as well as touching on some advanced features. Each of these areas has much more depth to explore, such as dealing with merge conflicts, managing remotes, and leveraging advanced rebasing and stashing strategies for complex workflows.

8. Dealing with Merge Conflicts

Understanding Merge Conflicts

Merge conflicts happen when Git is unable to automatically resolve differences in code between two commits. Conflicts only affect the developer conducting the merge; the rest of the team is unaffected until the conflict is resolved.

Resolving Merge Conflicts

  • When you encounter a merge conflict, Git will mark the files that are conflicting.
  • You can open these files and look for the lines marked with <<<<<<<, =======, and >>>>>>>. These markers define the conflicting sections.
  • Resolve the conflicts by editing the files to remove the markers and make sure the code is as you want it.
  • After fixing the conflicts, stage the files:
  git add <file>
  • Then, continue the merge process by committing the changes:
  git commit

9. Git Stash and Advanced Stashing

Using Git Stash

- `git stash` is useful when you need a clean working directory (for example, when pulling in changes from a remote repository).
- To stash changes:


git stash

- To list all stashes:

git stash list

- To apply a stash and remove it from the stash list:

git stash pop

- To apply a stash without removing it from the stash list:

git stash apply stash@{}

10. Rebasing in Detail

Rebasing vs. Merging

- Rebasing is a way to integrate changes from one branch into another by moving the entire branch to begin on the tip of the other branch.
- Unlike merging, rebasing flattens the history because it transfers the completed work from one branch to another in a linear process.

Performing a Rebase

- To rebase:

git checkout feature-branch
git rebase master

- If conflicts arise, resolve them in a similar way to merge conflicts.
- After solving conflicts, continue the rebase with:

git rebase –continue

11. Tags and Releases

Creating Tags

- Tags mark specific points in history as being significant, typically as release points.
- To create an annotated tag:

git tag -a v1.0 -m “Release version 1.0”

- To push tags to a remote repository:

git push origin –tags

12. Git Best Practices

  • Commit often. Smaller, more frequent commits are easier to understand and roll back if something goes wrong.
  • Write meaningful commit messages. Others should understand the purpose of your changes from the commit message.
  • Don’t commit half-done work.
  • Test before you commit. Don’t commit anything that breaks the development build.
  • Keep your branches focused. Each branch should represent a single feature or fix.

13. Git Workflows

Understanding and choosing the right Git workflow is crucial for a team to manage code changes effectively.

Centralized Workflow

  • Similar to SVN, all developers work on a single branch.
  • The master branch is the source of truth, and all changes are committed into this branch.

Feature Branch Workflow

  • Each feature is developed in its own branch and then merged into the master branch when complete.
  • Ensures the master branch always contains production-quality code.

Gitflow Workflow

  • A set structure that assigns very specific roles to different branches and defines how and when they should interact.
  • It uses individual branches for preparing, maintaining, and recording releases.

Forking Workflow

  • Each developer has their own server-side repository.
  • Offers a robust way to integrate contributions from all developers through pull requests or merge requests.

14. Git Hooks

  • Scripts that can run automatically before or after certain important Git actions, such as commit or push.
  • They are used for automating tasks and enforcing certain rules before a commit can be submitted.

15. Gitignore File

  • Specifies intentionally untracked files that Git should ignore.
  • Files already tracked by Git are not affected.

22. Collaborating with Pull Requests

  • Pull requests let you tell others about changes you’ve pushed to a branch in a repository on GitHub.
  • Once a pull request is opened, you can discuss and review the potential changes with collaborators.

Most Popular Git Interview Questions and Answers

Basic Git Commands:

  • git init: Initialize a local Git repository
  • git clone [url]: Create a local copy of a remote repository
  • git status: Check the status of your changes as untracked, modified, or staged
  • git add [file]: Add a file to the staging area
  • git commit -m “[message]”: Commit changes to head (but not yet to the remote repository)
  • git push [alias] [branch]: Transmit local branch commits to the remote repository branch
  • git pull: Update your local repository to the newest commit
  • git merge [branch]: Merge a different branch into your active branch
  • git branch: List your branches. a * will appear next to the currently active branch
  • git branch -d [branch]: Delete a branch
  • git checkout [branch-name]: Switch to a different branch and check it out into your working directory
  • git cherry pick: It introduces certain commits from one branch into another branch within the repository.
  • git checkout -b [branch-name]: Create a new branch and switch to it
  • git stash: Stash changes in a dirty working directory
  • git stash pop: Apply stashed changes to your working directory
  • git rebase: Reapply commits on top of another base tip
  • git reset: Undo commits or unstage files
  • git log: Display the entire commit history using the default format
  • git fetch [alias]: Fetch down all the branches from that Git remote
  • git config -l: List all the settings Git can find at that point

Scenario-based Git Interview Questions

What’s the difference between git fetch and git pull?

git fetch downloads the latest changes from the remote repository to your local repository but doesn’t merge them into your current branch. It’s a safe way to see the changes before integrating them.

git pull, on the other hand, is essentially a git fetch followed by a git merge, where it fetches the remote changes and immediately merges them into the current branch.

How would you temporarily store your current changes that you’re not ready to commit?

I would use git stash to temporarily store the changes:

git stash

Later, when I’m ready to work on them again, I would use git stash pop to apply the stashed changes to the current working directory.

How would you revert a commit that has just been pushed and made public?

 To revert a public commit, I would use the `git revert` command which creates a new commit that undoes the changes made in the pushed commit, without altering the project history. This is important for public or shared repositories because other users may have already pulled the changes. The command would be:

How will you know if a branch has just been merged into master in Git?

To check if a branch has been merged into master, I can use the following command:

git branch --merged master

This will list all the branches that have been merged into the master branch. If I want to check if a specific branch has been merged, I can use:

git revert <commit-hash>
git push origin <branch-name>
git branch --merged master | grep <branch-name>

Can you explain the difference between git revert and git reset? Provide examples and discuss when to use each command.

git revert and git reset are commands used to undo changes in a Git repository, but they work differently and are suited for different situations.

Git Revert:

  • Purpose: Creates a new commit that reverses the effect of earlier commits without altering the existing history.
  • When to Use: Ideal for public branches to undo changes while maintaining a clean project history. It ensures that other collaborators are not affected by history changes.
git revert abc1234

This command reverts the changes made by the commit abc1234 and creates a new commit with the reverted changes.

Git Reset:

  • Purpose: Resets the current branch head to a specific commit, optionally clearing changes in the staging area and working directory.
  • When to Use: Useful for local cleanup before pushing changes, as it can alter commit history, which can be disruptive if used on public branches.
  • Types of Reset:
    • --soft: Only moves the HEAD, keeping the working directory and staging area unchanged.
    • --mixed: Resets the staging area but keeps the working directory unchanged (default).
    • --hard: Resets the staging area and the working directory, potentially leading to data loss.
git reset --hard def5678
  • This resets everything to the commit def5678, discarding all changes in the staging area and working directory.

Summary: Use git revert to safely undo changes in shared branches, preserving history for collaboration. Use git reset for correcting local changes or reorganizing commits before they are shared with others.

What would you do to squash the last N commits into a single commit?

To squash the last N commits into a single commit, you can use the `git rebase` command with the interactive option:

git rebase -i HEAD~N

Where `N` is the number of commits you want to squash. In the text editor that pops up, you’ll see a list of commits. You should leave the first commit as `pick` and change the word `pick` to `squash` or `s` for all other commits you want to combine. Then, save and close the editor. Git will combine all the specified commits into one. After that, you can edit the commit message for the new single commit.

How would you remove a file from Git without removing it from your file system?

To remove a file from Git without deleting it from the local file system, you can use the `git rm` command with the `–cached` option:

git rm --cached <file-path>

After running this command, the file will be removed from version control but will remain in your working directory. Then you can commit this change.

When would you choose “git rebase” instead of “git merge”?

`git rebase` is typically used when you want to create a clean, linear project history without the merge commits that `git merge` would introduce. You would choose to rebase when:

– You’re working on a personal branch and want to update it with the latest changes from the main branch without a merge commit.
– You want to clean up your commit history before merging your changes into the main branch.
– You’re working in a workflow that values a clean history, like the rebase workflow.

Rebase rewrites the project history by creating new commits for each commit in the original branch, which can be a cleaner approach. However, it’s important to avoid rebasing branches that are public and shared with others, as it can cause confusion and complicated merge conflicts for other developers who have based their work on the original branch commit

You’ve made a typo in your last commit message. How do you correct it?

If it’s the very last commit and it hasn’t been pushed to the remote repository yet, you can use:

git commit --amend -m "New commit message"

If you’ve already pushed the commit, you will need to force push, but this should be done with caution if other team members are working on the branch.

Describe the steps you would take to resolve a merge conflict.

When a merge conflict occurs, I would:

  1. Identify the conflicting files with git status.
  2. Open the conflicting files and manually resolve the conflicts by editing the file to remove the <<<<, ====, >>>> conflict markers and making the appropriate code changes.
  3. After resolving the conflict, I would add the files to the staging area with git add.
  4. Finally, I would complete the merge with git commit, which will open an editor for a commit message confirming the merge conflict resolution.

Could you describe the Git branching strategy that is utilized in your company and how it contributes to your development and release process?

Our company uses a Git Flow branching strategy. This includes:

  • Feature Branches: Created from develop for new features and bug fixes, merged back after completion.
  • Develop Branch: Serves as the main integration branch for features.
  • Main Branch: Represents the production-ready state of our code.
  • Release Branches: Used for preparing a new production release, allowing only bug fixes and essential tasks.
  • Hotfix Branches: Address urgent issues in production, later merged into both main and develop.

This structure keeps our main branch stable, allows for organized development, and facilitates smooth releases.

What is a ‘pull request’?

A ‘pull request’ is a feature in version control systems like GitHub that lets you notify a repository’s owners that you want to make some changes to their code. It’s a request to review and then merge these changes into the main codebase.

How can you download a specific branch from a Git repository using the command line?

To download a specific branch from a Git repository, you can use the following command:

git clone -b <branch_name> --single-branch <repository_url>

Replace `<branch_name>` with the name of the branch you want to download and `<repository_url>` with the URL of the Git repository. This command clones only the history of the specified branch, reducing the amount of data downloaded and stored locally.