According to the latest Stack Overflow developer survey, more than 70 percent of developers use Git, making it the most-used VCS in the world. Git is commonly used for both open source and commercial software development, with significant benefits for individuals, teams and businesses.
🔴 Originally published on FullStack.Cafe - Kill Your Tech & Coding Interview
Q1: What is Git fork? What is difference between fork, branch and clone?
Topic: Git
Difficulty: ⭐⭐
- A fork is a remote, server-side copy of a repository, distinct from the original. A fork isn't a Git concept really, it's more a political/social idea.
- A clone is not a fork; a clone is a local copy of some remote repository. When you clone, you are actually copying the entire source repository, including all the history and branches.
- A branch is a mechanism to handle the changes within a single repository in order to eventually merge them with the rest of code. A branch is something that is within a repository. Conceptually, it represents a thread of development.
🔗Source: stackoverflow.com
Q2: What's the difference between a "pull request" and a "branch"?
Topic: Git
Difficulty: ⭐⭐
A branch is just a separate version of the code.
A pull request is when someone take the repository, makes their own branch, does some changes, then tries to merge that branch in (put their changes in the other person's code repository).
🔗Source: stackoverflow.com
Q3: What is the difference between "git pull" and "git fetch"?
Topic: Git
Difficulty: ⭐⭐
In the simplest terms, git pull
does a git fetch
followed by a git merge
.
When you use
pull
, Git tries to automatically do your work for you. It is context sensitive, so Git will merge any pulled commits into the branch you are currently working in.pull
automatically merges the commits without letting you review them first. If you don’t closely manage your branches, you may run into frequent conflicts.When you
fetch
, Git gathers any commits from the target branch that do not exist in your current branch and stores them in your local repository. However, it does not merge them with your current branch. This is particularly useful if you need to keep your repository up to date, but are working on something that might break if you update your files. To integrate the commits into your master branch, you usemerge
.
🔗Source: stackoverflow.com
Q4: How to revert previous commit in git?
Topic: Git
Difficulty: ⭐⭐⭐
Say you have this, where C is your HEAD and (F) is the state of your files.
(F)
A-B-C
↑
master
- To nuke changes in the commit: ```sh
git reset --hard HEAD~1
Now B is the HEAD. Because you used --hard, your files are reset to their state at commit B.
* To undo the commit but keep your changes:
```sh
git reset HEAD~1
Now we tell Git to move the HEAD pointer back one commit (B) and leave the files as they are and git status
shows the changes you had checked into C.
- To undo your commit but leave your files and your index ```sh
git reset --soft HEAD~1
When you do `git status`, you'll see that the same files are in the index as before.
🔗**Source:** [stackoverflow.com](https://stackoverflow.com/questions/927358/how-to-undo-the-most-recent-commits-in-git)
### Q5: What is "git cherry-pick"?
> Topic: **Git**<br/>Difficulty: ⭐⭐⭐
The command git *cherry-pick* is typically used to introduce particular commits from one branch within a repository onto a different branch. A common use is to forward- or back-port commits from a maintenance branch to a development branch.
This is in contrast with other ways such as merge and rebase which normally apply many commits onto another branch.
Consider:
```sh
git cherry-pick <commit-hash>
🔗Source: stackoverflow.com
Q6: Explain the advantages of Forking Workflow
Topic: Git
Difficulty: ⭐⭐⭐
The Forking Workflow is fundamentally different than other popular Git workflows. Instead of using a single server-side repository to act as the “central” codebase, it gives every developer their own server-side repository. The Forking Workflow is most often seen in public open source projects.
The main advantage of the Forking Workflow is that contributions can be integrated without the need for everybody to push to a single central repository that leads to a clean project history. Developers push to their own server-side repositories, and only the project maintainer can push to the official repository.
When developers are ready to publish a local commit, they push the commit to their own public repository—not the official one. Then, they file a pull request with the main repository, which lets the project maintainer know that an update is ready to be integrated.
🔗Source: atlassian.com
Q7: Tell me the difference between HEAD, working tree and index, in Git?
Topic: Git
Difficulty: ⭐⭐⭐
- The working tree/working directory/workspace is the directory tree of (source) files that you see and edit.
- The index/staging area is a single, large, binary file in /.git/index, which lists all files in the current branch, their sha1 checksums, time stamps and the file name - it is not another directory with a copy of files in it.
- HEAD is a reference to the last commit in the currently checked-out branch.
🔗Source: stackoverflow.com
Q8: Could you explain the Gitflow workflow?
Topic: Git
Difficulty: ⭐⭐⭐
Gitflow workflow employs two parallel long-running branches to record the history of the project, master
and develop
:
-
Master - is always ready to be released on LIVE, with everything fully tested and approved (production-ready).
-
Hotfix - Maintenance or “hotfix” branches are used to quickly patch production releases. Hotfix branches are a lot like release branches and feature branches except they're based on
master
instead ofdevelop
.
-
Hotfix - Maintenance or “hotfix” branches are used to quickly patch production releases. Hotfix branches are a lot like release branches and feature branches except they're based on
-
Develop - is the branch to which all feature branches are merged and where all tests are performed. Only when everything’s been thoroughly checked and fixed it can be merged to the
master
.-
Feature - Each new feature should reside in its own branch, which can be pushed to the
develop
branch as their parent one.
-
Feature - Each new feature should reside in its own branch, which can be pushed to the
🔗Source: atlassian.com
Q9: When should I use "git stash"?
Topic: Git
Difficulty: ⭐⭐⭐
The git stash
command takes your uncommitted changes (both staged and unstaged), saves them away for later use, and then reverts them from your working copy.
Consider:
$ git status
On branch master
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
$ git stash
Saved working directory and index state WIP on master: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage
$ git status
On branch master
nothing to commit, working tree clean
The one place we could use stashing is if we discover we forgot something in our last commit and have already started working on the next one in the same branch:
# Assume the latest commit was already done
# start working on the next patch, and discovered I was missing something
# stash away the current mess I made
$ git stash save
# some changes in the working dir
# and now add them to the last commit:
$ git add -u
$ git commit --ammend
# back to work!
$ git stash pop
🔗Source: atlassian.com
Q10: How to remove a file from git without removing it from your file system?
Topic: Git
Difficulty: ⭐⭐⭐⭐
If you are not careful during a git add
, you may end up adding files that you didn’t want to commit. However, git rm
will remove it from both your staging area (index), as well as your file system (working tree), which may not be what you want.
Instead use git reset
:
git reset filename # or
echo filename >> .gitingore # add it to .gitignore to avoid re-adding it
This means that git reset <paths>
is the opposite of git add <paths>
.
🔗Source: codementor.io
Q11: When do you use "git rebase" instead of "git merge"?
Topic: Git
Difficulty: ⭐⭐⭐⭐⭐
Both of these commands are designed to integrate changes from one branch into another branch - they just do it in very different ways.
Consider before merge/rebase:
A <- B <- C [master]
^
\
D <- E [branch]
after git merge master
:
A <- B <- C
^ ^
\ \
D <- E <- F
after git rebase master
:
A <- B <- C <- D <- E
With rebase you say to use another branch as the new base for your work.
When to use:
- If you have any doubt, use merge.
- The choice for rebase or merge based on what you want your history to look like.
More factors to consider:
-
Is the branch you are getting changes from shared with other developers outside your team (e.g. open source, public)? If so, don't rebase. Rebase destroys the branch and those developers will have broken/inconsistent repositories unless they use
git pull --rebase
. - How skilled is your development team? Rebase is a destructive operation. That means, if you do not apply it correctly, you could lose committed work and/or break the consistency of other developer's repositories.
- Does the branch itself represent useful information? Some teams use the branch-per-feature model where each branch represents a feature (or bugfix, or sub-feature, etc.) In this model the branch helps identify sets of related commits. In case of branch-per-developer model the branch itself doesn't convey any additional information (the commit already has the author). There would be no harm in rebasing.
- Might you want to revert the merge for any reason? Reverting (as in undoing) a rebase is considerably difficult and/or impossible (if the rebase had conflicts) compared to reverting a merge. If you think there is a chance you will want to revert then use merge.
🔗Source: stackoverflow.com
Thanks 🙌 for reading and good luck on your interview!
Check more FullStack Interview Questions & Answers on 👉 www.fullstack.cafe
Top comments (43)
Hi Alex. First of all thanks for your comment. You are absolutely right - fork is not a Git concept and it's specifically stated just right after the words you've cited. In regards of server-side, hmmm... fork in Github (that the majority of teams are working with) is a "server-side" clone of repo. If you think it's wrong to mention it on an interview and that words drove you crazy you should probably delegate interviewing to someone else. Also there is a great practical interview question about "Forking workflow" in the article that you alas missed. And by the way it's great you've just warned people from potential working with you - I would personally avoid any professional relationships with "teams" or "devs" who use phrases like "not read further, you have no idea about, will never hire" in their lexicon ;) So good luck in boosting your "authority" amongst the community and have a great working day!
Hi Alex and Aleksei
I think this thread is getting a little heated and that's not helping, and I don't want to fuel the fire, but I had exactly the same response as Aleksei - I got to your first definition and came to the comments to see if anyone had brought it up, and I didn't read any further at the time.
Alex, you used the phrase
What is Git fork?
and I immediately became confused since there's no such git command. It could be a typo for "what is a git fork" but since we're used to using git subcommands it seems to stand out.It's easy enough to use the wrong words, and sometimes it's more important than others.
If I was conducting an interview around version control workflows and someone citing git was talking about servers, I wouldn't dismiss the applicant, but I would ask them to clarify so they had a chance to convince me that they knew what they were doing.
Thank you for your reply Ben. As you stated the key point of any interview is to have a conversation around a question. I'm not pretending that the question "What is Git fork?" was intentionally created to confuse or derail a prospective but having to see in response the interviewee correction ("stars" would be immensely happy to do that) or mentioning that "a fork isn't a Git concept" for the rest of us is a solid and clear sign of a conceptually strong candidate (and that was "the" intention). It's again my pleasure to say thanks to you and AleX for pointing it out in a first place but let me leave that question title as it is to be the "anti-pattern" some people will stumble on and discuss :)
Thanks for the comment Ben here.
Aleksei, I just want to note that you could have approached this whole situation in a much more constructive way. And since you're generally a great community member, I just want to remind you to take the time to address issues you see in a less provocative way.
I know you're acting in good faith, so just want to remind you that expressing tone on the web can be hard but we have high standards for community members to put in the effort to be good about this stuff.
For Q10, one can also do
git rm --cached <filepath>
to remove the file from the git index and keep it in the working tree; which is the exact opposite ofgit add <filepath>
. This will also work on filepaths that have been committed, which is especially helpful in the case of newly ignoring a previously committed file.Also, conceptually
git reset <filepath>
is a wrong solution: it works only if you have not committed the addition of file (as you have said);git rm --cached <filepath>
always work (though you need to remember that it removes the file only from future commits, and the file will be present in history).Note that if you don't remember the command,
git status
would tell you how to do it.There are indeed some topics and concepts that only apply to social coding platforms such as GitHub. Maybe it's a good idea to specify this difference in the beginning of the post? 'The difference between Git and GitHub'
As a developer who has used both Github and GitLab, that could be another topic to explore, the differences between remote repo implementations and how the effect your workflow. Actually now that I have that written out, it might be the next topic I explore :) Thanks for your help with my brainstorming.
That's a great candidate for a post in and of itself.
Maybe I'll write something up!
I was about to do that... sometime ago..
Oh I've got a very clear answer when to use rebase: n-e-v-e-r. The process is obscure and the tooling is bad, even in modern IDEs such as IntelliJ it's not clear what is going on during a rebase. Just don't do it, the downsides by far outweigh the advantages. A force push is rarely a good idea. My team uses gitflow almost exclusively and we're quite happy with it, aside from the occasional "shouldn't we use rebase" discussion.
I’d like to disagree. While it requires some caution, pull —rebase / regular rebase of live branches / interactive rebase before merge / merge —no-ff workflow leads to a much cleaner history and makes reorganization/disaster recovery much easier, at least to my taste.
If rebase implies force push on shared branches and if you rely on automagic GUI trickery in your team, then you probably need training and discipline more that a simpler workflow.
Sure, why not having a civilized conversation by starting off with implying that the other guy has no idea what they are talking about and "need training". Way to go.
I've heard the arguments - all of them, plenty of times, over and over again. I am fully aware of the advantages. And I still think that it's a bad idea. You may call it a "clean history" - I say this is not how it happened. The result of a rebase is an arbitrarily twisted and warped version of the actual project history. If the sole reason for a rebase is a straight line in gitk, then count me out. Sticking to gitflow with merge commits gives you a history that actually deserves the name because it is based on facts. It is a perfectly fine workflow, even juniors get it quickly. I see no reason to add more complexity to that. And rebase is not without caveats.
Sorry if my tone was condescendent, I was just feeling that if your initial harsh rejection of rebase was because it was synonymous of force pushes and lack of proper GUI, it was pretty misguided.
If we start talking about the real stuff, then I’m not a gitk follower either. And I merge on trunks (no-ff), but after a rebase. Actually after regular rebases of living branches between their emergence and their merge. No rebase of shared branches (clone then rebase if the base is too old after a proper synchronization point), no push force either, publication of a private branch after rebase and before merge —no-ff to have the commits details on hand. Gitflow is ok to me, just feature/private branches handling feels better with rebases than with merges at least to me.
Sorry again if you took it personally, but you started 😝 by attacking cruelly my lovely rebase.
The main goal of rebase is to prepare a branch before submitting pull request (or equivalent), in the "blessed repository" workflow. It helps maintainer to have up-to-date changes, and less conflicts.
While at it, you can cleanup all the "fixup" commits with
git rebase --interactive
.Is the "blessed repository" or integrator workflow similar to a forking workflow? I was trying to research the difference but they sound similar to me.
I am talking here about workflow titled "Integration-Manager Workflow" in the "Pro Git" book, chapter 5.1: Distributed Workflows.
Got it, the infographics are quite helpful with reading through git workflows.
Excellent article. I won't cry, because i like git very much, but you're correct, those questions (at least some of them) are tricky and may cause problems especially during something as stresful as job interview.
Just one note: reverting a commit using reset is a bit too much in some cases and can be considered as a bad practice. For reverting single commit there's a "revert" command which is safer and can be better in some situations. "Explain difference between reset and revert" can be good interview question as well :).
Thanks for the article Alex.
For Q4 I feel you might be instructing users to do something a bit dangerous with
git reset --hard HEAD~1
.If commit C has been pushed anywhere then using the above command local project will result in your local project history being different from upstream. This will cause conflicts if you try to merge later.
If you want to revert a commit that's been pushed it's much safer to use a command like
git revert <commit>
. This will introduce an extra commit, the reverse of the commit you're attempting to undo.Though you end up with an extra commit no ones code will be broken, and this can be merged safely to remotes where the C commit might have been pushed.
You can read more on the
git revert
command hereThe terminology might not be 100% correct, because
git
itself doesn't have a concept of a "server" or a "fork", but the fact is that the vast majority of Git users do use Git concerning a server and forks. Togit
, there is no difference between a fork on a Github server and a clone elsewhere on my machine, but that knowledge really isn't necessary if you're not implementing the git protocol yourself or rolling your own Github. A fork is a remote copy of the repo, and that remote is a central server.What I mean by this is that me, as a developer just picking up git, am going to get extremely confused trying to contribute to a Github project if I know understand the difference between a clone and a fork. I will commit changes to my local clone, but will not understand why they don't immediately go to my fork on Github. Describing the decentralized nature of Git in this sense is not going to help me in any way get my changes back into the master repo on Github.
To to reiterate, the
git
tool itself has no such thing as a "fork" and doesn't have a concept of a "server", and yet a fork is a very real thing in the git workflow, and just about any project you contribute to will have a centralized server. Not only is it rude to harshly criticize the author in this regard, but it misses the point of why the question would be asked. In an interview, the employer doesn't want to know if you understand the full protocol of git, they're asking if you know how to use their development workflow.Thanks this is so helpful. Part of the knowledge I've enforced and with your notes, it's easier to make my own notes. I think when someone shares part of their knowledge we should always compare it with what we know. :) Thanks for sharing.
Nice article, I’d just like to add two pointers for those willing to push their git-fu further:
A last thing: with feature branches + rebase workflow, —no-ff is a must when merging to the trunk.
Thanks again for this nice article.
I think the Q2 is not really clear, while it's more correct in StackOverflow link.
"A pull request is when someone take the repository, makes their own branch, does some changes, then tries to merge that branch in (put their changes in the other person's code repository)."
I would have said that a Pull Request is not a Git concept but a Git projects hosting (github/bitbucket/etc) concept where a UI is associated to a branch to discuss about its purpose, to review code changes and to emit remarks or suggestions before merging it to another branch.
In other words, it's a relational step in a development workflow where all involved parties can discuss before merging a code change to the main codebase.