git

git++, The Advanced git!

knowing just git basics ain’t enough these days

Priyansh Khodiyar
26 min readMay 25, 2022

--

Photo by Roman Synkevych 🇺🇦 on Unsplash

The following article contains everything you will ever need if you know basic git commands such as:

git init 
git add
git commit
git push
git pull

If you are not so sure about the above-mentioned topics, please refer to my below article.

Okay, let’s jump right onto it.

These are the things we will cover right now:

git rm 
git commit
git diff
git log
git blame
git reflog
git checkout
git reset
git revert
git remote
git fetch
git merge
git push
git pull
git branch
git rebase
git clean
git ls
git stash
git cherry-pick
How to exit VIM for git
Change Default editor in git

“Golden git rule — only combine changes from a single topic, in a single commit”

Full forms:

  • -a means --all
  • -f means --force
  • -v means --verbose
  • -p means --prune
  • -m stands for --move.
xkcd

HOW TO GIT CLONE, properly.

To clone a specific branch,

git clone <url> --branch <branch> --single-branch

And if you want to download only a specific folder from that branch, you would do:

git clone <url> --branch <branch> --single-branch <folder>

HOW TO GIT ADD → properly.

git add .
git add -A
git add --all OR git add -a (both are exactly the same)
  • If you are located directly in the working directory, then git add -A and git add . work without the difference.
  • If you are in any subdirectory of the working directory, git add -A will add all files from the entire working directory, and git add . will add files from your current directory.

Note: I recommend using git add -A over git add .

ADD PATCH WISE TO A FILE:

git add -p <fileName>

When to use:

If you have made some changes to a file but for the time being, you only want to add a few changes to the staging area for making the commit, then, patch-wise adding is useful.

Here `-p` stands for `patch`.

When you run the following command on a file (which has some unstaged changes), a vim window opens up and you just need to press `y` for YES and `n` for NO, a step by step process follows, depending upon which all changes you wish to include or ignore for a staging area for the time being.

Now, after you are done with selecting individual patch level code, run

git status

you’ll see that `fileName` is present in the staging area as well as not the staging area. This is fine as only parts of the content of `fileName` will be committed.

HOW TO WRITE MULTILINE GIT COMMIT MESSAGES:

When you are done making changes and adding files to the staging area, type:

git commit

This opens up a vim editor, you can write a detailed git commit message here, 50 characters or so, and can include bullet points as well (or set up a default IDE of your choice).

The first line is for the commit title, if you leave the second line blank, the third line indicates the body of the commit message.
Press Esc and then type `:wq` to save and exit vim.

if it’s a minor commit, then simply use:

git commit -am “your commit message”

How to write good commit messages✓

Write your commit message in the imperative: “Fix bug” and not “Fixed bug” or “Fixes bug.”
This convention matches up with commit messages generated by commands like git merge and git revert.

A commit message should answer three primary questions:

  • Why is this change necessary?
  • How does this commit addresses the issue?
  • What effects does this change have?

To change the commit message of the last commit, use this git command.

git commit —-amend -m “New commit message”

GIT REMOVE ╳

The git rm command is used to remove files from a Git repository. It can be thought of as the inverse of the git add command.

  • git rm can be used to remove files from both the staging index and the working directory.
  • git rm does not remove branches.
git rm file1.txt

To remove a file both from the Git repository and the filesystem, you can use git rm without any parameters (except for the file’s name, of course).

git rm file1.txt --cached

If you only want to remove the file from the repository but keep it on the filesystem, you can add the “--cached flag”.

You can again add the file using git add <fileName>.

git rm Documentation/\*.txt

This example uses a wildcard file glob to remove all *.txt files that are children.

GIT DIFF

Shows modifications not yet staged:

git diff

Show modifications not yet committed:

git diff --staged

If you want to see how much each file has been changed, you can use the below command to see the number of lines changed in each file.

git diff --stat

Show all changes since the last commit:

git diff HEAD

Compares 2 branches (the (..) is actually an operator)

git diff branch1..other-feature-branch

Get the difference between branches:

git diff master --name-only

GIT LOG

Note: press `:q` to quit the log vim terminal editor.

See all commit history. Can also be used for a file with git log -p my_file. Enter q to exit. 📓

git log

Display only recent 3 commits:

git log -3

