Git 007 : Learn Advanced GIT topics like a Pro

Varsha VermaVarsha Verma
23 min read

Prerequisites:

Before proceeding with Advanced Git concepts, kindly visit my Git 101: A Beginners Guide for Git, which will clear the Basic to Intermediate concepts and will help you understand the Advance topic with better clarity.

GIT Merge:

Git Merge | Atlassian Git Tutorial

git merge <branchname> -m "Merge Message"

Let's understand this with the help of an example:

  • Suppose Our repo has multiple branches and we have to merge Branch2 to the Master Branch.

  • Then switch to Branch2 and check the content of the File which you want to modify. Here we are modifying File1.

  • Opening the File in Vi editor and adding a few lines of content.

  • Add it to the Staging area and commit it.

  • Checking the logs of the Branch2

  • Now switch to the Master Branch and edit the same file "File1" with different content this time.

  • Commit the File1 and check the logs

  • Now applying git merge in Master Branch for Branch2 i.e.., Branch 2 will be merged with the Master Branch.

  • Checking File 1 for merge conflict and keeping the required changes accordingly.

  • Now File1 will be untracked so we will be committing it like below and check the logs:

Yayy!! Merge completed 🥳

GIT Commands to Solve Merge Conflict

  1.     git diff
    

    This helps to identify the difference between the state's repositories/files.

  2.     git log --merge
    

    This helps to produce the list of commits that are causing the conflict.

  3.     git checkout
    

    This helps to undo the change made to the file or can be used to change the branch.

  4.     git reset --mixed
    

    This command helps to undo changes to the Working Directory/Staging Area.

  5.     git merge --abort
    

    This command helps in exiting the merge process and returning back to the state before the merging began.

For More Information refer:

  • Git documentation: gitmerge

GIT Ignore

  • A gitignore file specifies intentionally untracked files that Git should ignore. Files already tracked by Git were not gets affected.

  • There are mainly two kinds of .gitignorefiles: Local & Global

  • It is placed inside root (/) directory of a Project. You can create a global .gitignore file, and the entries inside the file will b ignored by all of the Git Repositories.

  • While creating a local gitignore file remembers to put a dot at the beginning and make it a normal text file. You can alter this file according to the requirements. Each line should list an additional file/folder or matching Patterns that you want Git to ignore.

Patterns:

  • * is used as a wildcard match

  • / is used to ignore pathnames relative to the .gitignore file

  • # is used to add comments to a .gitignore file

Examples:

# Ignore ALL .log files
*.log

# Ignore all text files
*.txt

# Ignore ALL files in ANY directory named temp
temp/

# Ignore Mac system files
.DS_store

# Ignore node_modules folder
node_modules

# Ignore files related to API keys
.env

# Ignore SASS config files
.sass-cache

To add or change your global .gitignore file:

git config --global core.excludesfile ~/.gitignore_global

This will create the file ~/.gitignore_global. You can edit this file the same way as a local .gitignore file. All of your Git repositories will ignore the files and folders listed in the global .gitignore file.

Untrack Already Committed Files via New Gitignore

To untrack a single file, ie stop tracking the file but not delete it from the system use:

git rm --cached filename

To untrack all the files in .gitignore, First commit the code changes

git rm -r --cached

This will remove any changed file from the Index/Staging Area then add and commit it:

git add .
git commit -m ".gitignore is now working!!!!"

Notes: To undo git rm --cached filename, use git add filename

For More Information refer:

GIT Restore

Git Restore is used to unstage or discard uncommitted local changes in a file.

git restore [--source=commit-hash] [--worktree] [--staged] [--] file
  • --worktree means to make the restore to worktree

  • --staged means make the restore to --staged.

  • specify both --staged and --worktree to make the restore from --source to both the worktree and the staging-area

  • when --source is specified the restore is always from the source

  • when --source is not specified and --staged is given the restore is from the HEAD

  • when neither --source nor --staged are specified then the restore is from staging area to the work tree

Suggestion - Use git restore to bring the files from

  • commit blob to the staging area and/or work tree.

  • staging-area to worktree

Notes: If you have deleted the file and already committed the changes, you need to use the git checkoutcommand to restore the file.

