Skip to main content

Command Palette

Search for a command to run...

Git (Advanced)

Updated
12 min readView as Markdown

A) Branching Strategies:-

Consider you want to take the data from the website and put the same data into the database using Python script. Then my manager said that you can put your code in git. I will merge and review it.

Here the real scenario us that there are 3 branches named as Master, Staging and Dev. In Dev branch, developer develops the code. They will create branch (let’s called Feat1) and merge into Dev. From Dev branch, the code passes to Staging Branch. In Staging branch, people like Beta users, Stakeholders, QA will test and put it into master branch (called as Current Release / Protected Branch).

Now I' will discuss another branching strategy. There are 3 branches named as Prod, Stg, Dev. As usual in Dev branch, codes are being developed by developer. Here, the working is being tested by CI/CD pipeline. Then it passes to Stg branch where QA people will test it out. If there is any error, it will goes to Dev and developer will make changes in the code. If there is no error at Stg branch, then it goes to Prod. All the deployment strategies will being done on Prod branch. If there is any error in Prod branch, a new branch is created called ‘Hotfix’. This branch will solves your error instantly. Once it resolves the error, then it goes to Prod and Stg branch. QA people will test it and from there developer will pull the code from Stg branch.

B)Revert: It is known as Undo

Consider there are 2 commits (C1, C2) in master branch. From 2nd commit, you had create a new branch called Dev. You have created (C3, C4 (considered as incorrect commit), C5). Now you want to revert C4. If you revert C4, then it creates a new commit C6 on Dev. Whatever file you revert, it will not shown on your git directory but it will be shown on commit history.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git branch

master ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git checkout -b dev

Switched to a new branch 'dev'

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ touch feat2.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git add feat2.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git commit -m "feat:added feat2"

[dev de7c089] feat:added feat2 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 feat2.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ touch feat3.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git add feat3.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git commit -m "feat:added feat3"

[dev fe4b4a5] feat:added feat3 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 feat3.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ touch gadbad.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git add gadbad.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git commit -m "feat: added gadbad"

[dev baf52b5] feat: added gadbad 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 gadbad.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ touch feat4.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git add feat4.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git commit -m "feat: added feat4"

[dev 555bc18] feat: added feat4 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 feat4.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git log --oneline

555bc18 (HEAD -> dev) feat: added feat4

baf52b5 feat: added gadbad

fe4b4a5 feat:added feat3

de7c089 feat:added

feat2 d81c429 (master) feat added feat1

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ ls

feat1.txt feat2.txt feat3.txt gadbad.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git revert baf52b5

[dev fbb8366] Revert "feat: added gadbad" 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 gadbad.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ ls

feat1.txt feat2.txt feat3.txt feat4.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git log --oneline

fbb8366 (HEAD -> dev) Revert "feat: added gadbad"

555bc18 feat: added feat4

baf52b5 feat: added gadbad

fe4b4a5 feat:added feat3

de7c089 feat:added feat2

d81c429 (master) feat added feat1

C)Reset:- Now I want to reset the gadbad file. But don’t perform this operation. You need to reset fe4b4a5 commit ID so that it will delete the commit from gadbad commit. But the file will be shown on ls command. This type of reset is known as soft commit which means that the file won’t remove from work directory but it will remove from commit history. Hard Reset means that the file will be removed from commit history as well as work directory.

Note:- Perform Revert & Reset on Dev branch only.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git branch

*dev

master

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git reset fe4b4a5

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ ls

feat1.txt feat2.txt feat3.txt feat4.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git log --oneline

fe4b4a5 (HEAD -> dev) feat:added feat3

de7c089 feat:added

feat2 d81c429 (master) feat added feat1

D)Merge:- Consider there are 2 branches. Master has C1, C2 and C3. From C3, I have created a branch called Dev having C4, C5, C6. When you do git status on C3, it will show as Nothing to commit. Head is pointing on C3. If you do git status on C6, it will show as Your branch is 3 commit ahead of master.

Now we want Dev branch into master branch. Here the master branch is known as Base branch. First go to base branch. Then run git merge Dev which creates a new commit on Master branch pointing from C3 to C7.

