Interview Questions for Web Developer - Git
Tags: git, interview
Published: 2024-01-01 10:36:08

## Possible questions

**1. What is GIT and why do we need it?**
Git is a distributed version control system designed to track changes in source code during software development. It allows multiple developers to collaborate on a project simultaneously, tracks changes made to files, facilitates branching and merging, and provides a history of revisions. Git helps maintain a consistent codebase, enables teamwork, provides a backup of code, and aids in tracking changes over time, ensuring better code management and project coordination.

**2. What basic Git commands do you know and how to use them?**
- `git init`: Initializes a new Git repository in the current directory. Use git init to start version controlling your project.

- `git clone [repository URL]`: Copies an existing Git repository from a remote location to your local machine. Use `git clone` followed by the repository URL to clone a repository.

- `git add [file]`: Adds changes in a file to the staging area for the next commit. Use `git add [file]` to stage specific files or `git add .` to stage all changes.

- `git commit -m "[commit message]"`: Records changes to the repository with a descriptive commit message. Use `git commit -m "[message]"` to commit staged changes.

- `git status`: Displays the current status of the working directory, showing changes that are staged, unstaged, or untracked.

- `git pull`: Fetches changes from a remote repository and integrates them into the current branch. Use `git pull` to update your local repository with changes from the remote repository.

- `git push`: Uploads local branch commits to the remote repository. Use `git push` to push committed changes to the remote repository.

- `git branch`: Lists, creates, or deletes branches in the repository. Use git branch to see existing branches, `git branch [branch-name]` to create a new branch, or `git branch -d [branch-name]` to delete a branch.

- `git checkout`: Switches between branches or restores files in the working directory to a specific commit. Use `git checkout [branch-name]` to switch branches or `git checkout [commit-hash] [file]` to restore a file to a specific commit.

**3. What is the difference between `git merge` and `git rebase`?**
The main difference between `git merge` and `git rebase` lies in how they integrate changes from one branch into another:

- `git merge`: Integrates changes by creating a new commit that combines the changes of the specified branch into the current branch. This results in a linear history and preserves the commit history of both branches.

- `git rebase`: Integrates changes by moving the entire branch to the tip of the specified branch, applying each commit on top of the destination branch. This results in a cleaner, linear history but can alter the commit history and potentially cause conflicts if used on shared branches.

In essence, `git merge` retains the original branch structure and creates a merge commit, while `git rebase` rewrites the commit history to incorporate changes more seamlessly but can lead to a cleaner and linear history. Use `git merge` for preserving branch history and `git rebase` for a cleaner commit history when working on feature branches.

**4. What is a commit in Git and how to form it correctly?**
In Git, a commit represents a snapshot of changes made to files in a repository at a specific point in time. It records the changes and includes a commit message that describes the purpose or context of the changes.

