Entering into DevOps: 01 Git Basics

Arjun Pandey
Dev Genius
Published in
23 min readDec 31, 2022

Being an IT professional for more than 15+ years, at various level: Individual contributor -> Team Lead -> Manager -> Director-> Leader/Individual contributor and working experienced with people across the globe, I thought of writting a series on DevOps tooling and its usage. The challenges are multi-fold as there are many tools, each tool has its own learning curve and each tool changes as per the market requirement very frequently.
Those who don’t grow in accordance with these technologies, gets automatically knocked off. From last few years, I have been mentoring for junior team members and I realised that in an attempt to become “Jack of all” we start loosing the basic core concepts. Infact I was also mindlessly repeating the same actions without realizing what was happening or why I was doing it hoping that everything would work out well for me.
With these articles, I wanted to share the information that helped me understand the overall DevOps tooling. This article is about “Git”.

Let’s roll…

What is git?
It is a version control software just like SVN, CVS etc and provides the basic core functionality….
1. Keep track of code changes.
2. Collaborate on code.
3. “Time Travel” back to previous versions
4. Revert to previous versions

Git vs GitHub?
→ Git is a version control software that runs locally and doesn’t need internet.
→ GitHub is a hosting service for Git repository in the cloud and makes it easier to collaborate.

How to configure Git?
There are many configuration options supported with git and we can use the below command to list all the available options.

% man git-config

One of the first things you need to set up is your name and email address, to let Git know “who you are?”.

#Setting user.name
% git config --global user.name parjun8840
#Validating user.name
% git config user.name
parjun8840
# Setting user.email
% git config --global user.email noreply@gmail.com
#Validating user.email
% git config user.email
noreply@gmail.com

What is a Git Repository?
A Git repository tracks and saves the history of all changes made to the files in a Git project. It saves this data in a directory called . git , also known as the repository folder. Let’s create one.

% mkdir firstRepo
% cd firstRepo
% git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: git branch -m <name>
Initialized empty Git repository in /Users/arjunpandey/gitrepos/firstRepo/.git/
% ls -lart
total 0
drwxr-xr-x 12 arjunpandey staff 384 Dec 31 15:30 .git

What is the git workflow?
There are three important areas to git. These are the Working Tree, the Staging Area (also known as Index), and the Local Repository. When working in a git repository files and modifications will travel from the Working Tree to the Staging Area and finish at the Local Repository.

Each commit made to the local repository acts as an point-in-time snapshot of the Project and we can restore the entire project at a given point-in-time.
commit = point-in-time snapshot of the Project = group of changes in multiple files recorded as a snapshot

Each file in your working directory can be in one of two states: tracked or untracked.
Tracked files are files that were in the last snapshot, as well as any newly staged files. In short, tracked files are files that Git knows about.
Untracked files are everything else- any files in your working directory that were not in your last snapshot and are not in your staging area.

Working directory: This area is also known as the “untracked” area of Git or in other words Git doesn’t track files in this area. If you make changes and do not explicitly save them to git, you will lose the changes made to your files.

Staging area: The staging area can be described as a preview of your next commit. When you create a git commit, Git takes changes that are in the staging area and make them as a new commit. You are allowed to add and remove changes from the staging area. Git doesn’t have a dedicated staging directory where it can store some objects representing file changes (blobs). Instead of this, it uses a file called index (inside .git directory).

Repository: The Local Repository is everything in your .git directory. Mainly what you will see in your Local Repository are all of your checkpoints or commits.

Three important areas in Git
The lifecycle of the status of your files

What is Atomic commit?
Atomic means all or nothing — either everything succeeds or all fails.
→Git is known to have atomic operations i.e. an environment issue will not cause git to commit half of the files into the repository and leave the rest.
→Similarly the code you check-in should also have the atomicity (atomic commit)per commit. Every commit should be related to one feature/bug only. Do not make a commit which is related to even two features/bugs.
Atomic commits are easier to revert, drop, and amend.

Let’s make first commit

% touch name.go contact.go

% git status
On branch vvmaster

No commits yet

Untracked files:
(use "git add <file>..." to include in what will be committed)
contact.go
name.go

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

% git add .

% git status
On branch master