List recent 4 commit history along with commit message.

git log -n 4

View commit’s by the mentioned author only

git log --author=”John”

Include which files were altered and the relative number of lines that were added or deleted from each of them.

git log --stat

Display the patch representing each commit. This shows the full diff of each commit, which is the most detailed view you can have of your project history.

git log -p

Use one-line output:

git log —-pretty=oneline

Note: Press `:q` to exit the terminal.

This command is a special version of git log intended for creating release announcements. It groups each commit by author and displays the first line of each commit message.

git shortlog

View branches:

git log --pretty=oneline --graph

Search commit messages:

git log — grep=’pattern’ —-pretty=oneline

View file history:

git log —-pretty=oneline —- <file>

Directory History:

git log --pretty=oneline —-all —-<dir>git log —-all —-decorate —-oneline —-graph

See your git history like a graph:

git log —-pretty=format:”%cn committed %h on %cd”

Example: John committed 400e4b7 on Fri Jun 24 12:30:04 2014 -0500.

The %cn, %h and %cd characters in the following command are replaced with the committer name, abbreviated commit hash, and the committer date, respectively.

GIT BLAME

To see who changed what and when in the file, use,

git blame <fileName>
  • The high-level function of git blame is the display of author metadata attached to specific committed lines in a file.
  • This is used to examine specific points of a file’s history and get context as to who the last author was that modified the line.
  • git blame only operates on individual files.
git blame -e README.md

The -e option shows the authors email address instead of username.

GIT REFLOG

It shows you a list of all the things you’ve done to the local repository’s HEAD.

git reflog

It then allows you to use git’s magical time-traveling skills to go back to any point in the past using:

git reset HEAD@{index}

when you run the `git reflog` command, you’ll see a list of logs and also `index` of each, like this `2b7e508`.

To revert back to that commit, just put that index value in the command above.

git reflog <subcommand> <options>

Git maintains a list of checkpoints which can accessed using reflog. You can use reflog to undo merges, recover lost commits or branches and a lot more.

The lost changes are even not shown by `git log`.

GIT CHECKOUT

Switches branch to the previous branch that we had checked out.
(`-` is single hyphen).

git checkout -

To discard all unstaged files everywhere:

git checkout --.
Note: The dot (.) refers to the current working directory

A checkout will have the same effect and restore the latest version of all files from HEAD

git checkout .

To checkout the branch named stuff:

git checkout stuff

To checkout the file named stuff:

git checkout --stuff

Note: git checkout <name> is really meant for branches, but Git syntax is relaxed, and if Git can’t find a branch, then it will look for a file.

GIT REMOTE

List the remote connections you have to other repositories

git remote

Same as the above command, but include the URL of each connection

git remote -v

Create a new connection to a remote repository. After adding a remote, you’ll be able to use <name> as a convenient shortcut for <url> in other Git commands

git remote add <name> <repository_url>

Remove the connection to the remote repository called <name>

git remote rm <name>

Rename a remote connection from <old-name> to <new-name>.

git remote rename <old-name> <new-name>

Output will contain a list of branches associated with the remote and also the endpoints attached for fetching and pushing.

git remote show upstream

GIT FETCH

The git fetch command downloads commits, files, and refs from a remote repository into your local repo.

Git isolates fetched content from existing local content; it has absolutely no effect on your local development work.

Fetched content has to be explicitly checked out using the git checkout command.

It will download the remote content but not update your local repo’s working state, leaving your current work intact.

Fetch all of the branches from the repository:

git fetch <remote>

Same as the above command, but only fetch the specified branch.

git fetch <remote> <branch>

A power move which fetches all registered remotes and their branches:

git fetch — all

The — dry-run option will perform a demo run of the command. It will output examples of actions it will take during the fetch but not apply them.

git fetch --dry-run

The below 3 steps is equivalent to a simple `git pull origin main`.

git fetch origin
git checkout main
git merge origin/main

Publishing local contributions to the central repository

The following example describes one of the standard methods for publishing local contributions to the central repository

git checkout main
git fetch origin main
git rebase -i origin/main

Here, you can Squash commits, fix up commit messages, etc and finally do a,

git push origin main

HOW TO SQUASH COMMITS

To “squash” in Git means to combine multiple commits into one. You can do this at any point in time (by using Git’s “Interactive Rebase” feature), though it is most often done when merging branches. Please note that there is no such thing as a stand-alone git squash command.