Example:

  • I have created an email script file like below:

  • Now I want to change the mail id to User1@example.com and check the difference from the last commit to the current state:

  • It shows that the Red highlighted part is removed and the Green highlighted part is added recently.

  • But then the requirement was altered and it was confirmed that the mail should be sent to admin instead of User1. And luckily we have not committed the changes yet so, in this scenario we will use git restore to get the script file in the previous state as it was in the last commit.

For More Information refer:

GIT Revert

How to Revert the Last Commit Locally and Remote in Git - Become A Better  Programmer

git revert <hashid>
  • It is a forward-moving undo operation that offers a safe method of undoing changes. We require the commit Id to revert the changes

  • Git Revert is used when we want to take a previous commit and add it as a new commit, keeping the log intact.

  • Instead of deleting or orphaning commits in the commit history, a revert will create a new commit that inverses the changes specified. Git revert is a safer alternative to git reset in regards to losing work.

  • Revert will also generate a hash id, as everything is a commit in git

Example:

  • Suppose you created a script to send an email and initially the requirement was to add email-id as admin@example.com. You worked on it and committed it like below:

  • After some time, they mentioned adding User1@example.com instead of Admin. You made the changes and committed it:

  • After further discussion, the requirement gets concluded that email needs to be sent to admin if the issue arrives not the user1. Here we will be using git revert to revert to the desired commit:

  • If you observe it closely then the git revert also creates a separate commit.

For More Information refer:

GIT Reset

Git Reset - javatpoint

git reset <index/commit number you want to roll back to>

This command is a little more complicated. It does a couple of different things depending on how it is invoked. It modifies the index (the so-called "staging area") Or it changes which commit a branch head is currently pointing at. This command may alter existing history (by changing the commit that a branch references).

  • You were in a detached head state - git reset would move the HEAD to the specified commit hash. Just like git checkout commit-hash

  • You were not in a detached head state - git reset would move the entire (HEAD -> branch) to the specified commit hash. If this resulted in commits that no branch is ahead of then those commits are removed from Git history

git reset also has three options --soft, --mixed, --hard. How should your work tree and Index(staging area) look once you have moved your HEAD to a different commit?

  • --hard - Both the Worktree and the Index match the files in the new commit you moved to. Here file will not come in the staging area after a hard reset (not advisable🙅🏾‍♀️).

  • --mixed (default) - Worktree remains as it was before you ran git reset and Index matches the files in the new commit you moved to.

  • --soft - Worktree and Index both remain as they were before you ran git reset.

    Here file will come to the staging area after a soft reset. So, you need to unstage it so it will not be tracked:

      git status  #To check the files which are in working area
      git restore --staged <Filename>
    

git reset for the most part can be replicated using a combination of git checkout, git branch -D and git restore except that there is no easy way to control the contents of work tree and staging area as well except if you don't use git reset

Suggestion: Have you made a few commits that should not have been made and have not pushed the changes to the public repo? Is it best to just have it as if these commits never existed? Use git reset. If you have pushed the changes to the public repo then as discussed earlier you want to use git revert.

Ex: Git RESET soft is used to roll back changes to previous commits i.e.., The index will be changed and show the previous one but the content will not be rolled back.

Example:

  • Here we have reverted the changes that created logs as well:

  • In order to go back to previous commit and wipeout the undesired commit logs, we will use soft reset

  • If you want to change the content of the file use git reset --hard:

Difference between GIT Revert and GIT Reset

  • While git reset does this by moving the current head of the branch back to the specified commit, thereby changing the commit history, git revert does this by creating a new commit that undoes the changes in the specified commit and so does not change the history.

  • Git revert is a safer alternative to git reset in regards to losing work.

Git Revert - Studytonight

For More Information refer:

GIT Cherry Picking

How To Cherry Pick Git Commits | When & How to use a Git Cherry Pick  Commit? – Junos Notes

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

  • git cherry-pick can be used for undoing changes. For example, when a commit is accidentally made to the wrong branch. You can switch to the correct branch and cherry-pick the commit to where it should belong.

  • It is a powerful command that enables arbitrary Git commits to be picked by reference and appended to the current working HEAD.

git cherry-pick <commitSha/commitID>