No commits yet

Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: contact.go
new file: name.go

% git commit -m "first commit"
[master (root-commit) 9d66e2d] first commit
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 contact.go
create mode 100644 name.go

% git status
On branch master
nothing to commit, working tree clean
%
Workflow for the above example

Let’s learn few commands

1) git add: The git add command adds a change from the working directory to the staging area. It tells Git that you want to include updates to particular files in the next commit. However, git add doesn’t really affect the repository in any significant way — changes are not actually recorded until you run git commit.

2) git commit: Commits changes from the staging area to the local repository. Each commit records a new versions of project into the repository’s history.

3) git log: For displaying the commits history in a repository. The advanced features of git log can be split into two categories:
→Formatting Log Output-
“ — oneline”: flag condenses each commit to a single line. By default, it displays only the commit ID and the first line of the commit message.

git log - oneline

→Filtering the Commit History-
By Amount: The most basic filtering option for git log is to limit the number of commits that are displayed.

git log -3

Creating one more commit and executing all the above commands

% touch address.go
% git add .
% git commit -m "adding second commit"
[master 03bf850] adding second commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 address.go

arjunpandey@Arjuns-MacBook-Pro firstRepo % git log
commit 03bf8506492dc913855a59049d21323244b1c6ad (HEAD -> master)
Author: parjun8840 <noreply@gmail.com>
Date: Sat Dec 31 22:35:53 2022 +0900

adding second commit

commit 9d66e2d9a476f0a2a676da4993928e65f7bd8331
Author: parjun8840 <noreply@gmail.com>
Date: Sat Dec 31 21:51:05 2022 +0900

first commit
arjunpandey@Arjuns-MacBook-Pro firstRepo % git log --oneline
03bf850 (HEAD -> master) adding second commit
9d66e2d first commit
arjunpandey@Arjuns-MacBook-Pro firstRepo % git log -1
commit 03bf8506492dc913855a59049d21323244b1c6ad (HEAD -> master)
Author: parjun8840 <noreply@gmail.com>
Date: Sat Dec 31 22:35:53 2022 +0900

adding second commit
arjunpandey@Arjuns-MacBook-Pro firstRepo % git log -1 --oneline
03bf850 (HEAD -> master) adding second commit
arjunpandey@Arjuns-MacBook-Pro firstRepo %

Rewriting history

Git or any Version control system is a Time Machine we can go back in time and undo the changes.
Git has several mechanisms for storing history and saving changes. These mechanisms include: Commit — amend, git rebase and git reflog

Changing the Last Commit (going back in time): git commit — amend
We will see a very basic and useful scenario in this example.
→Files to be commited: 2
→User forgot to commit 1 file
→Creating a new commit will increase the history & also won’t be a great impression on the person reviewing your work.

Incase you want to learn “go” with me, you can download & install it from here https://go.dev/dl/.

% cat ~/.zshrc 
export PATH=/opt/homebrew/bin:/usr/local/go/bin:$PATH
% source ~/.zshrc
% cat name.go
package main
import "fmt"
func main() {
fmt.Println("My name is: Arjun")
}

Or you can just write any text in "name.go"

Note: It isn’t mandatory to have go, I just want to keep things more practical by using the above go example.

% git add name.go 
% git commit -m "Add name.go"
[master 7ede2ba] Add name.go
1 file changed, 5 insertions(+)
% git status
On branch master
nothing to commit, working tree clean
%

Realise you forgot to: (1) add changes to the file contact.go with previous commit (2) The commit is not proper

% git status        
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: contact.go

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

% git commit --amend
hint: Waiting for your editor to close the file...
Add content to contact.go & name.go

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Tue Jan 3 10:42:00 2023 +0900
#
# On branch master
# Changes to be committed:
# modified: contact.go
# modified: name.go
arjunpandey@Arjuns-MBP firstRepo % git status
On branch master
nothing to commit, working tree clean
%
% git log --oneline
33475db (HEAD -> master) Add content to contact.go & name.go
03bf850 adding second commit
9d66e2d first commit
%

Ignoring files and directories

Git sees every file in your working copy as one of three things:
tracked- a file which has been previously staged or committed;
untracked- a file which has not been staged or committed; or
ignored- a file which Git has been explicitly told to ignore.