Note:- C7 is created from C6 (during merging). It is a normal merge called Fast Forward. If you don’t want a new commit, then you need to use No Fast Forward concept. C7 will be a new Head which points to Master, Dev.

Head points to the latest commit which maintains the previous commit history.

In Merge, we won’t see the timings of the commit and it’s history. Ge, Only C1, C2, C3, C7 will be carry out on Master.

Here in Dev bracnh, I have feat2.txt, feat3.txt and feat4.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ ls

feat1.txt feat2.txt feat3.txt feat4.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git log --oneline

fe4b4a5 (HEAD -> dev) feat:added feat3

de7c089 feat:added feat2

d81c429 (master) feat added feat1

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git status

On branch dev Untracked files: (use "git add ..." to include in what will be committed) feat4.txt

nothing added to commit but untracked files present (use "git add" to track)

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git branch

dev

*master

In Master, I have added feat1.txt and feat4.txt is now Untracked.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ ls

feat1.txt feat4.txt

Now I want feat2.txt and feat3.txt on Master branch.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git merge dev

Updating d81c429..fe4b4a5

Fast-forward

feat2.txt | 0

feat3.txt | 0

2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 feat2.txt create mode 100644 feat3.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ ls

feat1.txt feat2.txt feat3.txt feat4.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git log --oneline

fe4b4a5 (HEAD -> master, dev)

feat:added feat3

de7c089 feat:added

feat2 d81c429 feat added feat1

E)Rebase:- If we want C4, C5 on Master then we can use Rebase. I want to maintain linear history on Master. Here timing and commit history needs to be maintain in sequential manner.

Note:- Rebase will do merge and create a new commit but the branch will show the commits in linear manner.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git switch dev

Switched to branch 'dev'

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ ls

feat1.txt feat2.txt feat3.txt feat4.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git add feat4.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git commit -m "feat: added feat4"

[dev 8822ff5] feat: added feat4

1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 feat4.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git checkout master Switched to branch 'master'

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ ls

feat1.txt feat2.txt feat3.txt ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ touch feat5.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git add feat5.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git commit -m "feat:added feat5.txt"

[master 1220c47] feat:added feat5.txt

1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 feat5.txt

Where is feat4.txt file. It is present in Dev branch.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git log --oneline

1220c47 (HEAD -> master) feat:added feat5.txt

fe4b4a5 feat:added feat3

de7c089 feat:added feat2

d81c429 feat added feat1

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git merge dev

Merge made by the 'ort' strategy.

feat4.txt | 0

1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 feat4.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git log --oneline

ac2568f (HEAD -> master) Merge branch 'dev' 1220c47

feat:added feat5.txt

8822ff5 (dev) feat: added feat4

fe4b4a5 feat:added feat3

de7c089 feat:added feat2

d81c429 feat added feat1

HEAD doesn’t points on Master and Dev. Last time it was pointing to both. This is not necessary merge will point on both the branches.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git checkout dev

Switched to branch 'dev'

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git log --oneline

8822ff5 (HEAD -> dev) feat: added feat4

fe4b4a5 feat:added feat3

de7c089 feat:added feat2

d81c429 feat added feat1

Rebase will be done on dev, because I want master branch to sync here.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git rebase master

Successfully rebased and updated refs/heads/dev.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git log --oneline

ac2568f (HEAD -> dev, master) Merge branch 'dev'

1220c47 feat:added feat5.txt

8822ff5 feat: added feat4

fe4b4a5 feat:added feat3

de7c089 feat:added feat2

d81c429 feat added feat1

Same commit history will be shown on master

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git checkout master

Switched to branch 'master'

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git log --oneline

ac2568f (HEAD -> master, dev) Merge branch 'dev' 1220c47

feat:added feat5.txt

8822ff5 feat: added feat4

fe4b4a5 feat:added feat3

de7c089 feat:added feat2

d81c429 feat added feat1

F)How we can merge Pull Request on GitHub (PR)?

I want to push DevopsBatch directory on github

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git branch dev

*master

dev

Where I need to push, where is origin

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git remote -v

Create a new repository on Github with same name ‘DevopsBatch’

I am linking Github on my local

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git remote add origin https://github.com/bilal05041996/DevopsBatch.git

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git remote -v

origin https://github.com/bilal05041996/DevopsBatch.git (fetch)