Git cherry-pick can also be passed some execution options.

  • Passing the -edit option will cause git to prompt for a commit message before applying the cherry-pick operation
-edit
  • The --no-commit option will execute the cherry pick but instead of making a new commit it will move the contents of the target commit into the working directory of the current branch.
--no-commit
  • The --signoff option will add a 'signoff' signature line to the end of the cherry-pick commit message
--signoff

Choose Wisely when to use GIT Cherry-Pick

  • Git Cherry-Pick is a useful tool but not always a best practice.

  • Cherry Picking can cause duplicate commits.

  • Still today traditional merges are preferred instead of cherry picking.

  • Sometimes a feature branch may go stale and not get merged into main.

  • Sometimes a pull request might get closed without merging. Git never loses those commits and through commands like git log and git reflog they can be found and cherry picked back to life.

Example1:

  • Suppose we added email script where we made few alterations:

  • Later, we want to alter the file so we cherrypicked the commit. But it will abort cherrypicking because the same script file was there previously as well and later we added few lines of code to it. So, Git thinks of it, as if we want to merge it because the content is same for the first few lines. That is why we got merge conflict.

  • Script file will be in the working directory, so we have to alter the requirement and resolve the merge conflict. Post that again add and commit the script file:

Example2:

  • Suppose we cherrypick another file from the main branch.

  • After applying cherry pick, it will automatically open nano editor and show the changes it will make

  • Press Ctrl+X and it will exit the nano editor. If we see logs now then there is a recent commit message similar to the one that we cherrypicked but hash id changed

And you did it again!!!!! 👏🏾👏🏾 Keep going🔥🚀

For More Information refer:

GIT Rebase

Explaining How Git Rebase Works in Layman's Terms 🍕🥑🍖 | Mohammed Asker

  • Rebasing is the process of moving or combining a sequence of commits to a new base commit.

  • Git rebase takes commits from one Git branch and adds them to another. It can be helpful to think of this as a Git “cut-and-paste” action. When you Git rebase, you are essentially deleting commits from one branch and adding them to a different branch.

  • Rebasing is most useful and easily visualized in the context of a feature branching workflow.

  • The Primary reason for Rebasing is to maintain a linear Project history.

  • It is good to rebase your branch before merging it.

  • More detailed view:

Git rebase · Git · Topics · Help · GitLab

#Here’s the syntax for launching a standard Git rebase:
git rebase <base>

#And here’s the syntax for launching an interactive Git rebase:
git rebase --interactive <base>
git rebase <base>Performs the standard rebase
git rebase – interactive <base>Performs the interactive rebase
git rebase -- dThe commit gets discarded from the final combined commit block during playback.
git rebase -- pThis leaves the commit alone, not modifying the content or message, and keeping it as an individual commit in the branches’ history.
git rebase -- xThis executes a command line shell script for each marked commit during playback.
git statusChecks the rebase status.
git rebase -- continueContinue with the changes that you made.
git rebase --skipSkips the changes
git add <project file>Adds your branch to the repository
git commit -m "new commit for <branch name>."Commits the changes.

Know better when to use GIT Rebase:

  • Edit previous commit messages

  • Combine multiple commits into one

  • Delete or revert commits that are no longer necessary

Commands available while rebasing

pick

pick simply means that the commit is included. Rearranging the order of the pick commands changes the order of the commits when the rebase is underway. If you choose not to include a commit, you should delete the entire line.

reword

The reword command is similar to pick, but after you use it, the rebase process will pause and give you a chance to alter the commit message. Any changes made by the commit are not affected.

edit

If you choose to edit a commit, you'll be given the chance to amend the commit, meaning that you can add or change the commit entirely. You can also make more commits before you continue the rebase. This allows you to split a large commit into smaller ones, or, remove erroneous changes made in a commit.

squash

This command lets you combine two or more commits into a single commit. A commit is squashed into the commit above it. Git gives you the chance to write a new commit message describing both changes.

fixup

This is similar to squash, but the commit to be merged has its message discarded. The commit is simply merged into the commit above it, and the earlier commit's message is used to describe both changes.

exec

This lets you run arbitrary shell commands against a commit.

Break (-b)

The break option stops the rebasing at just position. It will continue rebasing later with 'git rebase --continue' command.

Drop (-d)