Ignored files are usually build artifacts and machine generated files that can be derived from your repository source or should otherwise not be committed. Some common examples are:
. dependency caches, such as the contents of /node_modules or /packages
. compiled code, such as .o, .pyc, and .class files
. build output directories, such as /bin, /out, or /target
. files generated at runtime, such as .log, .lock, or .tmp
. hidden system files, such as .DS_Store or Thumbs.db
. personal IDE config files, such as .idea/workspace.xml

In this example will generate a go artifact and put it in .gitignore
We generated an artifact as “name” which is an executable binary.

% go build name.go
arjunpandey@Arjuns-MBP firstRepo % ls -lrt
total 3792
-rw-r - r - 1 arjunpandey staff 0 Dec 31 22:35 address.go
-rw-r - r - 1 arjunpandey staff 79 Jan 3 10:32 name.go
-rw-r - r - 1 arjunpandey staff 19 Jan 3 10:43 contact.go
-rwxr-xr-x 1 arjunpandey staff 1931650 Jan 3 11:21 name
arjunpandey@Arjuns-MBP firstRepo % ./name
My name is: Arjun
%
#Running git status, shows we have an untracked file
% git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
name

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

Ignored files are tracked in a special file named .gitignore that is checked in at the root of your repository. There is no explicit git ignore command: instead the .gitignore file must be edited and committed by hand when you have new files that you wish to ignore. .gitignore files contain patterns that are matched against file names in your repository to determine whether or not they should be ignored.

% git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
name

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

#Adding gitignore file
% cat .gitignore
#Ignoring a particular file
name
#.log, debug.log, logs/debug.log
*.log
#Appending a slash indicates the pattern is a directory.
#logs/debug.log, build/logs/latest/debug.log
logs/

% git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore

nothing added to commit but untracked files present (use "git add" to track)
%
% git add .gitignore
% git commit -m "Adding gitignore file"
[master b2f2ca7] Adding gitignore file
1 file changed, 8 insertions(+)
create mode 100644 .gitignore
#We do have binary file still present in the working doirectory
% ls -lrta
total 3800
drwxr-xr-x 3 arjunpandey staff 96 Dec 31 14:51 ..
-rw-r--r-- 1 arjunpandey staff 0 Dec 31 22:35 address.go
-rw-r--r-- 1 arjunpandey staff 79 Jan 3 10:32 name.go
-rw-r--r-- 1 arjunpandey staff 19 Jan 3 10:43 contact.go
-rwxr-xr-x 1 arjunpandey staff 1931650 Jan 3 11:21 name
-rw-r--r-- 1 arjunpandey staff 182 Jan 3 11:35 .gitignore
drwxr-xr-x 8 arjunpandey staff 256 Jan 3 11:35 .
drwxr-xr-x 12 arjunpandey staff 384 Jan 3 11:39 .git

Git Branch

A branch represents an independent line of development. Branches serve as an abstraction for the edit/stage/commit process. You can think of them as a way to request a brand new working directory, staging area, and project history. New commits are recorded in the history for the current branch.

Incase you want to go little deeper into branches:
Each commit gets a hash value and internally git uses these hash values.
In Git, a branch is a pointer to one specific commit, while a commit is a snapshot of your repository at a specific point in time.
Your branch pointer moves along with each new commit you make.
Redefining the branch- A branch in Git is simply a lightweight movable pointer to one of these commits. The default branch name in Git is master.

% git log --pretty=raw
commit b2f2ca7916b181bace0f3f37344cf90076694aeb
tree 38d62a9b464743efc50fd7ffbad5e59e37cd1298
parent 33475db3ee49dbdf7b2e72d46378fc702dae0351
author parjun8840 <noreply@gmail.com> 1672713552 +0900
committer parjun8840 <noreply@gmail.com> 1672713552 +0900

Adding gitignore file

commit 33475db3ee49dbdf7b2e72d46378fc702dae0351
tree 1189289675346e3956e0fae8fdb4fef404dfe2e0
parent 03bf8506492dc913855a59049d21323244b1c6ad
author parjun8840 <noreply@gmail.com> 1672710120 +0900
committer parjun8840 <noreply@gmail.com> 1672710711 +0900