From this:

To this:

git rebase -i HEAD~3

Git will open up your default terminal text editor (most likely vim) and present you with a list of commits:

pick 7f9d4bf Accessibility fix for frontpage bug
pick 3f8e810 Updated screenreader attributes
pick ec48d74 Added comments & updated README
# Rebase 4095f73..ec48d74 onto 4095f73 (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit

There are a couple options here, but we’ll go ahead and mark commits we’d like to meld with it’s successor by changing pick to squash. (If you’re using VIM, type i to enter insert mode)

pick 7f9d4bf Accessibility fix for frontpage bug
squash 3f8e810 Updated screenreader attributes
squash ec48d74 Added comments & updated README

Press ESC then type :wq to save and exit the file (if you are using VIM)

At this point Git will pop up another dialog where you can rename the commit message of the new, larger squashed commit:

# This is a combination of 3 commits
# This is the 1st commit message:
Accessibility fix for frontpage bug
# This is the commit message for #1:
Updated screenreader attributes
# This is the commit message for #2:
Added comments & updated README
# Please enter the commit message for your changes. Lines starting
# with ‘#’ will be ignored, and an empty message aborts the commit

Simply saving this file without making changes will result in a single commit with a commit message that is a concatenation of all 3 messages. If you’d rather rename your new commit entirely, comment out each commit’s message, and write your own. Once you’ve done, save and exit:

GIT PULL

Fetch the specified remote’s copy of the current branch and immediately merge it into the loca.l copy

git pull <remote>

The above is the same as:

git fetch <remote> → git merge origin/<current-branch>

Similar to the default invocation, fetches the remote content but does not create a new merge commit.

git pull —-no-commit <remote>

Gives verbose output during a pull which displays the content being downloaded and the merge details.

git pull --verbose

git pull → git fetch origin HEAD + git merge HEAD

where HEAD is ref pointing to the current branch.

The following example demonstrates how to synchronize with the central repository’s main branch using a rebase:

git checkout main
git pull —-rebase origin

This simply moves your local changes onto the top of what everybody else has already contributed.

GIT BRANCH

Makes a new branch, when you make a new branch, the main branch is at par with your newly created branch

git branch NEW_BRANCH_NAME

Once a new branch has been created, say `develop_branch`, change your working branch from `main` to `develop_branch`

git checkout develop_branch

Once you do checkout to the new branch, the changes made henceforth will not affect the main branch state.

Shows all branches and current branch. A branch represents an independent line of development for your repository

git branch

Only shows current branch:

git branch --show-current

Note: Press `q` if the terminal asks for input after you run the below commands.

Shows all branches, even those of origin repo from where you forked i.e both local and remote branches.

git branch -a

See only remote branches:

git branch -r

To delete a branch:

git branch -d branch_name
git branch -D branch_name
  • The -d option stands for — delete, which would delete the local branch, only if you have already pushed and merged it with your remote branches.
  • The -D option stands for — delete — force, which deletes the branch regardless of its push and merge status, so be careful using this one!

To delete a remote branch you can use the following command:

git push <remote_name> — delete <branch_name>

OR

git push origin :crazy-experiment

This will push a delete signal to the remote origin repository that triggers a delete of the remote crazy-experiment branch.

Spelling mistake on branch name, here’s how to rename them.
Here, -m stands for --move.

git branch -m INCORRECT_BRANCH_NAME CORRECT_BRANCH_NAME

If you have already pushed to the misspelled branch, there are a couple of extra steps required.

git push origin — delete INCORRECT_BRANCH_NAMEgit push origin CORRECT_BRANCH_NAME

Push to a specified branch:

git push <remote> <branch>

Switch to the an already existing branch.

git checkout BRANCH_NAME

To create a new branch and immediately switch to it.

git checkout -b <name>

See remote branches and associated metadata.

git remote show
  • Remote repository means the online hosted repository on Github, BitBucket or GitLab or anywhere else.
  • The word “origin”, in most cases, is the name of the main remote repo to which we push our code.

To pull from some other branch

git pull origin BRANCH

This is what git does when you “git pull origin BRANCH”, a pull is just a fetch followed by a merge:

git fetch origin BRANCH && git merge BRANCH