The most common approach for commit messages is to use [conventional commit messages](https://www.conventionalcommits.org/en/v1.0.0/) e.g.

```bash
feat: add new feature
fix: resolve issue with function
docs: update documentation
```

**5. How to use tags in Git?**
In Git, tags are used to mark specific points in the commit history, such as releases, milestones, or significant versions. They provide a way to reference and label specific commits for easier identification.
To use tags in Git:
_Creating a tag:_

- Use `git tag [tag_name]` to create a lightweight tag pointing to the current commit.

- For annotated tags with additional information like a message, use `git tag -a [tag_name] -m "Tag message"`.

_Pushing tags to remote:_

- To push a single tag to the remote repository, use `git push origin [tag_name]`.

- To push all tags at once, use `git push origin --tags`.

_Viewing tags:_

- To list all tags, use `git tag`.

- To see details of a specific tag, use `git show [tag_name]`.

**6. What is a merge conflict and how to resolve it?**
A merge conflict in Git occurs when there are conflicting changes in the same part of a file or between different branches being merged. Git cannot automatically determine which changes to accept, resulting in a conflict that requires manual resolution. To resolve a merge conflict:

- Use `git status` to identify files with conflicts.

- Open the conflicted files in your code editor.

- Locate and manually resolve the conflicting sections marked by Git, keeping the desired changes.

- After resolving conflicts, add the modified files using `git add [file]`.

- Complete the merge process by committing the changes with `git commit`, leaving a descriptive commit message about the conflict resolution.

- Finally, complete the merge with `git merge --continue` or `git rebase --continue` if you were in the middle of a rebase.

Resolving merge conflicts involves understanding the conflicting changes, manually adjusting the code to incorporate desired modifications, and then committing the resolved changes to finalize the merge process.

**7. What are the best practices for working with remote repositories?**

Some best practices for working with remote repositories in Git include:

- _Frequent Pulls and Pushes_: Regularly pull changes from the remote repository (`git pull`) to keep your local copy up-to-date. Similarly, push your commits (`git push`) to the remote repository to share your changes and collaborate effectively.

- _Descriptive Commit Messages_: Write clear and descriptive commit messages to communicate the purpose and context of your changes to collaborators.

- _Branch Management_: Use branches for new features, bug fixes, or experiments. Push branches to the remote repository to facilitate collaboration and review before merging into the main branch.

- _Consistent Branch Naming_: Adopt a consistent branch naming convention, such as using prefixes like `feature/`, `bugfix/`, or `hotfix/` to organize and categorize branches.

- _Review and Pull Request_: Before merging changes, initiate pull requests or code reviews in the remote repository to ensure quality, discuss modifications, and receive feedback from team members.

- _Use SSH Keys or HTTPS Authentication_: Authenticate securely with the remote repository using SSH keys or HTTPS to ensure proper access control and security.

- _Regular Backups_: Regularly back up your work by pushing to remote repositories, reducing the risk of losing changes and ensuring a secure backup of your codebase.

**8. How to use the `.gitignore` file?**
The `.gitignore` file is used in Git to specify intentionally untracked files that Git should ignore. It helps prevent files or directories from being committed to the repository.

```bash
# Ignore log files
*.log

# Ignore node_modules directory
node_modules/

# Ignore .env file with sensitive information
.env

# Ignore files in a specific directory
src/temp/*

```

**9. How to revert a commit in the local repository?**

- Identify the Commit to Revert:
Find the commit hash of the commit you want to revert. You can use `git log` to view the commit history and copy the commit hash.

- Revert the Commit:
Use `git revert [commit_hash]` to create a new commit that undoes the changes made in the specified commit. For example:

```bash
git revert abcdef12345  # Replace 'abcdef12345' with the actual commit hash
```

- Push the Revert (if needed):
If you want to share the reverted changes with others, push the revert commit to the remote repository using `git push`.

```bash
git push origin <branch_name>
```

**10. How to revert a commit in the remote repository?**

- Identify the Commit to Revert: Find the commit hash of the commit you want to revert. Use git log to view the commit history and copy the commit hash.

- Reset the Branch: Use `git reset --hard HEAD~1` to move the branch pointer back to the previous commit (replace `HEAD~1` with the appropriate number of commits you want to revert). For example, to revert the last commit:

```bash
git reset --hard HEAD~1
```

- Push the Changes (if needed): If the changes have already been pushed to the remote repository and you've rewritten history using git reset, you might need to force push the changes to the remote branch using:

```bash
git push origin <branch_name> --force
```
Be extremely cautious when force pushing as it can overwrite changes on the remote branch and cause problems for other collaborators. Only force push if you're certain it won't impact others.

**11. How maintain conventional commits in a repo?**
The easiest way to maintain is to setup pre-commit hook that will runs every time you make a commit. There are specific libs for it, my preferred is [Husky](https://typicode.github.io/husky/). With it, you may define a rule like this below to check a commit message text:

```bash
red=$(tput setaf 1) # ANSI escape code for red color
reset=$(tput sgr0)  # ANSI escape code to reset color

#Get commit message
commit_msg=$(git log -1 --pretty=%B)

#Commit message check
if ! echo "$commit_msg" | grep -qE "^(feat|fix|chore|docs|test|style|refactor|perf|build|ci|revert)(\(.+?\))?:? .{1,}$
"; then
    echo "${red}Error${reset}: Invalid commit format, try: feat(feature): description." >&2
    exit 1
fi

if [ ${#commit_msg} -gt 88 ]; then
    echo "${red}Error${reset}: Invalid commit length. Your commit message is too long." >&2
    exit 1
fi
```

---

## Sources / Literature

- [Git official documentation](https://git-scm.com/)

- [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)