Add content to contact.go & name.go

commit 03bf8506492dc913855a59049d21323244b1c6ad
tree c31cd4d8074a58b329172852fb176ad27e509923
parent 9d66e2d9a476f0a2a676da4993928e65f7bd8331
author parjun8840 <noreply@gmail.com> 1672493753 +0900
committer parjun8840 <noreply@gmail.com> 1672493753 +0900

adding second commit

commit 9d66e2d9a476f0a2a676da4993928e65f7bd8331
tree f743e78d93c5feaacac9bdaad989e22509b2e584
author parjun8840 <noreply@gmail.com> 1672491065 +0900
committer parjun8840 <noreply@gmail.com> 1672491065 +0900

first commit
%

We can see the parent field, which connects the commit with its parent(s). Also the tree field, which connects the commit with a tree object.
Commits make the skeleton of the history, with other objects and refs attached to them.
It’s a directed graph structure.

Note: The “master” branch in Git is not a special branch. It is exactly like any other branch. The only reason nearly every repository has one is that the git init command creates it by default and most people don’t bother to change it.

Start branch name with a Group word: bug or wip or feature.
Example: wip-8840-short-taskname 8840- refers to ticket id of an task/issue.

Git checkout is the old command which was used to create and switch branches. It can also be used to restore changes from a certain commit. But git checkout does more than that.