The below lines are how fetch and merge works if you do not wish to use pull.

git fetch origin other-branchgit merge origin/other-branch

Download the state for all the branches

git fetch

Fetch for just one branch

git fetch <remote> <local><remote> is the name of the remote branch
<local> is the name of the local branch

an example of it is:

git fetch origin main

Compare code between two branches

git diff branch1 branch2

Unstage a File

git reset HEAD <file>

Unstages Everything

git reset HEAD

Discard changes to a file

git checkout — <file>
git checkout <commit_ID> fileName.txt

to revert back to the stage of fileName.txt of how it was when that <commit_ID> was being made. These are staged changes.

to get to how the fileName.txt was before reverting back, do

git reset HEAD
git restore fileName.txt

Now the file is how it was before reverting.

git rebase --abort

To abort and get back to the state before “git rebase”, run this.

A way to solve the problem of “This branch is 2 commits ahead and 2 commits behind” issue, is to create a new branch, make it up to date with the original repo where you wish to make a PR, and then make changes there and push it.

git push <repo name> <branch name>

basic syntax of pushing

git push origin <newBranch>

if you wish to push the changes to remote repository in a separate branch <newBranch>

-f and — force are both the same flag.

Push to a Specific Remote Repository and All Branches in it

git push — all <REMOTE-NAME>

REMOTE-NAME is the name of the remote repository to which you want to push the changes to. E.g — origin

Do ‘git remote show’ to see all remote branch names that are present

— all is the flag that signals that you want to push all branches to the remote repository

git fetch origin <that other separate branch>

if there exist a separate branch in remote repository and not in your local setup, do this. A new branch will be created in your local setup.

Run `git branch` to see.

git remote show origin

This command displays all the remotes associated with “origin”. This is the main remote attached to our repo.

Merge a branch with main branch (fast-forward merge)

Let’s say you have 2 branches, `main` and `deploy`. The deploy branch is ahead of main and now you wish to merge both into main branch. Run the following commands in order.

git status

to check if you any unstaged changes, make sure you commit your changes

git checkout main

switch to the main branch.

git merge future-plans

Merge changes from the deploy branch into the main branch.

git branch -d deploy

delete the deploy branch if you wish to.

It’s important to remember the following:

  1. The active branch matters. If you want to merge main into deploy, you want to have deploy checked out (active). The same is true if you want to merge deploy into main you need to have main checked out.
  2. To see what branch is active at any time use git branch and the active branch will have an asterisk or use git status and it will tell you want branch you are on and if there are pending local changes.
git fetch && git checkout test-2

use &&. to run 2 git commands together.

git revert

An ‘undo’ command, though not a traditional undo operation. Instead of removing the commit, it figures out how to invert the changes in the commit, then appends a new commit with the inverse content. This prevents Git from losing history, which is important for the integrity of your revision history and for reliable collaboration.

git reset

A versatile git command undoing changes.

if you have added 2 files (fileA.txt and fileB.txt) to staging area (but not commited them), and you want to commit them separately, use

git reset fileA.txt

to unstage fileA, now you are free to commit fileB.txt

git commit -m “Make some changes to fileB.txt”

and then,

git add fileA.txt
git commit -m “Edit fileA.txt”
git reset — hard HEAD~2

perform this hard reset if you wish to delete both the 2 commit recently made. That’s sad.

The `git reset HEAD~2` command moves the current branch backward by two commits

git checkout branchA
git rebase branchB

What will happen is that branchA will look like it was branched from branchB. (copy changes from another branch). OR, you have merged branchB into branchA. (git rebase works a bit similar to git merge). It rewrites commit history by creating new commits, use it carefully and never use it on remote code.

The advance is that it keeps git commit history a bit cleaner than git merge.

Undo git rebase with git reflog.

git add .
git commit — amend — no-edit

adds changes made in the last commit itself, no new commit is formed.

--no-edit means that the commit message does not change (no vim window will open for you to type in commit message)

git commit — amend

Add your staged changes to the most recently made commit. It lets you combine staged changes with the previous commit instead of creating an entirely new commit.

If nothing is staged, this command just allows you to edit the most recent commit message, this will open up a vim window to type in commit message.

Note: Don’t amend public / remote commits.

How to exit VIM

Note: Sometimes you are required to press escape key to be able to type these commands.