The drop option is used to remove the commit.

Label (-l)

The label option is used to mark the current head position with a name.

Reset (-t)

The reset option is used to reset head to a label.

Example:

  • We have created a new branch name "Feature" and added a feature.txt file.

  • Added a few lines and committed like below:

  • Now I checkout to the Main branch and applied
git rebase feature

If you are in the main and you applied rebase to Your branch then all the commits of yourbranch will be first synced with the Main and new commits will be added in the Main branch.

Git Merge vs. Rebase

Git Merge and rebase are two different ways which, can be used to merge changes from one branch into another. Git merge can develop a new commit that can integrate the changes from two branches. This new commit has two parent commits, one from each branch. Git rebase, execute the changes from one branch onto another and explore it as though the changes were made directly on that branch.

Git MergeGit Rebase
Merging creates a final commit at merging.Git rebase does not create any commit at rebasing.
It merges all commits as a single commit.It creates a linear track of commits.
It creates a graphical history that might be a bit complex to understand.It creates a linear history that can be easily understood.
It is safe to merge two branches.Git "rebase" deals with the severe operation.
Merging can be performed on both public and private branches.It is the wrong choice to use rebasing on public branches.
Merging integrates the content of the feature branch with the master branch. So, the master branch is changed, and feature branch history remains consistence.Rebasing of the master branch may affect the feature branch.
Merging preserves history.Rebasing rewrites history.
Git merge presents all conflicts at once.Git rebase presents conflicts one by one.

For More Information refer:

GIT Squash

Git Squash - Studytonight

  • "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.

  • Git Squash is a pretty powerful tool inside Git. It allows you to basically pick up a bunch of commits and just squash them together into a big commit.

git mege --squash
git rebase -i HEAD~n

Choose Wisely When to Squash:

  • If you decide to squash before merging, then all of those individual commits from your feature branch will be combined into a single commit. The main commit history, therefore, will only show a single commit for this integration.

  • If you decide AGAINST squashing, all of your individual commits will be preserved as such.

How to Squash Commits in Git via Interactive Rebase:

git rebase -i HEAD~n

In this process, you will grab all the commits with the git rebase command with the i flag and put them together with squash. Apart from squashing, the command also allows you to drop commits, reword commit messages, and add new files.

I have these commits I would like to combine into one:

In this process, you will grab all the commits with the git rebase command with the i flag and put them together with squash. Apart from squashing, the command also allows you to drop commits, reword commit messages, and add new files.

I have these commits I would like to combine into one:

Example:

  • Created Feature2.txt file and added few commits like below:

  • I will squash the latest two commits via interactive rebase, so will use:
git rebase -i HEAD~n

#where n could be the number of lines
example: git rebase -i HEAD~4
  • It will open up nano editor and we have to modify the lines which we want to squash into one.

Press Ctrl+X and give CTRL+Y. comment others Commits and write the one with which you want this merge to reflect into Feature branch's latest commit:

  • Checking git log on feature Branch:

**How to Squash Commits in Git via merge --**Squash:

git merge --squash

You can also combine multiple commits into one when you’re about to merge branches.

This helps clean up the incoming branch of redundant commits. The downside of this approach is that you don’t have much control as you do with rebase. It will simply squash all the commits of that branch into a single.

Example:

  • I have created a staging.txt file and made a few commits in the Staging branch.

  • Now I want to merge this Staging branch with the Main branch, as you could see there is no staging.txt file present yet in the Main branch

  • After applying the below command, i.e.., merge squashing and committing the changes in the Main branch. There will be a staging.txt file added in the Main branch and logs will also be updated
git merge --squash staging && git commit -m "Squashing the staging branch commits"

You really SQUASHED it like a Pro😎.

GIT STASH

Git Stash - javatpoint

  • It temporarily saves/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.

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

  • 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.

Git Stash Save (Saving Stashes with the message):

In Git, the changes can be stashed with a message. To stash a change with a message, run the below command:

git stash save "<Stashing Message>"

Git Stash List (Check the Stored Stashes)

It will show the list of stashes. It will show all the stashes with indexing as stash@{0}: stash@{1}. This is helpful if you have multiple files in Stash and you want to un-stash it to the desired one.

git stash list