git branch: List all of the branches in your repository.
git branch <branch>: Create a new branch called <branch>. This does not check out the new branch.
git branch -d <branch>: Delete the specified branch. This is a “safe” operation in that Git prevents you from deleting the branch if it has unmerged changes.
git branch -m <branch>: Rename the current branch to <branch>.
git branch -a: List all remote branches. (Don't worry about this now we will see it later)
git switch: Switch to a specified branch. Optionally a new branch could be created with either -c, -C, automatically from a remote branch of same name.
Using"switch" command to create and switch to the branch in a single command.
You can use "branch" command to create branch and then use "switch".
You can also use "checkout" command but refrain it from using this old style.
* show the current branch

% git branch
* master
% git switch -c wip-8840-user-module
Switched to a new branch 'wip-8840-user-module'
% git branch
master
* wip-8840-user-module
%
% git commit -a -m "addded 2 users"
[wip-8840-user-module c6bf0b0] addded 2 users
1 file changed, 7 insertions(+)
arjunpandey@Arjuns-MBP firstRepo %
% git commit -a -m "added code for multiple users"
[wip-8840-user-module 14e8101] added code for multiple users
1 file changed, 1 insertion(+), 1 deletion(-)
%
Only master branch
Branch with 2 new commits

“HEAD” branch, often this is also referred to as the “active” or “current” branch. It is a pointer to the current branch and by default it refers to the latest commit in a branch.

HEAD pointer moves with new commits
==> HEAD points to new commit

% git log --oneline
14e8101 (HEAD -> wip-8840-user-module) added code for multiple users
c6bf0b0 addded 2 users
b2f2ca7 Adding gitignore file
33475db Add content to contact.go & name.go
03bf850 adding second commit
9d66e2d first commit

% git switch master
Switched to branch 'master'
% git commit -a -m "added parjun8840 address"
[master e0e124c] added parjun8840 address
1 file changed, 8 insertions(+)
arjunpandey@Arjuns-MBP firstRepo % git status
On branch master
nothing to commit, working tree clean
%
% git log --oneline
e0e124c (HEAD -> master) added parjun8840 address
b2f2ca7 Adding gitignore file
33475db Add content to contact.go & name.go
03bf850 adding second commit
9d66e2d first commit
master branch and wip-8840-user-module branch graphical representation

Git checkout vs switch

+-----------+--------------------+--------------------------------------------+
| previous command | new command | Description |
+-----------+--------------------+--------------------------------------------+
| git checkout <branch> | git switch <branch> | Switch branches |
| git checkout | N/A | restore the contents |
| git checkout -b <branch> | git switch -c <branch> |Create branches |

+-----------+--------------------+--------------------------------------------+

==> Checkout demo to restore the contents from Git repository.
Even the staged changes also will be overwritten.

% cat contact.go
#This is a comment
I messed up with this file
I need to revert latest changes from the last snapshot or commited version.

% git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: address.go
modified: contact.go

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

#Restoring address.go
% git checkout address.go
Updated 1 path from the index
% git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: contact.go

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

#Restoring multiple files or working directory
% git checkout -f
% git status
On branch master
nothing to commit, working tree clean

Merging Branches

git merge — Joins two or more development histories together.
The git merge command lets you take the independent lines of development created by git branch and integrate them into a single branch.
The current branch will be updated to reflect the merge, but the target branch will be completely unaffected. Again, this means that git merge is often used in conjunction with git switch for selecting the current branch and git branch -d for deleting the obsolete target branch.

Git merge will combine multiple sequences of commits into one unified history.

Assume the following history exists and the current branch is “master”:

        A---B---C topic
/
D---E---F---G master

Then “git merge topic” will replay the changes made on the topic branch since it diverged from master (i.e., E) until its current commit © on top of master, and record the result in a new commit along with the names of the two parent commits and a log message from the user describing the changes.

         A---B---C topic
/ \
D---E---F---G---H master

The second syntax (“git merge — abort”) can only be run after the merge has resulted in conflicts. git merge — abort will abort the merge process and try to reconstruct the pre-merge state.

Fast Forward Merge
No new “merge commit” is created
Instead of “actually” merging the branches, all Git has to do to integrate the histories is move (i.e., “fast forward”) the current branch tip up to the target branch tip. This effectively combines the histories, since all of the commits reachable from the target branch are now available through the current one.
However, a fast-forward merge is not possible if the branches have diverged or when there is not a linear path to the target branch.

Fast-Forward merge

Lets create a branch “bug-8840-pagination” and commit a change to contact.go

==> Before merging
% git branch
* master
wip-8840-user-module
% git switch -c bug-8840-pagination
Switched to a new branch 'bug-8840-pagination'
%
% git branch
* bug-8840-pagination
master
wip-8840-user-module
%

% git log --oneline
fea3e9b (HEAD -> bug-8840-pagination) Edited contact.go
e0e124c (master) added parjun8840 address
b2f2ca7 Adding gitignore file
33475db Add content to contact.go & name.go
03bf850 adding second commit
9d66e2d first commit
%

==> As you can see the changes are linear from master branch to the tip of the target branch
Graphical representation of the above state
% git switch master
Switched to branch 'master'
%
% git merge bug-8840-pagination
Updating e0e124c..fea3e9b
Fast-forward
contact.go | 1 +
1 file changed, 1 insertion(+)
% git log --oneline
fea3e9b (HEAD -> master, bug-8840-pagination) Edited contact.go
e0e124c added parjun8840 address
b2f2ca7 Adding gitignore file
33475db Add content to contact.go & name.go
03bf850 adding second commit
9d66e2d first commit
%
Both master & bug-8840-pagination pointing to the same commit and no new commit

3-way merge
When there is not a linear path from the current branch to the target branch.
In the 3-way merge, Git uses three commits to generate the merge commit; two branch tips and their common ancestor.

3-way merge results in a New merge commit

Make a new commit to the master branch after creating a branch “wip-8840-authentication” from it.

% git switch -c wip-8840-authentication
Switched to a new branch 'wip-8840-authentication'
% vim name.go
% git commit -a -m "made changes to name.go"
[wip-8840-authentication cfa1fb9] made changes to name.go
1 file changed, 1 insertion(+)
% vim contact.go
% git commit -a -m "made changes to contact.go"
[wip-8840-authentication 122f7cc] made changes to contact.go
1 file changed, 3 insertions(+)
%
% git log --oneline
122f7cc (HEAD -> wip-8840-authentication) made changes to contact.go
cfa1fb9 made changes to name.go
1926717 (master) merged branch wip-8840-user-module
fea3e9b (bug-8840-pagination) Edited contact.go
e0e124c added parjun8840 address
14e8101 (wip-8840-user-module) added code for multiple users
c6bf0b0 addded 2 users
b2f2ca7 Adding gitignore file
33475db Add content to contact.go & name.go
03bf850 adding second commit
9d66e2d first commit
%

% git switch master
Switched to branch 'master'
% vim address.go
% git commit -a -m "made changes to address.go"
[master 4d66ed2] made changes to address.go
1 file changed, 3 insertions(+), 1 deletion(-)
% git log --oneline
4d66ed2 (HEAD -> master) made changes to address.go
1926717 merged branch wip-8840-user-module
fea3e9b (bug-8840-pagination) Edited contact.go
e0e124c added parjun8840 address
14e8101 (wip-8840-user-module) added code for multiple users
c6bf0b0 addded 2 users
b2f2ca7 Adding gitignore file
33475db Add content to contact.go & name.go
03bf850 adding second commit
9d66e2d first commit
Graphical representation of the branches and commits
% git merge wip-8840-authentication
hint: Waiting for your editor to close the file...
Merge branch 'wip-8840-authentication'
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.

Merge made by the 'ort' strategy.
contact.go | 3 +++
name.go | 1 +
2 files changed, 4 insertions(+)
% git status
On branch master
nothing to commit, working tree clean

% git log --oneline
02605a6 (HEAD -> master) Merge branch 'wip-8840-authentication'
4d66ed2 made changes to address.go
122f7cc (wip-8840-authentication) made changes to contact.go
cfa1fb9 made changes to name.go
1926717 merged branch wip-8840-user-module
fea3e9b (bug-8840-pagination) Edited contact.go
e0e124c added parjun8840 address
14e8101 (wip-8840-user-module) added code for multiple users
c6bf0b0 addded 2 users
b2f2ca7 Adding gitignore file
33475db Add content to contact.go & name.go
03bf850 adding second commit
9d66e2d first commit
%

3-way merge with Resolving conflict
If the two branches you’re trying to merge both changed the same part of the same file, Git won’t be able to figure out which version to use. When such a situation occurs, it stops right before the merge commit so that you can resolve the conflicts manually.
There are various MERGE STRATEGIES (what changes to pick and discard)

==> switch to 'wip-8840-user-module' branch and check history
% git switch wip-8840-user-module
Switched to branch 'wip-8840-user-module'
% git log --oneline
14e8101 (HEAD -> wip-8840-user-module) added code for multiple users
c6bf0b0 addded 2 users
b2f2ca7 Adding gitignore file
33475db Add content to contact.go & name.go
03bf850 adding second commit
9d66e2d first commit

==> switch to 'master' branch and check history
% git switch master
Switched to branch 'master'
% git log --oneline
fea3e9b (HEAD -> master, bug-8840-pagination) Edited contact.go
e0e124c added parjun8840 address
b2f2ca7 Adding gitignore file
33475db Add content to contact.go & name.go
03bf850 adding second commit
9d66e2d first commit

% git merge wip-8840-user-module
Auto-merging contact.go
CONFLICT (content): Merge conflict in contact.go
Automatic merge failed; fix conflicts and then commit the result.
% cat contact.go
#This is a comment
<<<<<<< HEAD
#Added second comment
=======
parjun8840:
email: noreply-arjun@gmail.com
address: amsterdam
sam:
email: noreply-sam@gmail.com
address: amsterdam

>>>>>>> wip-8840-user-module
% vim contact.go
% cat contact.go
parjun8840:
email: noreply-arjun@gmail.com
address: amsterdam
sam:
email: noreply-sam@gmail.com
address: amsterdam
% git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)

