SPAHUVSS AMS HF*SVLS|NS A hA#SVL ASA he?
Git
Merge & Rebase
FB vostSAHKVSSMHA*SVLAS ASML L_S)}N SARS?
Git Merge & Rebase
Both git merge and rebase, kind of perform the similar task of covabining/joining
the development histories together.
Now, what does that mean?
Sivaple, in git we have concept of branches, we usually have a default (master or
main) branch, and then as part of our regular development/fix work we create
feature/velease branches out of it. Once we are done making our changes in our
feature branches we want it to be published to remote branches and also combined
with the main or master branch to keep it unified and accessible to others with
their changes.
Hence, we need some feature ta jain these changes/histary from different branches,
Both Merge & Rebase let you do that. The end goal is to combine the changes but
how it is done is what waakes Merge & Rebase different.
Let's understand thera with a simple example -
oS featuve/one
ct - ¢2 - c4 - cS master
You basically created a feature branch ‘feature/one! from master when they were
both at covamit 'c2' and then you added a new commit ‘e3' to the feature and also
added 2 new commits 'c4' and '¢5" to master branch,
So, at the moment feature is unaware of the commits c4 & cS which are on the
master and also the master branch has no clue of covamit c3 which is on feature.
ideally that's fine as both are different branches, but if there is a need to combine
them into one destination, then it is needed to know about all these commits.SAHUVASASMHA*HLAS AM hA*bsL ASA hH?
Git Merge & Rebase
Now, suppose We Want to combine the changes from the master branch to
feature/one branch.
**Use the image in last slide as starting point for each of the below operation.
1. Let's perform Merge -
git checkout feature/one
git merge master
cS — cé feature/one
7 4
e1 - ¢2 - C4 - CS waster
You are at your feature branch and performed ‘git merge master’ to merge the
changes of master branch into your feature branch, So, in order to merge the
changes a néw merge Commit 'cé! got created which binds histories Frova both
the branches on feature branch,
So if you now do a ‘git log! you will see a chronological order of commits
For e.g -> CL - c2 - 63 - c4 - e& - c& (assuming ¢ commit was done prior to c+
wrt time)
2. Let's perform Rebase -
git checkout feature/one
git rebase waster
master
e1 - €2 - c4 - cS - c3*feature/one
Rebase, as its name suggests, it actually resets the base. So earlier 'c2' was Common
between feature and waster branch, we can call it the base.
Now, when we fire rebase commana, it will actually pick all commits in feature
after ‘¢2' which is just 'e3' commit. First it will apply all commits frou master into
the featuré and on top it it applies the 'c3' commit. Why ¢c3* é& not cB?
Will explain it.Git Merge with example - Partt
- We are on the master branch, and it has 2 commits.
Now, let's create a feature branch ‘feature/test_merge' from master branch
and switch to it. The commits ave same as master branch.
new commits to the feature branch and 1 new commit to the master]
g/git/merge_and_rebase (feature/test_merge
Let's draw an image which depicts the commits at the moment
to understand it better - (badfd7) - (75/0920) feature/test_merge
(a7efieb) - (61621997) - (4f4930a) master
- It's time to do the Merge.
We are on the master branch
and we merged feature into
master.Git Merge with example - Part2
As we merged the feature branch into the master. Master should now contain
all the changes from feature. Btw, when you ran the merge command a
text editor was opened for you to give the merge commit message.
Nac
Sea ee
(badfd7 9) - (75f071¢) feature/test_merge
4
(a7cfieb) - (61614947) - (4f4930a) - (Sad43fe) master
So, this is how the merge operation is performed.
You can clearly notice one important thing here, that in the histery every commit
hash is consistent. In other words no change in the history took place, but the
only change is addition of a new merge commit (Sad43fe in the above scenario)
fam sure you can imagine the simpl in the overall operation while
performing the merge. Looks like just a game of pointers.Git Rebase with example - Partt
Let's see how Rebase works and how it is different from Merge.
Again, our objective is same. We will create a feature out of master. We will
be adding new changes/commits to both feature and master, And then we will
doa rébase this time to Combine changes from feature to the master branch.
Both ‘master’ and
‘feature/test_vebase' ave
in-syne at the moment.
Now, let's add 2 new commits in the feature branch and + new covamit in the
master branch.
(bfazede) - (6722162) feature/test_rebase
“
(722fsfe) - (aeedeb?) - (ece72d9) masterGit Rebase with example - Part2
- It's time de perform Rebase.
What exactly happened here?
4. The base has been reset, from the last base to a new base
Earlier it was (aeadeb@) and now has been reset to (6722262)
2. The new commits from master (which were not in feature) are applied on top
Messagé 2 in this case.
feature
/testvebase (S4623fe) master
(722fSf2) - (aeedebq) - (bfa2ede) - (¢7222b2) - Koeezada)
Rebase operation is performed on the master branch. You can clearly see what
happened. Firstly all the commits of the ‘feature/test_rebase' are applied on the
last common commit between master and feature (aeedeba). And then on top of
it the new commit from master is applied (Message 3). But wait, the commit
hash looks different. Earlier it was ece72d9 and now it is Sdeasfe. Why?SAHSVASAS AM HhM*SL SSA bFHL_ SSA HH?
To Summarize -
It looks like both Rebase and Merge did there job well. And yes that's true.
In both the cases we got the feature branch changes combined into master branch.
But, one thing which is still not clear, why the commit hash changed in case of
Rebase operation.
Yes, that's how Rebase is done. When you did the merge, no change was done
wrt history (no commit hash changed), just a new merge commit was added.
But in case of Rebase, it actually rewrites the commit history. So, it is not basically
a lift and shift of pointers but also rewiting a new commit of same changes.
We first get the new base and then on top of it we write again the changes
as new commits.
And that's what makes Rebase a little risky and complicated operation if
not performed carefully as it is rewriting the history.
It is always suggested to avoid doing Rebase in a branch/repo being used publicly
or shared with other developers as it could create a mess. Use Merge in such
scenarios.
You can use Rebase when your changes are on your feature and don't affect
others. Like performing squash of commits ete.SAHSVASAS AM HhM*SL SSA bFHL_ SSA HH?
Git pull vs Git pull --rebase
git pull or git pull --merge
Performs : git fetch + git merge
This is the default case.
In this case, your local changes ave merged with the remote changes.
A new merge commit is created pointing to the latest local commit
and the latest remote commit.
git pull --rebase
Performs : git fetch + git rebase
In this case, your local changes are reapplied on top of the remote
changes. So, the new changes on your local ave picked, first the
remote changes are applied which gives a new base and then your
changes that were picked are applied on top as new commits.
Bonus command :P
git checkout -
To switch to the last branch you were at.
This command can be used to switeh to and fro between the branches.Resolving Conflicts
To generate a merge conflict - We created a text file ‘conflict.txt!
on both master and feature branch. Added 2 different ines in file on
each branch. Now we ave trying to merge master changes into the
feature branch.
The moment we did ‘git merge master on feature, it gave us merge
failed evvor and is expecting us to resolve the conflicts manually
We checked the content of conflict.txt file.
The content between "<<<<666e<¢ HEAD" & "= is from our current
=" &
"3292222 master" is from the branch which we ave merging which is
branch which is feature here. And the stuff between "=
master here.Suppose we want to keep the change from feature branch, hence we
will remove what's coming from the master and add this file again
Soi
eS r t stot
ena teas
iste
0 eo
ee Ree!
git merge --continue
To continue the merge operation.
git merge --abort
To abort the merge process.
It will try to reconstruct the pre-merge state
Thanks!!!ee ee ee
Git Stash
stash ~
to store safely in a hidden or secret place.
@mayank ahujaae
Let's understand with an actual scenario -
You are currently inside the local repository ‘git-demot’ which is in-sync with the remote repository
and you don't have any local changes.
aac)
Ret a ales
There is a text file ‘test.txt” which we will be using for the demo. Printed the content of the file.
@mayank ahujaae
Now, let's add new lines in the text file. Added 2 new lines.
ara
en
eee a
y eS
my fifth Tine
@mayank ahujaae
Now due to some reason you don’t want these new changes in the text file now, but you want to keep
them stored somewhere locally as you might need them later.
You basically need a clean working directory at the moment.
git stash’ can help you in this scenario. The command saves your local modifications away and reverts
the working directory to match the HEAD commit.
SCs
Panes
“git status’ shows that the test.txt file has been modified.
But as we wanted to stash the changes we ran ‘git stash save "message" command and did ‘git stash list’
to check the stash and we can see that our change has been saved.
@mayank ahujaae
Now if you do ‘git statu:
are gone.
as
ent
SO eo
oreo at
Soceeeimare
ro
ead
But what if you need the stashed changes back? You need those 2 lines back in the text file.
‘git stash pop’ command gives you the last stashed change.
arate
Soe
as) rd
reais ) aia EL
ana
ee
emer tier
That's mainly how stashing works. Now let's learn some more commands wrt git stash.
@mayank ahujaae
‘$e ‘git stash list” - to know all stashed changes that are available/stored
‘git stash save" is now deprecated and hence you can use ‘git stash push’ instead to stash a change
git stash push -m “message”
aoe
a aa
onan
ea mena
@mayank ahujaae
‘<$~ ‘git stash pop’ vs ‘git stash apply"
You can use either of them to re-apply the stashed change to the working directory, but the
difference is, pop will remove the change from stash (stack) but when you do apply it's kept intact
in the stack,
git stash pop
coe
Sos
ear
creer)
ePvats}
@mayank ahujaae
“> git stash apply
ra
PCs
Pei er errr cise)
eC ar
‘9/git/git-demol (m
You can clearly see that even though the change was re-applied the entry is still present in the stash.
@mayank ahujaae
> git stash apply
ad
Pec
eet
EC Ree)
pre Clears the stashed items.
ot) List shows no entries.
@mayank ahujaCOC
git
reset / revert
Let's UNDOCurrent state - The local repository is in-syne with the remote, we have 2
text files (demoOne & demoTwo) that already exsists on remote and our working
directory is clean(no local changes at the moment).
Let us learn, (master)
er
Se Cle ree a cee eae
Date: Tue Apr 26 21:39:58 2022 +0530
Ce Coan
eee Coreen eee eats
eC es esas herr eerer)
adding few Tines to demoOne file
rset ace
SUL ee berate eet
CCRC ea
a learn, Oro)
cars
Ce eens
Sa Oro)
eee eats
aie
en Rt
ae eR
acc
t us learn Oro)
Cad
VOC Rn
aera) forts]
eect
lon branch master
rc Ue een MC yee
nothing to commit, working tree cleanLet's add a new line in each file and ereate a new commit for each change.
eres (master)
ee eee Coots
eo (coe)
re
Let us learn, coe)
ee OC eC
eC eC)
1 file changed, 1 insertion(+)
are fore)
Pe i a ee Cr acd
oy cca)
rae oa (coe)
Case C CT Aunt Le
(master)
S$ git log
een ener eens nee Pare
pate: Tue Apr 26 2 eRrorietrrn
This is how th
pee ere meee is is haw the
commits look like
eee eee eee ren een eae now
CC tat eee Set cee cce)
Ce Ree aary Pec ornite
i added in our local
CUCM ae eee Re Cus eared
elas DC eed ees Pree repo.
adding demoTwo file
We are actually
eee eee ea now 2 conuuits
elas a ees fh re Ee)
ahead of the
coe
remote.
ee eee
Penta elas Perret Es
EC ot aa mayank Sgit reset --soft
Let om
(2th eee ele eee er Cee i)
eae rep)
caer)
POR eee eer aa ceec te L eare
tea Tue Apr 26 21:39:58 2022 +0530
ee ea
Se Cree eR ec ae
Tue Apr 26 21:39:09 2022 +0530
CC a ea
eee Ree eee
Tue Apr 26 21:38:20 2022 +0530
Cr Cut aa
Let us learn, cer)
Peer
Pu
Nour branch is up to date with ‘origin/master’.
GO Coe
(use "git restore —-staged reset to 2 commit after current
HEAD, HEAD~2 -> 2 commits after HEAD ete.)
When you perform reset, it always undo all commits after specitied commit
and not just that commit or a specific range. mayank_at a)git reset --mixed
ee
ee ee
ieee oad
In Cees
Im Cees
ey crap)
est
lon branch master
ree ee ar re ae
eee ese ect sd
Cr ae as oe a Mn)
(use "git restore ..." to discard changes in working directory)
ae cre]
rae)
Author: mydemo222
Conn seer re oraneLe
Sean
Mee reer Cee ce
fo Ce ed seer Relea)
Ce Re un
Me eee Cee ese
Ce ee oREL Eee eee)
Eee aa
What actually happened?
When you pass the flag ‘mixed! (which is default), it behaves similar to ‘soft! in
the sense that the changes are not lost from the local but are unstaged. So, you
need to add thera again if you need them back before doing commit or may
be stash them. Here we moved 1 commit ahead from prev HEAD. Or
in other words removed all commits after HEAD-1 . >git reset --hard
As in the last change we did soft reset, let's add back the unstaged files and
also commit them. Added a new commit '8b2¢a... HEAD pointer updated
[Crt s ia)
ws Tear Crp]
ECU
Se ec
Tue Apr 26 22:14:30 2022 +0530
Ce er
eee aoe eae
Sete Esme eerie tet)
Se
Now, when we use
Deets eed in
Tue Apr 26 21:39:09 2022 +0530 the flag ‘hard’ in
Roe Cee ee eae the reset command,
It vesets the
Sere eee ener ee ea ence ee commit but also
elas SCT es eee bear Lt)
removes all
Cm Cent aE changes from
rer (master) local which where
Feehan
eee eC Coc naa part of those
eae a) coop) commit(s).
eat
eee Working directory
Your branch is up to date with ‘origin/master’. .
is clean,
Inathing to commit, working tree clean
mw nk_ahu jaa og
git revert
This is the current state, we are in syne with the remote repo.
Seer Coe)
git revert command sounds similar to reset, and yes both are like performing the
undo operation, but reset was much cleaner that revert.
Why so? When you perfrom the vevert operation, it will undo the commit (or range
of commits) but it also adds extra commits te perform this revert.
So, basically git history would have the commit that had the change plus a commit
which was used to revert the change.
Let's see that in the next slide, what happened when we fired the revert, = >hen we fired the revert command in prev slide, it actually asked to add a
commit message for the revert we are going to perform. With revert
Sera en we can actually
Eee eta ter undo any specific
Please enter the commit message for your changes. Lines starting commit or range
eC UU me ae .
. 2 . of commits.
With reset
it was resetting
Om
Pee ee are
is
Se
3 ad everything
after the specified
commit. We
can't specify a
range there.
(master)
ar
Pe irre ec Reece eeece
Date: Tue Apr 26 22:15:33 2022 +0530 A new revert
a commit has
been added.
This is a Revert command demo ~ Reverting “adding demoTwo file
This reverts commit ca54bc9c0486922e6683eaf8442d1 eSdea8Safb9.
ee ree eer Rone Cae
Tue Apr 26 21:39:58 2022 +0530
Se a Now, doa
i ‘git push'
ee ree aera Rene eee gt P
ree eee eee) if you Want
ee a this change to
appear on the
: mydemo222 Part 1
Assume the local branch is in-sync with the remote branch at the moment.
Both ‘master’ (local copy) and ‘origin/master’ (pointer to remote master)
ave pointing to the same commit ‘s4ad...
Now, suppose one of your teammate has added/pushed a new file on master
remote branch. You local master is not aware of that change.
Let's do ‘git fetch’ and see what happens.
git fetch
[CeCe
Oh! t can only see ‘master’ pointing to 'séad..", but where is ‘origin/master' ?
in/master got updated to what's in the remote
When you did ‘git fetch’ the ovi
master. As your teammate added a new change, it must be pointing to it.git pull is git fetch + git merge -> Part 2
~ Let's find out where is ‘origin/master' _git log origin/master
er crest]
IS git log origin/master
Ce ee eee eee
SUE Laser CRs eee)
rcs
Pe ee eee eer
St ec LTe reese)
eae eas
See, the ovigin/master points to the latest commit which is on remote master,
but your local master still points te ‘sad. old covamit.
How can we syne them again?
git merge
we need to doa merge no
a forerio)
ec
Veta CLEC MET eet)
aera ger
Pieces
ad CReL ute Ea aT TGD)
eC
Awesome, both origin/master and master are now pointing to the same cormit.
ee)
ced
ee eee ese
CeCe Be Ser tertile dec ET)
es
pe eee ae ee
STE Beene Ee eae)
resendgit pull is git fetch + git merge -> Part 3
We can perform the complete ‘git fetch' + ‘get merge’
thing by just doing ‘git pull’.
Assume, that your teammate again added a new text file on remote master
and you local master is unaware of the change.
Current state - ‘git log!
arr (master)
ea)
ce
PO eee eee een ener a me
pris Thu Apr 28 21 5 2022 +0530
ccs
eee eee een
(re Cees S Eee cae)
aera
= Let's do ‘git pull' and see what happens : git pull When we did ‘git pull',
et us Tea (master) an
aie a ie it first performed
Sa ee eee ee ‘git . ed
eons ate CL eRe agit fetch’ followed by
Cet aa RCD CL ‘git merge’
Total 3 (delta 0), reused 0 (delta 0), p
Tiegh el Sian ee ee
enn ae urea reed
Cert ee ee
Tenet ae as p pointir
eo raaster’ pointing to
Panel samme new commit.
‘origin/master’ &
Cee eee
Thu Apr 28 21:42:50 2022 +0530
CS eaCreating and Publishing a Local branch to Remote
~ create a local branch ‘feature/demot' and switch te newly ereated branch.
git branch featuve/demo1
git checkout -b feature/demor OR git checkout feature/demot
ee er
Cor koe
ais c ona ean GESEL
fear)
rte branch ‘fea ae(creas)
t leg
cated
er eee een Cee es
Dee ee Een eee
Third commit
cue See et
Steeler aes s Sec LE)
Second commit
ee reseed
pr ae eee Perse rZ ae SEs)
aeons
- viewing last n commits (in this case 2 commits)
git log -n2
ian (master)
$ git log -n2
cies
Oe reece ae
(re ee Cea err BE MeL aeSC Es)
SR
eee ee ee eos
Thu Apr 28 20:42:42 2022 +0530
oer mets
— one liner info of every commit
git log --oneline
ey core)
er ae
ved Third commit
Second commit
eas(creas)
rey
cated
er eee een Cee es
tee ee
Third commit
See et
Ree CECE ar ese s Sec E
Second commit
eed Sec tar,
prea ee ere Pere cae)
aeons
- skipping last n commits (in this case 2 cormmits)
git log --skip=2
et u fcretaD]
IS git log --ski
Sees, eee a
(te ee ee Be reese ec)
oats
— grep commits by string/pattern
git log --grep="Second"
ae (creas
ea ee
ee ese
Thu Apr 28 20:42:42 2022 +0530
curesgit cherry-pick is cool
As the name sounds, it is used to pick changes from existing commit and
apply them by creating a new commit.
Let's see a simple example.
We are on ‘feature/demo' branch currently and we have added a new change
with commit id '32.904..'- Created hello file
Se at
We can see the ‘master’ is behind by 1 commit from the feature.
We know one way to updated ‘master’ is by doing merge with the feature branch.
But here, we will see how cherry-pick works. We can pick a commit and apply.
So let's pick the commit '32.904..' and apply it to master.
Let's switch to master and do cherry pick.
After cherry -pick
the same changes
from that commit
crc
1 file changed, 1 insertion(+) are applied to
re ae ee master branch.
s git To = / ? ee But it created a
new commit
with a different
oe Can
shat.Let's see the difference
- difference between 2 commits git diff commit commit2
al... from commits ‘s4ad...' & b/... is from commit2 ‘a7eLO..". You can see 2
files (hello.txt and pull.txt) were added in commit2.
~ similarly you can see diff of tip between two branches
git diff bvanchA branchB
- to see difference between your local (unstaged) vs staged(indexed) changes
git diff
to see difference between staged(indexed) changes vs what's commited your local
wepo git diff --staged
oR
git diff --cached
ens
eee)In a nutshell
Stash Working Staging Local Remote
as|
Tree, Area, Repo Repo
git stash git diff t git diff staged +
f git diff --cached!
git pop : o> >
git apply :
git ade + git commit git push
git rm :
git fetch
+ git merge
git rebase
git pull
"
& mrayank_ahuja