As we wade and plow through the files working, there are points in time when we need to review what-all changes we made. Sometimes even why we made those in first place. Wherein comes the version control systems
.
Git as it’s definition says on official source,
Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.
And it has a lot many small caveats and features which become almost a muscle memory as you work with git over the time. Since we devs favor CLI over GUI, there are always some command which are HOTTT !! in market forever and so are asked as a rite of passage in interviews.
One such eternal question among many others is difference between git pull
and git fetch
. For someone very keen on thinking IT is all about “meaningful” words, set to meaningful tasks, this is huge disappointment ask google meaning of fetch and pull , it says they are almost the same.
But for git NOPE! they are different. Like water and fire.
In git a fetch essentially is a query to update information from the remote source. It’s like going to online shopping site and checking-in for your favorite product and adding it to cart if you find desirable update, you don’t buy it though! It’s just there FYI.
A pull is like going to shopping site and then casually wandering in electronics section for products, and bam!! suddenly you own a 52 inch ultra-modern-not-needed TV. Hey it wasn’t intentional but a pull is like that, it updates everything local to match remote changes.
git pull = git fetch + git merge
Now let’s see the game in action.
Clone a repository , You should see a unimaginatively named example
directory in your current working directory, get inside the directory. When you clone a repository or repo
,as we call it, essentially makes a copy of everything that remote repository has.
# shows all branches
git branch -a
main
* trial-branch
trial-five
trial-four
trial-one
trial-three
trial-two
remotes/origin/HEAD -> origin/main
remotes/origin/main
remotes/origin/trial-branch
remotes/origin/trial-five
remotes/origin/trial-four
remotes/origin/trial-one
remotes/origin/trial-three
remotes/origin/trial-two
# shows many branches, branches with *remote* suffix are remote branches and others are local
This shows that currently I am on local-branch
called trial-branch
. If you list the content, a README.md
is found here with just one word inside FirstName
Now let’s go to github and make a change in this file. Any change.
I added another word LastName
and commit the change, so now the file looks something like this,
FirstName LastName
Now keep in mind that we made this change at the remote
and not at our local clone/copy of file.
Perform a git fetch
on your cli.
git fetch
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 675 bytes | 1024 bytes/s, done.
From github.com:mohitwasnik132/example
8a8f3cf..c3ab2d9 trial-branch -> origin/trial-branch
ignore the jargon for a moment and focus on last line.
what do you see?
8a8f3cf..c3ab2d9 trial-branch -> origin/trial-branch
this means.. there is some change in origin/trial-branch
commit id 8a8f3cf..c3ab2d9
which is not reflected in local branch we are on, the trail-branch
can be easily checked,
mohit@DESKTOP-HOME: example| on trial-branch
cat README.md
FirstName
So, the change we made at remote hasn’t been reflected but git informed us that there is a change in the branch, even if it isn’t showing what change, it has given a commit id which can be checked for particular change.
Let’s switch to remote
branch and check what this supposed change is.( since we only have one file, it’s obvious that we check README.md again)
mohit@DESKTOP-HOME: example| on trial-branch
git checkout origin/trial-branch
.
.
.
mohit@DESKTOP-HOME: example| on c3ab2d9
cat README.md
FirstName LastName
So the change can be seen.
What does this prove?
This proves that in simple terms, A git fetch will READ
the changes from the remote repository but it does NOT WRITE
them in the local repository.
To write these changes we have to perform a separate merge operation.
mohit@DESKTOP-HOME: example| on c3ab2d9
git checkout trial-branch
mohit@DESKTOP-HOME: example| on trial-branch
git merge origin/trial-branch
Updating 8a8f3cf..c3ab2d9
Fast-forward
README.md | 1 +
1 file changed, 1 insertion(+)
Now again if we check README.md
it’s reflecting the change we made earlier in remote branch, the local had no idea about.
mohit@DESKTOP-HOME: example| on trial-branch
cat README.md
FirstName LastName
what’s the use of git pull then?
Git pull is best when you know and trust the changes in remote repository will not hurt your current work.
A git pull always creates a new local merge commit
which has all the all the remote commits or to word it better, changes missing in the local branch compared to remote. Git pull is usually done with caution and with suitable strategies such as a rebase merging strategy
that is using git pull with --rebase
option.
It doesn’t ask if you need those changes, it just pulls and merges them right into work which wrecks havoc if not done carefully. So, as a beginner it’s good to be patient and do a fetch
instead of a pull
always remember,
PULL = FETCH + MERGE and no asking. No consulting. It’s just a leap of faith.
This was a long blog but I hope someone benefits from the details I tried to put in.
See you in next blog!