Changes to be committed:
modified: name.go

Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: contact.go

% git commit -a -m "merged branch wip-8840-user-module"
[master 1926717] merged branch wip-8840-user-module
% git log --oneline
1926717 (HEAD -> master) merged branch wip-8840-user-module
fea3e9b (bug-8840-pagination) Edited contact.go
e0e124c added parjun8840 address
14e8101 (wip-8840-user-module) added code for multiple users
c6bf0b0 addded 2 users
b2f2ca7 Adding gitignore file
33475db Add content to contact.go & name.go
03bf850 adding second commit
9d66e2d first commit

Stashing and Cleaning

The git stash command takes your uncommitted changes (staged), saves them away for later use, and then reverts them from your working copy.

In some urgent cases you may have to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the git stash command.
git stash temporarily shelves (or stashes) changes you’ve made to your working copy so you can work on something else, and then come back and re-apply them later on. Stashing is handy if you need to quickly switch context and work on something else, but you’re mid-way through a code change and aren’t quite ready to commit.
There are 2 possibilities: 1) My change comes with me to the destination branch (untracked files) 2) Git won’t let me switch if detects potential conflict (modified files)

1) My change comes with me to the destination branch (untracked files)

(master)$vim README.md
(master)$git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md

nothing added to commit but untracked files present (use "git add" to track)
(master)$git switch bug-8840-pagination
Switched to branch 'bug-8840-pagination'
(bug-8840-pagination)$git status
On branch bug-8840-pagination
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md

