GIT'Ting Upgraded: Git branches

Β·

10 min read

Previously

  • You learned about Version Control System(VCS), How Git came into existence, and how it's different from other distributed VCSs, stages, and sections of a git initialized repository did some Hands-On practice with git and configured your Git username and password globally so that you don't have to fill them each time when you push or pull the changes

  • If these sound new to you, please check out this GIT'ting Up: Ground Zero blog, this should give you a brief overview of the topics mentioned above

  • Now that you have a 101 in Git and GitHub, let's delve more into it

Now

Git Branches

  • Based on my experiences as an individual contributor to open-source projects, git branches are the way to do it, the changes I made need to be validated before, and then it is available for everyone
  • For an open-source project, folks are contributing to it from different parts of the world and committing to a single/parent branch, so it gets complex to deal with it

  • Everyone might be contributing to various parts of the project, It is the main branch that will be used by people, it's better not to commit right to the main branch because our changes might contain errors

  • it's better to create a new branch and work from there on, and branches in git don't get a whole copy of the project

  • Git branches are lightweight because they are just a pointer to a commit, due to that performing operations are instantaneous like switching between branches, also try out learngitbranching

  • So whenever you make a commit git stores a commit object containing a pointer to the snapshot with the content that you staged

  • Let's see what's a commit object

image.png

Screenshot from 2022-11-26 18-41-59.png image.png

What exactly happens when we stage a file?

1. Computes a checksum for each file
2. Stores the version of the file in a Git(.git) repository (a.k.a blobs)
3. Adds the checksum into the staging area
  • Now for all these staged files git creates a hexadecimal SHA1 HASH, let's call them blobs for now

When you create a commit

  • Git checksums each sub-directory and stores it as a tree object in Git(.git) repository

  • Whenever you make a change Git maps it to the snapshot of that particular blob

image.png

  • Let's make another commit

Screenshot from 2022-11-27 10-26-47.png

  • Now do you think it creates a new copy of the files with a checksum for them since there's a change only in one file, it only makes a snapshot for the blob README.md with a checksum for it, here's what it does com1 -> com2, tree1 -> tree2, blob2 -> blob4

image.png

  • Now let's see how commits are linked to each other with their respective snapshots

image.png

What are branches in Git?

  • Branches are a lightweight pointer allowing you to move to any commit you want to, that's a bit vague, let's understand them with a visual

  • Let's make another commit, at this point we only have a single branch which is main or master you can check that with git branch and use git log to see the commit history

Screenshot from 2022-11-27 12-04-07.png Screenshot from 2022-11-27 12-04-22.png

  • As you can see the main branch is currently pointing to the third commit, now make a new branch using git branch <branch-name>, and now there'll be another pointer to the latest commit with the branch-name you just created

  • Now we have two branches, and how do you what is your working branch, from the below picture you can see the asterisk (*) before the main branch, from the above pictures there's a HEAD pointer to the working branch

image.png Screenshot from 2022-11-27 12-32-00.png

  • If you want your branch other than main to be your working branch use git checkout <branch-name> or git checkout -b <branch-name> to create a new branch and switch to it

Screenshot from 2022-11-27 12-51-35.png Screenshot from 2022-11-27 12-43-24.png image.png

  • Make another commit and the testing will now point to the new commit and the master/main will still point to the commit it was pointing before

Screenshot from 2022-11-27 13-01-04.png image.png

  • Let's verify whether the main is still a commit behind

Screenshot from 2022-11-27 13-05-05.png

  • This proves that Git has reverted all the changes to the snapshot associated with commit-3, and any operations we perform from respective branches they're going to diverge from here onwards, to verify that, make a commit from the main/master branch

Screenshot from 2022-11-27 13-12-32.png image.png

  • A Git branch is a file containing 40 characters SHA1 checksum of the commit it's pointing to, deleting a branch is as simple as creating one using git branch -D <branch-name> to delete it, but you have to switch to another branch before doing it, now you won't cut the branch when you're on it right, Git doesn't allow you to do that though

  • You can also use git switch <branch-name> to switch the branch and to switch to the previous branch use git switch -

Git Branches: Hands-On

  • Create a new GitHub repository with the same name as your local repository, if you don't have one, create the directory and some files and initialize Git, push the changes to the remote repository

image.png

  • currently, you have 3 commits or for sake of understanding, let's assume you've made 3 commits and one working branch and your commit tree should look something like this

Screenshot from 2022-11-28 09-20-55.png image.png

Creating New branch & committing changes

  • Now from here on whenever you want to make any changes, create a branch and then proceed, let's create another directory use git switch -c <branch-name> to create and switch to the branch

  • It's good to keep the branch name more descriptive so that it says why it is created and what it does, currently, all the branches point to the latest commit, let's make a commit from the new branch you created