Hit the Esc key to enter “Normal mode”. Then you can type : to enter “Command-line mode”. A colon (:) will appear at the bottom of the screen and you can type in one of the following commands. To execute a command, press the Enter key.

  • :q to quit (short for :quit)
  • :q! to quit without saving (short for :quit!)
  • :wq to write and quit
  • :wq! to write and quit even if file has only read permission (if file does not have write permission: force write)
  • :x to write and quit (similar to :wq, but only write if there are changes)
  • :exit to write and exit (same as :x)
  • :qa to quit all (short for :quitall)
  • :cq to quit without saving and make Vim return non-zero error (i.e. exit with error)

Change Default Editor

To avoid Vim altogether, you can change your default editor in Git. Here are docs with the commands for common editors. Here’s the command to change the default to Atom:

git config — global core.editor “atom — wait”

and if you prefer Visual Studio Code:

git config — global core.editor “code — wait”

CLEANING IN GIT

git log — follow — <filename>

Show all commits where a particular file was changed

git restore .

revert the changes to your working copy use

git reset

remove all unpushed commits to master use

Remove file from a commit

git reset — soft HEAD^

This will bring the committed files to the staging area and then we can specify exactly which file to remove

git reset HEAD <filename>git revert <commit>

revert a change by a commit

git clean -f

remove untracked files

git clean -fd

remove untracked files or directories

git clean -igit clean -ndx

shows what files and directories will be deleted without actually removing them.

git clean -fdx

removes untracked files and

git clean -xf

Use,

The -n flag is for a dry run where nothing is deleted.Use the -f flag to actually remove the files.Use the -d flag to remove untracked directories.Use the -x flag for force removal of “ignored” files.Use the -i flag for interactive mode.

Whenever you do a commit in Git, the commit has an author name and author email tied to it, use

git config user.email “your email id”

to change email address for a certain project.

Every time you pull the code from the remote repository to the local repository a new merge commit is created in your local repository. This means that your local commit history is going to have a lot of merge commits which can make things look confusing to the reviewer.

How do you make the commit history look neater?

This is where rebase comes to the rescue.

git checkout feature (this is your branch, to which you want to copy things without creating a lot of merge commits)

git rebase release (this is the actual remote branch from which you are fetching)

Rebasing tries to add each commit, one by one, and checks for conflicts.

Use rebase when you are updating your local code repository with the latest code from the remote repository. Use merge when you are dealing with pull requests to merge the Feature branch back with the Release or Master branch.

Always use rebase only for the local repository, not on remote repository.

If there is a conflict rebasing, Git will notify you, and you will have to resolve the conflict manually. After the conflict is resolved use the following commands to continue rebasing.

git add fixedfile
git rebase — continue

WANT TO GO ONE COMMIT BACK

git loggit checkout c3d88eaa1aa4e4d5f

the above `c3d88eaa1aa4e4d5f` is a random hash, use the hash of the last commit (using git log) and perform the checkout.

git log — oneline

use this for a simplified log message

Ever wanted to clean-up all those local branches that have been merged into master and removed from remote? Just use this simple command:

git fetch — prune

or,

git fetch -p
git rebase -i HEAD~4

You can use rebase to combine all of those last 4 commits into a single, concise commit.

This above command will open up a vim terminal with a message similar to this:

pick 130deo9 oldest commit message
pick 4209fei second oldest commit message
pick 4390gne third oldest commit message
pick bmo0dne newest commit message

You need to press “a” or “i” to be able to edit the text, and to save and exit, you need to type the escape key followed by :wq. wp = write quit

pick 130deo9 oldest commit message
fixup 4209fei second oldest commit message
fixup 4390gne third oldest commit message
fixup bmo0dne newest commit message

This will merge all of your commits into the commit with the message “oldest commit message”.

git pull — rebase — autostash

to pull in the changes your colleague pushed to the remote repository and rebase your commits on top to form a proper update structure

git branch — merged

It provides you with a list of merged branches.

git reset /assets/img/misty-and-pepper.jpg

to remove a file that was added to git (but not commited)

git reset — soft HEAD~1
git reset /assets/img/misty-and-pepper.jpg
git rm /assets/img/misty-and-pepper.jpg
git commit

If you did commit the changes with an unnecessary file(an image in this case), this will undo the commit, remove the image, then add a new commit in its place.