origin https://github.com/bilal05041996/DevopsBatch.git (push)

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git push origin master Username for 'https://github.com': ^C

Create a token on github.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git remote set-url origin https://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@github.com/bilal05041996/DevopsBatch.git

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git remote -v origin https://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@github.com/bilal05041996/DevopsBatch.git (fetch) origin https://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@github.com/bilal05041996/DevopsBatch.git (push)

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git push origin master

A new branch is created called master on Github.

Note:- If I run git push origin main, then master branch will merge into main branch.

Now merge dev branch on Github.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git checkout dev

Switched to branch 'dev'

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git push origin dev

You can protect any one of the branch in Github. Go to Repository settings, click on Branches (shown on left side) > Add branch protection rule. Mention the branch pattern name as master. Go to Protect matching branches > Require a pull request before merging. No one will make changes in master branch before PR approval because master branch is now act as a Protected branch.

Create a new file in Dev branch. Once you created a file, then you need to click on Pull Request. Go to Settings > Collaborator. Add people so that they will get invitation. When you open PR, it means that you have make changes and now you will add into your project. Once they accept your invite then you can add them as a reviewer. They will approve or only commit or they will request some changes. Once hey approves, then you click on Merge. Here if you are merging dev branch into master branch on local, similarly when we perform same same operation on github, it is called as Pull Request. You can merge in 3 ways:-

a)Merge Commit: It will create a new commit after merge.

b)Squash and Merge: Consider Dev has 50 commits, master has 50 commits. If you merge dev into master, then master will contain 100 commits. It squash all the commits into one latest commit and merge.

c)Rebase and Merge: it will rebase and merged it.

Consider there is a dev branch on Github. When you run git pull origin dev on local, you are synchronizing both the branches. If there are multiple branches on GitHub, if you want to sync all the branches then we can run git fetch on local.

Create a new branch on Github called Staging

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git branch

*dev

master

I am adding staging changes on dev branch in my local.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git pull origin staging

Master and dev branch of Github sync on local.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git fetch

We can track remote branch.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git checkout staging

branch 'staging' set up to track 'origin/staging'.

Switched to a new branch 'staging'

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git branch

dev

master

*staging

You can fetch all branches.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git fetch --all

G)Hotfix / Cherrypick:-

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git checkout master Switched to branch 'master'

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ ls

feat1.txt feat2.txt feat3.txt feat4.txt feat5.txt

Consider feat4.txt has a bug

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git checkout -b hotfix

Switched to a new branch 'hotfix'

This was a bug → Add content in feat4.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git add feat4.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git commit -m "feat: resolved bug"

[hotfix 765e223] feat: resolved bug 1 file changed, 1 insertion(+)

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ touch feat-not-needed.txt ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git add feat-not-needed.txt ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git commit -m "added unwanted feature"

[hotfix 739aea5] added unwanted feature 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 feat-not-needed.txt

If I merge hotfix branch into master branch, the hotfix will come as well as unwanted feature would also come.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git log --oneline

739aea5 (HEAD -> hotfix) added unwanted feature

765e223 feat: resolved bug

ac2568f (origin/staging, origin/master, staging, master, dev) Merge branch 'dev' 1220c47 feat:added feat5.txt

8822ff5 feat: added feat4

fe4b4a5 feat:added feat3

de7c089 feat:added feat2

d81c429 feat added feat1

I want 765e223 commit ID in master

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git checkout master

Switched to branch 'master'

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git cherry-pick 765e223 [master d67219f] feat: resolved bug Date: Mon Oct 28 06:49:25 2024 +0000 1 file changed, 1 insertion(+)

unwanted feature doesn’t come into master

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ ls

feat1.txt feat2.txt feat3.txt feat4.txt feat5.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ cat feat4.txt

This was a bug

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git log --oneline

d67219f (HEAD -> master) feat: resolved bug

ac2568f (origin/staging, origin/master, staging, dev) Merge branch 'dev'

1220c47 feat:added feat5.txt

8822ff5 feat: added feat4

fe4b4a5 feat:added feat3

de7c089 feat:added feat2

d81c429 feat added feat1

H)Stashing:- It hides your current changes.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git checkout dev