Screenshot from 2022-11-28 10-28-19.png

  • If you modified the files after switching to another branch and didn't commit them, Git wouldn't allow us to switch to the main branch, but you can switch, you'll figure that out when dealing with git amends and stashing, for now, proceed this way

  • After this, our commit tree should be looking like this, head points to the add-devops-tools branch since it's your working branch, and the contents of both branches would be different

image.png

Committing Changes to Another Branch

  • Let's switch back to the main branch, create and switch to a new branch to modify another file, and commit the changes

Screenshot from 2022-11-28 11-17-32.png

  • Let's take a look at the commit tree

image.png

  • Let's push the changes to the remote repo

Screenshot from 2022-11-28 11-27-32.png

git merge | Merging Commits

  • Apart from the main branch you had two more branches but only one of them was pushed hence only that branch is visible in the remote repo, you can also see the compare & pull request button which will merge the changes, that's one way of doing it

Screenshot from 2022-11-28 11-30-33.png

  • The other way is through the CLI and it'll work because you are the owner of that repository

Screenshot from 2022-11-28 11-40-39.png

  • since the branch is merged, you can delete that branch, click view all branches in the main dropdown button to do that, but the branch would still be there in your local repo, to delete it use git branch -d <branch-name>

  • Check the contents of the remote repo and the other branch which is not pushed, so the changes aren't visible yet, another look at your current commit tree, fast forward in the git merge message means that the branch commit was on a linear path with the main commit, the main pointer will be forwarded to that branch commit

  • HEAD will change accordingly and the branch wouldn't be there since we deleted it

image.png

3-Way Merge

  • Let's make another commit on the other branch which is in our local system and merge it with the main, and push it to the remote repo

Screenshot from 2022-11-28 13-46-07.png Screenshot from 2022-11-28 13-48-57.png

  • Here's how it looks after committing the changes

image.png

  • You want the c5 of the add-devops-tools branch to get merged with c4 of the main branch, and c2 is the common ancestor(commit) for both the branches, previously, while merging c4 with main branch Git used fast-forwarding

  • But here c5 isn't the direct child of c2, Git uses 3-way merge to merge the commits, it creates a new snapshot, and points the commitc6 to that snapshot whose parents are c4 & c5 taking required data from each of them

Screenshot from 2022-11-28 13-58-10.png

  • If an editor opens up after executing git merge <branch-name>, just do ctrl + x, it looks like this

Screenshot from 2022-11-28 13-50-42.png

  • here's how the commit tree looks like after the 3-way merge and you can delete the branch from both local and remote repositories

image.png

Merge Conflicts

  • Let's know how merge conflicts occur, create and switch to that branch, modified a few files, stage, commit and push them

Screenshot from 2022-11-28 14-27-15.png

  • Now switch back to the default branch, and do it again, make changes in the same file you did previously from another branch and push them

Screenshot from 2022-11-28 14-32-47.png Screenshot from 2022-11-28 14-43-53.png

  • delete the branch from the remote repo as well, and click on the new pull request of the test1 branch, it should show this

Screenshot from 2022-11-28 14-44-52.png

  • try merging it from Git-CLI, we get an error because the changes are made on the same file and at the same place, Git cannot decide from which commit it should take changes from the lines from and lines above = sign is already merged, and below = is the change coming at the same place from another branch

Screenshot from 2022-11-28 14-48-45.png

  • Until this is resolved, you can't commit and move forward, so you can choose either version of them or both, just remove the line 6, 10, and 12, for now, we don't want the random gibberish

Screenshot from 2022-11-28 14-54-42.png Screenshot from 2022-11-28 15-02-08.png

  • check the remote repo, the latest commit should be resolved conflicts and there's no need for the test1 branch anymore, go ahead and delete it, since you know how

Screenshot from 2022-11-28 15-04-43.png

Branch Management

  • When you are working on a project, you might create a lot of branches and you can keep deleting them, but whenever you can get confused between branches, finding out the last commit from each branch will help, the command for that is git branch -v

  • You can also look up the merged branches to the branch you are currently in using git branch --merged, in your case you're in the main branch so executing this command will show the branches merged with main which is test1, if you do the same after switching to test1 it won't show any except test1

  • Similarly, you can also check branches that are not merged with the branch you currently in using git branch --no-merged

Deleting a branch that is not merged and has commits

  • To delete a branch that has commits use git branch -D <branch-name>, so create a branch, switch to it, modify a few files, stage them, commit them, switch back to the main use git branch -d <branch-name>

Screenshot from 2022-11-28 16-42-36.png Screenshot from 2022-11-28 16-42-59.png

git log

  • To see the commit history of your git repo use git log, if you want it more detailed use git log --stat, and if you feel it's cluttered for a shorter format of your commit history use git log --pretty=oneline

Conclusion

You have seen what are git branches and their practical usage

AND That's It, for now, Thanks for reading it till the end, Hope you found this helpful and got to learn something from this

Please share your feedback, that will help me a lot

This a blog version of this Git and GitHub Masterclass by Apoorv Goyal

Keep Working Hard and Happy Learning

Β