1. Git stores the content of your files in objects called “blobs”

2. Your folders turn into objects called “trees’ containing other “trees’ (subfolders) and ‘blobs’

3. A commit is a type of object containing a “tree’. Once created, objects cannot change.

That is basically it. 99% of your Git work is just creating those objects and manipulating pointers that reference them.

If you’re using GitHub and you’re pushing code to a GitHub repo that’s stored online, you’re using a remote repo. The default name (also known as an alias) for that remote repo is origin. If you’ve copied a project from Github, it already has an origin. You can view that origin with the command git remote -v, which will list the URL of the remote repo.

TO UNDO THINGS

  1. git reset
  2. git checkout
  3. git revert
git reset — hard HEAD

Discard staged and unstaged changes since the most recent commit.

git checkout my_commit

Discard unstaged changes since my_commit.

HEAD is often used for my_commit to discard changes to your local working directory since the most recent commit.

git revert my_commit

Undo the effects of changes in my_commit. revert makes a new commit when it undoes the changes.

revert is safe for collaborative projects because it doesn’t overwrite history that other users’ branches might depend upon.

Debugging using git bisect

Merge the master branch into the feature branch using the checkout and merge commands.

git checkout featuregit merge master

(or)

git merge master feature

This will create a new “Merge commit” in the feature branch that holds the history of both branches.

  • git revert is the best tool for undoing shared public changes
  • git reset is best used for undoing local private changes
git revert HEAD

go back one step back in commit history state of the project.

The flag “-e OR — edit” — to edit the commit message to revert changes.

The flag “- -no-edit” — won’t open any editor.

The flag “-n OR — no-commit” — Passing this option will prevent git revert from creating a new commit that inverses the target commit. Instead of creating the new commit this option will add the inverse changes to the Staging Index and Working Directory.

RESETTING VS REVERTING

It’s important to understand that git revert undoes a single commit — it does not “revert” back to the previous state of a project by removing all subsequent commits. In Git, this is actually called a reset, not a revert.

Reverting has two important advantages over resetting. First, it doesn’t change the project history, which makes it a “safe” operation for commits that have already been published to a shared repository.

If git revert is a “safe” way to undo changes, you can think of git reset as the dangerous method. There is a real risk of losing work with git reset. Git reset will never delete a commit, however, commits can become ‘orphaned’ which means there is no direct path from a ref to access them. These orphaned commits can usually be found and restored using git reflog.

Git will permanently delete any orphaned commits after it runs the internal garbage collector. By default, Git is configured to run the garbage collector every 30 days.

git reset HEAD~2

moves back 2 commits from the current branch, and those 2 commits will be deleted when git performs its garbage collection.

git revert HEAD~2

moves back 2 commits from the current branch, and those 2 commits will not be deleted, it just creates a 3rd commit on top of it.

git revert should be used to undo changes on a public branch, and git reset should be reserved for undoing changes on a private branch.

git checkout HEAD foo.py has the effect of discarding unstaged changes to foo.py

git ls-files -s

This command is essentially a debug utility for inspecting the state of the Staging Index tree

MERGE 2 BRANCHES

Suppose there are 2 branches, deploy and master.

Deploy branch is ahead of master branch and now you wish to merge deploy to master branch.

You current are in deploy branch.

git checkout mastergit merge deploy

The above 2 git commands will merge contents of branch `deploy` to branch `master`.

GIT STASH

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

When to use stash?

You may use stash when you have some uncommited changes and you want to make those very changes/commits in a separate branch.

Now perform the stash operation (provided you have some unstaged and uncommited things)

git stash

>At this point you’re free to make changes, create new commits, switch branches, and perform any other Git operations; then come back and re-apply your stash when you’re ready.

Note that the stash is local to your Git repository; stashes are not transferred to the server when you push.

got stash will remove the files (deleted ones as well as newly created one, as well as modified one), and wait till you perform git apply somewhere.

git stash list

gives list of all stashes, e.g- stash@{0}, stash@{1}, etc

type `:q` to exit the window

git stash pop

brings back your last stashed changes, and apply it to your working directory. It also removes that stash from stash list.

git stash apply

Alternatively, you can reapply the changes to your working copy and keep them in your stash with

git stash apply 0

here, `0` is the index of stash that was made.