Switched to branch 'dev'

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ vim feat6.txt

This is an ongoing feature → Content of feat6.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git add feat6.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git commit -m "added feat6"

Now I’m adding other content in feat6.txt

I added a few changes → Content

Whatever you have changes in feat6.txt will be removed.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git checkout master

error: Your local changes to the following files would be overwritten by checkout: feat6.txt

Please commit your changes or stash them before you switch branches.

Aborting

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git stash

Saved working directory and index state WIP on dev: d25e6b4 added feat6

Now you can switch to master

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git checkout master

Switched to branch 'master'

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git status

On branch dev nothing to commit,

working tree clean

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git stash pop

On branch dev

Changes not staged for commit:

(use "git add ..." to update what will be committed)

(use "git restore ..." to discard changes in working directory)

modified: feat6.txt

no changes added to commit (use "git add" and/or "git commit -a")

Dropped refs/stash@{0} (ad4a3615b8c87857358c5156a2641524cc3eaf93)

git diff: You can see what changes you have added

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git diff

diff --git a/feat6.txt b/feat6.txt

index 0f5efeb..49dae68 100644

--- a/feat6.txt

+++ b/feat6.txt

@@ -1 +1,2 @@ This is an ongoing feature

+I added a few changes.

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git add feat6.txt

ubuntu@ip-172-31-25-118:~/impprojects/DevopsBatch$ git commit -m "I have modified few changes"

I)Conflict Merge:- Conflict Merges can occur when multiple developers are working on the same project and making changes to the same files, or when a single developer is working on multiple branches and making conflicting changes to the same files. Git tries to automatically merge the changes, but if can’t determine which changes to keep, it will stop and make the file as confict.

Case 1: Single developer work on multiple branches

ubuntu@ip-172-31-25-118:~$ mkdir MergeConflict

ubuntu@ip-172-31-25-118:~$ cd MergeConflict/

ubuntu@ip-172-31-25-118:~/MergeConflict$ git init

ubuntu@ip-172-31-25-118:~/MergeConflict$ vi index.html

Content: <h1> This is a Website </h1>

ubuntu@ip-172-31-25-118:~/MergeConflict$ git add index.html

ubuntu@ip-172-31-25-118:~/MergeConflict$ git commit -m "index.html file is created"

ubuntu@ip-172-31-25-118:~/MergeConflict$ git checkout -b b1

Content: <h1> This is b1 branch </h1>

ubuntu@ip-172-31-25-118:~/MergeConflict$ git add index.html

ubuntu@ip-172-31-25-118:~/MergeConflict$ git commit -m "b1 branch heading"

ubuntu@ip-172-31-25-118:~/MergeConflict$ cat index.html

This is b1 branch

ubuntu@ip-172-31-25-118:~/MergeConflict$ git checkout master

ubuntu@ip-172-31-25-118:~/MergeConflict$ cat index.html

This is a webiste

Switch to master and create a new branch b2

ubuntu@ip-172-31-25-118:~/MergeConflict$ git checkout -b b2

Content: <h1> This is b2 branch </h1>

ubuntu@ip-172-31-25-118:~/MergeConflict$ git add index.html

ubuntu@ip-172-31-25-118:~/MergeConflict$ git commit -m "b2 branch heading"

I want the changes of b2 branch into b1 branch. It will get an error when we try to edit same file at same line.

ubuntu@ip-172-31-25-118:~/MergeConflict$ git merge b2

Auto-merging index.html

CONFLICT (content): Merge conflict in index.html

Automatic merge failed; fix conflicts and then commit the result.

ubuntu@ip-172-31-25-118:~/MergeConflict$ cat index.html

<<<<<<< HEAD

This is b1 branch

=======

This is b2 branch

>>>>>>> b2

You can abort the merge conflict.

ubuntu@ip-172-31-25-118:~/MergeConflict$ git merge --abort

You need to resolve the conflicts manually.

Open index.html and remove b1 code.

ubuntu@ip-172-31-25-118:~/MergeConflict$ git add index.html

ubuntu@ip-172-31-25-118:~/MergeConflict$ git commit

[b1 b6ef6e9] Merge branch 'b2' into b1

12 views

More from this blog

Untitled Publication

36 posts