Git Stash Changes

We can track the stashes and their changes. To see the changes in the file before stash and after stash operation, run the below command:

git stash show

The above command will show the file that is stashed and changes made on them. Consider the below output:

We can exactly track what changes are made on the file. To display the changed content of the file, perform the below command

git stash show -p
# p is for partial stash

How to Reapply Your Stashed Changes?

  • 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.

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

  • This is useful if you want to apply the same stashed changes to multiple branches.

    Now that you know the basics of stashing, there is one caveat with git stash you need to be aware of: by default Git won't stash changes made to untracked or ignored files.

  • The key difference between git stash pop and apply involves the stash history. When a developer uses the git stash apply command, the most recently saved stash overwrites files in the current working tree but leaves the stash history alone. In contrast, the pop command restores files but then deletes the applied stash. If a developer ever feels the need to use that restored stash again, it will be saved in the local file system.

  • Think of the git stash pop command as a two-step process. It pulls the most recent stash from history, makes the appropriate changes to files in the local workspace and then deletes that entry from the stash history. Once the git stash pop command is successfully invoked, the stash is permanently deleted and can never be accessed again.

  • For more details: Git Stash

Git Stash Apply

You can re-apply the changes that you just stashed by using the git stash command. To apply the commit, use the git stash command, followed by the apply option. It is used as:

git stash apply

The above output restores the last stash. Now, if you will check the status of the repository, it will show the changes that are made to the file.

you can see that the repository is restored to its previous state before stash. It is showing output as "Changes not staged for commit." So you have to add thema nd commit to apply the changes:

But still that Stash is reflecting while listing the stashes:

To delete it from stash list either use git stash drop (This will delete the stash forever)or git stash pop (This will unstash the file and remove the entry in stash list)

In case of more than one stash, you can use "git stash apply" command followed by stash index id to apply the particular commit. It is used as

git stash apply <Stash Index ID>

If we don't specify a stash, Git takes the most recent stash and tries to apply it.

Git Stash Pop (Reapplying Stashed Changes)

Git allows the user to re-apply the previous commits by using the git stash pop command. The popping option removes the changes from stash and applies them to your working file.

The git stash pop command is quite similar to git stash apply. The main difference between both of these commands is stash pop command that deletes the stash from the stack after it is applied.

git stash pop 
git stash pop <Stash Index>

It will re-apply the previous commits to the repository. Consider the below output.

Git Stash Drop (Unstash)

The git stash drop command is used to delete a stash from the queue. Generally, it deletes the most recent stash. Caution should be taken before using the stash drop command, as it is difficult to undo if once applied.

The only way to revert it is if you do not close the terminal after deleting the stash. The stash drop command will be used as:

git stash drop

for deleting a particular Stash from the list then use:

git stash drop <stash id>

Git Stash Clear

The git stash clear command allows deleting all the available stashes at once. To delete all the available stashes that exist in the repository.

git stash clear

Git Stash Branch

If you stashed some work on a particular branch and continue working on that branch. Then, it may create a conflict during merging. So, it is good to stash work on a separate branch.

The git stash branch command allows the user to stash work on a separate branch to avoid conflicts. The syntax for this branch is as follows:

git stash branch <Branch Name>

The above command will create a new branch and transfer the stashed work on that.

Congratulations on your Milestone🏆 You have completed GIT Advanced Topic too like a Pro. Thanks for reading my Blog till the end, I hope you got some knowledge. Here is a BONUS to make you smile #DevOps_Memes:

git init? git fetch? git pull? git push? git wtf? - Internet Grandma | Make  a Meme

If you like my work, Let's connect and collaborate😃. I am available on the below platforms and very much active there:

Linkedinℹ️
GitHub😻
Blogs👩🏾‍💻
Topmate 🏆

If you find the blogs helpful, you can sponsor me too. Letting you know Just in case 😶‍🌫️🤭

6
Subscribe to my newsletter

Read articles from Varsha Verma directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Varsha Verma
Varsha Verma

👋 Hi, I’m @Varsha-Verma 👀 I’m interested in Cloud 🌱 I’m currently learning multi-cloud technologies and Devops 📫 How to reach me www.linkedin.com/in/Varsha-Verma-Cloud-DevOps