nothing added to commit but untracked files present (use "git add" to track)
2) Git won't let me switch if detects potential conflicts. I have to either commit or stash the current work

(master)$git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: name.go

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: address.go

(master)$git switch bug-8840-pagination
error: Your local changes to the following files would be overwritten by checkout:
name.go
Please commit your changes or stash them before you switch branches.
error: Your local changes to the following files would be overwritten by checkout:
address.go
Please commit your changes or stash them before you switch branches.
Aborting
(master)$
(master)$git stash
Saved working directory and index state WIP on master: 02605a6 Merge branch 'wip-8840-authentication'

#You can run git stash several times to create multiple stashes, and then use git stash list to view them.
(master)$git stash list
stash@{0}: WIP on master: 02605a6 Merge branch 'wip-8840-authentication'
(master)$
(master)$git switch bug-8840-pagination
Switched to branch 'bug-8840-pagination'
(bug-8840-pagination)$vim contact.go
(bug-8840-pagination)$git commit -a -m "changed contact.go in branch bug-8840-pagination"
[bug-8840-pagination e4c3edd] changed contact.go in branch bug-8840-pagination
1 file changed, 1 insertion(+)
(bug-8840-pagination)$git status
On branch bug-8840-pagination
nothing to commit, working tree clean
(bug-8840-pagination)$git switch master
Switched to branch 'master'

(master)$git status
On branch master
nothing to commit, working tree clean
(master)$git stash list
stash@{0}: WIP on master: 02605a6 Merge branch 'wip-8840-authentication'
arjunpandey@Arjuns-MBP firstRepo % (master)$git stash pop
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: address.go
modified: name.go

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (7145ff8932ef5e4a0282377de179d25e690c8697)
(master)$git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: address.go
modified: name.go

no changes added to commit (use "git add" and/or "git commit -a")
(master)$git commit -a -m "stash example modified address.go name.go"
[master 6806b24] stash example modified address.go name.go
2 files changed, 3 insertions(+), 1 deletion(-)

Applying stash:
→You can reapply previously stashed changes with git stash pop. Popping your stash removes the changes from your stash and reapplies them to your working copy.

(master)$git status
On branch master
nothing to commit, working tree clean
(master)$git stash list
stash@{0}: WIP on master: 02605a6 Merge branch 'wip-8840-authentication'
(master)$git stash pop
On branch master
Changes not staged for commit:
(use "git add <file>…" to update what will be committed)
(use "git restore <file>…" to discard changes in working directory)
modified: address.go
modified: name.go
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (7145ff8932ef5e4a0282377de179d25e690c8697)

→Alternatively, you can reapply the changes to your working copy and keep them in your stash with “git stash apply”.

Cleaning up your stash:
→If you decide you no longer need a particular stash, you can delete it with “git stash drop”.

→Alternatively you can delete all of your stashes with “git stash clear”


(master)$git stash drop stash@{1}
Dropped stash@{1} (17eff97fd8251df6163117cb9e58c1f62a5e7cdb)

(master)$git stash list
stash@{0}: WIP on master: 6806b24 stash example modified address.go name.go

(master)$git stash clear
(master)$git stash list
(master)$

That’s it for this part. Next part will be more on GitHub…. Please follow me on medium.com , linkedin.com/in/arjun-pandey to motivate me & stay tune for the next part in this series….

Thank you patiently reading patiently…

For the Next part in this series please follow this link GitHub basics

There are 2 important points I would like to highlight:
→Please don’t make direct changes to master/main branch.
→Spotted something wrong/misleading information in the article? Apologies!! Please help me to amend the same ASAP.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

What are your thoughts?