git stash -u

to stash untracked files which do not get stashed automatically.

git stash show 0

shows which all files are present in stash for that `0` stash ID.

git stash show -p 0

shows the content of stashed files in tree view. `-p` stands for patch.

git stash push -m “stash message”git stash branch NEWBRANCH 0

A new branch gets created and stashed changes in `0` stash ID are ready to be commited in the new branch.

git stash clear

removes every stash present in the `git stash list.`

git stash drop 0

drops only the stash with index id of 0.

Note: by default Git won’t stash changes made to untracked or ignored files.

By default, running git stash will stash:

  • changes that have been added to your index (staged changes)
  • changes made to files that are currently tracked by Git (unstaged changes)

But it will not stash:

  • new files in your working copy that have not yet been staged
  • files that have been ignored

GIT CHERRY PICK

Cherry picking is the act of picking a commit from a branch and applying it to another.

Let us consider 2 branch,

  1. main
  2. deploy

The main branch has 2 commits and the commit messages are:

  1. add fileA
  2. add fileB

The deploy branch has 2 commits and the commit messages are:

  1. add fileC
  2. add fileD

now you wish to have only the single commit “add fileD” to your main branch. How to do that? Using cheery picking.

git checkout deploy

switch to deploy branch

git log

displays those 2 commit logs with commit message and commit hash / ID

copy the commit hash you wish to include, looks somethinglike `a9oshex`

git checkout main

come back to main branch

git cherry-pick a9oshex

voild, you just picked only the specific commit and merged it to your main branch.

Note: use -n flag to avoid making a commit for git cherry-pick command.

git cherry-pick a9oshex hdovuqw

to cherry pick 2 commits and merge them to main branch.

at the end, you have to commit those ’brought-in’ changes.

git commit -m “cherry picking done”

RESOLVE MERGE CONFLICTS

<<<<<<HEAD
This section contains the code that you previously had
more lines
more burgers
========
This section contains the code which wants to get merged with the existing code on this file, but causing a merge conflict.
[incoming changes section]
>>>>>>>>

If you panic out and want to stop this merge, without resolving the merge conflict, take a deep breath and type.

git merge — -abort

and hence, safely back from merge conflict hell that you just witnessed.

If you are being brave and want to resolve the merge conflict, congrats, VS Code is here to help you.

Whenever a merge conflict occurs, VS Code provides 4 inbuilt UI buttons, those are

  1. Accept Current Change
  2. Accept Incoming Change
  3. Accept Both Changes
  4. Compare Changes
[look at the above picture to see those clickable buttons]

After you have resolved Merge conflicts, do

git commit -am “resolve conflict”

and you are pretty much done.

GIT BISECT

helps you find bugs in your code.

Imagine you have 10 commits, the feature was working till commit 3 and now you are at commit 10 and there are some bugs.

git bisect start

How this works is that now you have to label, Is the present commit good OR bad?, meaning, if the buggy feature working currently or not.

If currently it’s not working, perform a

git bisect bad

now that you have marked the recent commit as `bad`, you need to tell git What is a good commit?

so go back to git log and find the commit till which the feature was working, take the commit ID and do this.

git bisect good <commit ID>

now git will automatically take you back to previous commits for you to make sure is the feature working now? If No, the proceed for further operation.

mark it as bad

git bisect bad

then, it will checkout another commit (automatically, plus it will display the commit message as well as commit ID it is currently on) and now you have to check if the feature is working or not. If the feature is working correctly, do

git bisect goodgit bisect reset

now, it will create a different branch named `new-bisect`, with a previous commit being checked out.

references

https://medium.com/free-code-camp/how-to-become-a-git-expert-e7c38bf54826

https://www.freecodecamp.org/news/how-to-use-git-efficiently-54320a236369

https://towardsdatascience.com/10-git-commands-you-should-know-df54bea1595c

https://medium.com/free-code-camp/how-not-to-be-afraid-of-git-anymore-fe1da7415286

https://github.com/RichardLitt/knowledge/blob/master/github/amending-a-commit-guide.md

https://medium.com/@patrickporto/4-branching-workflows-for-git-30d0aaee7bf

--

--

Priyansh Khodiyar

I write highly researched technical articles on things I daily learn, sometimes code, and interview people. khodiyarPriyansh@gmail.com. Check my About section.